Helper functions for querying the DB and inserting or updating records using Toucan models.
Helper functions for querying the DB and inserting or updating records using Toucan models.
Bind this to enable automatic conversion between dashes and underscores for indentifiers. Provided for cases where you want to override the behavior (such as when connecting to a different DB) without changing the default value.
Bind this to enable automatic conversion between dashes and underscores for indentifiers. Provided for cases where you want to override the behavior (such as when connecting to a different DB) without changing the default value.
Bind this to override the default DB connection used by toucan.db
functions. Provided for situations where you'd
like to connect to a DB other than the primary application DB, or connect to it with different connection options.
Bind this to override the default DB connection used by `toucan.db` functions. Provided for situations where you'd like to connect to a DB other than the primary application DB, or connect to it with different connection options.
Should we disable logging for database queries? Normally false
, but bind this to true
to keep logging from
getting too noisy during operations that require a lot of DB access, like the sync process.
Should we disable logging for database queries? Normally `false`, but bind this to `true` to keep logging from getting too noisy during operations that require a lot of DB access, like the sync process.
Bind this to override the identifier quoting style. Provided for cases where you want to override the quoting style (such as when connecting to a different DB) without changing the default value.
Bind this to override the identifier quoting style. Provided for cases where you want to override the quoting style (such as when connecting to a different DB) without changing the default value.
(-do-with-call-counting f)
Execute F with DB call counting enabled. F is passed a single argument, a function that can be used to retrieve the
current call count. (It's probably more useful to use the macro form of this function, with-call-counting
,
instead.)
Execute F with DB call counting enabled. F is passed a single argument, a function that can be used to retrieve the current call count. (It's probably more useful to use the macro form of this function, `with-call-counting`, instead.)
(-do-with-debug-print-queries f)
Execute f
with debug query logging enabled. Don't use this directly; prefer the debug-print-queries
macro form
instead.
Execute `f` with debug query logging enabled. Don't use this directly; prefer the `debug-print-queries` macro form instead.
(automatically-convert-dashes-and-underscores?)
Deterimine whether we should automatically convert dashes and underscores in identifiers.
Returns the value of *automatically-convert-dashes-and-underscores*
if it is bound, otherwise returns the
default-automatically-convert-dashes-and-underscores
, which is normally false
; this can be changed by calling
set-default-automatically-convert-dashes-and-underscores!
.
Deterimine whether we should automatically convert dashes and underscores in identifiers. Returns the value of `*automatically-convert-dashes-and-underscores*` if it is bound, otherwise returns the `default-automatically-convert-dashes-and-underscores`, which is normally `false`; this can be changed by calling `set-default-automatically-convert-dashes-and-underscores!`.
(connection)
Fetch the JDBC connection details for passing to clojure.java.jdbc
. Returns *db-connection*
, if it is set;
otherwise *transaction-connection*
, if we're inside a transaction
(this is bound automatically); otherwise the
default DB connection, set by set-default-db-connection!
.
If no DB connection has been set this function will throw an exception.
Fetch the JDBC connection details for passing to `clojure.java.jdbc`. Returns `*db-connection*`, if it is set; otherwise `*transaction-connection*`, if we're inside a `transaction` (this is bound automatically); otherwise the default DB connection, set by `set-default-db-connection!`. If no DB connection has been set this function will throw an exception.
(count model & options)
Select the count of objects matching some condition.
;; Get all Users whose email is non-nil (count 'User :email [:not= nil]) -> 12
Select the count of objects matching some condition. ;; Get all Users whose email is non-nil (count 'User :email [:not= nil]) -> 12
(debug-count-calls & body)
Print the number of DB calls executed inside body
to stdout
. Intended for use during REPL development.
Print the number of DB calls executed inside `body` to `stdout`. Intended for use during REPL development.
(debug-print-queries & body)
Print the HoneySQL and SQL forms of any queries executed inside body
to stdout
. Intended for use during REPL
development.
Print the HoneySQL and SQL forms of any queries executed inside `body` to `stdout`. Intended for use during REPL development.
(delete! model & conditions)
Delete of object(s). For each matching object, the pre-delete
multimethod is called, which should do
any cleanup needed before deleting the object, (such as deleting objects related to the object about to
be deleted), or otherwise enforce preconditions before deleting (such as refusing to delete the object if
something else depends on it).
(delete! Database :id 1)
Delete of object(s). For each matching object, the `pre-delete` multimethod is called, which should do any cleanup needed before deleting the object, (such as deleting objects related to the object about to be deleted), or otherwise enforce preconditions before deleting (such as refusing to delete the object if something else depends on it). (delete! Database :id 1)
(do-in-transaction f)
Execute F inside a DB transaction. Prefer macro form transaction
to using this directly.
Execute F inside a DB transaction. Prefer macro form `transaction` to using this directly.
(do-post-select model objects)
Perform post-processing for objects fetched from the DB. Convert results objects
to entity
record types and
call the model's post-select
method on them.
Perform post-processing for objects fetched from the DB. Convert results `objects` to `entity` record types and call the model's `post-select` method on them.
(execute! honeysql-form & {:as options})
Compile honeysql-form
and call jdbc/execute!
against the application DB.
options
are passed directly to jdbc/execute!
and can be things like :multi?
(default false
) or
:transaction?
(default true
).
Compile `honeysql-form` and call `jdbc/execute!` against the application DB. `options` are passed directly to `jdbc/execute!` and can be things like `:multi?` (default `false`) or `:transaction?` (default `true`).
(exists? model & kvs)
Easy way to see if something exists in the DB.
(db/exists? User :id 100)
Easy way to see if something exists in the DB. (db/exists? User :id 100)
(get-inserted-id primary-key insert-result)
Get the ID of a row inserted by jdbc/db-do-prepared-return-keys
.
Get the ID of a row inserted by `jdbc/db-do-prepared-return-keys`.
(honeysql->sql honeysql-form)
Compile honeysql-form
to SQL.
This returns a vector with the SQL string as its first item and prepared statement params as the remaining items.
Compile `honeysql-form` to SQL. This returns a vector with the SQL string as its first item and prepared statement params as the remaining items.
(insert! model row-map)
(insert! model k v & more)
Insert a new object into the Database. Resolves entity
, calls its pre-insert
method on row-map
to prepare
it before insertion; after insert, it fetches and the newly created object, passes it to post-insert
, and
returns the results.
For flexibility, insert!
can handle either a single map or individual kwargs:
(db/insert! Label {:name "Toucan Unfriendly"}) (db/insert! 'Label :name "Toucan Friendly")
Insert a new object into the Database. Resolves `entity`, calls its `pre-insert` method on `row-map` to prepare it before insertion; after insert, it fetches and the newly created object, passes it to `post-insert`, and returns the results. For flexibility, `insert!` can handle either a single map or individual kwargs: (db/insert! Label {:name "Toucan Unfriendly"}) (db/insert! 'Label :name "Toucan Friendly")
(insert-many! model row-maps)
Insert several new rows into the Database. Resolves entity
, and calls pre-insert
on each of the row-maps
.
Returns a sequence of the IDs of the newly created objects.
Note: this does not call post-insert
on newly created objects. If you need post-insert
behavior, use
insert!
instead. (This might change in the future: there is an open issue to consider
this).
(db/insert-many! 'Label [{:name "Toucan Friendly"} {:name "Bird Approved"}]) -> [38 39]
Insert several new rows into the Database. Resolves `entity`, and calls `pre-insert` on each of the `row-maps`. Returns a sequence of the IDs of the newly created objects. Note: this *does not* call `post-insert` on newly created objects. If you need `post-insert` behavior, use `insert!` instead. (This might change in the future: there is an [open issue to consider this](https://github.com/metabase/toucan/issues/4)). (db/insert-many! 'Label [{:name "Toucan Friendly"} {:name "Bird Approved"}]) -> [38 39]
(qualified? field-name)
Is field-name
qualified (e.g. with its table name)?
Is `field-name` qualified (e.g. with its table name)?
(qualify model field-name)
Qualify a field-name
name with the name its entity
. This is necessary for disambiguating fields for HoneySQL
queries that contain joins.
(db/qualify 'CardFavorite :id) -> :report_cardfavorite.id
Qualify a `field-name` name with the name its `entity`. This is necessary for disambiguating fields for HoneySQL queries that contain joins. (db/qualify 'CardFavorite :id) -> :report_cardfavorite.id
(query honeysql-form & {:as options})
Compile honeysql-from
and call jdbc/query
against the application database. Options are passed along to
jdbc/query
.
Compile `honeysql-from` and call `jdbc/query` against the application database. Options are passed along to `jdbc/query`.
(quote-fn)
The function that JDBC should use to quote identifiers for our database. This is passed as the :entities
option
to functions like jdbc/insert!
.
The function that JDBC should use to quote identifiers for our database. This is passed as the `:entities` option to functions like `jdbc/insert!`.
(quoting-style)
Fetch the HoneySQL quoting style that should be used to quote identifiers. One of :ansi
, :mysql
, or
:sqlserver
.
Returns the value of *quoting-style*
if it is bound, otherwise returns the default quoting style, which is
normally :ansi
; this can be changed by calling set-default-quoting-style!
.
Fetch the HoneySQL quoting style that should be used to quote identifiers. One of `:ansi`, `:mysql`, or `:sqlserver`. Returns the value of `*quoting-style*` if it is bound, otherwise returns the default quoting style, which is normally `:ansi`; this can be changed by calling `set-default-quoting-style!`.
(reducible-query honeysql-form & {:as options})
Compile honeysql-from
and call jdbc/reducible-query
against the application database. Options are passed along
to jdbc/reducible-query
. Note that the query won't actually be executed until it's reduced.
Compile `honeysql-from` and call `jdbc/reducible-query` against the application database. Options are passed along to `jdbc/reducible-query`. Note that the query won't actually be executed until it's reduced.
(resolve-model model)
Resolve a model if it's quoted. This also unwraps entities when they're inside vectores.
(resolve-model Database) -> #'my-project.models.database/Database (resolve-model [Database :name]) -> #'my-project.models.database/Database (resolve-model 'Database) -> #'my-project.models.database/Database
Resolve a model *if* it's quoted. This also unwraps entities when they're inside vectores. (resolve-model Database) -> #'my-project.models.database/Database (resolve-model [Database :name]) -> #'my-project.models.database/Database (resolve-model 'Database) -> #'my-project.models.database/Database
(select model & options)
Select objects from the database.
(select 'Database :name [:not= nil] {:limit 2}) -> [...]
Select objects from the database. (select 'Database :name [:not= nil] {:limit 2}) -> [...]
(select-field field model & options)
Select values of a single field for multiple objects. These are returned as a set if any matching fields
were returned, otherwise nil
.
(select-field :name 'Database) -> #{"Sample Dataset", "test-data"}
Select values of a single field for multiple objects. These are returned as a set if any matching fields were returned, otherwise `nil`. (select-field :name 'Database) -> #{"Sample Dataset", "test-data"}
(select-field->field k v model & options)
Select fields k
and v
from objects in the database, and return them as a map from k
to v
.
(select-field->field :id :name 'Database) -> {1 "Sample Dataset", 2 "test-data"}
Select fields `k` and `v` from objects in the database, and return them as a map from `k` to `v`. (select-field->field :id :name 'Database) -> {1 "Sample Dataset", 2 "test-data"}
(select-field->id field model & options)
Select FIELD and :id
from objects in the database, and return them as a map from field
to :id
.
(select-field->id :name 'Database) -> {"Sample Dataset" 1, "test-data" 2}
Select FIELD and `:id` from objects in the database, and return them as a map from `field` to `:id`. (select-field->id :name 'Database) -> {"Sample Dataset" 1, "test-data" 2}
(select-id->field field model & options)
Select field
and :id
from objects in the database, and return them as a map from :id
to field
.
(select-id->field :name 'Database) -> {1 "Sample Dataset", 2 "test-data"}
Select `field` and `:id` from objects in the database, and return them as a map from `:id` to `field`. (select-id->field :name 'Database) -> {1 "Sample Dataset", 2 "test-data"}
(select-ids model & options)
Select IDs for multiple objects. These are returned as a set if any matching IDs were returned, otherwise nil
.
(select-ids 'Table :db_id 1) -> #{1 2 3 4}
Select IDs for multiple objects. These are returned as a set if any matching IDs were returned, otherwise `nil`. (select-ids 'Table :db_id 1) -> #{1 2 3 4}
(select-one model & options)
Select a single object from the database.
(select-one ['Database :name] :id 1) -> {:name "Sample Dataset"}
Select a single object from the database. (select-one ['Database :name] :id 1) -> {:name "Sample Dataset"}
(select-one-field field model & options)
Select a single field
of a single object from the database.
(select-one-field :name 'Database :id 1) -> "Sample Dataset"
Select a single `field` of a single object from the database. (select-one-field :name 'Database :id 1) -> "Sample Dataset"
(select-one-id model & options)
Select the :id
of a single object from the database.
(select-one-id 'Database :name "Sample Dataset") -> 1
Select the `:id` of a single object from the database. (select-one-id 'Database :name "Sample Dataset") -> 1
(select-reducible model & options)
Select objects from the database, returns a reducible.
(transduce (map :name) conj [] (select 'Database :name [:not= nil] {:limit 2})) -> ["name1", "name2"]
Select objects from the database, returns a reducible. (transduce (map :name) conj [] (select 'Database :name [:not= nil] {:limit 2})) -> ["name1", "name2"]
(set-default-automatically-convert-dashes-and-underscores!
new-automatically-convert-dashes-and-underscores)
Set the default value for allowing dashes in field names. Defaults to true
.
Set the default value for allowing dashes in field names. Defaults to `true`.
(set-default-db-connection! db-connection-map)
Set the JDBC connecton details map for the default application DB connection. This connection is used by default by
the various toucan.db
functions.
db-connection-map
is passed directly to clojure.java.jdbc
; it can be anything that is accepted by it.
(db/set-default-db-connection! {:classname "org.postgresql.Driver" :subprotocol "postgresql" :subname "//localhost:5432/my_db" :user "cam"})
Set the JDBC connecton details map for the default application DB connection. This connection is used by default by the various `toucan.db` functions. `db-connection-map` is passed directly to `clojure.java.jdbc`; it can be anything that is accepted by it. (db/set-default-db-connection! {:classname "org.postgresql.Driver" :subprotocol "postgresql" :subname "//localhost:5432/my_db" :user "cam"})
(set-default-quoting-style! new-quoting-style)
Set the default quoting style that should be used to quote identifiers. Defaults to :ansi
, but you can instead
set it to :mysql
or :sqlserver
.
Set the default quoting style that should be used to quote identifiers. Defaults to `:ansi`, but you can instead set it to `:mysql` or `:sqlserver`.
(simple-delete! model)
(simple-delete! model conditions)
(simple-delete! model k v & more)
Delete an object or objects from the application DB matching certain constraints.
Returns true
if something was deleted, false
otherwise.
(db/simple-delete! 'Label) ; delete all Labels (db/simple-delete! Label :name "Cam") ; delete labels where :name == "Cam" (db/simple-delete! Label {:name "Cam"}) ; for flexibility either a single map or kwargs are accepted
Unlike delete!
, this does not call pre-delete
on the object about to be deleted.
Delete an object or objects from the application DB matching certain constraints. Returns `true` if something was deleted, `false` otherwise. (db/simple-delete! 'Label) ; delete all Labels (db/simple-delete! Label :name "Cam") ; delete labels where :name == "Cam" (db/simple-delete! Label {:name "Cam"}) ; for flexibility either a single map or kwargs are accepted Unlike `delete!`, this does not call `pre-delete` on the object about to be deleted.
(simple-insert! model row-map)
(simple-insert! model k v & more)
Do a simple JDBC insert
of a single object.
This is similar to insert!
but returns the ID of the newly created object rather than the object itself,
and does not call pre-insert
or post-insert
.
(db/simple-insert! 'Label :name "Toucan Friendly") -> 1
Like insert!
, simple-insert!
can be called with either a single row-map
or kv-style arguments.
Do a simple JDBC `insert` of a single object. This is similar to `insert!` but returns the ID of the newly created object rather than the object itself, and does not call `pre-insert` or `post-insert`. (db/simple-insert! 'Label :name "Toucan Friendly") -> 1 Like `insert!`, `simple-insert!` can be called with either a single `row-map` or kv-style arguments.
(simple-insert-many! model row-maps)
Do a simple JDBC insert!
of multiple objects into the database.
Normally you should use insert-many!
instead, which calls the model's pre-insert
method on the row-maps
;
simple-insert-many!
is offered for cases where you'd like to specifically avoid this behavior. Returns a sequences
of IDs of newly inserted objects.
(db/simple-insert-many! 'Label [{:name "Toucan Friendly"} {:name "Bird Approved"}]) ;;=> (38 39)
Do a simple JDBC `insert!` of multiple objects into the database. Normally you should use `insert-many!` instead, which calls the model's `pre-insert` method on the `row-maps`; `simple-insert-many!` is offered for cases where you'd like to specifically avoid this behavior. Returns a sequences of IDs of newly inserted objects. (db/simple-insert-many! 'Label [{:name "Toucan Friendly"} {:name "Bird Approved"}]) ;;=> (38 39)
(simple-select model honeysql-form)
Select objects from the database.
Like select
, but doesn't offer as many conveniences, so prefer that instead; like select
,
simple-select
callts post-select
on the results, but unlike select
, only accepts a single
raw HoneySQL form as an argument.
(db/simple-select 'User {:where [:= :id 1]})
Select objects from the database. Like `select`, but doesn't offer as many conveniences, so prefer that instead; like `select`, `simple-select` callts `post-select` on the results, but unlike `select`, only accepts a single raw HoneySQL form as an argument. (db/simple-select 'User {:where [:= :id 1]})
(simple-select-one model)
(simple-select-one model honeysql-form)
Select a single object from the database.
Like select-one
, but doesn't offer as many conveniences, so prefer that instead; like select-one
,
simple-select-one
callts post-select
on the results, but unlike select-one
, only accepts a single raw HoneySQL
form as an argument.
(db/simple-select-one 'User (h/where [:= :first-name "Cam"]))
Select a single object from the database. Like `select-one`, but doesn't offer as many conveniences, so prefer that instead; like `select-one`, `simple-select-one` callts `post-select` on the results, but unlike `select-one`, only accepts a single raw HoneySQL form as an argument. (db/simple-select-one 'User (h/where [:= :first-name "Cam"]))
(simple-select-reducible model honeysql-form)
Select objects from the database.
Same as simple-select
, but returns something reducible instead of a result set. Like simple-select
, will call
post-select
on the results, but will do so lazily.
(transduce (filter can-read?) conj [] (simple-select-reducible 'User {:where [:= :id 1]}))
Select objects from the database. Same as `simple-select`, but returns something reducible instead of a result set. Like `simple-select`, will call `post-select` on the results, but will do so lazily. (transduce (filter can-read?) conj [] (simple-select-reducible 'User {:where [:= :id 1]}))
(transaction body)
(transaction options & body)
Execute all queries within the body in a single transaction.
Execute all queries within the body in a single transaction.
(update! model honeysql-form)
(update! model id kvs)
(update! model id k v & more)
Update a single row in the database. Returns true
if a row was affected, false
otherwise. Accepts either a
single map of updates to make or kwargs. entity
is automatically resolved, and pre-update
is called on kvs
before the object is inserted into the database.
(db/update! 'Label 11 :name "ToucanFriendly") (db/update! 'Label 11 {:name "ToucanFriendly"})
Update a single row in the database. Returns `true` if a row was affected, `false` otherwise. Accepts either a single map of updates to make or kwargs. `entity` is automatically resolved, and `pre-update` is called on `kvs` before the object is inserted into the database. (db/update! 'Label 11 :name "ToucanFriendly") (db/update! 'Label 11 {:name "ToucanFriendly"})
(update-non-nil-keys! model id kvs)
(update-non-nil-keys! model id k v & more)
Like update!
, but filters out KVS with nil
values.
Like `update!`, but filters out KVS with `nil` values.
(update-where! model conditions-map & {:as values})
Convenience for updating several objects matching conditions-map
. Returns true
if any objects were affected.
For updating a single object, prefer using update!
, which calls entity
's pre-update
method first.
(db/update-where! Table {:name table-name :db_id (:id database)} :active false)
Convenience for updating several objects matching `conditions-map`. Returns `true` if any objects were affected. For updating a single object, prefer using `update!`, which calls `entity`'s `pre-update` method first. (db/update-where! Table {:name table-name :db_id (:id database)} :active false)
(with-call-counting [call-count-fn-binding] & body)
Execute body
and track the number of DB calls made inside it. call-count-fn-binding
is bound to a zero-arity
function that can be used to fetch the current DB call count.
(db/with-call-counting [call-count] ... (call-count))
Execute `body` and track the number of DB calls made inside it. `call-count-fn-binding` is bound to a zero-arity function that can be used to fetch the current DB call count. (db/with-call-counting [call-count] ... (call-count))
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close