Implement *Database protocols in our db component ns

This commit is contained in:
Marcin Kulik 2017-02-15 12:48:35 +00:00
parent 597c838d35
commit d5addad542
5 changed files with 67 additions and 43 deletions

View File

@ -1,7 +1,7 @@
{:components {:components
{:app #var duct.component.handler/handler-component {:app #var duct.component.handler/handler-component
:http #var asciinema.component.aleph/aleph-server :http #var asciinema.component.aleph/aleph-server
:db #var duct.component.hikaricp/hikaricp :db #var asciinema.component.db/hikaricp
:ragtime #var duct.component.ragtime/ragtime :ragtime #var duct.component.ragtime/ragtime
:file-store #var asciinema.component.s3-file-store/s3-file-store :file-store #var asciinema.component.s3-file-store/s3-file-store
:file-server #var asciinema.component.s3-file-server/s3-file-server} :file-server #var asciinema.component.s3-file-server/s3-file-server}

View File

@ -1,36 +1,5 @@
(ns asciinema.boundary.asciicast-database (ns asciinema.boundary.asciicast-database)
(:require [clojure.java.jdbc :as jdbc]
[clj-time.coerce :as timec]
[duct.component.hikaricp :as hikaricp]))
(defprotocol AsciicastDatabase (defprotocol AsciicastDatabase
(get-asciicast-by-id [this id]) (get-asciicast-by-id [this id])
(get-asciicast-by-token [this token])) (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)))))

View File

@ -0,0 +1,4 @@
(ns asciinema.boundary.user-database)
(defprotocol UserDatabase
(get-user-by-id [this id]))

View File

@ -0,0 +1,50 @@
(ns asciinema.component.db
(:require [asciinema.boundary.asciicast-database :refer :all]
[asciinema.boundary.user-database :refer :all]
[clojure.java.jdbc :as jdbc]
[clj-time.coerce :as timec]
[duct.component.hikaricp :as hikaricp]))
(extend-protocol jdbc/ISQLValue
org.joda.time.DateTime
(sql-value [val]
(timec/to-sql-time val)))
(extend-protocol jdbc/IResultSetReadColumn
java.sql.Timestamp
(result-set-read-column [x _ _]
(timec/from-sql-time x)))
;; AsciicastDatabase
(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)))))
;; UserDatabase
(def q-get-user-by-id "SELECT * FROM users WHERE id=?")
(extend-protocol UserDatabase
duct.component.hikaricp.HikariCP
(get-user-by-id [{db :spec} id]
(first (jdbc/query db [q-get-user-by-id id]))))
;; constructor
(def hikaricp hikaricp/hikaricp)

View File

@ -1,12 +1,13 @@
(ns asciinema.boundary.asciicast-database-test (ns asciinema.component.db-test
(:require [clojure.test :refer :all] (:require [clojure.test :refer :all]
[clojure.java.jdbc :as jdbc] [clojure.java.jdbc :as jdbc]
[clj-time.local :as timel] [clj-time.local :as timel]
[com.stuartsierra.component :as component] [com.stuartsierra.component :as component]
[asciinema.boundary.asciicast-database :as db])) [asciinema.component.db :as db]
[asciinema.boundary.asciicast-database :as adb]))
(defmacro with-db-component [component-var & body] (defmacro with-db-component [component-var & body]
`(let [component# (-> (duct.component.hikaricp/hikaricp {:uri "jdbc:postgresql://localhost:15432/asciinema_test?user=vagrant"}) `(let [component# (-> (db/hikaricp {:uri "jdbc:postgresql://localhost:15432/asciinema_test?user=vagrant"})
component/start)] component/start)]
(try (try
(jdbc/with-db-transaction [db# (:spec component#)] (jdbc/with-db-transaction [db# (:spec component#)]
@ -32,22 +33,22 @@
(testing "for existing asciicast" (testing "for existing asciicast"
(with-db-component db (with-db-component db
(let [asciicast (insert-asciicast (:spec db))] (let [asciicast (insert-asciicast (:spec db))]
(is (map? (db/get-asciicast-by-id db (:id asciicast))))))) (is (map? (adb/get-asciicast-by-id db (:id asciicast)))))))
(testing "for non-existing asciicast" (testing "for non-existing asciicast"
(with-db-component db (with-db-component db
(is (nil? (db/get-asciicast-by-id db 1)))))) (is (nil? (adb/get-asciicast-by-id db 1))))))
(deftest get-asciicast-by-token-test (deftest get-asciicast-by-token-test
(testing "for existing public asciicast" (testing "for existing public asciicast"
(with-db-component db (with-db-component db
(let [asciicast (insert-asciicast (:spec db) {:private false})] (let [asciicast (insert-asciicast (:spec db) {:private false})]
(is (map? (db/get-asciicast-by-token db (:secret_token asciicast)))) (is (map? (adb/get-asciicast-by-token db (:secret_token asciicast))))
(is (map? (db/get-asciicast-by-token db (-> asciicast :id str))))))) (is (map? (adb/get-asciicast-by-token db (-> asciicast :id str)))))))
(testing "for existing private asciicast" (testing "for existing private asciicast"
(with-db-component db (with-db-component db
(let [asciicast (insert-asciicast (:spec db) {:private true})] (let [asciicast (insert-asciicast (:spec db) {:private true})]
(is (map? (db/get-asciicast-by-token db (:secret_token asciicast)))) (is (map? (adb/get-asciicast-by-token db (:secret_token asciicast))))
(is (nil? (db/get-asciicast-by-token db (-> asciicast :id str))))))) (is (nil? (adb/get-asciicast-by-token db (-> asciicast :id str)))))))
(testing "for non-existing asciicast" (testing "for non-existing asciicast"
(with-db-component db (with-db-component db
(is (nil? (db/get-asciicast-by-token db "1")))))) (is (nil? (adb/get-asciicast-by-token db "1"))))))