@@ -57,16 +57,21 @@ So what's the solution? Keep the SQL as SQL. Have one file with your
5757query:
5858
5959``` sql
60+ -- name: users-by-country
6061SELECT *
6162FROM users
62- WHERE country_code = ?
63+ WHERE country_code = :country
6364```
6465
65- ...and then pull it in and use it as a regular Clojure function:
66+ ...and then read that file to turn it into a regular Clojure function:
6667
6768``` clojure
68- (defquery users-by-country " some/where/users_by_country.sql" )
69- (users-by-country db-spec " GB" )
69+ (defqueries " some/where/users_by_country.sql"
70+ {:connection db-spec})
71+
72+ ; ;; A function with the name `users-by-country` is created. Let's use it:
73+
74+ (users-by-country {:country " GB" })
7075```
7176
7277By keeping the SQL and Clojure separate you get:
@@ -107,9 +112,17 @@ Make sure it's on the classpath. For this example, it's in
107112` src/some/where/ ` . Now we can use it in our Clojure program.
108113
109114``` clojure
110- ; Import the SQL query as a function.
111115(require '[yesql.core :refer [defquery ]])
112- (defquery users-by-country " some/where/users_by_country.sql" )
116+
117+ ; Define a database connection spec. (This is standard clojure.java.jdbc.)
118+ (def db-spec {:classname " org.postgresql.Driver"
119+ :subprotocol " postgresql"
120+ :subname " //localhost:5432/demo"
121+ :user " me" })
122+
123+ ; Import the SQL query as a function.
124+ (defquery users-by-country " some/where/users_by_country.sql"
125+ {:connection db-spec})
113126```
114127
115128Lo! It has automatic, useful docstrings in the REPL:
@@ -119,28 +132,25 @@ Lo! It has automatic, useful docstrings in the REPL:
119132
120133; => -------------------------
121134; => user/users-by-country
122- ; => ([db country_code])
135+ ; => ([{:keys [country_code]}]
136+ ; => [{:keys [country_code]} {:keys [connection]}])
137+ ; =>
123138; => Counts the users in a given country.
124139```
125140
126141Now we can use it:
127142
128143``` clojure
129- ; Define a database connection spec. (This is standard clojure.java.jdbc.)
130- (def db-spec {:classname " org.postgresql.Driver"
131- :subprotocol " postgresql"
132- :subname " //localhost:5432/demo"
133- :user " me" })
134-
135144; Use it standalone. Note that the first argument is the db-spec.
136- (users-by-country db-spec " GB" )
145+ (users-by-country { :country " GB" } )
137146; => ({:count 58})
138147
139148; Use it in a clojure.java.jdbc transaction.
140149(require '[clojure.java.jdbc :as jdbc])
150+
141151(jdbc/with-db-transaction [connection db-spec]
142- {:limeys (users-by-country connection " GB" )
143- :yanks (users-by-country connection " US" )})
152+ {:limeys (users-by-country { :country " GB" } { :connection connection} )
153+ :yanks (users-by-country { :country " US" } { :connection connection} )})
144154```
145155
146156### One File, Many Queries
@@ -166,7 +176,8 @@ Then read the file in like so:
166176
167177``` clojure
168178(require '[yesql.core :refer [defqueries ]])
169- (defqueries " some/where/queryfile.sql" )
179+ (defqueries " some/where/queryfile.sql"
180+ {:connection db-spec})
170181```
171182
172183` defqueries ` returns a sequence of the vars it binds, which can be
@@ -192,8 +203,11 @@ AND age > :min_age
192203And then supply the ` IN ` -list as a vector, like so:
193204
194205``` clojure
195- (defqueries " some/where/queryfile.sql" )
196- (find-users db-spec [1001 1003 1005 ] 18 )
206+ (defqueries " some/where/queryfile.sql"
207+ {:connection db-spec})
208+
209+ (find-users {:id [1001 1003 1005 ]
210+ :maxage 18 })
197211```
198212
199213The query will be automatically expanded to `... IN (1001, 1003, 1005)
@@ -216,7 +230,8 @@ WHERE id = :id
216230```
217231
218232``` clojure
219- (save-person! db-spec " Dave" 1 )
233+ (save-person! {:name " Dave"
234+ :id 1 })
220235; => 1
221236```
222237
@@ -239,7 +254,7 @@ INSERT INTO person ( name ) VALUES ( :name )
239254```
240255
241256``` clojure
242- (create-person<! db-spec " Dave" )
257+ (create-person<! { :name " Dave" } )
243258; => {:name "Dave" :id 5}
244259```
245260
0 commit comments