Skip to content

Commit

Permalink
remove experimental name-fn option
Browse files Browse the repository at this point in the history
Signed-off-by: Sean Corfield <sean@corfield.org>
  • Loading branch information
seancorfield committed Nov 24, 2024
1 parent bcc6ad8 commit ecd950d
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 130 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ Only accretive/fixative changes will be made from now on.
* Address [#288](https://github.com/seancorfield/next-jdbc/issues/288) by adding speculative support for `:dbtype "xtdb"`.
* Fix [#287](https://github.com/seancorfield/next-jdbc/issues/287) by merging user-supplied options over `:return-keys true`.
* Fix [#282](https://github.com/seancorfield/next-jdbc/issues/282) by tracking raw `Connection` objects for active TXs, which relaxes several of the conditions around nested transactions.
* Removed (experimental) `:name-fn` option since the driver for it no longer exists (qualified columns names in XTDB).

* 1.3.955 -- 2024-10-06
* Address [#285](https://github.com/seancorfield/next-jdbc/issues/285) by setting the default Clojure version to the earliest supported (1.10.3) to give a better hint to users.
* Update PostgreSQL **Tips & Tricks** example code to fix possible NPE. PR [#284](https://github.com/seancorfield/next-jdbc/pull/284) from [@ExNexu](https://github.com/ExNexu).
* Address [#283](https://github.com/seancorfield/next-jdbc/issues/283) by adding a note in the documentation, linking to the PostgreSQL bug report about `ANY(array)`.
* Address [#269](https://github.com/seancorfield/next-jdbc/issues/269) by adding `:name-fn` as an option (primarily for the SQL builder functions, but also for result set processing); the default is `clojure.core/name` but you can now use `next.jdbc.sql.builder/qualified-name` to preserve the qualifier.
* ~Address [#269](https://github.com/seancorfield/next-jdbc/issues/269) by adding `:name-fn` as an option (primarily for the SQL builder functions, but also for result set processing); the default is `clojure.core/name` but you can now use `next.jdbc.sql.builder/qualified-name` to preserve the qualifier.~ _[This was remove in 1.3.next since XTDB no longer supports qualified column names]_
* Update testing deps; `docker-compose` => `docker compose`.

* 1.3.939 -- 2024-05-17
Expand Down
2 changes: 0 additions & 2 deletions doc/all-the-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ Except for `query` (which is simply an alias for `execute!`), all the "friendly"

* `:table-fn` -- the quoting function to be used on the string that identifies the table name, if provided; this also applies to assumed table names when `nav`igating schemas,
* `:column-fn` -- the quoting function to be used on any string that identifies a column name, if provided; this also applies to the reducing function context over `plan` and to assumed foreign key column names when `nav`igating schemas.
* `:name-fn` -- may be provided as `next.jdbc.sql.builder/qualified-name` to preserve qualifiers on table and column names; you will need to provide `:table-fn` and/or `:column-fn` as well, in order to quote qualified names properly; new in 1.3.955.

They also support a `:suffix` argument which can be used to specify a SQL string that should be appended to the generated SQL string before executing it, e.g., `:suffix "FOR UPDATE"` or, for an `insert!` call `:suffix "RETURNING *"`.
The latter is particularly useful for databases, such as SQLite these days,
Expand Down Expand Up @@ -71,7 +70,6 @@ Any function that might realize a row or a result set will accept:
* `:label-fn` -- if `:builder-fn` is specified as one of `next.jdbc.result-set`'s `as-modified-*` builders, this option must be present and should specify a string-to-string transformation that will be applied to the column label for each returned column name.
* `:qualifier-fn` -- if `:builder-fn` is specified as one of `next.jdbc.result-set`'s `as-modified-*` builders, this option should specify a string-to-string transformation that will be applied to the table name for each returned column name. It will be called with an empty string if the table name is not available. It can be omitted for the `as-unqualified-modified-*` variants.
* `:column-fn` -- if present, applied to each column name before looking up the column in the `ResultSet` to get that column's value.
* `:name-fn` -- may be provided as `next.jdbc.sql.builder/qualified-name` to preserve qualifiers on keyword used as column names; by default, a keyword like `:foo/bar` is treated as `"bar"` when looking up columns in a `ResultSet`; `:name-fn` allows you to refer to column names that contain `/`, which some databases allow; if both `:name-fn` and `:column-fn` are provided, `:name-fn` is applied first to the keyword (to produce a string) and then `:column-fn` is applied to that; new in 1.3.955.

In addition, `execute!` accepts the `:multi-rs true` option to return multiple result sets -- as a vector of result sets.

Expand Down
5 changes: 2 additions & 3 deletions src/next/jdbc/result_set.clj
Original file line number Diff line number Diff line change
Expand Up @@ -486,10 +486,9 @@
(metadata-preserving) operations on it."
[^ResultSet rs opts]
(let [builder (delay ((get opts :builder-fn as-maps) rs opts))
name-fn (:name-fn opts name)
name-fn (if (contains? opts :column-fn)
(comp (get opts :column-fn) name-fn)
name-fn)]
(comp (get opts :column-fn) name)
name)]
(reify

MapifiedResultSet
Expand Down
51 changes: 17 additions & 34 deletions src/next/jdbc/sql/builder.clj
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,11 @@
;; characters in table and column names when building SQL:
(def ^:private ^:dynamic *allow-suspicious-entities* false)

(defn qualified-name
"Like `clojure.core/name` but preserves the qualifier, if any.
Intended for use with `:name-fn`, instead of the default `name`."
[k]
(cond-> (str k)
(keyword? k)
(subs 1)))

(defn- safe-name
"A wrapper for `name` that throws an exception if the
resulting string looks 'suspicious' as a table or column."
[k name-fn]
(let [entity (name-fn k)
[k]
(let [entity (name k)
suspicious #";"]
(when-not *allow-suspicious-entities*
(when (re-find suspicious entity)
Expand All @@ -57,18 +48,17 @@
as simple aliases, e.g., `[:foo :bar]`, or as expressions with an
alias, e.g., `[\"count(*)\" :total]`."
[cols opts]
(let [col-fn (:column-fn opts identity)
name-fn (:name-fn opts name)]
(let [col-fn (:column-fn opts identity)]
(str/join ", " (map (fn [raw]
(if (vector? raw)
(if (keyword? (first raw))
(str (col-fn (safe-name (first raw) name-fn))
(str (col-fn (safe-name (first raw)))
" AS "
(col-fn (safe-name (second raw) name-fn)))
(col-fn (safe-name (second raw))))
(str (first raw)
" AS "
(col-fn (safe-name (second raw) name-fn))))
(col-fn (safe-name raw name-fn))))
(col-fn (safe-name (second raw)))))
(col-fn (safe-name raw))))
cols))))


Expand All @@ -87,16 +77,15 @@
Applies any `:column-fn` supplied in the options."
[key-map clause opts]
(let [entity-fn (:column-fn opts identity)
name-fn (:name-fn opts name)
[where params] (reduce-kv (fn [[conds params] k v]
(let [e (entity-fn (safe-name k name-fn))]
(let [e (entity-fn (safe-name k))]
(if (and (= :where clause) (nil? v))
[(conj conds (str e " IS NULL")) params]
[(conj conds (str e " = ?")) (conj params v)])))
[[] []]
key-map)]
(assert (seq where) "key-map may not be empty")
(into [(str (str/upper-case (safe-name clause name-fn)) " "
(into [(str (str/upper-case (safe-name clause)) " "
(str/join (if (= :where clause) " AND " ", ") where))]
params)))

Expand All @@ -111,12 +100,11 @@
`DELETE ...` statement."
[table where-params opts]
(let [entity-fn (:table-fn opts identity)
name-fn (:name-fn opts name)
where-params (if (map? where-params)
(by-keys where-params :where opts)
(into [(str "WHERE " (first where-params))]
(rest where-params)))]
(into [(str "DELETE FROM " (entity-fn (safe-name table name-fn))
(into [(str "DELETE FROM " (entity-fn (safe-name table))
" " (first where-params)
(when-let [suffix (:suffix opts)]
(str " " suffix)))]
Expand All @@ -132,11 +120,10 @@
`INSERT ...` statement."
[table key-map opts]
(let [entity-fn (:table-fn opts identity)
name-fn (:name-fn opts name)
params (as-keys key-map opts)
places (as-? key-map opts)]
(assert (seq key-map) "key-map may not be empty")
(into [(str "INSERT INTO " (entity-fn (safe-name table name-fn))
(into [(str "INSERT INTO " (entity-fn (safe-name table))
" (" params ")"
" VALUES (" places ")"
(when-let [suffix (:suffix opts)]
Expand All @@ -163,11 +150,10 @@
(assert (seq cols) "cols may not be empty")
(assert (seq rows) "rows may not be empty")
(let [table-fn (:table-fn opts identity)
name-fn (:name-fn opts name)
batch? (:batch opts)
params (as-cols cols opts)
places (as-? (first rows) opts)]
(into [(str "INSERT INTO " (table-fn (safe-name table name-fn))
(into [(str "INSERT INTO " (table-fn (safe-name table))
" (" params ")"
" VALUES "
(if batch?
Expand All @@ -188,13 +174,12 @@
"Given a column name, or a pair of column name and direction,
return the sub-clause for addition to `ORDER BY`."
[col opts]
(let [entity-fn (:column-fn opts identity)
name-fn (:name-fn opts name)]
(let [entity-fn (:column-fn opts identity)]
(cond (keyword? col)
(entity-fn (safe-name col name-fn))
(entity-fn (safe-name col))

(and (vector? col) (= 2 (count col)) (keyword? (first col)))
(str (entity-fn (safe-name (first col) name-fn))
(str (entity-fn (safe-name (first col)))
" "
(or (get {:asc "ASC" :desc "DESC"} (second col))
(throw (IllegalArgumentException.
Expand Down Expand Up @@ -231,7 +216,6 @@
`SELECT ...` statement."
[table where-params opts]
(let [entity-fn (:table-fn opts identity)
name-fn (:name-fn opts name)
where-params (cond (map? where-params)
(by-keys where-params :where opts)
(= :all where-params)
Expand All @@ -252,7 +236,7 @@
(if-let [cols (seq (:columns opts))]
(as-cols cols opts)
"*")
" FROM " (entity-fn (safe-name table name-fn))
" FROM " (entity-fn (safe-name table))
(when-let [clause (first where-params)]
(str " " clause))
(when-let [order-by (:order-by opts)]
Expand Down Expand Up @@ -281,13 +265,12 @@
`UPDATE ...` statement."
[table key-map where-params opts]
(let [entity-fn (:table-fn opts identity)
name-fn (:name-fn opts name)
set-params (by-keys key-map :set opts)
where-params (if (map? where-params)
(by-keys where-params :where opts)
(into [(str "WHERE " (first where-params))]
(rest where-params)))]
(-> [(str "UPDATE " (entity-fn (safe-name table name-fn))
(-> [(str "UPDATE " (entity-fn (safe-name table))
" " (first set-params)
" " (first where-params)
(when-let [suffix (:suffix opts)]
Expand Down
Loading

0 comments on commit ecd950d

Please sign in to comment.