Move SQL sugar functions to next.jdbc.sql

Make SQL string builder functions private.
This commit is contained in:
Sean Corfield 2019-04-17 23:56:44 -07:00
parent a17054b61a
commit 5019995feb
4 changed files with 102 additions and 105 deletions

View file

@ -18,9 +18,6 @@
via a schema definition).
* 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:
* :entities -- specify a function used to convert strings to SQL entity names
(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.protocols :as p]
[next.jdbc.result-set :as rs]
[next.jdbc.sql :as sql]
[next.jdbc.transaction])) ; used to extend protocols
(set! *warn-on-reflection* true)
@ -186,89 +182,3 @@
* :rollback-only -- true / false."
[[sym connectable opts] & 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)))

View file

@ -390,8 +390,8 @@
(try
(let [entity-fn (:entities opts identity)
exec-fn! (if (= :many cardinality)
execute!
execute-one!)]
p/-execute-all
p/-execute-one)]
(exec-fn! connectable
[(str "SELECT * FROM "
(entity-fn (name table))
@ -399,7 +399,6 @@
(entity-fn (name fk))
" = ?")
v]
#(datafiable-row % connectable opts)
opts))
(catch Exception _
;; assume an exception means we just cannot

View file

@ -1,17 +1,18 @@
;; copyright (c) 2019 Sean Corfield, all rights reserved
(ns next.jdbc.sql
"Utilities to construct SQL strings (and lists of parameters) for
various types of SQL statements.
"Some utility functions that make common operations easier by
providing some syntactic sugar over 'execute!'/'execute-one!'.
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
like HoneySQL https://github.com/jkk/honeysql to generate SQL + parameters.
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),
return a vector of a SQL clause and its parameters.
@ -29,7 +30,7 @@
(str/join (if (= :where clause) " AND " ", ") where))]
params)))
(defn as-keys
(defn- as-keys
"Given a hash map of column names and values, return a string of all the
column names.
@ -37,13 +38,13 @@
[key-map opts]
(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,
return a string of ? placeholders for them."
[key-map opts]
(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
vector of SQL (where clause) and its parameters, return a vector of the
full SELECT SQL string and its parameters.
@ -59,7 +60,7 @@
" " (first 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
vector of SQL (where clause) and its parameters, return a vector of the
full DELETE SQL string and its parameters.
@ -75,7 +76,7 @@
" " (first 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
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
@ -95,7 +96,7 @@
(into (rest set-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,
return a vector of the full INSERT SQL string and its parameters.
@ -109,7 +110,7 @@
" VALUES (" places ")")]
(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
(each row is a vector of its values), return a vector of the full INSERT
SQL string and its parameters.
@ -127,6 +128,92 @@
cat
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
(require '[next.jdbc.quoted :refer [mysql]])
(by-keys {:a nil :b 42 :c "s"} :where {})

View file

@ -2,7 +2,8 @@
"Not exactly a test suite -- more a series of examples."
(:require [clojure.test :refer [deftest is testing]]
[next.jdbc :refer :all]
[next.jdbc.result-set :as rs]))
[next.jdbc.result-set :as rs]
[next.jdbc.sql :refer :all]))
(deftest a-test
(testing "FIXME, I fail."