{:group-id "io.github.camsaul", :artifact-id "toucan2", :version "1.0.539", :analysis {"clj" ({:name toucan2.connection, :publics ({:name *current-connectable*, :file "toucan2/connection.clj", :line 64, :dynamic true, :doc "The current connectable or connection. If you get a connection with [[with-connection]] or [[with-transaction]], it\nwill be bound here. You can also bind this yourself to a connectable or connection, and Toucan methods called without\nan explicit will connectable will use it rather than the `:default` connection.", :type :var} {:name connection-string-protocol, :file "toucan2/connection.clj", :line 208, :arglists ([connection-string]), :doc "Extract the protocol part of a `connection-string`.\n\n```clj\n(connection-string-protocol \"jdbc:postgresql:...\")\n=>\n\"jdbc\"\n```", :type :var} {:name do-with-connection, :file "toucan2/connection.clj", :line 70, :arglists ([connectable₁ f]), :doc "Take a *connectable*, get a connection of some sort from it, and execute `(f connection)` with an open connection. A\n normal implementation might look something like:\n\n ```clj\n (m/defmethod t2.conn/do-with-connection ::my-connectable\n [_connectable f]\n (with-open [conn (get-connection)]\n (f conn)))\n ```\n\n Another common use case is to define a 'named' connectable that acts as an alias for another more complicated\n connectable, such as a JDBC connection string URL. You can do that like this:\n\n ```clj\n (m/defmethod t2.conn/do-with-connection ::a-connectable\n [_connectable f]\n (t2.conn/do-with-connection\n \"jdbc:postgresql://localhost:5432/toucan2?user=cam&password=cam\"\n f))\n ```\n\ndo-with-connection is defined in [[toucan2.connection]] (toucan2/connection.clj:70).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{javax.sql.DataSource #{clojure.lang.IPersistentMap}}`.\n\nThe default value is `:toucan2.connection/default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:toucan2.connection/default`, defined in [[toucan2.connection]] (toucan2/connection.clj:174) \n\n* `:default`, defined in [[toucan2.connection]] (toucan2/connection.clj:184) \n\n* `nil`, defined in [[toucan2.connection]] (toucan2/connection.clj:194) \n \n It has the following documentation:\n \n `nil` means use the current connection.\n \n The difference between `nil` and using [[*current-connectable*]] directly is that this waits until it gets resolved\n by [[do-with-connection]] to get the value for [[*current-connectable*]]. For a reducible query this means you'll get\n the value at the time you reduce the query rather than at the time you build the reducible query.\n\n* `java.lang.String`, defined in [[toucan2.connection]] (toucan2/connection.clj:229) \n \n It has the following documentation:\n \n Implementation for Strings. Hands off to [[do-with-connection-string]].\n\n* `java.sql.Connection`, defined in [[toucan2.jdbc.connection]] (toucan2/jdbc/connection.clj:11) \n\n* `javax.sql.DataSource`, defined in [[toucan2.jdbc.connection]] (toucan2/jdbc/connection.clj:15) \n\n* `clojure.lang.IPersistentMap`, defined in [[toucan2.jdbc.connection]] (toucan2/jdbc/connection.clj:20) \n \n It has the following documentation:\n \n Implementation for map connectables. Treats them as a `clojure.java.jdbc`-style connection spec map, converting them to\n a `java.sql.DataSource` with [[next.jdbc/get-datasource]].\n\nThese aux methods are known:\n\n`:around` methods:\n\n* `:toucan2.connection/default`, defined in [[toucan2.connection]] (toucan2/connection.clj:106) \n \n It has the following documentation:\n \n Do some debug logging/context capture. Bind [[*current-connectable*]] to the connection `f` is called with inside of\n `f`.", :type :var} {:name do-with-connection-string, :file "toucan2/connection.clj", :line 220, :arglists ([connection-string f]), :doc "Implementation of [[do-with-connection]] for strings. Dispatches on the [[connection-string-protocol]] of the string,\n e.g. `\"jdbc\"` for `\"jdbc:postgresql://localhost:3000/toucan\"`.\n\ndo-with-connection-string is defined in [[toucan2.connection]] (toucan2/connection.clj:220).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `\"jdbc\"`, defined in [[toucan2.jdbc.connection]] (toucan2/jdbc/connection.clj:29) \n \n It has the following documentation:\n \n Implementation of `do-with-connection-string` (and thus [[do-with-connection]]) for all strings starting with `jdbc:`.\n Calls `java.sql.DriverManager/getConnection` on the connection string.", :type :var} {:name do-with-transaction, :file "toucan2/connection.clj", :line 236, :arglists ([connection₁ options f]), :doc "`options` are options for determining what type of transaction we'll get. See dox for [[with-transaction]] for more\n information.\n\ndo-with-transaction is defined in [[toucan2.connection]] (toucan2/connection.clj:236).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:toucan2.connection/default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `java.sql.Connection`, defined in [[toucan2.jdbc.connection]] (toucan2/jdbc/connection.clj:36) \n\nThese aux methods are known:\n\n`:around` methods:\n\n* `:toucan2.connection/default`, defined in [[toucan2.connection]] (toucan2/connection.clj:245) \n \n It has the following documentation:\n \n Bind [[*current-connectable*]] to the connection `f` is called with inside of `f`.", :type :var} {:name with-connection, :file "toucan2/connection.clj", :line 120, :arglists ([[connection-binding] & body] [[connection-binding connectable] & body]), :doc "Execute `body` with an open connection. There are three ways to use this.\n\nWith no args in the bindings vector, `with-connection` will use the *current connection* -- [[*current-connectable*]]\nif one is bound, or the *default connectable* if not. See docstring for [[toucan2.connection]] for more information.\n\n```clj\n(t2/with-connection []\n ...)\n```\n\nWith one arg, `with-connection` still uses the *current connection*, but binds it to something (`conn` in the example\nbelow):\n\n```clj\n(t2/with-connection [conn]\n ...)\n```\n\nIf you're using the default JDBC backend, `conn` will be an instance of `java.sql.Connection`. Since Toucan 2 is also\nwritten to work with other backend besides JDBC, `conn` does *not* include `java.sql.Connection` `:tag` metadata! If\nyou're doing Java interop with `conn`, make sure to tag it yourself:\n\n```clj\n (t2/with-connection [^java.sql.Connection conn]\n (let [metadata (.getMetaData conn)]\n ...))\n```\n\nWith a connection binding *and* a connectable:\n\n```clj\n(t2/with-connection [conn ::my-connectable]\n ...)\n```\n\nThis example gets a connection by calling [[do-with-connection]] with `::my-connectable`, ignoring the *current\nconnection*.", :type :macro} {:name with-transaction, :file "toucan2/connection.clj", :line 251, :arglists ([[conn-binding connectable options?] & body]), :doc "Gets a connection with [[with-connection]], and executes `body` within that transaction.\n\nAn `options` map, if specified, determine what sort of transaction we're asking for (stuff like the read isolation\nlevel and what not). One key, `:nested-transaction-rule`, is handled directly in Toucan 2; other options are passed\ndirectly to the underlying implementation, such as [[next.jdbc.transaction]].\n\n`:nested-transaction-rule` must be one of `#{:allow :ignore :prohibit}`, a set of possibilities borrowed from\n`next.jdbc`. For non-JDBC implementations, you should treat `:allow` as the default behavior if unspecified.", :type :macro}), :doc "#### Connection Resolution\n\nThe rules for determining which connection to use are as follows. These are tried in order until one returns\nnon-nil:\n\n1. The connectable specified in the function arguments.\n\n2. The [[toucan2.connection/*current-connectable*]], if bound. This is bound automatically when\n using [[with-connection]] or [[with-transaction]]\n\n3. The [[toucan2.model/default-connectable]] for the model resolved from the `modelable` in the function arguments;\n\n4. The `:default` implementation of [[toucan2.connection/do-with-connection]]\n\nYou can define a 'named' connectable such as `::db` by adding an implementation\nof [[toucan2.connection/do-with-connection]], or use things like JDBC URL connection strings or [[clojure.java.jdbc]]\nconnection properties maps directly.\n\nIMPORTANT CAVEAT! Positional connectables will be used in preference to [[*current-connectable*]], even when it was\nbound by [[with-transaction]] -- this means your query will run OUTSIDE of the current transaction! Sometimes, this is\nwhat you want, because maybe a certain query is meant to run against a different database! Usually, however, it is\nnot! So in that case you can either do something like\n\n```clj\n(t2/query (or conn/*current-connectable* ::my-db) ...)\n```\n\nto use the current connection if it exists, or define your named connectable method like\n\n```clj\n(m/defmethod conn/do-with-connection ::my-db\n [_connectable f]\n (conn/do-with-connection\n (if (and conn/*current-connectable*\n (not= conn/*current-connectable* ::my-db))\n conn/*current-connectable*\n \"jdbc:postgresql://...\")\n f))\n```\n\nThis, however, is super annoying! So I might reconsider this behavior in the future.\n\nFor reducible queries, the connection is not resolved until the query is executed, so you may create a reducible query\nwith no default connection available and execute it later with one bound. (This also means\nthat [[toucan2.execute/reducible-query]] does not capture dynamic bindings such\nas [[toucan2.connection/*current-connectable*]] -- you probably wouldn't want it to, anyway, since we have no\nguarantees and open connection will be around when we go to use the reducible query later.\n\nThe default JDBC implementations for methods here live in [[toucan2.jdbc.connection]]."} {:name toucan2.delete, :publics ({:name delete!, :file "toucan2/delete.clj", :line 8, :arglists ([modelable & conditions? queryable?] [:conn connectable modelable & conditions? queryable?]), :doc "Delete instances of a model that match `conditions` or a `queryable`. Returns the number of rows deleted.\n\n```clj\n;; delete a row by primary key\n(t2/delete! :models/venues 1)\n\n;; Delete all rows matching a condition\n(t2/delete! :models/venues :name \"Bird Store\")\n```\n\nAllowed syntax is identical to [[toucan2.select/select]], including optional positional parameters like `:conn`;\nsee [[toucan2.query/parse-args]] and the `:toucan2.query/default-args` spec.", :type :var}), :doc "Implementation of [[delete!]].\n\nCode for building Honey SQL for DELETE lives in [[toucan2.honeysql2]]"} {:name toucan2.execute, :publics ({:name query, :file "toucan2/execute.clj", :line 61, :arglists ([queryable] [connectable queryable] [connectable modelable queryable] [connectable query-type modelable queryable]), :doc "Like [[reducible-query]], but immediately executes and fully reduces the query.\n\n```clj\n(query ::my-connectable [\"SELECT * FROM venues;\"])\n;; => [{:id 1, :name \"Tempest\"}\n {:id 2, :name \"BevMo\"}]\n```\n\nLike [[reducible-query]], this may be used with either `SELECT` queries that return rows or things like `UPDATE` that\nnormally return the count of rows updated.", :type :var} {:name query-one, :file "toucan2/execute.clj", :line 81, :arglists ([queryable] [connectable queryable] [connectable modelable queryable] [connectable query-type modelable queryable]), :doc "Like [[query]], and immediately executes the query, but realizes and returns only the first result.\n\n```clj\n(query-one ::my-connectable [\"SELECT * FROM venues;\"])\n;; => {:id 1, :name \"Tempest\"}\n```\n\nLike [[reducible-query]], this may be used with either `SELECT` queries that return rows or things like `UPDATE` that\nnormally return the count of rows updated.", :type :var} {:name reducible-query, :file "toucan2/execute.clj", :line 41, :arglists ([queryable] [connectable queryable] [connectable modelable queryable] [connectable query-type modelable queryable]), :doc "Create a reducible query that when reduced with resolve and compile `queryable`, open a connection using `connectable`\nand [[toucan2.connection/with-connection]], execute the query, and reduce the results.\n\nNote that this query can be something like a `SELECT` query, or something that doesn't normally return results, like\nan `UPDATE`; this works either way. Normally something like an `UPDATE` will reduce to the number of rows\nupdated/inserted/deleted, e.g. `[5]`.\n\nYou can specify `modelable` to execute the query in the context of a specific model; for queries returning rows, the\nrows will be returned as an [[toucan2.instance/instance]] of the resolved model.\n\nSee [[toucan2.connection]] for Connection resolution rules.", :type :var} {:name with-call-count, :file "toucan2/execute.clj", :line 114, :arglists ([[call-count-fn-binding] & body]), :doc "Execute `body`, trackingthe number of database queries and statements executed. This number can be fetched at any\ntime within `body` by calling function bound to `call-count-fn-binding`:\n\n```clj\n(with-call-count [call-count]\n (select ...)\n (println \"CALLS:\" (call-count))\n (insert! ...)\n (println \"CALLS:\" (call-count)))\n;; -> CALLS: 1\n;; -> CALLS: 2\n```", :type :macro}), :doc "Code for executing queries and statements, and reducing their results.\n\nThe functions here meant for use on a regular basis are:\n\n* [[query]] -- resolve and compile a connectable, execute it using a connection from a connectable, and immediately\n fully realize the results.\n\n* [[query-one]] -- like [[query]], but only realizes the first result.\n\n* [[reducible-query]] -- like [[query]], but returns a [[clojure.lang.IReduceInit]] that can be reduced later rather\n than immediately realizing the results.\n\n* [[with-call-count]] -- helper macro to count the number of queries executed within a `body`."} {:name toucan2.honeysql2, :publics ({:name *options*, :file "toucan2/honeysql2.clj", :line 18, :dynamic true, :doc "Option override when to pass to [[honey.sql/format]].\n", :type :var} {:name condition->honeysql-where-clause, :file "toucan2/honeysql2.clj", :line 35, :arglists ([k v]), :doc "Something sequential like `:id [:> 5]` becomes `[:> :id 5]`. Other stuff like `:id 5` just becomes `[:= :id 5]`.\n", :type :var} {:name global-options, :file "toucan2/honeysql2.clj", :line 15, :doc "Default global options to pass to [[honey.sql/format]].\n", :type :var} {:name include-default-select?, :file "toucan2/honeysql2.clj", :line 94, :arglists ([honeysql-query]), :doc "Should we splice in the default `:select` clause for this `honeysql-query`? Only splice in the default `:select` if we\ndon't have `:union`, `:union-all`, or `:select-distinct` in the resolved query.", :type :var} {:name options, :file "toucan2/honeysql2.clj", :line 22, :arglists ([]), :doc "Get combined Honey SQL options for building and compiling queries by merging [[global-options]] and [[*options*]].\n", :type :var} {:name table-and-alias, :file "toucan2/honeysql2.clj", :line 54, :arglists ([model]), :doc "Build an Honey SQL `[table]` or `[table alias]` (if the model has a [[toucan2.model/namespace]] form) for `model` for\nuse in something like a `:select` clause.", :type :var})} {:name toucan2.insert, :publics ({:name insert!, :file "toucan2/insert.clj", :line 74, :arglists ([modelable row-or-rows-or-queryable] [modelable k v & more] [modelable columns row-vectors] [:conn connectable modelable row-or-rows] [:conn connectable modelable k v & more] [:conn connectable modelable columns row-vectors]), :doc "Insert a row or rows into the database. Returns the number of rows inserted.\n\nThis function is pretty flexible in what it accepts:\n\nInsert a single row with key-value args:\n\n```clj\n(t2/insert! :models/venues :name \"Grant & Green\", :category \"bar\")\n```\n\nInsert a single row as a map:\n\n```clj\n(t2/insert! :models/venues {:name \"Grant & Green\", :category \"bar\"})\n```\n\nInsert multiple row maps:\n\n```clj\n(t2/insert! :models/venues [{:name \"Grant & Green\", :category \"bar\"}\n {:name \"Savoy Tivoli\", :category \"bar\"}])\n```\n\nInsert rows with a vector of column names and a vector of value maps:\n\n```clj\n(t2/insert! :models/venues [:name :category] [[\"Grant & Green\" \"bar\"]\n [\"Savoy Tivoli\" \"bar\"]])\n```\n\nAs with other Toucan 2 functions, you can optionally pass a connectable if you pass `:conn` as the first arg. Refer to\nthe `:toucan2.insert/args` spec for the complete syntax.\n\nNamed connectables can also be used to define the rows:\n\n```clj\n(t2/define-named-query ::named-rows\n {:rows [{:name \"Grant & Green\", :category \"bar\"}\n {:name \"North Beach Cantina\", :category \"restaurant\"}]})\n\n(t2/insert! :models/venues ::named-rows)\n```", :type :var} {:name insert-returning-instance!, :file "toucan2/insert.clj", :line 165, :arglists ([modelable row-or-rows-or-queryable] [modelable k v & more] [modelable columns row-vectors] [:conn connectable modelable row-or-rows] [:conn connectable modelable k v & more] [:conn connectable modelable columns row-vectors]), :doc "Like [[insert-returning-instances!]], but for one-row insertions. Returns the inserted object as a map.\n", :type :var} {:name insert-returning-instances!, :file "toucan2/insert.clj", :line 154, :arglists ([modelable-columns row-or-rows-or-queryable] [modelable-columns k v & more] [modelable-columns columns row-vectors] [:conn connectable modelable-columns row-or-rows] [:conn connectable modelable-columns k v & more] [:conn connectable modelable-columns columns row-vectors]), :doc "Like [[insert!]], but returns a vector of maps representing the inserted objects.\n", :type :var} {:name insert-returning-pk!, :file "toucan2/insert.clj", :line 141, :arglists ([modelable row-or-rows-or-queryable] [modelable k v & more] [modelable columns row-vectors] [:conn connectable modelable row-or-rows] [:conn connectable modelable k v & more] [:conn connectable modelable columns row-vectors]), :doc "Like [[insert-returning-pks!]], but for one-row insertions. For models with a single primary key, this returns just the\nnew primary key as a scalar value (e.g. `1`). For models with a composite primary key, it will return a single tuple\nas determined by [[model/primary-keys]] (e.g. `[1 \"Cam\"]`).", :type :var} {:name insert-returning-pks!, :file "toucan2/insert.clj", :line 126, :arglists ([modelable row-or-rows-or-queryable] [modelable k v & more] [modelable columns row-vectors] [:conn connectable modelable row-or-rows] [:conn connectable modelable k v & more] [:conn connectable modelable columns row-vectors]), :doc "Like [[insert!]], but returns a vector of the primary keys of the newly inserted rows rather than the number of rows\ninserted. The primary keys are determined by [[model/primary-keys]]. For models with a single primary key, this\nreturns a vector of single values, e.g. `[1 2]` if the primary key is `:id` and you've inserted rows 1 and 2; for\ncomposite primary keys this returns a vector of tuples where each tuple has the value of corresponding primary key as\nreturned by [[model/primary-keys]], e.g. for composite PK `[:id :name]` you might get `[[1 \"Cam\"] [2 \"Sam\"]]`.", :type :var}), :doc "Implementation of [[insert!]].\n\nThe code for building an INSERT query as Honey SQL lives in [[toucan2.honeysql2]]"} {:name toucan2.instance, :publics ({:name *print-original*, :file "toucan2/instance.clj", :line 23, :dynamic true, :doc "For debugging purposes: whether to print the original version of an instance, in addition to the current version, when\nprinting an [[instance]].", :type :var} {:name instance, :file "toucan2/instance.clj", :line 235, :arglists ([] [model] [model m] [model k v & more]), :doc "Create a new Toucan 2 instance. See the namespace docstring for [[toucan2.instance]] for more information about *what*\na Toucan 2 instance is.\n\nThis function has several arities:\n\n* With no args, creates an empty instance with its *model* set to `nil`\n\n* With one arg, creates an empty instance of a *model*.\n\n* With two args, creates an instance of a *model* from an existing map. This is optimized: if the map is already an\n instance of the model, returns the map as-is.\n\n* With three or more args, creates an instance of a *model* with key-value args.", :type :var} {:name instance-of?, :file "toucan2/instance.clj", :line 39, :arglists ([model x]), :doc "True if `x` is a Toucan2 instance, and its [[protocols/model]] `isa?` `model`.\n\n```clj\n(instance-of? ::bird (instance ::toucan {})) ; -> true\n(instance-of? ::toucan (instance ::bird {})) ; -> false\n```", :type :var} {:name instance?, :file "toucan2/instance.clj", :line 28, :arglists ([x]), :doc "True if `x` is a Toucan2 instance, i.e. a `toucan2.instance.Instance` or some other class that satisfies the correct\ninterfaces.\n\nToucan instances need to implement [[protocols/IModel]], [[protocols/IWithModel]], and [[protocols/IRecordChanges]].", :type :var} {:name reset-original, :file "toucan2/instance.clj", :line 287, :arglists ([an-instance]), :doc "Return a copy of `an-instance` with its `original` value set to its current value, discarding the previous original\nvalue. No-ops if `an-instance` is not a Toucan 2 instance.", :type :var} {:name update-current, :file "toucan2/instance.clj", :line 305, :arglists ([an-instance f & args]), :doc "Applies `f` directly to the underlying `current` map of `an-instance`; useful if you need to operate on it directly.\nActs like regular `(apply f instance args)` if `an-instance` is not an [[Instance]].", :type :var} {:name update-original, :file "toucan2/instance.clj", :line 297, :arglists ([an-instance f & args]), :doc "Applies `f` directly to the underlying `original` map of `an-instance`. No-ops if `an-instance` is not\nan [[Instance]].", :type :var} {:name update-original-and-current, :file "toucan2/instance.clj", :line 311, :arglists ([an-instance f & args]), :doc "Like `(apply f instance args)`, but affects both the `original` map and `current` map of `an-instance` rather than\njust the current map. Acts like regular `(apply f instance args)` if `instance` is not an `Instance`.\n\n`f` is applied directly to the underlying `original` and `current` maps of `instance` itself. `f` is only applied\nonce if `original` and `current` are currently the same object (i.e., the new `original` and `current` will also be\nthe same object). If `current` and `original` are not the same object, `f` is applied twice.", :type :var}), :doc "Toucan 2 instances are a custom map type that does two things regular maps do not do:\n\n1. They are associated with a particular model; [[toucan2.protocols/model]] can be used to get it. This is usually set\n when the instance comes out of that database.\n\n2. They track their [[toucan2.protocols/original]] version when they come out of the application database. This can in\n turn be used to calculate the [[toucan2.protocols/changes]] that have been made, which powers features\n like [[toucan2.save/save!]].\n\nNormally a Toucan instance is considered equal to a plain map with the same\ncurrent (via [[toucan2.protocols/current]]) value. It is considered equal to other instances if they have the same\ncurrent value and their model is the same."} {:name toucan2.jdbc, :publics ()} {:name toucan2.jdbc.connection, :publics ()} {:name toucan2.jdbc.mysql-mariadb, :publics (), :doc "MySQL and MariaDB integration (mostly workarounds for broken stuff).\n"} {:name toucan2.jdbc.options, :publics ({:name *options*, :file "toucan2/jdbc/options.clj", :line 9, :dynamic true, :doc "Options to pass to `next.jdbc` when executing queries or statements. Overrides the [[global-options]].\n", :type :var} {:name global-options, :file "toucan2/jdbc/options.clj", :line 5, :doc "Default options automatically passed to all `next.jdbc` queries and builder functions. This is stored\nas an atom; `reset!` or `swap!` it to define other default options.", :type :var} {:name merge-options, :file "toucan2/jdbc/options.clj", :line 13, :arglists ([extra-options]), :doc "Merge maps of `next.jdbc` options together. `extra-options` are ones passed in as part of the query execution pipeline\nand override [[*options*]], which in turn override the default [[global-options]].", :type :var})} {:name toucan2.jdbc.pipeline, :publics ()} {:name toucan2.jdbc.postgres, :publics (), :doc "PostgreSQL integration.\n"} {:name toucan2.jdbc.read, :publics ({:name get-object-of-class-thunk, :file "toucan2/jdbc/read.clj", :line 81, :arglists ([rset i klass]), :doc "Return a thunk that will be used to fetch values at column index `i` from ResultSet `rset` as a given class. Calling\nthis thunk is equivalent to\n\n```clj\n(.getObject rset i klass)\n```\n\nbut includes extra logging.", :type :var} {:name read-column-thunk, :file "toucan2/jdbc/read.clj", :line 32, :arglists ([conn₁ model₂ rset rsmeta₍₃₎ i]), :doc "Return a zero-arg function that, when called, will fetch the value of the column from the current row.\n\n Dispatches on `java.sql.Connection` class, `model`, and the `java.sql.Types` mapping for the column, e.g.\n `java.sql.Types/TIMESTAMP`.\n\n ### TODO -- dispatch for this method is busted.\n\n 1. The `java.sql.Types` column type should be an explicit parameter. A little weird to dispatch off of something\n that's not even one of the parameters\n\n 2. Should this also dispatch off of the actual underlying column name? So you can read a column in different ways for\n different models.\n\n 3. Should this dispatch off of the underlying database column type name string, e.g. `timestamp` or `timestamptz`? It\n seems like a lot of the time we need to do different things based on that type name.\n\nread-column-thunk is defined in [[toucan2.jdbc.read]] (toucan2/jdbc/read.clj:32).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{[:toucan2.jdbc.mysql-mariadb/connection :default 93] #{[java.sql.Connection :default 93]}, [:toucan2.jdbc.postgres/connection :default 93] #{[java.sql.Connection :default 93]}}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.jdbc.read]] (toucan2/jdbc/read.clj:68) \n\n* `[:default :default 92]`, defined in [[toucan2.jdbc.read]] (toucan2/jdbc/read.clj:123) \n\n* `[:default :default 2005]`, defined in [[toucan2.jdbc.read]] (toucan2/jdbc/read.clj:106) \n\n* `[:toucan2.jdbc.mysql-mariadb/connection :default 93]`, defined in [[toucan2.jdbc.mysql-mariadb]] (toucan2/jdbc/mysql_mariadb.clj:27) \n \n It has the following documentation:\n \n MySQL/MariaDB `timestamp` is normalized to UTC, so return it as an `OffsetDateTime` rather than a `LocalDateTime`.\n `datetime` columns should be returned as `LocalDateTime`. Both `timestamp` and `datetime` seem to come back as\n `java.sql.Types/TIMESTAMP`, so check the actual database column type name so we can fetch objects as the correct\n class.\n\n* `[:toucan2.jdbc.postgres/connection :default 93]`, defined in [[toucan2.jdbc.postgres]] (toucan2/jdbc/postgres.clj:18) \n \n It has the following documentation:\n \n Both Postgres `timestamp` and `timestamp with time zone` come back as `java.sql.Types/TIMESTAMP`; check the actual\n database column type name so we can fetch objects as the correct class.\n\n* `[:default :default 2014]`, defined in [[toucan2.jdbc.read]] (toucan2/jdbc/read.clj:115) \n\n* `[:default :default 93]`, defined in [[toucan2.jdbc.read]] (toucan2/jdbc/read.clj:111) \n\n* `[:default :default 91]`, defined in [[toucan2.jdbc.read]] (toucan2/jdbc/read.clj:119) \n\n* `[:default :default 2013]`, defined in [[toucan2.jdbc.read]] (toucan2/jdbc/read.clj:127) \n\nThese aux methods are known:\n\n`:after` methods:\n\n* `:default`, defined in [[toucan2.jdbc.read]] (toucan2/jdbc/read.clj:75) ", :type :var} {:name type-name, :file "toucan2/jdbc/read.clj", :line 22, :arglists ([i] [i not-found]), :doc "Map of `java.sql.Types` enum integers (e.g. `java.sql.Types/FLOAT`, whose value is `6`) to the string type name e.g.\n`FLOAT`.\n\n```clj\n(type-name java.sql.Types/FLOAT) -> (type-name 6) -> \"FLOAT\"\n```", :type :var}), :doc "[[read-column-thunk]] method, which is used to determine how to read values of columns in results, and default\nimplementations"} {:name toucan2.jdbc.result-set, :publics ({:name builder-fn, :file "toucan2/jdbc/result_set.clj", :line 25, :arglists ([conn₁ model₂ rset opts]), :doc "Return the `next.jdbc` builder function to use to create the results when querying a model. By default, this\n uses [[instance-builder-fn]], and returns Toucan 2 instances; but if you want to use plain maps you can use one of the\n other builder functions that ships with `next.jdbc`, or write your own custom builder function.\n\nbuilder-fn is defined in [[toucan2.jdbc.result-set]] (toucan2/jdbc/result_set.clj:25).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.jdbc.result-set]] (toucan2/jdbc/result_set.clj:119) \n \n It has the following documentation:\n \n Default `next.jdbc` builder function. Uses [[instance-builder-fn]] to return Toucan 2 instances.\n\n* `[:toucan2.jdbc.mysql-mariadb/connection :default]`, defined in [[toucan2.jdbc.mysql-mariadb]] (toucan2/jdbc/mysql_mariadb.clj:133) \n \n It has the following documentation:\n \n This is an icky hack for MariaDB/MySQL. Inserted rows come back with the newly inserted ID as `:insert-id` rather than\n the actual name of the primary key column. So tweak the `:label-fn` we pass to `next.jdbc` to rename `:insert-id` to\n the actual PK name we'd expect. This only works for tables with a single-column PK.", :type :var} {:name instance-builder-fn, :file "toucan2/jdbc/result_set.clj", :line 96, :arglists ([model rset opts]), :doc "Create a result set map builder function appropriate for passing as the `:builder-fn` option to `next.jdbc` that\nwill create [[toucan2.instance]]s of `model` using namespaces determined\nby [[toucan2.model/table-name->namespace]].", :type :var}), :doc "Implementation of a custom `next.jdbc` result set builder function, [[builder-fn]], and the default\nimplementation; [[reduce-result-set]] which is used to reduce results from JDBC databases."} {:name toucan2.log, :publics ({:name *level*, :file "toucan2/log.clj", :line 16, :dynamic true, :doc "The current log level (as a keyword) to log messages directly to stdout with. By default this is `nil`, which means\ndon't log any messages to stdout regardless of their level. (They are still logged via `clojure.tools.logging`.)\n\nYou can dynamically bind this to enable logging at a higher level in the REPL for debugging purposes. You can also set\na default value for this by setting the atom [[level]].", :type :var} {:name debugf, :file "toucan2/log.clj", :line 252, :arglists ([throwable? s] [throwable? format-string & args]), :doc "Most log messages should be this level.\n", :type :macro} {:name errorf, :file "toucan2/log.clj", :line 220, :arglists ([throwable? s] [throwable? format-string & args]), :doc "Log an error message for a `topic`. Optionally include a `throwable`. Only things that are actually serious errors\nshould be logged at this level.", :type :macro} {:name infof, :file "toucan2/log.clj", :line 242, :arglists ([throwable? s] [throwable? format-string & args]), :doc "Only things that all users should see by default without configuring a logger should be this level.\n", :type :macro} {:name level, :file "toucan2/log.clj", :line 24, :doc "The default log level to log messages directly to stdout with. Takes the value of the env var\n`TOUCAN_DEBUG_LEVEL`, if set. Can be overridden with [[*level*]]. This is stored as an atom, so you can `swap!` or\n`reset!` it.", :type :var} {:name tracef, :file "toucan2/log.clj", :line 262, :arglists ([throwable? s] [throwable? format-string & args]), :doc "Log messages that are done once-per-row should be this level.\n", :type :macro} {:name warnf, :file "toucan2/log.clj", :line 231, :arglists ([throwable? s] [throwable? format-string & args]), :doc "Log a warning for a `topic`. Optionally include a `throwable`. Bad things that can be worked around should be logged at\nthis level.", :type :macro}), :doc "Toucan 2 logging utilities. This is basically just a fancy wrapper around `clojure.tools.logging` that supports some\nadditional debugging facilities, such as dynamically enabling logging for different topics or levels from the REPL."} {:name toucan2.model, :publics ({:name default-connectable, :file "toucan2/model.clj", :line 42, :arglists ([model₁]), :doc "The default connectable that should be used when executing queries for `model` if\n no [[toucan2.connection/*current-connectable*]] is currently bound. By default, this just returns the global default\n connectable, `:default`, but you can tell Toucan to use a different default connectable for a model by implementing\n this method.\n\ndefault-connectable is defined in [[toucan2.model]] (toucan2/model.clj:42).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.model]] (toucan2/model.clj:50) \n \n It has the following documentation:\n \n Return `nil`, so we can fall thru to something else (presumably `:default` anyway)?", :type :var} {:name model->namespace, :file "toucan2/model.clj", :line 162, :arglists ([model₁]), :doc "Return a map of namespaces to use when fetching results with this model.\n\n ```clj\n (m/defmethod model->namespace ::my-model\n [_model]\n {::my-model \"x\"\n ::another-model \"y\"})\n ```\n\nmodel->namespace is defined in [[toucan2.model]] (toucan2/model.clj:162).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.model]] (toucan2/model.clj:176) \n \n It has the following documentation:\n \n By default, don't namespace column names when fetching rows.\n\nThese aux methods are known:\n\n`:after` methods:\n\n* `:default`, defined in [[toucan2.model]] (toucan2/model.clj:181) \n \n It has the following documentation:\n \n Validate the results.", :type :var} {:name namespace, :file "toucan2/model.clj", :line 205, :arglists ([model]), :doc "Get the namespace that should be used to prefix keys associated with a `model` in query results. This is taken from the\nmodel's implementation of [[model->namespace]].", :type :var} {:name primary-key-values-map, :file "toucan2/model.clj", :line 141, :arglists ([instance] [model m]), :doc "Return a map of primary key values for a Toucan 2 `instance`.\n", :type :var} {:name primary-keys, :file "toucan2/model.clj", :line 106, :arglists ([model₁]), :doc "Return a sequence of the primary key columns names, as keywords, for a model. The default primary keys for a model are\n `[:id]`; implement this method if your model has different primary keys.\n\n ```clj\n ;; tell Toucan that :model/bird has a composite primary key consisting of the columns :id and :name\n (m/defmethod primary-keys :model/bird\n [_model]\n [:id :name])\n ```\n\n If an implementation returns a single keyword, the default `:around` method will automatically wrap it in a vector. It\n also validates that the ultimate result is a sequence of keywords, so it is safe to assume that calls to this will\n always return a sequence of keywords.\n\nprimary-keys is defined in [[toucan2.model]] (toucan2/model.clj:106).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.model]] (toucan2/model.clj:215) \n \n It has the following documentation:\n \n By default the primary key for a model is the column `:id`; or `:some-namespace/id` if the model defines a namespace\n for itself with [[model->namespace]].\n\nThese aux methods are known:\n\n`:around` methods:\n\n* `:default`, defined in [[toucan2.model]] (toucan2/model.clj:125) \n \n It has the following documentation:\n \n If the PK comes back unwrapped, wrap it -- make sure results are always returned as a vector of keywords. Throw an\n error if results are in the incorrect format.", :type :var} {:name resolve-model, :file "toucan2/model.clj", :line 18, :arglists ([modelable₁]), :doc "Resolve a *modelable* to an actual Toucan *model* (usually a keyword). A modelable is anything that can be resolved to\n a model via this method. You can implement this method to define special model resolution behavior, for example\n `toucan2-toucan1` defines a method for `clojure.lang.Symbol` that does namespace resolution to return an appropriate\n model keyword.\n\n You can also implement this method to do define behaviors when a model is used, for example making sure some namespace\n with method implementation for the model is loaded, logging some information, etc.\n\nresolve-model is defined in [[toucan2.model]] (toucan2/model.clj:18).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.model]] (toucan2/model.clj:29) \n \n It has the following documentation:\n \n Default implementation. Return `modelable` as is, i.e., there is nothing to resolve, and we can use it directly as a\n model.\n\nThese aux methods are known:\n\n`:around` methods:\n\n* `:default`, defined in [[toucan2.model]] (toucan2/model.clj:35) \n \n It has the following documentation:\n \n Log model resolution as it happens for debugging purposes.", :type :var} {:name select-pks-fn, :file "toucan2/model.clj", :line 149, :arglists ([modelable]), :doc "Return a function to get the value(s) of the primary key(s) from a row, as a single value or vector of values. Used\nby [[toucan2.select/select-pks-reducible]] and thus\nby [[toucan2.select/select-pks-set]], [[toucan2.select/select-pks-vec]], etc.\n\nThe primary keys are determined by [[primary-keys]]. By default this is simply the keyword `:id`.", :type :var} {:name table-name, :file "toucan2/model.clj", :line 55, :arglists ([model₁]), :doc "Return the actual underlying table name that should be used to query a `model`.\n\n By default for things that implement `name`, the table name is just `(keyword (name x))`.\n\n ```clj\n (t2/table-name :models/user)\n ;; =>\n :user\n ```\n\n You can write your own implementations for this for models whose table names do not match their `name`.\n\n This is guaranteed to return a keyword, so it can easily be used directly in Honey SQL queries and the like; if you\n return something else, the default `:after` method will convert it to a keyword for you.\n\ntable-name is defined in [[toucan2.model]] (toucan2/model.clj:55).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.model]] (toucan2/model.clj:75) \n \n It has the following documentation:\n \n Fallback implementation. Redirects keywords to the implementation for `clojure.lang.Named` (use the `name` of the\n keyword). For everything else, throws an error, since we don't know how to get a table name from it.\n\n* `clojure.lang.Named`, defined in [[toucan2.model]] (toucan2/model.clj:91) \n \n It has the following documentation:\n \n Default implementation for anything that is a `clojure.lang.Named`, such as a keywords or symbols. Use the `name` as\n the table name.\n \n ```clj\n (t2/table-name :models/user) => :user\n ```\n\n* `java.lang.String`, defined in [[toucan2.model]] (toucan2/model.clj:101) \n \n It has the following documentation:\n \n Implementation for strings. Use the string name as-is.\n\nThese aux methods are known:\n\n`:after` methods:\n\n* `:default`, defined in [[toucan2.model]] (toucan2/model.clj:84) \n \n It has the following documentation:\n \n Always return table names as keywords. This will facilitate using them directly inside Honey SQL, e.g.\n \n {:select [:*], :from [(t2/table-name MyModel)]}", :type :var} {:name table-name->namespace, :file "toucan2/model.clj", :line 191, :arglists ([model]), :doc "Take the [[model->namespace]] map for a model and return a map of string table name -> namespace. This is used to\ndetermine how to prefix columns in results based on their table name;\nsee [[toucan2.jdbc.result-set/instance-builder-fn]] for an example of this usage.", :type :var}), :doc "Methods related to resolving Toucan 2 models, appropriate table names to use when building queries for them, and\nnamespaces to use for columns in query results."} {:name toucan2.pipeline, :publics ({:name *build*, :file "toucan2/pipeline.clj", :line 213, :arglists ([query-type model parsed-args resolved-query]), :dynamic true, :doc "The function to use when building a query. Normally [[build]], but you can bind this to intercept build behavior to\ndo something different.", :type :var} {:name *compile*, :file "toucan2/pipeline.clj", :line 218, :arglists ([query-type model built-query]), :dynamic true, :doc "The function to use when compiling a query. Normally [[compile]], but you can bind this to intercept normal\ncompilation behavior to do something different.", :type :var} {:name *parsed-args*, :file "toucan2/pipeline.clj", :line 229, :dynamic true, :doc "The parsed args seen at the beginning of the pipeline. This is bound in case methods in later stages of the pipeline,\nsuch as [[results-transform]], need it for one reason or another. (See for example [[toucan2.tools.default-fields]],\nwhich applies different behavior if a query was initiated with `[model & columns]` syntax vs. if it was not.)", :type :var} {:name *resolved-query*, :file "toucan2/pipeline.clj", :line 235, :dynamic true, :doc "The query after it has been resolved. This is bound in case methods in the later stages of the pipeline need it for one\nreason or another.", :type :var} {:name build, :file "toucan2/pipeline.clj", :line 145, :arglists ([query-type₁ model₂ parsed-args resolved-query₃]), :doc "Build a query by applying `parsed-args` to `resolved-query` into something that can be compiled by [[compile]], e.g.\n build a Honey SQL query by applying `parsed-args` to an initial `resolved-query` map.\n\n You can implement this method to write a custom query compilation backend, for example to compile some certain record\n type in a special way. See [[toucan2.honeysql2]] for an example implementation.\n\n In addition to dispatching on `query-type` and `model`, this dispatches on the type of `resolved-query`, in a special\n way: for plain maps this will dispatch on the current [[map/backend]].\n\nbuild is defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:145).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `[:default :default java.lang.String]`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:181) \n \n It has the following documentation:\n \n Default implementation for plain strings. Wrap the string in a vector and recurse.\n\n* `[:toucan.query-type/select.count :default clojure.lang.IPersistentMap]`, defined in [[toucan2.honeysql2]] (toucan2/honeysql2.clj:140) \n \n It has the following documentation:\n \n Build an efficient `count(*)` query to power [[toucan2.select/count]].\n\n* `[:toucan.query-type/insert.* :toucan2.tools.before-insert/before-insert clojure.lang.IPersistentMap]`, defined in [[toucan2.tools.before-insert]] (toucan2/tools/before_insert.clj:39) \n \n It has the following documentation:\n \n Apply [[before-insert]] to `:rows` in the `resolved-query` or `parsed-args` for Honey SQL queries.\n\n* `[:toucan.query-type/select.exists :default clojure.lang.IPersistentMap]`, defined in [[toucan2.honeysql2]] (toucan2/honeysql2.clj:148) \n \n It has the following documentation:\n \n Build an efficient query like `SELECT exists(SELECT 1 FROM ...)` query to power [[toucan2.select/exists?]].\n\n* `[:default :default nil]`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:164) \n \n It has the following documentation:\n \n Something like (select my-model nil) should basically mean SELECT * FROM my_model WHERE id IS NULL\n\n* `:default`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:160) \n\n* `[:toucan.query-type/update.* :default :default]`, defined in [[toucan2.update]] (toucan2/update.clj:31) \n \n It has the following documentation:\n \n Default method for building UPDATE queries. Code for building Honey SQL for UPDATE lives\n in [[toucan2.honeysql2]].\n \n This doesn't really do much, but if the query has no `:changes`, returns the special flag `:toucan2.pipeline/no-op`.\n\n* `[:toucan.query-type/insert.* :default clojure.lang.IPersistentMap]`, defined in [[toucan2.honeysql2]] (toucan2/honeysql2.clj:163) \n \n It has the following documentation:\n \n Build a Honey SQL 2 INSERT query.\n \n if `rows` is just a single empty row then insert it with\n \n ```sql\n INSERT INTO table DEFAULT VALUES\n ```\n \n (Postgres/H2/etc.)\n \n or\n \n ```sql\n INSERT INTO table () VALUES ()\n ```\n \n (MySQL/MariaDB)\n\n* `[:toucan.query-type/insert.* :default :default]`, defined in [[toucan2.insert]] (toucan2/insert.clj:60) \n \n It has the following documentation:\n \n Default INSERT query method. No-ops if there are no `:rows` to insert in either `parsed-args` or `resolved-query`.\n\n* `[:default :default clojure.lang.Sequential]`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:186) \n \n It has the following documentation:\n \n Default implementation of vector [query & args] queries.\n\n* `[:toucan.query-type/select.instances.from-update :default clojure.lang.IPersistentMap]`, defined in [[toucan2.honeysql2]] (toucan2/honeysql2.clj:217) \n \n It has the following documentation:\n \n Treat the resolved query as a conditions map but otherwise behave the same as the `:toucan.query-type/select.instances`\n impl.\n\n* `[:toucan.query-type/select.* :default clojure.lang.IPersistentMap]`, defined in [[toucan2.honeysql2]] (toucan2/honeysql2.clj:120) \n \n It has the following documentation:\n \n Build a Honey SQL 2 SELECT query.\n\n* `[:toucan.query-type/select.* :toucan2.tools.before-select/model :default]`, defined in [[toucan2.tools.before-select]] (toucan2/tools/before_select.clj:29) \n\n* `[:default :default clojure.lang.IPersistentMap]`, defined in [[toucan2.honeysql2]] (toucan2/honeysql2.clj:111) \n \n It has the following documentation:\n \n Base map backend implementation. Applies the `:kv-args` in `parsed-args` using [[query/apply-kv-args]], and ignores\n other parsed args.\n\n* `[:default :default java.lang.Integer]`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:171) \n \n It has the following documentation:\n \n Treat lone integers as queries to select an integer primary key.\n\n* `[:default :default java.lang.Long]`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:176) \n \n It has the following documentation:\n \n Treat lone integers as queries to select an integer primary key.\n\n* `[:toucan.query-type/delete.* :default clojure.lang.IPersistentMap]`, defined in [[toucan2.honeysql2]] (toucan2/honeysql2.clj:237) \n \n It has the following documentation:\n \n Build a Honey SQL 2 DELETE query.\n \n If the table for `model` should not be aliased (i.e., [[toucan2.model/namespace]] returns `nil`), builds a query that\n compiles to something like:\n \n ```sql\n DELETE FROM my_table\n WHERE ...\n ```\n \n If the table is aliased, this looks like\n \n ```sql\n DELETE FROM my_table AS t1\n WHERE ...\n ```\n \n for Postgres/H2/etc., or like\n \n ```sql\n DELETE t1\n FROM my_table AS t1\n WHERE ...\n ```\n \n for MySQL/MariaDB. MySQL/MariaDB does not seem to support aliases in `DELETE FROM`, so we need to use this alternative\n syntax; H2 doesn't support it however. So it has to be compiled differently based on the DB.\n\n* `[:toucan.query-type/update.* :default clojure.lang.IPersistentMap]`, defined in [[toucan2.honeysql2]] (toucan2/honeysql2.clj:196) \n \n It has the following documentation:\n \n Build a Honey SQL 2 UPDATE query.", :type :var} {:name compile, :file "toucan2/pipeline.clj", :line 109, :arglists ([query-type₁ model₂ built-query₃]), :doc "Compile a `built-query` to something that can be executed natively by the query execution backend, e.g. compile a Honey\n SQL map to a `[sql & args]` vector.\n\n You can implement this method to write a custom query compilation backend, for example to compile some certain record\n type in a special way. See [[toucan2.honeysql2]] for an example implementation.\n\n In addition to dispatching on `query-type` and `model`, this dispatches on the type of `built-query`, in a special\n way: for plain maps this will dispatch on the current [[map/backend]].\n\ncompile is defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:109).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:123) \n \n It has the following documentation:\n \n Default implementation: return query as-is (i.e., consider it to already be compiled). Check that the query is non-nil\n and, if it is a collection, non-empty. Everything else is fair game.\n\n* `[:default :default java.lang.String]`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:137) \n \n It has the following documentation:\n \n Compile a string query. Default impl wraps the string in a vector and recursively calls [[compile]].\n\n* `[:default :default clojure.lang.IPersistentMap]`, defined in [[toucan2.honeysql2]] (toucan2/honeysql2.clj:277) \n \n It has the following documentation:\n \n Compile a Honey SQL 2 map to [sql & args].", :type :var} {:name compile*, :file "toucan2/pipeline.clj", :line 407, :arglists ([built-query] [query-type built-query] [query-type model built-query]), :doc "Helper for compiling a `built-query` to something that can be executed natively.\n", :type :var} {:name default-rf, :file "toucan2/pipeline.clj", :line 329, :arglists ([query-type]), :doc "The default reducing function for queries of `query-type`. Used for non-reducible operations\n like [[toucan2.select/select]] or [[toucan2.execute/query]].\n\ndefault-rf is defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:329).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:toucan.result-type/update-count`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:337) \n \n It has the following documentation:\n \n The reducing function for queries returning an update count. Sums all numbers passed in.\n\n* `:toucan.result-type/pks`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:344) \n \n It has the following documentation:\n \n The reducing function for queries returning PKs. Presumably these will come back as a map, but that map doesn't need to\n be realized. This needs to be combined with a transducer like `map` [[toucan2.model/select-pks-fn]] to get the PKs\n themselves.\n\n* `:toucan.result-type/*`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:351) \n \n It has the following documentation:\n \n The default reducing function for all query types unless otherwise specified. Returns realized maps (by default, Toucan\n 2 instances).", :type :var} {:name resolve, :file "toucan2/pipeline.clj", :line 200, :arglists ([query-type₁ model₂ queryable₃]), :doc "Resolve a `queryable` to an actual query, e.g. resolve a named query defined by [[toucan2.tools.named-query]] to an\n actual Honey SQL map.\n\nresolve is defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:200).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:208) \n \n It has the following documentation:\n \n The default implementation considers a query to already be resolved, and returns it as-is.", :type :var} {:name results-transform, :file "toucan2/pipeline.clj", :line 80, :arglists ([query-type₁ model₂]), :doc "The transducer that should be applied to the reducing function executed when running a query of\n `query-type` (see [[toucan2.types]]) for `model` (`nil` if the query is ran without a model, e.g.\n with [[toucan2.execute/query]]). The default implementation returns `identity`; add your own implementations as\n desired to apply additional results transforms.\n\n Be sure to `comp` the transform from `next-method`:\n\n ```clj\n (m/defmethod t2/results-transform [:toucan.query-type/select.* :my-model]\n [query-type model]\n (comp (next-method query-type model)\n (map (fn [instance]\n (assoc instance :num-cans 2)))))\n ```\n\n It's probably better to put the transducer returned by `next-method` first in the call to `comp`, because `cond` works\n like `->` when composing transducers, and since `next-method` is by definition the less-specific method, it makes\n sense to call that transform before we apply our own. This means our own transforms will get to see the results of the\n previous stage, rather than vice-versa.\n\nresults-transform is defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:80).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{[:toucan.result-type/instances :toucan2.tools.after-select/after-select] #{[:toucan.result-type/instances :toucan2.tools.after/model]}}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:105) \n\n* `[:toucan.result-type/instances :toucan2.tools.after/model]`, defined in [[toucan2.tools.after]] (toucan2/tools/after.clj:38) \n\n* `[:toucan.result-type/instances :toucan2.tools.after-select/after-select]`, defined in [[toucan2.tools.after-select]] (toucan2/tools/after_select.clj:20) ", :type :var} {:name transduce-execute-with-connection, :file "toucan2/pipeline.clj", :line 43, :arglists ([rf conn₁ query-type₂ model₃ compiled-query]), :doc "The final stage of the Toucan 2 query execution pipeline. Execute a compiled query (as returned by [[compile]]) with a\n database connection, e.g. a `java.sql.Connection`, and transduce results with reducing function `rf`.\n\n The only reason you should need to implement this method is if you are writing a new query execution backend.\n\ntransduce-execute-with-connection is defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:43).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{[:toucan2.jdbc.mysql-mariadb/connection :toucan.query-type/insert.pks :default] #{[java.sql.Connection :toucan.result-type/pks :default]}, [:toucan2.jdbc.mysql-mariadb/connection :toucan.query-type/update.pks :default] #{[java.sql.Connection :toucan.result-type/pks :default]}}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `[java.sql.Connection :default :default]`, defined in [[toucan2.jdbc.pipeline]] (toucan2/jdbc/pipeline.clj:9) \n \n It has the following documentation:\n \n Default impl for the JDBC query execution backend.\n\n* `[java.sql.Connection :toucan.result-type/pks :default]`, defined in [[toucan2.jdbc.pipeline]] (toucan2/jdbc/pipeline.clj:22) \n \n It has the following documentation:\n \n JDBC query execution backend for executing queries that return PKs (`:toucan.result-type/pks`).\n \n Applies transducer to call [[toucan2.model/select-pks-fn]] on each result row.\n\n* `[java.sql.Connection :toucan2.jdbc.pipeline/DML-queries-returning-instances :default]`, defined in [[toucan2.jdbc.pipeline]] (toucan2/jdbc/pipeline.clj:52) \n \n It has the following documentation:\n \n DML queries like `UPDATE` or `INSERT` don't usually support returning instances, at least not with JDBC. So for these\n situations we'll fake it by first running an equivalent query returning inserted/affected PKs, and then do a\n subsequent SELECT to get those rows. Then we'll reduce the rows with the original reducing function.\n\n* `[:toucan2.jdbc.mysql-mariadb/connection :toucan.query-type/insert.pks :default]`, defined in [[toucan2.jdbc.mysql-mariadb]] (toucan2/jdbc/mysql_mariadb.clj:46) \n \n It has the following documentation:\n \n Apparently `RETURN_GENERATED_KEYS` doesn't work for MySQL/MariaDB if:\n \n 1. Values for the primary key are specified in the INSERT itself, *and*\n \n 2. The primary key is not an integer.\n \n So to work around this we will look at the rows we're inserting: if every rows specifies the primary key\n column(s) (including `nil` values), we'll transduce those specified values rather than what JDBC returns.\n \n This seems like it won't work if these values were arbitrary Honey SQL expressions. I suppose we could work around\n THAT problem by running the primary key values thru another SELECT query... but that just seems like too much. I guess\n we can cross that bridge when we get there.\n\n* `[:toucan2.jdbc.mysql-mariadb/connection :toucan.query-type/update.pks :default]`, defined in [[toucan2.jdbc.mysql-mariadb]] (toucan2/jdbc/mysql_mariadb.clj:98) \n \n It has the following documentation:\n \n MySQL and MariaDB don't support returning PKs for UPDATE. Execute a SELECT query to capture the PKs of the rows that\n will be affected BEFORE performing the UPDATE. We need to capture PKs for both `:toucan.query-type/update.pks` and for\n `:toucan.query-type/update.instances`, since ultimately the latter is implemented on top of the former.\n\nThese aux methods are known:\n\n`:before` methods:\n\n* `:default`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:57) \n \n It has the following documentation:\n \n Count all queries that are executed by calling [[*call-count-thunk*]] if bound.", :type :var} {:name transduce-query, :file "toucan2/pipeline.clj", :line 254, :arglists ([rf query-type₁ model₂ parsed-args resolved-query₃]), :doc "One of the primary customization points for the Toucan 2 query execution pipeline. [[build]] and [[compile]] a\n `resolved-query`, then open a connection, execute the query, and transduce the results\n with [[transduce-execute-with-connection]] (using the [[results-transform]]).\n\n You can implement this method to introduce custom behavior that should happen before a query is built or compiled,\n e.g. transformations to the `parsed-args` or other shenanigans like changing underlying query type being\n executed (e.g. [[toucan2.tools.after]], which 'upgrades' queries returning update counts or PKs to ones returning\n instances so [[toucan2.tools.after-update]] and [[toucan2.tools.after-insert]] can be applied to affected rows).\n\ntransduce-query is defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:254).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.pipeline]] (toucan2/pipeline.clj:269) \n\n* `[:toucan2.tools.after/query-type :toucan2.tools.after/model :default]`, defined in [[toucan2.tools.after]] (toucan2/tools/after.clj:84) \n \n It has the following documentation:\n \n 'Upgrade' a query so that it returns instances, and run the upgraded query so that we can apply [[each-row-fn]] to the\n results. Then apply [[result-type-rf]] to the results of the original expected type are ultimately returned.\n\n* `[:toucan.query-type/delete.* :toucan2.tools.before-delete/before-delete :default]`, defined in [[toucan2.tools.before-delete]] (toucan2/tools/before_delete.clj:43) \n \n It has the following documentation:\n \n Do a recursive SELECT query with the args passed to `delete!`; apply [[before-delete]] to all matching rows. Then call\n the `next-method`. This is all done inside of a transaction.\n\nThese aux methods are known:\n\n`:around` methods:\n\n* `[:toucan.query-type/insert.* :toucan2.tools.before-insert/before-insert :default]`, defined in [[toucan2.tools.before-insert]] (toucan2/tools/before_insert.clj:31) \n \n It has the following documentation:\n \n Execute [[before-insert]] methods and the INSERT query inside a transaction.", :type :var}), :doc "This is a low-level namespace implementing our query execution pipeline. Most of the stuff you'd use on a regular basis\nare implemented on top of stuff here.\n\nPipeline order is\n\n1. [[toucan2.query/parse-args]] (entrypoint fn: [[transduce-unparsed]])\n2. [[toucan2.model/resolve-model]] (entrypoint fn: [[transduce-parsed]])\n3. [[resolve]]\n4. [[transduce-query]]\n5. [[build]]\n6. [[compile]]\n7. [[results-transform]]\n8. [[transduce-execute-with-connection]]\n\nThe main pipeline entrypoint is [[transduce-unparsed]]."} {:name toucan2.protocols, :publics ({:name IDeferrableUpdate, :file "toucan2/protocols.clj", :line 109, :type :protocol, :members ({:name deferrable-update, :arglists ([this k f]), :doc "Like [[clojure.core/update]], but this update can be deferred until later. For things like transient rows where you\nmight want to apply transforms to values that ultimately get realized, but not *cause* them to be realized. Unlike\n[[clojure.core/update]], does not support additional args to pass to `f`.", :type :var})} {:name IDispatchValue, :file "toucan2/protocols.clj", :line 88, :doc "Protocol to get the value to use for multimethod dispatch in Toucan from something.\n", :type :protocol, :members ({:name dispatch-value, :arglists ([this]), :doc "Get the value that we should dispatch off of in multimethods for `this`. By default, the dispatch of a keyword is\nitself while the dispatch value of everything else is its [[type]].", :type :var})} {:name IModel, :file "toucan2/protocols.clj", :line 7, :doc "Protocol for something that is-a or has-a model.\n", :type :protocol, :members ({:name model, :arglists ([this]), :doc "Get the Toucan model associated with `this`.\n", :type :var})} {:name IRecordChanges, :file "toucan2/protocols.clj", :line 30, :doc "Protocol for something that records the changes made to it, e.g. a Toucan instance.\n", :type :protocol, :members ({:name changes, :arglists ([instance]), :doc "Get a map with any changes made to `instance` since it came out of the DB. Only includes keys that have been\nadded or given different values; keys that were removed are not counted. Returns `nil` if there are no changes.", :type :var} {:name current, :arglists ([instance]), :doc "Return the underlying map representing the current state of an `instance`.\n", :type :var} {:name original, :arglists ([instance]), :doc "Get the original version of `instance` as it appeared when it first came out of the DB.\n", :type :var} {:name with-current, :arglists ([instance new-current]), :doc "Return a copy of `instance` with its underlying `current` map set to `new-current`.\n", :type :var} {:name with-original, :arglists ([instance new-original]), :doc "Return a copy of `instance` with its `original` map set to `new-original`.\n", :type :var})} {:name IWithModel, :file "toucan2/protocols.clj", :line 22, :doc "Protocol for something that has-a model that supports creating a copy with a different model.\n", :type :protocol, :members ({:name with-model, :arglists ([this new-model]), :doc "Return a copy of `instance` with its model set to `new-model.`\n", :type :var})})} {:name toucan2.query, :publics ({:name apply-kv-arg, :file "toucan2/query.clj", :line 124, :arglists ([model₁ resolved-query₂ k₃ v]), :doc "Merge a key-value pair into a `query`, presumably a map. What this means depends on\n the [[toucan2.protocols/dispatch-value]] of `query` -- for a plain map, the default Honey SQL backend applies `k` and\n `v` as a `:where` condition:\n\n ```clj\n (apply-kv-arg :default {} :k :v)\n ;; =>\n {:where [:= :k :v]}\n ```\n\n You can add new implementations of this method to special behaviors for support arbitrary keys, or to support new\n query backends. `:toucan/pk` support is implemented this way.\n\napply-kv-arg is defined in [[toucan2.query]] (toucan2/query.clj:124).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `[:default clojure.lang.IPersistentMap :default]`, defined in [[toucan2.honeysql2]] (toucan2/honeysql2.clj:44) \n \n It has the following documentation:\n \n Apply key-value args to a Honey SQL 2 query map.\n\nThese aux methods are known:\n\n`:around` methods:\n\n* `[:default :default :toucan/pk]`, defined in [[toucan2.query]] (toucan2/query.clj:202) \n \n It has the following documentation:\n \n Implementation for handling key-value args for `:toucan/pk`.\n \n This is an `:around` so we can intercept the normal handler. This 'unpacks' the PK and ultimately uses the normal\n calls to [[apply-kv-arg]].", :type :var} {:name apply-kv-args, :file "toucan2/query.clj", :line 216, :arglists ([model query kv-args]), :doc "Convenience. Merge a map of `kv-args` into a resolved `query` with repeated calls to [[apply-kv-arg]].\n", :type :var} {:name parse-args, :file "toucan2/query.clj", :line 91, :arglists ([query-type₁ unparsed-args]), :doc "`parse-args` takes a sequence of unparsed args passed to something like [[toucan2.select/select]] and parses them into\n a parsed args map. The default implementation uses [[clojure.spec.alpha]] to parse the args according to `args-spec`.\n\n These keys are commonly returned by several of the different implementations `parse-args`, and other tooling is\n build to leverage them:\n\n * `:modelable` -- usually the first of the `unparsed-args`, this is the thing that should get resolved to a model\n with [[toucan2.model/resolve-model]].\n\n * `:queryable` -- something that can be resolved to a query, for example a map or integer or 'named query' keyword.\n The resolved query is ultimately combined with other parsed args and built into something like a Honey SQL map, then\n compiled to something like SQL.\n\n * `:kv-args` -- map of key-value pairs. When [[build]] builds a query, it calls [[apply-kv-arg]] for each of the\n key-value pairs. The default behavior is to append a Honey SQL `:where` clause based on the pair; but you can\n customize the behavior for specific keywords to do other things -- `:toucan/pk` is one such example.\n\n * `:columns` -- for things that return instances, `:columns` is a sequence of columns to return. These are commonly\n specified by wrapping the modelable in a `[modelable & columns]` vector.\n\nparse-args is defined in [[toucan2.query]] (toucan2/query.clj:91).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.query]] (toucan2/query.clj:116) \n \n It has the following documentation:\n \n The default implementation calls [[parse-args-with-spec]] with the `:toucan2.query/default-args` spec.\n\n* `:toucan.query-type/insert.*`, defined in [[toucan2.insert]] (toucan2/insert.clj:32) \n \n It has the following documentation:\n \n Default args parsing method for [[toucan2.insert/insert!]]. Uses the spec `:toucan2.insert/args`.\n\n* `:toucan.query-type/update.*`, defined in [[toucan2.update]] (toucan2/update.clj:24) ", :type :var} {:name parse-args-with-spec, :file "toucan2/query.clj", :line 66, :arglists ([query-type spec unparsed-args]), :doc "Parse `unparsed-args` for `query-type` with the given `spec`. See documentation for [[parse-args]] for more details.\n", :type :var})} {:name toucan2.realize, :publics ({:name Realize, :file "toucan2/realize.clj", :line 10, :type :protocol, :members ({:name realize, :arglists ([x]), :doc "Fully realize either a reducible query, or a result row from that query.\n", :type :var})})} {:name toucan2.save, :publics ({:name save!, :file "toucan2/save.clj", :line 55, :arglists ([object] [connectable object]), :type :var} {:name save!*, :file "toucan2/save.clj", :line 19, :arglists ([object]), :doc "save!* is defined in [[toucan2.save]] (toucan2/save.clj:19).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese aux methods are known:\n\n`:around` methods:\n\n* `:default`, defined in [[toucan2.save]] (toucan2/save.clj:26) \n\nsave!* is defined in [[toucan2.save]] (toucan2/save.clj:19).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.save]] (toucan2/save.clj:34) \n\nThese aux methods are known:\n\n`:around` methods:\n\n* `:default`, defined in [[toucan2.save]] (toucan2/save.clj:26) ", :type :var})} {:name toucan2.select, :publics ({:name count, :file "toucan2/select.clj", :line 238, :arglists ([modelable-columns & kv-args? query?] [:conn connectable modelable-columns & kv-args? query?]), :doc "Like [[select]], but returns the number of rows that match in an efficient way.\n\n### Implementation note:\n\nThe default Honey SQL 2 map query compilation backend builds an efficient\n\n```sql\nSELECT count(*) AS \"count\" FROM ...\n```\n\nquery. Custom query compilation backends should do the equivalent by implementing [[toucan2.pipeline/build]] for the\nquery type `:toucan.query-type/select.count` and build a query that returns the key `:count`, If an efficient\nimplementation does not exist, this will fall back to simply counting all matching rows.", :type :var} {:name exists?, :file "toucan2/select.clj", :line 273, :arglists ([modelable-columns & kv-args? query?] [:conn connectable modelable-columns & kv-args? query?]), :doc "Like [[select]], but returns whether or not *any* rows match in an efficient way.\n\n### Implementation note:\n\nThe default Honey SQL 2 map query compilation backend builds an efficient\n\n```sql\nSELECT exists(SELECT 1 FROM ... WHERE ...) AS exists\n```", :type :var} {:name reducible-select, :file "toucan2/select.clj", :line 37, :arglists ([modelable-columns & kv-args? query?] [:conn connectable modelable-columns & kv-args? query?]), :doc "Like [[select]], but returns an `IReduceInit`.\n", :type :var} {:name select, :file "toucan2/select.clj", :line 44, :arglists ([modelable-columns & kv-args? query?] [:conn connectable modelable-columns & kv-args? query?]), :type :var} {:name select-fn->fn, :file "toucan2/select.clj", :line 181, :arglists ([f1 f2 modelable-columns & kv-args? query?] [f1 f2 :conn connectable modelable-columns & kv-args? query?]), :doc "Return a map of `(f1 instance)` -> `(f2 instance)` for instances matching the query.\n\n```clj\n(t2/select-fn->fn :id (comp str/upper-case :name) :models/people)\n;; => {1 \"CAM\", 2 \"SAM\", 3 \"PAM\", 4 \"TAM\"}\n```", :type :var} {:name select-fn->pk, :file "toucan2/select.clj", :line 197, :arglists ([f modelable-columns & kv-args? query?] [f :conn connectable modelable-columns & kv-args? query?]), :doc "The inverse of [[select-pk->fn]]. Return a map of `(f instance)` -> *primary key* for instances matching the query.\n\n```clj\n(t2/select-fn->pk (comp str/upper-case :name) :models/people)\n;; => {\"CAM\" 1, \"SAM\" 2, \"PAM\" 3, \"TAM\" 4}\n```", :type :var} {:name select-fn-reducible, :file "toucan2/select.clj", :line 60, :arglists ([f modelable-columns & kv-args? query?] [f :conn connectable modelable-columns & kv-args? query?]), :doc "Like [[reducible-select]], but returns a reducible sequence of results of `(f row)`.\n", :type :var} {:name select-fn-set, :file "toucan2/select.clj", :line 69, :arglists ([f modelable-columns & kv-args? query?] [f :conn connectable modelable-columns & kv-args? query?]), :doc "Like [[select]], but returns a *set* of values of `(f instance)` for the results. Returns `nil` if the set is empty.\n\n```clj\n(t2/select-fn-set (comp str/upper-case :category) :models/venues :category \"bar\")\n;; =>\n#{\"BAR\"}\n```", :type :var} {:name select-fn-vec, :file "toucan2/select.clj", :line 85, :arglists ([f modelable-columns & kv-args? query?] [f :conn connectable modelable-columns & kv-args? query?]), :doc "Like [[select]], but returns a *vector* of values of `(f instance)` for the results. Returns `nil` if the vector is\nempty.\n\n```clj\n(t2/select-fn-vec (comp str/upper-case :category) :models/venues :category \"bar\")\n;; =>\n[\"BAR\" \"BAR\"]\n```\n\nNOTE: If your query does not specify an `:order-by` clause (or equivalent), the results are like indeterminate. Keep\nthis in mind!", :type :var} {:name select-one, :file "toucan2/select.clj", :line 50, :arglists ([modelable-columns & kv-args? query?] [:conn connectable modelable-columns & kv-args? query?]), :doc "Like [[select]], but only fetches a single row, and returns only that row.\n", :type :var} {:name select-one-fn, :file "toucan2/select.clj", :line 105, :arglists ([f modelable-columns & kv-args? query?] [f :conn connectable modelable-columns & kv-args? query?]), :doc "Like [[select-one]], but applies `f` to the result.\n\n```clj\n(t2/select-one-fn :id :models/people :name \"Cam\")\n;; => 1\n```", :type :var} {:name select-one-pk, :file "toucan2/select.clj", :line 167, :arglists ([modelable-columns & kv-args? query?] [:conn connectable modelable-columns & kv-args? query?]), :doc "Return the primary key of the first row matching the query. Models with just a single primary key columns will be\n'unwrapped' (i.e., the values of that column will be returned); models with compound primary keys (i.e., more than one\ncolumn) will be returned in vectors as if by calling `juxt`.\n\n```clj\n(t2/select-one-pk :models/people :name \"Cam\")\n;; => 1\n```", :type :var} {:name select-pk->fn, :file "toucan2/select.clj", :line 210, :arglists ([f modelable-columns & kv-args? query?] [f :conn connectable modelable-columns & kv-args? query?]), :doc "The inverse of [[select-fn->pk]]. Return a map of *primary key* -> `(f instance)` for instances matching the query.\n\n```clj\n(t2/select-pk->fn (comp str/upper-case :name) :models/people)\n;; => {1 \"CAM\", 2 \"SAM\", 3 \"PAM\", 4 \"TAM\"}\n```", :type :var} {:name select-pks-reducible, :file "toucan2/select.clj", :line 122, :arglists ([modelable-columns & kv-args? query?] [:conn connectable modelable-columns & kv-args? query?]), :doc "Returns a reducible sequence of all primary keys\n\n```clj\n(into [] (t2/select-pks-reducible :models/venues :category \"bar\"))\n;; => [1 2]\n```", :type :var} {:name select-pks-set, :file "toucan2/select.clj", :line 134, :arglists ([modelable-columns & kv-args? query?] [:conn connectable modelable-columns & kv-args? query?]), :doc "Returns a *set* of all primary keys (as determined by [[toucan2.model/primary-keys]]\nand [[toucan2.model/select-pks-fn]]) of instances matching the query. Models with just a single primary key columns\nwill be 'unwrapped' (i.e., the values of that column will be returned); models with compound primary keys (i.e., more\nthan one column) will be returned in vectors as if by calling `juxt`.\n\n```clj\n(t2/select-pks-set :models/venues :category \"bar\")\n;; => #{1 2}\n```", :type :var} {:name select-pks-vec, :file "toucan2/select.clj", :line 149, :arglists ([modelable-columns & kv-args? query?] [:conn connectable modelable-columns & kv-args? query?]), :doc "Returns a *vector* of all primary keys (as determined by [[toucan2.model/primary-keys]]\nand [[toucan2.model/select-pks-fn]]) of instances matching the query. Models with just a single primary key columns\nwill be 'unwrapped' (i.e., the values of that column will be returned); models with compound primary keys (i.e., more\nthan one column) will be returned in vectors as if by calling `juxt`.\n\n```clj\n(t2/select-pks-vec :models/venues :category \"bar\")\n;; => [1 2]\n```\n\nNOTE: If your query does not specify an `:order-by` clause (or equivalent), the results are like indeterminate. Keep\nthis in mind!", :type :var}), :doc "Implementation of [[select]] and variations.\n\nThe args spec used by [[select]] lives in [[toucan2.query]], specifically `:toucan2.query/default-args`.\n\nCode for building Honey SQL for a SELECT lives in [[toucan2.honeysql2]].\n\n### Functions that return primary keys\n\nFunctions that return primary keys such as [[select-pks-set]] determine which primary keys to return by\ncalling [[toucan2.model/select-pks-fn]], which is based on the model's implementation\nof [[toucan2.model/primary-keys]]. Models with just a single primary key column will return primary keys 'unwrapped',\ni.e., the values of that column will be returned directly. Models with compound primary keys (i.e., primary keys\nconsisting of more than one column) will be returned in vectors as if by calling `juxt`.\n\n```clj\n;; A model with a one-column primary key, :id\n(t2/select-pks-vec :models/venues :category \"bar\")\n;; => [1 2]\n\n;; A model with a compound primary key, [:id :name]\n(t2/select-pks-vec :models/venues.compound-key :category \"bar\")\n;; => [[1 \"Tempest\"] [2 \"Ho's Tavern\"]]\n```"} {:name toucan2.tools.after, :publics ({:name define-after, :file "toucan2/tools/after.clj", :line 115, :arglists ([query-type model [instance-binding] & body]), :type :macro} {:name each-row-fn, :file "toucan2/tools/after.clj", :line 16, :arglists ([query-type₁ model₂]), :doc "Should return a function with the signature\n\n ```clj\n (f instance)\n ```\n\n This function is only done for side-effects for query types that return update counts or PKs.\n\neach-row-fn is defined in [[toucan2.tools.after]] (toucan2/tools/after.clj:16).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese aux methods are known:\n\n`:after` methods:\n\n* `:default`, defined in [[toucan2.tools.after]] (toucan2/tools/after.clj:29) ", :type :var}), :doc "Common code shared by various `after-` methods. Since the `after` methods operate over instances, we need to upgrade\n`result-type/pks` and `result-type/update-count` queries to `result-type/instances`, run them with the 'upgraded'\nresult type, run our after stuff on each row, and then return the original results."} {:name toucan2.tools.after-insert, :publics ({:name define-after-insert, :file "toucan2/tools/after_insert.clj", :line 8, :arglists ([model [instance-binding] & body]), :type :macro})} {:name toucan2.tools.after-select, :publics ({:name after-select, :file "toucan2/tools/after_select.clj", :line 12, :arglists ([instance]), :type :var} {:name define-after-select, :file "toucan2/tools/after_select.clj", :line 26, :arglists ([model [instance-binding] & body]), :type :macro})} {:name toucan2.tools.after-update, :publics ({:name define-after-update, :file "toucan2/tools/after_update.clj", :line 10, :arglists ([model [instance-binding] & body]), :type :macro})} {:name toucan2.tools.before-delete, :publics ({:name before-delete, :file "toucan2/tools/before_delete.clj", :line 16, :arglists ([model₁ instance]), :doc "Underlying method implemented when using [[define-before-delete]]. You *probably* shouldn't be adding implementations\n to this method directly, unless you know what you are doing!\n\nbefore-delete is defined in [[toucan2.tools.before-delete]] (toucan2/tools/before_delete.clj:16).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese aux methods are known:\n\n`:around` methods:\n\n* `:default`, defined in [[toucan2.tools.before-delete]] (toucan2/tools/before_delete.clj:24) ", :type :var} {:name define-before-delete, :file "toucan2/tools/before_delete.clj", :line 63, :arglists ([model [instance-binding] & body]), :doc "Define a method that will be called for every instance that is about to be deleted. The results of this before-delete\nmethod are ultimately ignored, but the entire operation (both the original delete and the recursive select) are done\nin a transaction, so you can use before-delete to enforce preconditions and abort deletes when they fail, or do\nsomething for side effects.\n\nBefore-delete is implemented by first selecting all the rows matching the [[toucan2.delete/delete!]] conditions and\nthen transducing those rows and calling the [[before-delete]] method this macro defines on each row. Because\nbefore-delete has to fetch every instance matching the condition, defining a before-delete method can be quite\nexpensive! For example, a `delete!` operation that deletes a million rows would normally be a single database call;\nwith before-delete in place, it would have to fetch and transduce all million rows and apply [[before-delete]] to each\nof them *before* even getting to the `DELETE` operation! So be sure you *really* need before-delete behavior before\nopting in to it.\n\nTo skip before-delete behavior, you can always use the model's raw table name directly, e.g.\n\n```clj\n(t2/delete! (t2/table-name :models/user) ...)\n```\n\nThis might be wise when deleting a large number of rows.", :type :macro})} {:name toucan2.tools.before-insert, :publics ({:name before-insert, :file "toucan2/tools/before_insert.clj", :line 13, :arglists ([model₁ row]), :type :var} {:name define-before-insert, :file "toucan2/tools/before_insert.clj", :line 62, :arglists ([model [instance-binding] & body]), :type :macro})} {:name toucan2.tools.before-select, :publics ({:name before-select, :file "toucan2/tools/before_select.clj", :line 14, :arglists ([model₁ parsed-args]), :doc "Impl for [[define-before-select]].\n\nbefore-select is defined in [[toucan2.tools.before-select]] (toucan2/tools/before_select.clj:14).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese aux methods are known:\n\n`:around` methods:\n\n* `:default`, defined in [[toucan2.tools.before-select]] (toucan2/tools/before_select.clj:21) ", :type :var} {:name define-before-select, :file "toucan2/tools/before_select.clj", :line 36, :arglists ([model [args-binding] & body]), :type :macro})} {:name toucan2.tools.before-update, :publics ({:name before-update, :file "toucan2/tools/before_update.clj", :line 21, :arglists ([model₁ row]), :doc "Do before-update operations for side effects and transformations to a `row` (presumably a Toucan instance?) before\n applying an UPDATE operation.\n\nbefore-update is defined in [[toucan2.tools.before-update]] (toucan2/tools/before_update.clj:21).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese aux methods are known:\n\n`:around` methods:\n\n* `:default`, defined in [[toucan2.tools.before-update]] (toucan2/tools/before_update.clj:30) ", :type :var} {:name define-before-update, :file "toucan2/tools/before_update.clj", :line 122, :arglists ([model [instance-binding] & body]), :type :macro})} {:name toucan2.tools.compile, :publics ({:name -resolved, :file "toucan2/tools/compile.clj", :line 40, :arglists ([thunk]), :type :var} {:name build, :file "toucan2/tools/compile.clj", :line 34, :arglists ([& body]), :doc "Return the built query before compilation that would have been executed by `body` without compiling or executing it.\n", :type :macro} {:name compile, :file "toucan2/tools/compile.clj", :line 14, :arglists ([& body]), :doc "Return the compiled query that would be executed by a form, rather than executing that form itself.\n\n```clj\n(compile\n (delete/delete :table :id 1))\n=>\n[\"DELETE FROM table WHERE ID = ?\" 1]\n```", :type :macro} {:name resolved, :file "toucan2/tools/compile.clj", :line 45, :arglists ([& body]), :doc "Return the resolved query and parsed args *before* building a query (e.g. before creating a Honey SQL query from the\nargs passed to [[toucan2.select/select]] created by `body` without building a query, compiling it, or executing it.", :type :macro}), :doc "Macros that can wrap a form and return the built query, compiled query, etc. without executing it.\n"} {:name toucan2.tools.debug, :publics ({:name -debug, :file "toucan2/tools/debug.clj", :line 10, :arglists ([thunk]), :type :var} {:name debug, :file "toucan2/tools/debug.clj", :line 20, :arglists ([& body]), :doc "Simple debug macro. This is a placeholder until I come up with a more sophisticated version.\n", :type :macro})} {:name toucan2.tools.default-fields, :publics ({:name *skip-default-fields*, :file "toucan2/tools/default_fields.clj", :line 55, :dynamic true, :doc "Whether to skip applying default Fields because the query already includes explicit fields, e.g. `:select` for a Honey\nSQL query.", :type :var} {:name default-fields, :file "toucan2/tools/default_fields.clj", :line 23, :arglists ([model]), :doc "The default fields to return for a model `model` that derives from `:toucan2.tools.default-fields/default-fields`. You\n probably don't need to use this directly; use [[toucan2.tools.default-fields/define-default-fields]] instead.\n\ndefault-fields is defined in [[toucan2.tools.default-fields]] (toucan2/tools/default_fields.clj:23).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese aux methods are known:\n\n`:around` methods:\n\n* `:default`, defined in [[toucan2.tools.default-fields]] (toucan2/tools/default_fields.clj:31) ", :type :var} {:name define-default-fields, :file "toucan2/tools/default_fields.clj", :line 120, :arglists ([model & body]), :type :macro})} {:name toucan2.tools.disallow, :publics ()} {:name toucan2.tools.hydrate, :publics ({:name *error-on-unknown-key*, :file "toucan2/tools/hydrate.clj", :line 530, :dynamic true, :type :var} {:name batched-hydrate, :file "toucan2/tools/hydrate.clj", :line 392, :arglists ([model₁ k₂ instances]), :doc "Hydrate the key `k` in one or more `instances` of `model`. Implement this method to support batched hydration for the\nkey `k`. Example implementation:\n\n```clj\n;; This method defines a batched hydration strategy for the :bird-type key for all models.\n(m/defmethod hydrate/batched-hydrate [:default :is-bird?]\n [_model _k instances]\n ;; fetch a set of all the non-nil bird IDs in instances.\n (let [bird-ids (into #{} (comp (map :bird-id) (filter some?)) instances)\n ;; if bird-ids is non-empty, fetch a map of bird ID => bird type\n bird-id->bird-type (when (seq bird-ids)\n (select/select-pk->fn :bird-type :models/bird :id [:in bird-ids]))]\n ;; for each instance add a :bird-type key.\n (for [instance instances]\n (assoc instance :bird-type (get bird-id->bird-type (:bird-id instance))))))\n```\n\nBatched hydration implementations should try to be efficient, e.g. minimizing the number of database calls made rather\nthan doing one call per instance. If you just want to hydrate each instance independently,\nimplement [[simple-hydrate]] instead. If you are hydrating entire instances of some other model, consider setting up\nautomagic batched hydration using [[model-for-automagic-hydration]] and possibly [[fk-keys-for-automagic-hydration]].", :type :var} {:name can-hydrate-with-strategy?, :file "toucan2/tools/hydrate.clj", :line 164, :arglists ([model₁ strategy₂ k₃]), :doc "Can we hydrate the key `k` in instances of `model` using a specific hydration `strategy`?\n\n Normally you should never need to call this yourself. The only reason you would implement it is if you are\n implementing a custom hydration strategy.\n\ncan-hydrate-with-strategy? is defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:164).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `[:default :toucan2.tools.hydrate/automagic-batched :default]`, defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:252) \n\n* `[:default :toucan2.tools.hydrate/multimethod-batched :default]`, defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:419) \n\n* `[:default :toucan2.tools.hydrate/multimethod-simple :default]`, defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:492) ", :type :var} {:name fk-keys-for-automagic-hydration, :file "toucan2/tools/hydrate.clj", :line 256, :arglists ([original-model₁ dest-key₂ hydrating-model₃]), :doc "The keys in we should use when automagically hydrating the key `dest-key` in instances of `original-model` with\n instances `hydrating-model`.\n\n ```clj\n ;; when hydrating :user in an order with a user, fetch the user based on the value of the :user-id key\n ;;\n ;; This means we take the value of :user-id from our order and then fetch the user with the matching primary key\n ;; (by default, :id)\n (fk-keys-for-automagic-hydration :models/orders :user :models/user) => [:user-id]\n ```\n\n The model that we are hydrating with (e.g. `:models/user`) is determined by [[model-for-automagic-hydration]].\n\n By default [[fk-keys-for-automagic-hydration]] is just the key we're hydrating, with `-id` appended to it; e.g. if\n we're hydrating `:user` the default FK key to use is `:user-id`. *If this convention is fine, you do not need to\n implement this method.* If you want to do something that does not follow this convention, like hydrate a `:user` key\n based on values of `:creator-id`, you should implement this method.\n\n Example implementation:\n\n ```clj\n ;; hydrate orders :user key using values of :creator-id\n (m/defmethod hydrate/fk-keys-for-automagic-hydration [:model/orders :user :default]\n [_original-model _dest-key _hydrating-model]\n [:creator-id])\n ```\n\n #### Tips\n\n When implementing this method, you probably do not want to specialize on the `hydrating-model` (the third part of the\n dispatch value) -- the model to use is normally determined by [[model-for-automagic-hydration]]. The only time you\n might want to specialize on `hydrating-model` is you wanted to do something like\n\n ```clj\n ;; by default when we hydrate the :user key with a :models/user, use :creator-id as the source FK\n (m/defmethod hydrate/fk-keys-for-automagic-hydration [:default :model/orders :user :models/user]\n [_original-model _dest-key _hydrating-model]\n [:creator-id])\n ```\n\nfk-keys-for-automagic-hydration is defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:256).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:301) \n\nThese aux methods are known:\n\n`:around` methods:\n\n* `:default`, defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:307) ", :type :var} {:name global-error-on-unknown-key, :file "toucan2/tools/hydrate.clj", :line 532, :doc "Whether hydration should error when it encounters a key that has no hydration methods associated with\nit (default: `false`). Global default value. You can bind [[*error-on-unknown-key*]] to temporarily override this\nvalue.", :type :var} {:name hydrate, :file "toucan2/tools/hydrate.clj", :line 670, :arglists ([instance-or-instances] [instance-or-instances & ks]), :doc "Hydrate the keys `ks` in a single instance or sequence of instances. See [[toucan2.tools.hydrate]] for more\ninformation.", :type :var} {:name hydrate-with-strategy, :file "toucan2/tools/hydrate.clj", :line 174, :arglists ([model strategy₁ k instances]), :doc "Hydrate the key `k` in `instances` of `model` using a specific hydration `strategy`.\n\n Normally you should not call this yourself. The only reason you would implement this method is if you are implementing\n a custom hydration strategy.\n\nhydrate-with-strategy is defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:174).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:toucan2.tools.hydrate/automagic-batched`, defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:376) \n\n* `:toucan2.tools.hydrate/multimethod-batched`, defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:470) \n\n* `:toucan2.tools.hydrate/multimethod-simple`, defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:496) ", :type :var} {:name model-for-automagic-hydration, :file "toucan2/tools/hydrate.clj", :line 204, :arglists ([original-model₁ k₂]), :doc "The model that should be used to automagically hydrate the key `k` in instances of `original-model`.\n\n ```clj\n (model-for-automagic-hydration :some-table :user) :-> :myapp.models/user\n ```\n\n Dispatches off of the [[toucan2.protocols/dispatch-value]] (normally [[toucan2.protocols/model]]) of the instance\n being hydrated and the key `k` that we are attempting to hydrate. To hydrate the key `k` for *any* model, you can use\n `:default` in your `defmethod` dispatch value. Example implementation:\n\n ```clj\n ;; when hydrating the :user key for *any* model, hydrate with instances of the model :models/user\n ;;\n ;; By default, this will look for values of :user-id in the instances being hydrated and then fetch the instances of\n ;; :models/user with a matching :id\n (m/defmethod hydrate/model-for-automagic-hydration [:default :user]\n [_original-model _k]\n :models/user)\n\n ;; when hydrating the :user key for instances of :models/orders, hydrate with instances of :models/user\n (m/defmethod hydrate/model-for-automagic-hydration [:models/orders :user]\n [_original-model _k]\n :models/user)\n ```\n\n Automagic hydration looks for the [[fk-keys-for-automagic-hydration]] in the instance being hydrated, and if they're\n all non-`nil`, fetches instances of [[model-for-automagic-hydration]] with the\n corresponding [[toucan2.model/primary-keys]]. Thus you might also want to implement\n\n - [[fk-keys-for-automagic-hydration]] for the model whose instances hydrating and the key being hydrated\n (e.g. `:models/orders` and `:user`)\n\n - [[toucan2.model/primary-keys]] for the model you want to hydrate with (e.g. `:models/user`)\n\n #### Tips\n\n - You probably don't want to write an implementation for `[ :default]` or `[:default :default]`, unless\n you want every key that we attempt to hydrate to be hydrated by that method.\n\nmodel-for-automagic-hydration is defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:204).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:248) ", :type :var} {:name needs-hydration?, :file "toucan2/tools/hydrate.clj", :line 185, :arglists ([model₁ k₂ instance]), :doc "Whether an `instance` of `model` needs the key `k` to be hydrated. By default, this is true if `(get instance k)` is\n `nil`. You can override this if you want to force a key to always be re-hydrated even if it is already present.\n\nneeds-hydration? is defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:185).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.tools.hydrate]] (toucan2/tools/hydrate.clj:193) ", :type :var} {:name simple-hydrate, :file "toucan2/tools/hydrate.clj", :line 481, :arglists ([model₁ k₂ instance]), :doc "Implementations should return a version of map `instance` with the key `k` added.\n", :type :var}), :doc "[[hydrate]] adds one or more keys to an instance or instances using various hydration strategies, usually using one of\nthe existing keys in those instances. A typical use case would be to take a sequence of `orders` and add `:user` keys\nto them based on their values of the foreign key `:user-id`.\n\n[[hydrate]] is how you *use* the hydration facilities; everything else in this namespace is only for extending\nhydration to support your models.\n\nToucan 2 ships with several hydration strategies out of the box:\n\n#### Automagic Batched Hydration (via [[model-for-automagic-hydration]])\n\n[[hydrate]] attempts to do a *batched hydration* where possible. If the key being hydrated is defined as one of some\ntable's [[model-for-automagic-hydration]], `hydrate` will do a batched\n[[toucan2.select/select]] if a corresponding key (by default, the same key suffixed by `-id`) is found in the\nobjects being batch hydrated. The corresponding key can be customized by\nimplementing [[fk-keys-for-automagic-hydration]].\n\n```clj\n(hydrate [{:user_id 100}, {:user_id 101}] :user)\n```\n\nSince `:user` is a hydration key for `:models/User`, a single [[toucan2.select/select]] will used to fetch Users:\n\n```clj\n(db/select :models/User :id [:in #{100 101}])\n```\n\nThe corresponding Users are then added under the key `:user`.\n\n#### Function-Based Batched Hydration (via [[batched-hydrate]] methods)\n\nIf the key can't be hydrated auto-magically with the appropriate [[model-for-automagic-hydration]],\n[[hydrate]] will attempt to do batched hydration if it can find a matching method\nfor [[batched-hydrate]]. If a matching function is found, it is called with a collection of\nobjects, e.g.\n\n```clj\n(m/defmethod hydrate/batched-hydrate [:default :fields]\n [_model _k instances]\n (let [id->fields (get-some-fields instances)]\n (for [instance instances]\n (assoc instance :fields (get id->fields (:id instance))))))\n```\n\n#### Simple Hydration (via [[simple-hydrate]] methods)\n\nIf the key is *not* eligible for batched hydration, [[hydrate]] will look for a matching\n[[simple-hydrate]] method. `simple-hydrate` is called with a single instance.\n\n```clj\n(m/defmethod simple-hydrate [:default :dashboard]\n [_model _k {:keys [dashboard-id], :as instance}]\n (assoc instance :dashboard (select/select-one :models/Dashboard :toucan/pk dashboard-id)))\n```\n\n#### Hydrating Multiple Keys\n\nYou can hydrate several keys at one time:\n\n```clj\n(hydrate {...} :a :b)\n -> {:a 1, :b 2}\n```\n\n#### Nested Hydration\n\nYou can do recursive hydration by listing keys inside a vector:\n\n```clj\n(hydrate {...} [:a :b])\n -> {:a {:b 1}}\n```\n\nThe first key in a vector will be hydrated normally, and any subsequent keys will be hydrated *inside* the\ncorresponding values for that key.\n\n```clj\n(hydrate {...}\n [:a [:b :c] :e])\n -> {:a {:b {:c 1} :e 2}}\n```\n\n### Forcing Hydration\n\nNormally, hydration is skipped if an instance already has a non-nil value for the key being hydrated, but you can\noverride this behavior by implementing [[needs-hydration?]].\n\n### Flowchart\n\nIf you're digging in to the details, this is a flowchart of how hydration works:\n\n```\n hydrate ◄─────────────┐\n │ │\n ▼ │\n hydrate-forms │\n │ │\n ▼ │ (recursively)\n hydrate-one-form │\n │ │\n keyword? ◄─┴─► sequence? │\n │ │ │\n ▼ ▼ │\n hydrate-key hydrate-key-seq ─┘\n │\n ▼\n (for each strategy) ◄────────┐\n ::automagic-batched │\n ::multimethod-batched │\n ::multimethod-simple │\n │ │ (try next strategy)\n ▼ │\n can-hydrate-with-strategy? │\n │ │\n yes ◄──┴──► no ────────────┘\n │\n ▼\nhydrate-with-strategy\n```"} {:name toucan2.tools.identity-query, :publics ({:name identity-query, :file "toucan2/tools/identity_query.clj", :line 27, :arglists ([reducible-rows]), :doc "A queryable that returns `reducible-rows` as-is without compiling anything or running anything against a database.\nGood for mocking stuff.\n\n```clj\n(def parrot-query\n (identity-query [{:id 1, :name \"Parroty\"}\n {:id 2, :name \"Green Friend\"}]))\n\n(select/select ::parrot parrot-query)\n=>\n[(instance ::parrot {:id 1, :name \"Parroty\"})\n (instance ::parrot {:id 2, :name \"Green Friend\"})]\n```", :type :var})} {:name toucan2.tools.named-query, :publics ({:name define-named-query, :file "toucan2/tools/named_query.clj", :line 10, :arglists ([query-name resolved-query] [query-name query-type model resolved-query]), :doc "Helper for defining 'named' queries.\n\n```clj\n;; define a custom query ::my-count that you can then use with select and the like\n(define-named-query ::my-count\n {:select [:%count.*], :from [(keyword (model/table-name model))]})\n\n(select :model/user ::my-count)\n```", :type :macro})} {:name toucan2.tools.simple-out-transform, :publics ({:name -xform, :file "toucan2/tools/simple_out_transform.clj", :line 10, :arglists ([f]), :type :var} {:name define-out-transform, :file "toucan2/tools/simple_out_transform.clj", :line 17, :arglists ([[query-type model-type] [instance-binding] & body]), :type :macro})} {:name toucan2.tools.transformed, :publics ({:name deftransforms, :file "toucan2/tools/transformed.clj", :line 355, :arglists ([model column->direction->fn]), :doc "Define type transforms to use for a specific model. `transforms` should be a map of\n\n```clj\n{:column-name {:in , :out }}\n```\n\n`:in` transforms are applied to values going over the wire to the database; these generally only applied to values\npassed at or near the top level to various functions; don't expect Toucan 2 to parse your SQL to find out which\nparameter corresponds to what in order to apply transforms or to apply transforms inside JOINS in hand-written\nHoneySQL. That said, unless you're doing something weird your transforms should generally get applied.\n\n`:out` transforms are applied to values coming out of the database; since nothing weird really happens there this is\ndone consistently.\n\nTransform functions for either case are skipped for `nil` values.\n\nExample:\n\n```clj\n(deftransforms :models/user\n {:type {:in name, :out keyword}})\n```\n\nYou can also define transforms independently, and derive a model from them:\n\n```clj\n(deftransforms ::type-keyword\n {:type {:in name, :out keyword}})\n\n(derive :models/user ::type-keyword)\n(derive :models/user ::some-other-transform)\n```\n\nDon't derive a model from multiple [[deftransforms]] for the same key in the same direction.\n\nWhen multiple transforms match a given model they are combined into a single map of transforms with `merge-with\nmerge`. If multiple transforms match a given column in a given direction, only one of them will be used; you should\nassume which one is used is indeterminate. (This may be made an error, or at least a warning, in the future.)\n\nUntil upstream issue https://github.com/camsaul/methodical/issues/97 is resolved, you will have to specify which\nmethod should be applied first in cases of ambiguity using [[methodical.core/prefer-method!]]:\n\n```clj\n(m/prefer-method! transforms ::user-with-location ::user-with-password)\n```\n\nIf you want to override transforms completely for a model, and ignore transforms from ancestors of a model, you can\ncreate an `:around` method:\n\n```clj\n(m/defmethod toucan2.tools.transforms :around ::my-model\n [_model]\n {:field {:in name, :out keyword}})\n```", :type :macro} {:name transforms, :file "toucan2/tools/transformed.clj", :line 52, :arglists ([model₁]), :doc "Return a map of\n\n```clj\n{column-name {:in , :out }}\n```\n\nFor a given `model`, all matching transforms are combined with `merge-with merge` in an indeterminate order, so don't\ntry to specify multiple transforms for the same column in the same direction for a given model -- compose your\ntransform functions instead if you want to do that. See [[toucan2.tools.transformed/deftransforms]] for more info.", :type :var})} {:name toucan2.tools.with-temp, :publics ({:name do-with-temp, :file "toucan2/tools/with_temp.clj", :line 71, :arglists ([modelable attributes f]), :type :var} {:name do-with-temp*, :file "toucan2/tools/with_temp.clj", :line 26, :arglists ([model₁ explicit-attributes f]), :doc "Implementation of [[with-temp]]. You can implement this if you need to do some sort of special behavior for a\n particular model. But normally you would just implement [[with-temp-defaults]]. If you need to do special setup when\n using [[with-temp]], you can implement a `:before` method:\n\n ```clj\n (m/defmethod do-with-temp* :before :default\n [_model _explicit-attributes f]\n (set-up-db!)\n f)\n ```\n\n `explicit-attributes` are the attributes specified in the `with-temp` form itself, any may be `nil`. The default\n implementation merges the attributes from [[with-temp-defaults]] like\n\n ```clj\n (merge {} (with-temp-defaults model) explict-attributes)\n ```\n\ndo-with-temp* is defined in [[toucan2.tools.with-temp]] (toucan2/tools/with_temp.clj:26).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.tools.with-temp]] (toucan2/tools/with_temp.clj:49) ", :type :var} {:name with-temp, :file "toucan2/tools/with_temp.clj", :line 75, :arglists ([[modelable temp-object-binding attributes & more] & body]), :doc "Define a temporary instance of a model and bind it to `temp-object-binding`. The object is inserted\nusing [[insert/insert-returning-instances!]] using the values from [[with-temp-defaults]] merged with a map of\n`attributes`. At the conclusion of `body`, the object is deleted. This is primarily intended for usage in tests, so\nthis adds a [[clojure.test/testing]] context around `body` as well.\n\n[[with-temp]] can create multiple objects in one form if you pass additional bindings.\n\n`temp-object-binding` and `attributes` are optional, and default to `_` and `nil`, respectively. If you're creating\nmultiple objects at once these must be explicitly specified.\n\nExamples:\n\n```clj\n;;; use the with-temp-defaults for :models/bird\n(with-temp [:models/bird bird]\n (do-something bird))\n\n;;; use the with-temp-defaults for :models/bird merged with {:name \"Lucky Pigeon\"}\n(with-temp [:models/bird bird {:name \"Lucky Pigeon\"}]\n (do-something bird))\n\n;;; define multiple instances at the same time\n(with-temp [:models/bird bird-1 {:name \"Parroty\"}\n :models/bird bird-2 {:name \"Green Friend\", :best-friend-id (:id bird-1)}]\n (do-something bird))\n```\n\nIf you want to implement custom behavior for a model other than default values, you can implement [[do-with-temp*]].", :type :macro} {:name with-temp-defaults, :file "toucan2/tools/with_temp.clj", :line 16, :arglists ([model]), :doc "with-temp-defaults is defined in [[toucan2.tools.with-temp]] (toucan2/tools/with_temp.clj:16).\n\nIt caches methods using a `methodical.impl.cache.watching.WatchingCache`.\n\nIt uses the method combination `methodical.impl.combo.threaded.ThreadingMethodCombination`\nwith the threading strategy `:thread-last`.\n\nIt uses the dispatcher `methodical.impl.dispatcher.multi_default.MultiDefaultDispatcher`\nwith hierarchy `#'clojure.core/global-hierarchy`\nand prefs `{}`.\n\nThe default value is `:default`.\n\nIt uses the method table `methodical.impl.method_table.standard.StandardMethodTable`.\n\nThese primary methods are known:\n\n* `:default`, defined in [[toucan2.tools.with-temp]] (toucan2/tools/with_temp.clj:22) ", :type :var})} {:name toucan2.types, :publics ({:name base-query-type, :file "toucan2/types.clj", :line 122, :arglists ([query-type]), :doc "E.g. something like `:toucan.query-type/insert.*`. The immediate descendant of `:toucan.query-type/*`.\n\n```clj\n(base-query-type :toucan.query-type/insert.instances)\n=>\n:toucan.query-type/insert.*\n```", :type :var} {:name or-default-spec, :file "toucan2/types.clj", :line 155, :arglists ([spec]), :doc "Helper for creating a spec that also accepts the `:default` keyword.\n", :type :var} {:name parent-query-type, :file "toucan2/types.clj", :line 116, :arglists ([query-type]), :type :var} {:name query-type?, :file "toucan2/types.clj", :line 103, :arglists ([query-type]), :doc "True if `query-type` derives from one of the various abstract query keywords such as `:toucan.result-type/*` or\n`:toucan.query-type/*`. This does not guarantee that the query type is a 'concrete', just that it is something with\nsome sort of query type information.", :type :var} {:name similar-query-type-returning, :file "toucan2/types.clj", :line 138, :arglists ([query-type result-type]), :doc "```clj\n(similar-query-type-returning :toucan.query-type/insert.instances :toucan.result-type/pks)\n=>\n:toucan.query-type/insert.pks\n```", :type :var}), :doc "Toucan 2 query type hierarchy.\n"} {:name toucan2.update, :publics ({:name reducible-update, :file "toucan2/update.clj", :line 45, :arglists ([modelable pk? conditions-map-or-query? & conditions-kv-args changes-map]), :type :var} {:name reducible-update-returning-pks, :file "toucan2/update.clj", :line 55, :arglists ([modelable pk? conditions-map-or-query? & conditions-kv-args changes-map]), :type :var} {:name update!, :file "toucan2/update.clj", :line 50, :arglists ([modelable pk? conditions-map-or-query? & conditions-kv-args changes-map]), :type :var} {:name update-returning-pks!, :file "toucan2/update.clj", :line 60, :arglists ([modelable pk? conditions-map-or-query? & conditions-kv-args changes-map]), :type :var}), :doc "Implementation of [[update!]].\n"} {:name toucan2.util, :publics ({:name ->kebab-case, :file "toucan2/util.clj", :line 106, :arglists ([x]), :doc "Like `camel-snake-kebab.core/->kebab-case`, but supports namespaced keywords.\n", :type :var} {:name dispatch-on-first-arg, :file "toucan2/util.clj", :line 16, :arglists ([x & _]), :doc "Dispatch on the first argument using [[dispatch-value]], and ignore all other args.\n", :type :var} {:name dispatch-on-first-three-args, :file "toucan2/util.clj", :line 24, :arglists ([x y z & _]), :doc "Dispatch on the three arguments using [[protocols/dispatch-value]], and ignore all other args.\n", :type :var} {:name dispatch-on-first-two-args, :file "toucan2/util.clj", :line 20, :arglists ([x y & _]), :doc "Dispatch on the two arguments using [[protocols/dispatch-value]], and ignore all other args.\n", :type :var} {:name lower-case-en, :file "toucan2/util.clj", :line 28, :arglists ([s]), :doc "Locale-agnostic version of [[clojure.string/lower-case]]. `clojure.string/lower-case` uses the default locale in\nconversions, turning `ID` into `ıd`, in the Turkish locale. This function always uses the `Locale/US` locale.", :type :var} {:name maybe-derive, :file "toucan2/util.clj", :line 34, :arglists ([child parent]), :doc "Derive `child` from `parent` only if `child` is not already a descendant of `parent`.\n", :type :var} {:name try-with-error-context, :file "toucan2/util.clj", :line 88, :arglists ([additional-context & body]), :type :macro})})}, :pom-str "\n\n 4.0.0\n jar\n io.github.camsaul\n toucan2\n 1.0.539\n toucan2\n \n \n org.clojure\n clojure\n 1.11.1\n \n \n better-cond\n better-cond\n 2.1.5\n \n \n org.clojure\n tools.logging\n 1.2.4\n \n \n mvxcvi\n puget\n 1.3.4\n \n \n org.clojure\n tools.trace\n 0.7.11\n \n \n methodical\n methodical\n 0.15.1\n \n \n com.github.seancorfield\n honeysql\n 2.4.1066\n \n \n environ\n environ\n 1.2.0\n \n \n com.github.seancorfield\n next.jdbc\n 1.3.894\n \n \n potemkin\n potemkin\n 0.4.6\n \n \n pretty\n pretty\n 1.0.5\n \n \n camel-snake-kebab\n camel-snake-kebab\n 0.4.3\n \n \n \n src\n \n \n \n clojars\n https://repo.clojars.org/\n \n \n A library for delightful database interaction.\n https://github.com/camsaul/toucan2\n \n \n Eclipse Public License\n http://www.eclipse.org/legal/epl-v10.html\n \n \n \n \n Cam Saul\n \n \n \n https://github.com/camsaul/toucan2\n scm:git:git@github.com:camsaul/toucan2.git\n scm:git:git@github.com:camsaul/toucan2.git\n 3cb36674ca0ab2e732c5ba2983db5052cf4c9b7b\n \n\n"}