Last active
August 29, 2015 13:57
-
-
Save bguthrie/9497397 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns persistable.async | |
(:import [persistable.core Persistable]) | |
(:require [persistable.core :as core])) | |
(defn async-persistable [wrapped] | |
(reify Persistable | |
(update [this id values] (future (core/update wrapped id values))) | |
(insert [this values] (future (core/insert wrapped values))) | |
(delete [this query] (future (core/delete wrapped query))) | |
(find-one [this query] (future (core/find-one wrapped query))) | |
(find-all [this query] (future (core/find-all wrapped query))) | |
(count-all [this query] (future (core/count-all wrapped query))))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns persistable.core | |
(:require [clojure.java.jdbc :as sql] | |
[honeysql.core :as honey])) | |
;; Interface | |
;; Presumes nothing about the underlying datastore or the kinds of queries it's expected to perform. | |
(defprotocol Persistable | |
(update [this id values] "Given an id and a map of values, updates the record and returns the updated values.") | |
(insert [this values] "Given a map of values, inserts the record and returns the updated values.") | |
(delete [this query] "Given a query, deletes all records that match it and returns the number affected.") | |
(find-one [this query] "Given a query, returns the first record matching it.") | |
(find-all [this query] "Given a query, returns all records matching it.") | |
(count-all [this query] "Given a query, returns the count of records matching it.")) | |
;; Stuff you can do now that you have an interface. | |
(defn find-by-id [persistable id] | |
(find-one persistable [:= :id id])) | |
(defn reload [persistable values] | |
(find-by-id persistable (:id values))) | |
(defn delete-by-id [persistable id] | |
(delete persistable ["id = ?" id])) | |
(defn exists? [persistable query] | |
(= 0 (count-all persistable query))) | |
(defn new-record? [persistable values] | |
(or (nil? (:id values)) (not (exists? [:= :id (:d values)])))) | |
(defn save [persistable values] | |
(if (new-record? persistable values) | |
(insert persistable values) | |
(update persistable (:id values) values))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns persistable.honey | |
(:import [persistable.core Persistable]) | |
(:require [honeysql.core :as honey])) | |
; Helper to merge Honey queries. | |
(defn- merge-query [base-query where-query] | |
(merge base-query (if (vector? where-query) {:where where-query} where-query))) | |
(defn db-persistable | |
([conn table-name] (db-persistable conn table-name identity identity)) | |
([conn table-name ->db <-db] | |
(reify Persistable | |
(update [this id values] | |
(sql/with-connection conn | |
(sql/update-values table-name [:id id] (->db values)))) | |
(insert [this values] | |
(sql/with-connection conn | |
(sql/insert-record table-name (->db values)))) | |
(delete [this query] | |
(sql/with-connection conn | |
(sql/delete-rows table-name query))) | |
(find-one [this query] | |
(sql/with-connection conn | |
(sql/with-query-results res | |
(honey/format (merge-query {:select [:*] :from [table-name] :limit 1} query)) | |
(when-let [record (first res)] (<-db record))))) | |
(find-all [this query] | |
(sql/with-connection conn | |
(sql/with-query-results res | |
(honey/format (merge-query {:select [:*] :from [table-name]} query)) | |
(map <-db (doall res)))))) | |
(count-all [this query] | |
(sql/with-connection conn | |
(sql/with-query-results res | |
(honey/format (merge-query {:select [:%count.*] :from [table-name]} query)) | |
(:count (first res)))))))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns persistable.stub | |
(:import [persistable.core Persistable])) | |
(defn stub-persistable [& stubs] | |
(let [stubs (or (first stubs) {})] | |
(reify Persistable | |
(update [this id values] (or (:update stubs) values)) | |
(insert [this values] (or (:insert stubs) values)) | |
(delete [this query] (or (:delete stubs) 0)) | |
(find-one [this query] (or (:find-one stubs) {})) | |
(find-all [this query] (or (:find-all stubs) [])) | |
(count-all [this query] (or (:count stubs) 0))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment