AsciicastDatabase component
parent
dca6f92e6b
commit
70aedbf12c
@ -0,0 +1,36 @@
|
||||
(ns asciinema.boundary.asciicast-database
|
||||
(:require [clojure.java.jdbc :as jdbc]
|
||||
[clj-time.coerce :as timec]
|
||||
[duct.component.hikaricp :as hikaricp]))
|
||||
|
||||
(defprotocol AsciicastDatabase
|
||||
(get-asciicast-by-id [this id])
|
||||
(get-asciicast-by-token [this token]))
|
||||
|
||||
(extend-protocol clojure.java.jdbc/ISQLValue
|
||||
org.joda.time.DateTime
|
||||
(sql-value [val]
|
||||
(timec/to-sql-time val)))
|
||||
|
||||
(extend-protocol clojure.java.jdbc/IResultSetReadColumn
|
||||
java.sql.Timestamp
|
||||
(result-set-read-column [x _ _]
|
||||
(timec/from-sql-time x)))
|
||||
|
||||
(def q-get-asciicast-by-id "SELECT * FROM asciicasts WHERE id=?")
|
||||
(def q-get-asciicast-by-secret-token "SELECT * FROM asciicasts WHERE secret_token=?")
|
||||
(def q-get-public-asciicast-by-id "SELECT * FROM asciicasts WHERE id=? AND private=FALSE")
|
||||
|
||||
(extend-protocol AsciicastDatabase
|
||||
duct.component.hikaricp.HikariCP
|
||||
|
||||
(get-asciicast-by-id [{db :spec} id]
|
||||
(first (jdbc/query db [q-get-asciicast-by-id id])))
|
||||
|
||||
(get-asciicast-by-token [{db :spec} token]
|
||||
(when-let [query (cond
|
||||
(re-matches #"\d+" token)
|
||||
[q-get-public-asciicast-by-id (Long/parseLong token)]
|
||||
(= (count token) 25)
|
||||
[q-get-asciicast-by-secret-token token])]
|
||||
(first (jdbc/query db query)))))
|
@ -0,0 +1,53 @@
|
||||
(ns asciinema.boundary.asciicast-database-test
|
||||
(:require [clojure.test :refer :all]
|
||||
[clojure.java.jdbc :as jdbc]
|
||||
[clj-time.local :as timel]
|
||||
[com.stuartsierra.component :as component]
|
||||
[asciinema.boundary.asciicast-database :as db]))
|
||||
|
||||
(defmacro with-db-component [component-var & body]
|
||||
`(let [component# (-> (duct.component.hikaricp/hikaricp {:uri "jdbc:postgresql://localhost:15432/asciinema_test?user=vagrant"})
|
||||
component/start)]
|
||||
(try
|
||||
(jdbc/with-db-transaction [db# (:spec component#)]
|
||||
(let [~component-var (assoc component# :spec db#)]
|
||||
(jdbc/db-set-rollback-only! db#)
|
||||
~@body))
|
||||
(finally
|
||||
(component/stop component#)))))
|
||||
|
||||
(defn insert-asciicast
|
||||
([db] (insert-asciicast db {}))
|
||||
([db attrs]
|
||||
(first (jdbc/insert! db :asciicasts (merge {:duration 10.0
|
||||
:terminal_columns 80
|
||||
:terminal_lines 24
|
||||
:created_at (timel/local-now)
|
||||
:updated_at (timel/local-now)
|
||||
:version 1
|
||||
:secret_token "abcdeabcdeabcdeabcdeabcde"}
|
||||
attrs)))))
|
||||
|
||||
(deftest get-asciicast-by-id-test
|
||||
(testing "for existing asciicast"
|
||||
(with-db-component db
|
||||
(let [asciicast (insert-asciicast (:spec db))]
|
||||
(is (map? (db/get-asciicast-by-id db (:id asciicast)))))))
|
||||
(testing "for non-existing asciicast"
|
||||
(with-db-component db
|
||||
(is (nil? (db/get-asciicast-by-id db 1))))))
|
||||
|
||||
(deftest get-asciicast-by-token-test
|
||||
(testing "for existing public asciicast"
|
||||
(with-db-component db
|
||||
(let [asciicast (insert-asciicast (:spec db) {:private false})]
|
||||
(is (map? (db/get-asciicast-by-token db (:secret_token asciicast))))
|
||||
(is (map? (db/get-asciicast-by-token db (-> asciicast :id str)))))))
|
||||
(testing "for existing private asciicast"
|
||||
(with-db-component db
|
||||
(let [asciicast (insert-asciicast (:spec db) {:private true})]
|
||||
(is (map? (db/get-asciicast-by-token db (:secret_token asciicast))))
|
||||
(is (nil? (db/get-asciicast-by-token db (-> asciicast :id str)))))))
|
||||
(testing "for non-existing asciicast"
|
||||
(with-db-component db
|
||||
(is (nil? (db/get-asciicast-by-token db "1"))))))
|
Loading…
Reference in New Issue