Improve docstrings throughout

This commit is contained in:
Sean Corfield 2019-04-01 21:31:38 -07:00
parent 28f735bafd
commit 81be787316
4 changed files with 87 additions and 15 deletions

View file

@ -6,7 +6,8 @@
The basic building blocks are the java.sql/javax.sql classes:
* DataSource -- something to get connections from,
* Connection -- an active connection to the database,
* PreparedStatement -- SQL and parameters combined, from a connection,
* PreparedStatement -- SQL and parameters combined, from a connection
and the following two functions and a macro:
* reducible! -- given a connectable and SQL + parameters or a statement,
return a reducible that, when reduced will execute the SQL and consume
the ResultSet produced,
@ -22,7 +23,8 @@
The following options are supported generally:
* :entities -- specify a function used to convert strings to SQL entity names
(to turn table and column names into appropriate SQL names),
(to turn table and column names into appropriate SQL names -- see the
next.jdbc.quoted namespace for the most common ones you might need),
* :identifiers -- specify a function used to convert SQL entity (column)
names to Clojure names (that are then turned into keywords),
* :row-fn -- when consuming a ResultSet, apply this function to each row of
@ -46,7 +48,42 @@
(set! *warn-on-reflection* true)
(defn get-datasource
"Given some sort of specification of a database, return a DataSource."
"Given some sort of specification of a database, return a DataSource.
A specification can be a JDBC URL string (which is passed to the JDBC
driver as-is), or a hash map. For the hash map, these keys are required:
* :dbtype -- a string indicating the type of the database
* :dbname -- a string indicating the name of the database to be used
The following optional keys are commonly used:
* :user -- the username to authenticate with
* :password -- the password to authenticate with
* :host -- the hostname or IP address of the database (default: 127.0.0.1)
* :port -- the port for the database connection (the default is database-
specific -- see below)
* :classname -- if you need to override the default for the :dbtype
(or you want to use a database that next.jdbc does not know about!)
Any additional options provided will be passed to the JDBC driver's
.getConnection call as a java.util.Properties structure.
Database types supported, and their defaults:
* derby -- org.apache.derby.jdbc.EmbeddedDriver -- also pass :create true
if you want the database to be automatically created
* h2 -- org.h2.Driver -- for an on-disk database
* h2:mem -- org.h2.Driver -- for an in-memory database
* hsqldb, hsql -- org.hsqldb.jdbcDriver
* jtds:sqlserver, jtds -- net.sourceforge.jtds.jdbc.Driver -- 1433
* mysql -- com.mysql.cj.jdbc.Driver, com.mysql.jdbc.Driver -- 3306
* oracle:oci -- oracle.jdbc.OracleDriver -- 1521
* oracle:thin, oracle -- oracle.jdbc.OracleDriver -- 1521
* oracle:sid -- oracle.jdbc.OracleDriver -- 1521 -- uses the legacy :
separator for the database name but otherwise behaves like oracle:thin
* postgresql, postgres -- org.postgresql.Driver -- 5432
* pgsql -- com.impossibl.postgres.jdbc.PGDriver -- no default port
* redshift -- com.amazon.redshift.jdbc.Driver -- no default port
* sqlite -- org.sqlite.JDBC
* sqlserver, mssql -- com.microsoft.sqlserver.jdbc.SQLServerDriver -- 1433"
[spec]
(p/get-datasource spec))
@ -56,25 +93,37 @@
In general, this should be used via with-open:
(with-open [con (get-connection spec opts)]
(run-some-ops con))"
(run-some-ops con))
If you call get-connection on a DataSource, it just calls .getConnection
and applies the :auto-commit and/or :read-only options, if provided.
If you call get-connection on anything else, it will call get-datasource
first to try to get a DataSource, and then call get-connection on that."
[spec opts]
(p/get-connection spec opts))
(defn prepare
"Given some sort of specification of a database, and a vector containing
SQL and any parameters it needs, return a new PreparedStatement.
"Given a connection to a database, and a vector containing SQL and any
parameters it needs, return a new PreparedStatement.
In general, this should be used via with-open:
(with-open [stmt (prepare spec sql-params opts)]
(run-some-ops stmt))"
[spec sql-params opts]
(p/prepare spec sql-params opts))
(run-some-ops stmt))
See the list of options above (in the namespace docstring) for what can
be passed to prepare."
[connection sql-params opts]
(p/prepare connection sql-params opts))
(defn reducible!
"General SQL execution function.
Returns a reducible that, when reduced, runs the SQL and yields the result."
Returns a reducible that, when reduced, runs the SQL and yields the result.
Can be called on a PreparedStatement, a Connection, or something that can
produce a Connection via a DataSource."
([stmt] (p/-execute stmt [] {}))
([connectable sql-params & [opts]]
(p/-execute connectable sql-params opts)))
@ -82,7 +131,10 @@
(defn execute!
"General SQL execution function.
Invokes 'reducible!' and then reduces that into a vector of hash maps."
Invokes 'reducible!' and then reduces that into a vector of hash maps.
Can be called on a PreparedStatement, a Connection, or something that can
produce a Connection via a DataSource."
([stmt]
(rs/execute! stmt [] {}))
([connectable sql-params]
@ -93,7 +145,10 @@
(defn execute-one!
"General SQL execution function that returns just the first row of a result.
Invokes 'reducible!' but immediately returns the first row."
Invokes 'reducible!' but immediately returns the first row.
Can be called on a PreparedStatement, a Connection, or something that can
produce a Connection via a DataSource."
([stmt]
(rs/execute-one! stmt [] {}))
([connectable sql-params]

View file

@ -64,7 +64,7 @@
"oracle:sid" ":"})
(defn- ^Properties as-properties
"Convert any seq of pairs to a java.utils.Properties instance.
"Convert any seq of pairs to a java.util.Properties instance.
Uses as-sql-name to convert both keys and values into strings."
[m]
(let [p (Properties.)]

View file

@ -130,19 +130,32 @@
(comment
(require '[next.jdbc.quoted :refer [mysql]])
(by-keys {:a nil :b 42 :c "s"} :where {})
;=> ["WHERE a IS NULL AND b = ? AND c = ?" 42 "s"]
(as-keys {:a nil :b 42 :c "s"} {})
;=> a, b, c
(as-? {:a nil :b 42 :c "s"} {})
;=> ?, ?, ?
(for-query :user {:id 9} {:entities mysql})
;=> ["SELECT * FROM `user` WHERE `id` = ?" 9]
(for-query :user {:id nil} {:entities mysql})
;=> ["SELECT * FROM `user` WHERE `id` IS NULL"]
(for-query :user ["id = ? and opt is null" 9] {:entities mysql})
;=> ["SELECT * FROM `user` WHERE id = ? and opt is null" 9]
(for-delete :user {:opt nil :id 9} {:entities mysql})
;=> ["DELETE FROM `user` WHERE `opt` IS NULL AND `id` = ?" 9]
(for-delete :user ["id = ? and opt is null" 9] {:entities mysql})
;=> ["DELETE FROM `user` WHERE id = ? and opt is null" 9]
(for-update :user {:status 42} {} {:entities mysql})
;=> ["UPDATE `user` SET `status` = ? WHERE " 42]
(for-update :user {:status 42} {:id 9} {:entities mysql})
;=> ["UPDATE `user` SET `status` = ? WHERE `id` = ?" 42 9]
(for-update :user {:status 42, :opt nil} ["id = ?" 9] {:entities mysql})
;=> ["UPDATE `user` SET `status` = ?, `opt` = ? WHERE id = ?" 42 nil 9]
(for-insert :user {:id 9 :status 42 :opt nil} {:entities mysql})
;=> ["INSERT INTO `user` (`id`, `status`, `opt`) VALUES (?, ?, ?)" 9 42 nil]
(for-insert-multi :user [:id :status]
[[42 "hello"]
[35 "world"]
[64 "dollars"]]
{:entities mysql}))
;=> ["INSERT INTO `user` (`id`, `status`) VALUES (?, ?), (?, ?), (?, ?)" 42 "hello" 35 "world" 64 "dollars"])

View file

@ -1,7 +1,7 @@
;; copyright (c) 2018-2019 Sean Corfield, all rights reserved
(ns next.jdbc.transaction
""
"SQL Transaction logic."
(:require [next.jdbc.protocols :as p])
(:import (java.sql Connection
SQLException)))
@ -17,7 +17,11 @@
:serializable Connection/TRANSACTION_SERIALIZABLE})
(defn- transact*
""
"Run the given function inside a transaction created on the given connection.
Isolation level options can be provided, as well as marking the transaction
as read-only and/or rollback-only (so it will automatically rollback
instead of committing any changes)."
[^Connection con f opts]
(let [{:keys [isolation read-only rollback-only]} opts
old-autocommit (.getAutoCommit con)