revise api
This commit is contained in:
parent
f3556016aa
commit
b9f1e17c91
5 changed files with 60 additions and 40 deletions
47
README.md
47
README.md
|
|
@ -7,7 +7,8 @@ SQL as Clojure data structures.
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```clj
|
```clj
|
||||||
(require '[honeysql.core :refer [format-sql sql merge-sql sql-fn sql-raw]])
|
(require '[honeysql.core :as sql :refer [select from where limit merge-select
|
||||||
|
merge-where]])
|
||||||
|
|
||||||
;; Everything is centered around maps representing SQL queries
|
;; Everything is centered around maps representing SQL queries
|
||||||
(def sqlmap {:select [:a :b :c]
|
(def sqlmap {:select [:a :b :c]
|
||||||
|
|
@ -15,43 +16,55 @@ SQL as Clojure data structures.
|
||||||
:where [:= :f.a "baz"]})
|
:where [:= :f.a "baz"]})
|
||||||
|
|
||||||
;; format-sql turns maps into clojure.java.jdbc-compatible, parameterized SQL
|
;; format-sql turns maps into clojure.java.jdbc-compatible, parameterized SQL
|
||||||
(format-sql sqlmap)
|
(sql/format sqlmap)
|
||||||
=> ["SELECT a, b, c FROM foo WHERE (f.a = ?)" ["baz"]]
|
=> ["SELECT a, b, c FROM foo WHERE (f.a = ?)" ["baz"]]
|
||||||
|
|
||||||
;; The sql function is a helper for building query maps
|
;; The sql function is a helper for building query maps
|
||||||
(= sqlmap
|
(= sqlmap
|
||||||
(sql :select [:a :b :c]
|
(sql/sql :select [:a :b :c]
|
||||||
:from :foo
|
:from :foo
|
||||||
:where [:= :f.a "baz"]))
|
:where [:= :f.a "baz"]))
|
||||||
=> true
|
=> true
|
||||||
|
|
||||||
;; Providing a map as the first argument to sql will use that map as a base,
|
;; You can also use clause-specific helper functions, if you prefer. They
|
||||||
;; with the new clauses replacing old ones
|
;; compose together nicely.
|
||||||
(format-sql (sql sqlmap :select :* :limit 10))
|
(= sqlmap
|
||||||
|
(-> (select :a :b :c)
|
||||||
|
(from :foo)
|
||||||
|
(where [:= :f.a "baz"])))
|
||||||
|
=> true
|
||||||
|
|
||||||
|
;; Providing a map as the first argument to sql or clause helper functions will
|
||||||
|
;; use that map as a base, with the new clauses replacing old ones
|
||||||
|
(sql/format (sql/sql sqlmap :select :* :limit 10))
|
||||||
|
=> ["SELECT * FROM foo WHERE (f.a = ?) LIMIT 10" ["baz"]]
|
||||||
|
(sql/format (-> sqlmap (select :*) (limit 10)))
|
||||||
=> ["SELECT * FROM foo WHERE (f.a = ?) LIMIT 10" ["baz"]]
|
=> ["SELECT * FROM foo WHERE (f.a = ?) LIMIT 10" ["baz"]]
|
||||||
|
|
||||||
;; To add to clauses instead of replacing them, use merge-sql
|
;; To add to clauses instead of replacing them, use merge-sql, or merge-select,
|
||||||
(format-sql
|
;; merge-from, etc.
|
||||||
(merge-sql sqlmap :select [:d :e] :where [:> :b 10]))
|
(sql/format
|
||||||
|
(sql/merge-sql sqlmap :select [:d :e] :where [:> :b 10]))
|
||||||
|
=> ["SELECT a, b, c, d, e FROM foo WHERE ((f.a = ?) AND (b > 10))" ["baz"]]
|
||||||
|
(sql/format
|
||||||
|
(-> sqlmap (merge-select :d :e) (merge-where [:> :b 10])))
|
||||||
=> ["SELECT a, b, c, d, e FROM foo WHERE ((f.a = ?) AND (b > 10))" ["baz"]]
|
=> ["SELECT a, b, c, d, e FROM foo WHERE ((f.a = ?) AND (b > 10))" ["baz"]]
|
||||||
|
|
||||||
;; Queries can be nested
|
;; Queries can be nested
|
||||||
(format-sql
|
(sql/format
|
||||||
(sql :select :*
|
(sql/sql :select :*
|
||||||
:from :foo
|
:from :foo
|
||||||
:where [:in :foo.a (sql :select :a
|
:where [:in :foo.a (sql/sql :select :a :from :bar)]))
|
||||||
:from :bar)]))
|
|
||||||
=> ["SELECT * FROM foo WHERE (foo.a IN (SELECT a FROM bar))"]
|
=> ["SELECT * FROM foo WHERE (foo.a IN (SELECT a FROM bar))"]
|
||||||
|
|
||||||
;; There are helper functions and data literals for handling SQL function
|
;; There are helper functions and data literals for handling SQL function
|
||||||
;; calls and raw SQL fragments
|
;; calls and raw SQL fragments
|
||||||
(sql :select [(sql-fn :count :*) (sql-raw "@var := foo.bar")]
|
(sql/sql :select [(sql/call :count :*) (sql/raw "@var := foo.bar")]
|
||||||
:from :foo)
|
:from :foo)
|
||||||
=> {:from (:foo), :select (#sql/fn [:count :*] #sql/raw "@var := foo.bar")}
|
=> {:from (:foo), :select (#sql/call [:count :*] #sql/raw "@var := foo.bar")}
|
||||||
|
|
||||||
(format-sql *1)
|
(sql/format *1)
|
||||||
=> ["SELECT COUNT(*), @var := foo.bar FROM foo"]
|
=> ["SELECT COUNT(*), @var := foo.bar FROM foo"]
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
{sql/fn honeysql.format/read-sql-fn
|
{sql/call honeysql.format/read-sql-call
|
||||||
sql/raw honeysql.format/read-sql-raw}
|
sql/raw honeysql.format/read-sql-raw}
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
(ns honeysql.core
|
(ns honeysql.core
|
||||||
(:refer-clojure :exclude [group-by])
|
(:refer-clojure :exclude [group-by format])
|
||||||
(:require [honeysql.format :as format]))
|
(:require [honeysql.format :as format]
|
||||||
|
[honeysql.util :refer [defalias]]))
|
||||||
|
|
||||||
(def sql-fn format/sql-fn)
|
(defalias call format/call)
|
||||||
(def sql-raw format/sql-raw)
|
(defalias raw format/raw)
|
||||||
(def format-sql format/format-sql)
|
(defalias format format/format)
|
||||||
|
|
||||||
(defn select [& fields]
|
(defn select [& fields]
|
||||||
(let [[m fields] (if (map? (first fields))
|
(let [[m fields] (if (map? (first fields))
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,34 @@
|
||||||
(ns honeysql.format
|
(ns honeysql.format
|
||||||
|
(:refer-clojure :exclude [format])
|
||||||
(:require [clojure.string :as string]))
|
(:require [clojure.string :as string]))
|
||||||
|
|
||||||
;;(set! *warn-on-reflection* true)
|
;;(set! *warn-on-reflection* true)
|
||||||
|
|
||||||
;;;;
|
;;;;
|
||||||
|
|
||||||
(deftype SqlFn [name args])
|
(deftype SqlCall [name args])
|
||||||
|
|
||||||
(defn sql-fn [name & args]
|
(defn call [name & args]
|
||||||
(SqlFn. name args))
|
(SqlCall. name args))
|
||||||
|
|
||||||
(defn read-sql-fn [form]
|
(defn read-sql-call [form]
|
||||||
(apply sql-fn form))
|
(apply call form))
|
||||||
|
|
||||||
(defmethod print-method SqlFn [^SqlFn o ^java.io.Writer w]
|
(defmethod print-method SqlCall [^SqlCall o ^java.io.Writer w]
|
||||||
(.write w (str "#sql/fn " (pr-str (into [(.name o)] (.args o))))))
|
(.write w (str "#sql/call " (pr-str (into [(.name o)] (.args o))))))
|
||||||
|
|
||||||
(defmethod print-dup SqlFn [o w]
|
(defmethod print-dup SqlCall [o w]
|
||||||
(print-method o w))
|
(print-method o w))
|
||||||
|
|
||||||
;;;;
|
;;;;
|
||||||
|
|
||||||
(deftype SqlRaw [s])
|
(deftype SqlRaw [s])
|
||||||
|
|
||||||
(defn sql-raw [s]
|
(defn raw [s]
|
||||||
(SqlRaw. (str s)))
|
(SqlRaw. (str s)))
|
||||||
|
|
||||||
(defn read-sql-raw [form]
|
(defn read-sql-raw [form]
|
||||||
(sql-raw form))
|
(raw form))
|
||||||
|
|
||||||
(defmethod print-method SqlRaw [^SqlRaw o ^java.io.Writer w]
|
(defmethod print-method SqlRaw [^SqlRaw o ^java.io.Writer w]
|
||||||
(.write w (str "#sql/raw " (pr-str (.s o)))))
|
(.write w (str "#sql/raw " (pr-str (.s o)))))
|
||||||
|
|
@ -75,7 +76,7 @@
|
||||||
|
|
||||||
(declare to-sql)
|
(declare to-sql)
|
||||||
|
|
||||||
(defn format-sql [sql-map]
|
(defn format [sql-map]
|
||||||
(binding [*params* (atom [])]
|
(binding [*params* (atom [])]
|
||||||
(let [sql-str (to-sql sql-map)]
|
(let [sql-str (to-sql sql-map)]
|
||||||
(if (seq @*params*)
|
(if (seq @*params*)
|
||||||
|
|
@ -104,7 +105,7 @@
|
||||||
(str (to-sql (first x))
|
(str (to-sql (first x))
|
||||||
" AS "
|
" AS "
|
||||||
(to-sql (second x)))))
|
(to-sql (second x)))))
|
||||||
SqlFn
|
SqlCall
|
||||||
(-to-sql [x] (binding [*fn-context?* true]
|
(-to-sql [x] (binding [*fn-context?* true]
|
||||||
(let [fn-name (name (.name x))
|
(let [fn-name (name (.name x))
|
||||||
fn-name (fn-aliases fn-name fn-name)
|
fn-name (fn-aliases fn-name fn-name)
|
||||||
|
|
@ -152,7 +153,7 @@
|
||||||
(paren-wrap
|
(paren-wrap
|
||||||
(string/join (str " " (string/upper-case op-name) " ")
|
(string/join (str " " (string/upper-case op-name) " ")
|
||||||
(map format-predicate args)))
|
(map format-predicate args)))
|
||||||
(to-sql (apply sql-fn pred)))))))
|
(to-sql (apply call pred)))))))
|
||||||
|
|
||||||
(defmulti format-clause
|
(defmulti format-clause
|
||||||
"Takes a map entry representing a clause and returns an SQL string"
|
"Takes a map entry representing a clause and returns an SQL string"
|
||||||
|
|
|
||||||
5
src/honeysql/util.clj
Normal file
5
src/honeysql/util.clj
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
(ns honeysql.util)
|
||||||
|
|
||||||
|
(defmacro defalias [sym var-sym]
|
||||||
|
`(let [v# (var ~var-sym)]
|
||||||
|
(intern *ns* (with-meta (quote ~sym) (meta v#)) @v#)))
|
||||||
Loading…
Reference in a new issue