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
(-> (table :one) distinct)")

(pick! [this kw]
"For queries where you know only a single result will be returned,
pick calls the keyword on that result. You can supply multiple keywords
in a collection. Returns nil for no-hits, throws
an exception on multiple hits.

(transform [this fn]
"Transforms results using fn when deref or with-results is called.
The pick helper function is implemented using this.
Ex. (-> (table :users)
(select (where (= :id 5))) ; We know this will only match 1 row
(pick :email))")
(select (where (= :id 5)))
(transform #(map :email %))")

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

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

Relation
(apply-on [this f]
(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]
(let [results @this]
(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")))))
(transform [this fn]
(if transform
(assoc this :transform (comp fn transform))
(assoc this :transform fn)))

(select [this clause]
(if (and (has-aggregate? this) (seq grouped-by))
Expand Down Expand Up @@ -421,7 +419,7 @@
(let [connection-info (if (fn? 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
"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"
[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]])]
(is (= (map :name @users)
(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]))))