diff options
Diffstat (limited to 'src/clojure_sql/dsl.clj')
-rw-r--r-- | src/clojure_sql/dsl.clj | 73 |
1 files changed, 18 insertions, 55 deletions
diff --git a/src/clojure_sql/dsl.clj b/src/clojure_sql/dsl.clj index a31a913..c091d0e 100644 --- a/src/clojure_sql/dsl.clj +++ b/src/clojure_sql/dsl.clj @@ -35,7 +35,7 @@ :query query}))) (defn ^:private same-rename-error [alias renames & [query]] - (throw (ex-info (str "Cannot rename two fields to the same alias: " alias) + (throw (ex-info (str "Cannot rename multiple fields to the same alias: " alias) {:alias alias :renames renames :query query}))) @@ -70,13 +70,16 @@ :right right :type type }))) +(defn ^:private invalid-union [queries] + (throw (ex-info "Cannot union queries with different fields" + {:queries queries}))) + (defn table [arg] - (into (q/->Query) - (let [alias (keyword (gensym (if (u/named? arg) - (name arg) - "table")))] - {:tables {alias arg} - :joins [alias]}))) + (q/map->Query (let [alias (keyword (gensym (if (u/named? arg) + (name arg) + "table")))] + {:tables {alias arg} + :joins [alias]}))) (defn ^:private rename-table [query from to] (q/map->Query (walk/prewalk-replace {from to} (into {} query)))) @@ -98,7 +101,7 @@ (let [table (if (= (count (:tables query)) 1) (-> query :tables first key)) alias-lookup (or (:fields query) {}) - get-real-name #(resolve-fields table alias-lookup %) + get-real-name #(process-expression table alias-lookup %) fields (if (map? fields) fields (zipmap fields fields))] @@ -120,10 +123,6 @@ {} fields)))) (defn ^:private rename-with-map [query field-renames] - {:pre [;; the intersection of the new aliases with the old aliases NOT renamed by this operation - #_(empty? (set/intersection (set (vals field-renames)) - (set/difference (set (keys (:fields query))) - (set (keys field-renames)))))]} (doseq [[field alias] field-renames] (if-not (contains? (:fields query) field) (missing-rename-error field field-renames query))) @@ -161,10 +160,14 @@ (defn ^:private joinable? [query] (and (nil? (:group query)) (nil? (:having query)))) + (defn ^:private convert-to-subquery [query] (-> (table query) (project (keys (:fields query))))) +(defn ^:private remove-sort [query] + (dissoc query :sort)) + (def ^:private valid-join-type? (comp boolean #{:cross :inner :outer :full-outer})) (defn join [left right & {:keys [on type]}] (if (= type :right) @@ -174,10 +177,10 @@ type) left (if (joinable? left) left - (convert-to-subquery left)) + (convert-to-subquery (remove-sort left))) right (if (joinable? right) right - (convert-to-subquery right)) + (convert-to-subquery (remove-sort right))) common-tables (set/intersection (set (keys (:tables left))) (set (keys (:tables right)))) right (reduce (fn [query [alias table]] @@ -187,7 +190,7 @@ merged-tables (merge (:tables left) (:tables right)) common-fields (set/intersection (set (keys (:fields left))) (set (keys (:fields right)))) - merged-fields (merge (:fields left) (:fields right)) + merged-fields (merge (:fields right) (:fields left)) ;; favour the left name for outer joins join-condition (cond (nil? on) (let [implicit (map (fn [field] `(~'= @@ -260,43 +263,3 @@ resolved-expression (process-expression table-name (:fields query) expression) new-having (combine-conjunctions old-having resolved-expression)] (assoc query :having new-having))) - -(-> (table :x) - (project [:x]) - (join (-> (table :y) - (select `(= :id 10))) - :type :right)) - -(let [users (-> (table :users) - (project [:id]))] - (join users users)) - -(-> (table :x) - (project [:x]) - (join (-> (table :y) - #_(select `(= :id 10))) - :type :full-outer)) - -(-> (table :x) - (project [:x]) - (join (-> (table :y) - (project [:x])))) - -#_(-> (table :x) - (project [:x]) - (rename {:y :z})) - -(-> (table :x) - (project [:x]) - (rename {:x :y})) - -(-> (table :people) - (project '{(count *) :count}) - (group [:age]) - (sort [:age]) - (join (-> (table :number-count) - (project [:number :text]) - (sort [:number])) - :on `(= :count :number)) - (project [:text]) - println) |