Most functions can also return {error, unsupported}
if the feature isn't supported in that database. For example, transactions or pubsub functionality.
start_pool(Ref, NbWorkers, PoolOpts) -> ok
stop_pool(Ref) -> ok
Start and stop a pool of workers. These functions cannot be used from inside a worker.
restart_pool(Ref, PoolOpts) -> ok
Restarts the pool, one worker at a time. This operation returns immediately and is performed asynchronously. Workers are restarted one by one, by first removing the worker from the ets table, sending a message telling it to stop, waiting for it to finish processing its requests until it can stop safely, and then starting a new worker to replace it.
The goal of this operation is to allow safe reconnection with new options while making sure we don't get any query ignored or failed, and also making sure we don't overflow the server with new connections (which is why we do one by one). This operation should take a few minutes at most.
query(Ref, Query) -> bank:result()
query(Ref, Query, Params) -> bank:result()
query(Ref, Query, Params, Opts) -> bank:result() | {async, AsyncRef}
Execute a query.
prepare(Ref, Stmt, Query) -> ok
prepare(Ref, Stmt, Query, Opts) -> ok
unprepare(Ref, Stmt) -> ok
unprepare(Ref, Stmt, Opts) -> ok
Prepare or forget a statement. These functions can only be used from inside a worker. This also means that they cannot be ran asynchronously.
execute(Ref, Stmt, Params) -> bank:result()
execute(Ref, Stmt, Params, Opts) -> bank:result() | {async, AsyncRef}
Execute a prepared statement.
batch(Ref, Fun) -> any()
batch(Ref, Fun, Opts) -> any() | {async, AsyncRef}
Execute a batch fun from in a worker context.
transaction(Ref, Fun) -> any()
transaction(Ref, Fun, Opts) -> any() | {async, AsyncRef}
Execute a batch fun inside a transaction in a worker context.
sub(Ref, Channel) -> ok
sub(Ref, Channel, Opts) -> ok | {async, AsyncRef}
Subscribe to Channel
if the server supports notifications. This function cannot be used from inside a worker.
unsub(Ref, Channel) -> ok
unsub(Ref, Channel, Opts) -> ok | {async, AsyncRef}
Unsubscribe from Channel
. This function cannot be used from inside a worker.
pub(Ref, Channel, Message) -> ok
pub(Ref, Channel, Message, Opts) -> ok | {async, AsyncRef}
Publish to Channel
.
{driver, BankDriver, DriverOpts}
Driver to be used. Example: {driver, bank_pgsql, {tcp, Host, Port, [{username, Username}, {password, Password}]}}
.
{connect_retry, Time = 5000}
Time before reconnecting when the connection fails. Bank never gives up reconnecting.
{keepalive, Time = 10000}
Interval between pings.
{onconnect, Fun}
Fun that will be executed on connect.
These options are common to all kinds of queries.
async
Whether to return immediately. A ref AsyncRef
is returned to identify the result of the query that will be sent as a message.
{timeout, Time = infinity}
Timeout before giving up on the query.
{bank, AsyncRef, ok, AffectedRows, InsertID}
{bank, AsyncRef, rows, fin | nofin, Rows}
: there might be more than one such message sent,fin
indicates the last message{bank, AsyncRef, error, Reason, String}
{bank, AsyncRef, notify, Message}
Other SQL Frameworks
Java JDBC
There is no out of the box connection pooling for JDBC. Connection pooling is usually provided by an JEE application server like: TomEE, Glassfish or JBOSS. There are also Servlet Containers like Tomcat which provide connection pooling for resources.
The JDBC API also covers database meta-data in a uniform way.
Perl DBI
The same as the above but implemented in Perl using DBI
There's also support for meta-data in DBI. No built in pooling is provided, but usually there are no long running processes in Perl, so there's no real need for it. Prepared statements can not be unprepared.
Haskell HDBC
I haven't tried to implement the above in Haskell. HDBC has drivers for MySQL, PostgreSQL, SQLite and ODBC.