One DBAdapter implementation, over a per-engine spec.
There used to be four, and they were copies: each query.clj was the same
sixty lines turning on two decisions, and each core.clj was thirty lines of
delegation. A fix landed in one and not its neighbours — that is how H2 came
to carry a table-exists? workaround while SQLite and MySQL reported every
table as absent (BOU-430).
A spec names what the port says may differ between engines, and nothing else:
:label for log lines — "MySQL"
:dialect what callers dispatch on; nil means PostgreSQL
:driver JDBC driver class name
:jdbc-url (fn [db-config] -> String)
:pool HikariCP defaults
:session-statements (fn [db-config] -> seq of JDBC param vectors)
:booleans :native or :int
:string-match :like or :ilike
:table-exists? (fn [datasource table-name] -> boolean)
:table-info (fn [datasource table-name] -> vector of column maps)
:unique-keys optional (fn [datasource table-name] -> vector of column-name
vectors); without one, read from the JDBC metadata
:engine :postgresql, :mysql, :sqlite or :h2
:capabilities a subset of protocols/capability-keywords
:column-types {logical-type DDL-type} for protocols/logical-column-types;
a string is VARCHAR(length) unless :string names one type for all
:now-ms-sql SQL for the database clock in epoch millis
:on-connect optional (fn [java.sql.Connection]), run on each new
connection after the session statements
:param->db optional (fn [value] -> value) for each query parameter;
without one, instant->iso
:db->value optional (fn [value] -> value) for each value read
One `DBAdapter` implementation, over a per-engine spec.
There used to be four, and they were copies: each `query.clj` was the same
sixty lines turning on two decisions, and each `core.clj` was thirty lines of
delegation. A fix landed in one and not its neighbours — that is how H2 came
to carry a `table-exists?` workaround while SQLite and MySQL reported every
table as absent (BOU-430).
A spec names what the port says may differ between engines, and nothing else:
:label for log lines — "MySQL"
:dialect what callers dispatch on; nil means PostgreSQL
:driver JDBC driver class name
:jdbc-url (fn [db-config] -> String)
:pool HikariCP defaults
:session-statements (fn [db-config] -> seq of JDBC param vectors)
:booleans :native or :int
:string-match :like or :ilike
:table-exists? (fn [datasource table-name] -> boolean)
:table-info (fn [datasource table-name] -> vector of column maps)
:unique-keys optional (fn [datasource table-name] -> vector of column-name
vectors); without one, read from the JDBC metadata
:engine :postgresql, :mysql, :sqlite or :h2
:capabilities a subset of protocols/capability-keywords
:column-types {logical-type DDL-type} for protocols/logical-column-types;
a string is VARCHAR(length) unless :string names one type for all
:now-ms-sql SQL for the database clock in epoch millis
:on-connect optional (fn [java.sql.Connection]), run on each new
connection after the session statements
:param->db optional (fn [value] -> value) for each query parameter;
without one, `instant->iso`
:db->value optional (fn [value] -> value) for each value read(boolean->db representation value)Encode value the way representation (:native or :int) stores booleans.
Encode `value` the way `representation` (:native or :int) stores booleans.
(build-where-clause {:keys [string-match booleans]} filters)Build a WHERE fragment from filters, in this engine's terms.
string-match is the containment operator (PostgreSQL matches
case-insensitively with ILIKE; the rest use LIKE) and booleans is how the
engine stores a boolean. Those two were the whole of the difference between
the four copies this replaces.
Build a WHERE fragment from `filters`, in this engine's terms. `string-match` is the containment operator (PostgreSQL matches case-insensitively with ILIKE; the rest use LIKE) and `booleans` is how the engine stores a boolean. Those two were the whole of the difference between the four copies this replaces.
(case-insensitive-like string-match field mode value)field LIKE value, literally and ignoring case, where mode puts it (see
protocols/like-pattern, BOU-684).
`field` LIKE `value`, literally and ignoring case, where `mode` puts it (see `protocols/like-pattern`, BOU-684).
(db->boolean representation value)Decode a stored boolean written by boolean->db.
Decode a stored boolean written by `boolean->db`.
(instant->iso value)An Instant parameter as its ISO string, anything else as it is: PostgreSQL and H2 parse that into a timestamp column and keep it verbatim in a text one, where a bound timestamp became unreadable text (BOU-655).
An Instant parameter as its ISO string, anything else as it is: PostgreSQL and H2 parse that into a timestamp column and keep it verbatim in a text one, where a bound timestamp became unreadable text (BOU-655).
(new-adapter spec)Build the adapter described by spec. See this namespace's docstring.
Build the adapter described by `spec`. See this namespace's docstring.
(run-session-statements! label datasource statements)Run each statement, and keep going when one fails.
Session settings are best-effort: a connection that could not be told to use
UTC still works. They are run independently because they used to share a
single try — MySQL's sql_mode is rejected by MySQL 8, which meant the
timezone and charset statements after it never ran at all (BOU-367).
Run each statement, and keep going when one fails. Session settings are best-effort: a connection that could not be told to use UTC still works. They are run independently because they used to share a single try — MySQL's `sql_mode` is rejected by MySQL 8, which meant the timezone and charset statements after it never ran at all (BOU-367).
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |