summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlo Zancanaro <carlo@clearboxsystems.com.au>2013-11-25 01:13:11 +1100
committerCarlo Zancanaro <carlo@clearboxsystems.com.au>2013-11-25 01:13:11 +1100
commit2746c6b08b878190ee7c54a7414bf444c660ff1e (patch)
tree5484cb43cb1da1c8a4ccd4207ac5a6cdf311002d
parenta2aabf7b89da6313c3b47e603a2668d55ad946b7 (diff)
Add a 'distinct' operator - still a bug to fix on renaming
-rw-r--r--src/clojure_sql/compiler.clj4
-rw-r--r--src/clojure_sql/core.clj10
-rw-r--r--src/clojure_sql/dsl.clj11
3 files changed, 22 insertions, 3 deletions
diff --git a/src/clojure_sql/compiler.clj b/src/clojure_sql/compiler.clj
index 50c14af..828da64 100644
--- a/src/clojure_sql/compiler.clj
+++ b/src/clojure_sql/compiler.clj
@@ -225,7 +225,7 @@
(def ^:private set-operations {:union "UNION", :intersect "INTERSECT"})
(defmulti compile-query (fn [db _] db) :default :postgres)
-(defmethod compile-query :postgres [db {:keys [tables fields joins where sort group having take drop set-operation queries]}]
+(defmethod compile-query :postgres [db {:keys [tables fields joins where sort group having take drop distinct set-operation queries]}]
(or (if set-operation
(let [op-str (str ") " (get set-operations set-operation) " (")]
(->> queries
@@ -234,6 +234,8 @@
((p-lift string/join op-str))
$add-parentheses)))
($str (return "SELECT ")
+ (return (if distinct
+ "DISTINCT "))
(compile-fields db fields)
(if tables
($str (return " FROM ")
diff --git a/src/clojure_sql/core.clj b/src/clojure_sql/core.clj
index 415c7f4..613adf6 100644
--- a/src/clojure_sql/core.clj
+++ b/src/clojure_sql/core.clj
@@ -17,7 +17,7 @@
(pull clojure-sql.dsl
table join
- project rename
+ project rename distinct
prefix-names-matching prefix-names as-subobject
select
group
@@ -63,3 +63,11 @@
[query]
(assert (:executor query) "Cannot execute a query without a query executor")
(q/delete! (:executor query) query))
+
+(join (-> (table :x)
+ (project [:a :b]))
+ (-> (table :x)
+ (project [:a :b])
+ distinct))
+
+
diff --git a/src/clojure_sql/dsl.clj b/src/clojure_sql/dsl.clj
index 2a22eea..5c804d2 100644
--- a/src/clojure_sql/dsl.clj
+++ b/src/clojure_sql/dsl.clj
@@ -69,7 +69,6 @@
(throw (ex-info "Cannot union queries with different fields"
{:queries queries})))
-
(defn ^:private rename-table [query from to]
(q/map->Query (walk/prewalk-replace {from to} (into {} query))))
@@ -201,6 +200,7 @@
(nil? (:having query))
(nil? (:take query))
(nil? (:drop query))
+ (nil? (:distinct query))
(nil? (:set-operation query))))
(defn ^:private convert-to-subquery [query]
@@ -214,6 +214,7 @@
(cond (joinable? query) query
(:take query) (convert-to-subquery query)
(:drop query) (convert-to-subquery query)
+ (:distinct query) (convert-to-subquery query)
:else (convert-to-subquery (remove-sort query))))
(defn ^:private rename-all-tables [query]
@@ -393,6 +394,14 @@
(assoc query :drop (+ old-drop n))
(assoc query :drop n))))
+(defn distinct
+ "Return only unique rows from this query."
+ [query]
+ (assoc (if (or (:take query) (:drop query))
+ (convert-to-subquery query)
+ query)
+ :distinct true))
+
(defn ^:private union-compatible? [& queries]
(and (every? (comp seq keys :fields) queries)
(apply = (map (comp set keys :fields) queries))