Move SQL sugar functions to next.jdbc.sql
Make SQL string builder functions private.
This commit is contained in:
parent
a17054b61a
commit
5019995feb
4 changed files with 102 additions and 105 deletions
|
|
@ -18,9 +18,6 @@
|
||||||
via a schema definition).
|
via a schema definition).
|
||||||
* with-transaction -- execute a series of SQL operations within a transaction.
|
* with-transaction -- execute a series of SQL operations within a transaction.
|
||||||
|
|
||||||
In addition, there are some utility functions that make common operations
|
|
||||||
easier by providing some syntactic sugar over 'execute!'.
|
|
||||||
|
|
||||||
The following options are supported generally:
|
The following options are supported generally:
|
||||||
* :entities -- specify a function used to convert strings to SQL entity names
|
* :entities -- specify a function used to convert strings to SQL entity names
|
||||||
(to turn table and column names into appropriate SQL names -- see the
|
(to turn table and column names into appropriate SQL names -- see the
|
||||||
|
|
@ -42,7 +39,6 @@
|
||||||
[next.jdbc.prepare :as prepare] ; used to extend protocols
|
[next.jdbc.prepare :as prepare] ; used to extend protocols
|
||||||
[next.jdbc.protocols :as p]
|
[next.jdbc.protocols :as p]
|
||||||
[next.jdbc.result-set :as rs]
|
[next.jdbc.result-set :as rs]
|
||||||
[next.jdbc.sql :as sql]
|
|
||||||
[next.jdbc.transaction])) ; used to extend protocols
|
[next.jdbc.transaction])) ; used to extend protocols
|
||||||
|
|
||||||
(set! *warn-on-reflection* true)
|
(set! *warn-on-reflection* true)
|
||||||
|
|
@ -186,89 +182,3 @@
|
||||||
* :rollback-only -- true / false."
|
* :rollback-only -- true / false."
|
||||||
[[sym connectable opts] & body]
|
[[sym connectable opts] & body]
|
||||||
`(transact ~connectable ~opts (fn [~sym] ~@body)))
|
`(transact ~connectable ~opts (fn [~sym] ~@body)))
|
||||||
|
|
||||||
(defn insert!
|
|
||||||
"Syntactic sugar over execute-one! to make inserting hash maps easier.
|
|
||||||
|
|
||||||
Given a connectable object, a table name, and a data hash map, inserts the
|
|
||||||
data as a single row in the database and attempts to return a map of generated
|
|
||||||
keys."
|
|
||||||
([connectable table key-map]
|
|
||||||
(insert! connectable table key-map {}))
|
|
||||||
([connectable table key-map opts]
|
|
||||||
(execute-one! connectable
|
|
||||||
(sql/for-insert table key-map opts)
|
|
||||||
(merge {:return-keys true} opts))))
|
|
||||||
|
|
||||||
(defn insert-multi!
|
|
||||||
"Syntactic sugar over execute! to make inserting columns/rows easier.
|
|
||||||
|
|
||||||
Given a connectable object, a table name, a sequence of column names, and
|
|
||||||
a vector of rows of data (vectors of column values), inserts the data as
|
|
||||||
multiple rows in the database and attempts to return a vector of maps of
|
|
||||||
generated keys."
|
|
||||||
([connectable table cols rows]
|
|
||||||
(insert-multi! connectable table cols rows {}))
|
|
||||||
([connectable table cols rows opts]
|
|
||||||
(execute! connectable
|
|
||||||
(sql/for-insert-multi table cols rows opts)
|
|
||||||
(merge {:return-keys true} opts))))
|
|
||||||
|
|
||||||
(defn query
|
|
||||||
"Syntactic sugar over execute! to provide a query alias.
|
|
||||||
|
|
||||||
Given a connectable object, and a vector of SQL and its parameters,
|
|
||||||
returns a vector of hash maps of rows that match."
|
|
||||||
([connectable sql-params]
|
|
||||||
(query connectable sql-params {}))
|
|
||||||
([connectable sql-params opts]
|
|
||||||
(execute! connectable sql-params opts)))
|
|
||||||
|
|
||||||
(defn find-by-keys
|
|
||||||
"Syntactic sugar over execute! to make certain common queries easier.
|
|
||||||
|
|
||||||
Given a connectable object, a table name, and a hash map of columns and
|
|
||||||
their values, returns a vector of hash maps of rows that match."
|
|
||||||
([connectable table key-map]
|
|
||||||
(find-by-keys connectable table key-map {}))
|
|
||||||
([connectable table key-map opts]
|
|
||||||
(execute! connectable (sql/for-query table key-map opts) opts)))
|
|
||||||
|
|
||||||
(defn get-by-id
|
|
||||||
"Syntactic sugar over execute-one! to make certain common queries easier.
|
|
||||||
|
|
||||||
Given a connectable object, a table name, and a primary key value, returns
|
|
||||||
a hash map of the first row that matches.
|
|
||||||
|
|
||||||
By default, the primary key is assumed to be 'id' but that can be overridden
|
|
||||||
in the five-argument call."
|
|
||||||
([connectable table pk]
|
|
||||||
(get-by-id connectable table pk :id {}))
|
|
||||||
([connectable table pk opts]
|
|
||||||
(get-by-id connectable table pk :id opts))
|
|
||||||
([connectable table pk pk-name opts]
|
|
||||||
(execute-one! connectable (sql/for-query table {pk-name pk} opts) opts)))
|
|
||||||
|
|
||||||
(defn update!
|
|
||||||
"Syntactic sugar over execute-one! to make certain common updates easier.
|
|
||||||
|
|
||||||
Given a connectable object, a table name, a hash map of columns and values
|
|
||||||
to set, and either a hash map of columns and values to search on or a vector
|
|
||||||
of a SQL where clause and parameters, perform an update on the table."
|
|
||||||
([connectable table key-map where-params]
|
|
||||||
(update! connectable table key-map where-params {}))
|
|
||||||
([connectable table key-map where-params opts]
|
|
||||||
(execute-one! connectable
|
|
||||||
(sql/for-update table key-map where-params opts)
|
|
||||||
opts)))
|
|
||||||
|
|
||||||
(defn delete!
|
|
||||||
"Syntactic sugar over execute-one! to make certain common deletes easier.
|
|
||||||
|
|
||||||
Given a connectable object, a table name, and either a hash map of columns
|
|
||||||
and values to search on or a vector of a SQL where clause and parameters,
|
|
||||||
perform a delete on the table."
|
|
||||||
([connectable table where-params]
|
|
||||||
(delete! connectable table where-params {}))
|
|
||||||
([connectable table where-params opts]
|
|
||||||
(execute-one! connectable (sql/for-delete table where-params opts) opts)))
|
|
||||||
|
|
|
||||||
|
|
@ -390,8 +390,8 @@
|
||||||
(try
|
(try
|
||||||
(let [entity-fn (:entities opts identity)
|
(let [entity-fn (:entities opts identity)
|
||||||
exec-fn! (if (= :many cardinality)
|
exec-fn! (if (= :many cardinality)
|
||||||
execute!
|
p/-execute-all
|
||||||
execute-one!)]
|
p/-execute-one)]
|
||||||
(exec-fn! connectable
|
(exec-fn! connectable
|
||||||
[(str "SELECT * FROM "
|
[(str "SELECT * FROM "
|
||||||
(entity-fn (name table))
|
(entity-fn (name table))
|
||||||
|
|
@ -399,7 +399,6 @@
|
||||||
(entity-fn (name fk))
|
(entity-fn (name fk))
|
||||||
" = ?")
|
" = ?")
|
||||||
v]
|
v]
|
||||||
#(datafiable-row % connectable opts)
|
|
||||||
opts))
|
opts))
|
||||||
(catch Exception _
|
(catch Exception _
|
||||||
;; assume an exception means we just cannot
|
;; assume an exception means we just cannot
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,18 @@
|
||||||
;; copyright (c) 2019 Sean Corfield, all rights reserved
|
;; copyright (c) 2019 Sean Corfield, all rights reserved
|
||||||
|
|
||||||
(ns next.jdbc.sql
|
(ns next.jdbc.sql
|
||||||
"Utilities to construct SQL strings (and lists of parameters) for
|
"Some utility functions that make common operations easier by
|
||||||
various types of SQL statements.
|
providing some syntactic sugar over 'execute!'/'execute-one!'.
|
||||||
|
|
||||||
This is intended to provide a minimal level of parity with clojure.java.jdbc
|
This is intended to provide a minimal level of parity with clojure.java.jdbc
|
||||||
(insert!, update!, delete!, etc). For anything more complex, use a library
|
(insert!, update!, delete!, etc). For anything more complex, use a library
|
||||||
like HoneySQL https://github.com/jkk/honeysql to generate SQL + parameters.
|
like HoneySQL https://github.com/jkk/honeysql to generate SQL + parameters.
|
||||||
|
|
||||||
This is primarily intended to be an implementation detail."
|
This is primarily intended to be an implementation detail."
|
||||||
(:require [clojure.string :as str]))
|
(:require [clojure.string :as str]
|
||||||
|
[next.jdbc :refer [execute! execute-one!]]))
|
||||||
|
|
||||||
(defn by-keys
|
(defn- by-keys
|
||||||
"Given a hash map of column names and values and a clause type (:set, :where),
|
"Given a hash map of column names and values and a clause type (:set, :where),
|
||||||
return a vector of a SQL clause and its parameters.
|
return a vector of a SQL clause and its parameters.
|
||||||
|
|
||||||
|
|
@ -29,7 +30,7 @@
|
||||||
(str/join (if (= :where clause) " AND " ", ") where))]
|
(str/join (if (= :where clause) " AND " ", ") where))]
|
||||||
params)))
|
params)))
|
||||||
|
|
||||||
(defn as-keys
|
(defn- as-keys
|
||||||
"Given a hash map of column names and values, return a string of all the
|
"Given a hash map of column names and values, return a string of all the
|
||||||
column names.
|
column names.
|
||||||
|
|
||||||
|
|
@ -37,13 +38,13 @@
|
||||||
[key-map opts]
|
[key-map opts]
|
||||||
(str/join ", " (map (comp (:entities opts identity) name) (keys key-map))))
|
(str/join ", " (map (comp (:entities opts identity) name) (keys key-map))))
|
||||||
|
|
||||||
(defn as-?
|
(defn- as-?
|
||||||
"Given a hash map of column names and values, or a vector of column names,
|
"Given a hash map of column names and values, or a vector of column names,
|
||||||
return a string of ? placeholders for them."
|
return a string of ? placeholders for them."
|
||||||
[key-map opts]
|
[key-map opts]
|
||||||
(str/join ", " (repeat (count key-map) "?")))
|
(str/join ", " (repeat (count key-map) "?")))
|
||||||
|
|
||||||
(defn for-query
|
(defn- for-query
|
||||||
"Given a table name and either a hash map of column names and values or a
|
"Given a table name and either a hash map of column names and values or a
|
||||||
vector of SQL (where clause) and its parameters, return a vector of the
|
vector of SQL (where clause) and its parameters, return a vector of the
|
||||||
full SELECT SQL string and its parameters.
|
full SELECT SQL string and its parameters.
|
||||||
|
|
@ -59,7 +60,7 @@
|
||||||
" " (first where-params))]
|
" " (first where-params))]
|
||||||
(rest where-params))))
|
(rest where-params))))
|
||||||
|
|
||||||
(defn for-delete
|
(defn- for-delete
|
||||||
"Given a table name and either a hash map of column names and values or a
|
"Given a table name and either a hash map of column names and values or a
|
||||||
vector of SQL (where clause) and its parameters, return a vector of the
|
vector of SQL (where clause) and its parameters, return a vector of the
|
||||||
full DELETE SQL string and its parameters.
|
full DELETE SQL string and its parameters.
|
||||||
|
|
@ -75,7 +76,7 @@
|
||||||
" " (first where-params))]
|
" " (first where-params))]
|
||||||
(rest where-params))))
|
(rest where-params))))
|
||||||
|
|
||||||
(defn for-update
|
(defn- for-update
|
||||||
"Given a table name, a vector of column names to set and their values, and
|
"Given a table name, a vector of column names to set and their values, and
|
||||||
either a hash map of column names and values or a vector of SQL (where clause)
|
either a hash map of column names and values or a vector of SQL (where clause)
|
||||||
and its parameters, return a vector of the full UPDATE SQL string and its
|
and its parameters, return a vector of the full UPDATE SQL string and its
|
||||||
|
|
@ -95,7 +96,7 @@
|
||||||
(into (rest set-params))
|
(into (rest set-params))
|
||||||
(into (rest where-params)))))
|
(into (rest where-params)))))
|
||||||
|
|
||||||
(defn for-insert
|
(defn- for-insert
|
||||||
"Given a table name and a hash map of column names and their values,
|
"Given a table name and a hash map of column names and their values,
|
||||||
return a vector of the full INSERT SQL string and its parameters.
|
return a vector of the full INSERT SQL string and its parameters.
|
||||||
|
|
||||||
|
|
@ -109,7 +110,7 @@
|
||||||
" VALUES (" places ")")]
|
" VALUES (" places ")")]
|
||||||
(vals key-map))))
|
(vals key-map))))
|
||||||
|
|
||||||
(defn for-insert-multi
|
(defn- for-insert-multi
|
||||||
"Given a table name, a vector of column names, and a vector of row values
|
"Given a table name, a vector of column names, and a vector of row values
|
||||||
(each row is a vector of its values), return a vector of the full INSERT
|
(each row is a vector of its values), return a vector of the full INSERT
|
||||||
SQL string and its parameters.
|
SQL string and its parameters.
|
||||||
|
|
@ -127,6 +128,92 @@
|
||||||
cat
|
cat
|
||||||
rows)))
|
rows)))
|
||||||
|
|
||||||
|
(defn insert!
|
||||||
|
"Syntactic sugar over execute-one! to make inserting hash maps easier.
|
||||||
|
|
||||||
|
Given a connectable object, a table name, and a data hash map, inserts the
|
||||||
|
data as a single row in the database and attempts to return a map of generated
|
||||||
|
keys."
|
||||||
|
([connectable table key-map]
|
||||||
|
(insert! connectable table key-map {}))
|
||||||
|
([connectable table key-map opts]
|
||||||
|
(execute-one! connectable
|
||||||
|
(for-insert table key-map opts)
|
||||||
|
(merge {:return-keys true} opts))))
|
||||||
|
|
||||||
|
(defn insert-multi!
|
||||||
|
"Syntactic sugar over execute! to make inserting columns/rows easier.
|
||||||
|
|
||||||
|
Given a connectable object, a table name, a sequence of column names, and
|
||||||
|
a vector of rows of data (vectors of column values), inserts the data as
|
||||||
|
multiple rows in the database and attempts to return a vector of maps of
|
||||||
|
generated keys."
|
||||||
|
([connectable table cols rows]
|
||||||
|
(insert-multi! connectable table cols rows {}))
|
||||||
|
([connectable table cols rows opts]
|
||||||
|
(execute! connectable
|
||||||
|
(for-insert-multi table cols rows opts)
|
||||||
|
(merge {:return-keys true} opts))))
|
||||||
|
|
||||||
|
(defn query
|
||||||
|
"Syntactic sugar over execute! to provide a query alias.
|
||||||
|
|
||||||
|
Given a connectable object, and a vector of SQL and its parameters,
|
||||||
|
returns a vector of hash maps of rows that match."
|
||||||
|
([connectable sql-params]
|
||||||
|
(query connectable sql-params {}))
|
||||||
|
([connectable sql-params opts]
|
||||||
|
(execute! connectable sql-params opts)))
|
||||||
|
|
||||||
|
(defn find-by-keys
|
||||||
|
"Syntactic sugar over execute! to make certain common queries easier.
|
||||||
|
|
||||||
|
Given a connectable object, a table name, and a hash map of columns and
|
||||||
|
their values, returns a vector of hash maps of rows that match."
|
||||||
|
([connectable table key-map]
|
||||||
|
(find-by-keys connectable table key-map {}))
|
||||||
|
([connectable table key-map opts]
|
||||||
|
(execute! connectable (for-query table key-map opts) opts)))
|
||||||
|
|
||||||
|
(defn get-by-id
|
||||||
|
"Syntactic sugar over execute-one! to make certain common queries easier.
|
||||||
|
|
||||||
|
Given a connectable object, a table name, and a primary key value, returns
|
||||||
|
a hash map of the first row that matches.
|
||||||
|
|
||||||
|
By default, the primary key is assumed to be 'id' but that can be overridden
|
||||||
|
in the five-argument call."
|
||||||
|
([connectable table pk]
|
||||||
|
(get-by-id connectable table pk :id {}))
|
||||||
|
([connectable table pk opts]
|
||||||
|
(get-by-id connectable table pk :id opts))
|
||||||
|
([connectable table pk pk-name opts]
|
||||||
|
(execute-one! connectable (for-query table {pk-name pk} opts) opts)))
|
||||||
|
|
||||||
|
(defn update!
|
||||||
|
"Syntactic sugar over execute-one! to make certain common updates easier.
|
||||||
|
|
||||||
|
Given a connectable object, a table name, a hash map of columns and values
|
||||||
|
to set, and either a hash map of columns and values to search on or a vector
|
||||||
|
of a SQL where clause and parameters, perform an update on the table."
|
||||||
|
([connectable table key-map where-params]
|
||||||
|
(update! connectable table key-map where-params {}))
|
||||||
|
([connectable table key-map where-params opts]
|
||||||
|
(execute-one! connectable
|
||||||
|
(for-update table key-map where-params opts)
|
||||||
|
opts)))
|
||||||
|
|
||||||
|
(defn delete!
|
||||||
|
"Syntactic sugar over execute-one! to make certain common deletes easier.
|
||||||
|
|
||||||
|
Given a connectable object, a table name, and either a hash map of columns
|
||||||
|
and values to search on or a vector of a SQL where clause and parameters,
|
||||||
|
perform a delete on the table."
|
||||||
|
([connectable table where-params]
|
||||||
|
(delete! connectable table where-params {}))
|
||||||
|
([connectable table where-params opts]
|
||||||
|
(execute-one! connectable (for-delete table where-params opts) opts)))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(require '[next.jdbc.quoted :refer [mysql]])
|
(require '[next.jdbc.quoted :refer [mysql]])
|
||||||
(by-keys {:a nil :b 42 :c "s"} :where {})
|
(by-keys {:a nil :b 42 :c "s"} :where {})
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
"Not exactly a test suite -- more a series of examples."
|
"Not exactly a test suite -- more a series of examples."
|
||||||
(:require [clojure.test :refer [deftest is testing]]
|
(:require [clojure.test :refer [deftest is testing]]
|
||||||
[next.jdbc :refer :all]
|
[next.jdbc :refer :all]
|
||||||
[next.jdbc.result-set :as rs]))
|
[next.jdbc.result-set :as rs]
|
||||||
|
[next.jdbc.sql :refer :all]))
|
||||||
|
|
||||||
(deftest a-test
|
(deftest a-test
|
||||||
(testing "FIXME, I fail."
|
(testing "FIXME, I fail."
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue