Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

transform and changing pick! to pick #71

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 25 additions & 18 deletions src/clojureql/core.clj
Expand Up @@ -135,15 +135,12 @@
(modify \"TOP 5\")) ; MSSqls special LIMIT syntax (modify \"TOP 5\")) ; MSSqls special LIMIT syntax
(-> (table :one) distinct)") (-> (table :one) distinct)")


(pick! [this kw] (transform [this fn]
"For queries where you know only a single result will be returned, "Transforms results using fn when deref or with-results is called.
pick calls the keyword on that result. You can supply multiple keywords The pick helper function is implemented using this.
in a collection. Returns nil for no-hits, throws
an exception on multiple hits.

Ex. (-> (table :users) Ex. (-> (table :users)
(select (where (= :id 5))) ; We know this will only match 1 row (select (where (= :id 5)))
(pick :email))") (transform #(map :email %))")


(conj! [this records] (conj! [this records]
"Inserts record(s) into the table "Inserts record(s) into the table
Expand Down Expand Up @@ -194,23 +191,24 @@


(defrecord RTable [cnx tname tcols restriction renames joins (defrecord RTable [cnx tname tcols restriction renames joins
grouped-by pre-scope scope order-by modifiers grouped-by pre-scope scope order-by modifiers
combinations having] combinations having transform]
clojure.lang.IDeref clojure.lang.IDeref
(deref [this] (deref [this]
(apply-on this doall)) (apply-on this doall))


Relation Relation
(apply-on [this f] (apply-on [this f]
(with-cnx cnx (with-cnx cnx
(with-results* (compile this cnx) f))) (with-results* (compile this cnx)
(fn [results]
(f (if transform
(transform results)
results))))))


(pick! [this kw] (transform [this fn]
(let [results @this] (if transform
(if (or (= 1 (count results)) (empty? results)) (assoc this :transform (comp fn transform))
(if (coll? kw) (assoc this :transform fn)))
(map (first results) kw)
(kw (first results)))
(throw (Exception. "Multiple items in resultsetseq, keyword lookup not possible")))))


(select [this clause] (select [this clause]
(if (and (has-aggregate? this) (seq grouped-by)) (if (and (has-aggregate? this) (seq grouped-by))
Expand Down Expand Up @@ -421,7 +419,7 @@
(let [connection-info (if (fn? connection-info) (let [connection-info (if (fn? connection-info)
(connection-info) (connection-info)
connection-info)] connection-info)]
(RTable. connection-info table-name [:*] nil nil nil nil nil nil nil nil nil nil)))) (RTable. connection-info table-name [:*] nil nil nil nil nil nil nil nil nil nil nil))))


(defmacro declare-tables (defmacro declare-tables
"Given a connection info map (or nil) and as list "Given a connection info map (or nil) and as list
Expand All @@ -442,3 +440,12 @@
"Returns true if tinstance is an instnce of RTable" "Returns true if tinstance is an instnce of RTable"
[tinstance] [tinstance]
(instance? clojureql.core.RTable tinstance)) (instance? clojureql.core.RTable tinstance))

(defn pick [table kw]
(transform table
(fn [results]
(if (or (= 1 (count results)) (empty? results))
(if (coll? kw)
(map (first results) kw)
(kw (first results)))
(throw (Exception. "Multiple items in resultsetseq, keyword lookup not possible"))))))
27 changes: 27 additions & 0 deletions test/clojureql/test/integration.clj
Expand Up @@ -183,3 +183,30 @@
[:name :as :dupe]])] [:name :as :dupe]])]
(is (= (map :name @users) (is (= (map :name @users)
(map :dupe @tbl))))) (map :dupe @tbl)))))

(database-test test-transform
(is (= @(transform users #(map (juxt :id :name) %))
'([1 "Lau Jensen"] [2 "Christophe"] [3 "sthuebner"] [4 "Frank"]))))

(database-test test-transform-and-with-results
(with-results [names (transform users #(map :name %))]
(is (= names
'("Lau Jensen" "Christophe" "sthuebner" "Frank")))))

(database-test test-pick
(is (= @(-> (select users (where (= :id 4)))
(pick :name))
"Frank")))

(database-test test-composing-transforms
(is (= @(-> users
(transform #(map (juxt :id :name) %))
(transform first))
[1 "Lau Jensen"])))

(database-test test-transform-with-join
(is (= @(-> users
(transform #(map (juxt :name :wage) %))
(join (transform salary first) ; this transform will be ignored
(where (= :users.id :salary.id))))
'(["Lau Jensen" 100] ["Christophe" 200] ["sthuebner" 300] ["Frank" 400]))))