Module esqlcipher

Erlang API for sqlite3 and sqlcipher databases.

Copyright © 2011 - 2021 Maas-Maarten Zeeman, Felix Kiunke

Version: 2.0.0-rc.2

Authors: Maas-Maarten Zeeman (mmzeeman@xs4all.nl), Felix Kiunke (dev@fkiunke.de).

Description

Erlang API for sqlite3 and sqlcipher databases. This is an adaptation of Maas-Maarten Zeeman's esqlite package for sqlcipher encrypted sqlite3 databases.

All functions (except is_encrypted/1) take an optional Timeout argument. The default value for this timeout is 5 seconds (5000). Note that Timeout is merely a lower bound. Several functions call multiple lower level calls, in which case each of those has is given that timeout. Thus, the actual timeout might be several times the value of Timeout for some functions.

To open or create a database, use either open/2 or open_encrypted/3. These return a database connection that can be used in the other functions and should be closed afterwards using close/2.

Queries

One-off queries that do not return anything can be executed using exec/3, exec/4 (with Query Parameters), or insert/3 (which returns the row id of the row inserted last).

In most cases, however, you'll want to use prepared statemtents that can contain Query Parameters. These statements are created using prepare/3. If it contains parameters, you can then bind values to those using bind/3 (you can do both in one step using prepare_bind/4. Afterwards, you can run the statement using run/2 (if you don't care about any rows that are possibly returned), or the fetch family (fetch_one/2, fetch_chunk/3, fetch_all/3). You can use column_names/2 and column_types/2 on a prepared statement to get the actual names and types of the columns that will be returned by it. Using reset/3, the prepared statement's initial state will be restored and you can run it once more.

Additionally, there is the q/4 and the foreach/5 and map/5 higher-order functions. These do not return {ok, _} or {error, _} tuples; if errors occur, they are thrown.

Query Parameters

SQLite statements can have parameters that values can be bound to. They take the following forms

Prefer numbered or named over anonymous parameters and do not mix named and numbered parameters! See bind/3 for further details!

The following data types are supported by sqlite3: Note that sqlite3 does not have a boolean data type. Use integers. Values are translated between Erlang and sqlite3 data types when binding or fetching. Trying to bind any other types, such as atoms or booleans, will result in an error.

Data Types

bind_values()

bind_values() = [sql_value() | {pos_integer() | atom(), sql_value()}]

List of values for statement parameters (see bind/3).

connection()

connection() = {connection, reference(), plaintext | encrypted}

Database connection type. Returned by open/2 and open_encrypted/3.

foreach_function()

foreach_function() = fun((Row::row()) -> any()) | fun((ColNames::[atom()], Row::row()) -> any())

Type of functions used in foreach/5.

map_function()

map_function(ReturnType) = fun((Row::row()) -> ReturnType) | fun((ColNames::[atom()], Row::row()) -> ReturnType)

Type of functions used in map/5.

row()

row() = [sql_value()]

SQL row type.

sql()

sql() = iodata()

SQL string type.

sql_value()

sql_value() = number() | nil | iodata() | {'$blob', iodata()}

SQL value type.

sqlite_error()

sqlite_error() = {error, {atom(), string()}}

Error return type. Contains an error id atom and a reason/error message.

statement()

statement() = {statement, reference(), connection()}

Prepared statement type. Returned by prepare/3 or prepare_bind/4.

Function Index

bind/2Equivalent to bind(Statement, Args, 5000).
bind/3Bind values to a prepared statement created by prepare/3.
changes/1Equivalent to changes(Connection, 5000).
changes/2Return the number of the rows that have been modified, inserted, or deleted by the last statement (see the sqlite3 docs for further information).
close/1Equivalent to close(Connection, 5000).
close/2Close the database connection.
column_names/1Equivalent to column_names(Statement, 5000).
column_names/2Return the column names of the prepared statement.
column_types/1Equivalent to column_types(Statement, 5000).
column_types/2Return the declared column types of the prepared statement.
exec/2Equivalent to exec(Sql, Connection, 5000).
exec/3Execute (simple or prepared) SQL statement without returning anything.
exec/4Execute prepared SQL statement without returning anything.
fetch_all/1Equivalent to fetch_all(Statement, 5000, 5000).
fetch_all/2Equivalent to fetch_all(Statement, ChunkSize, 5000).
fetch_all/3Fetch all records.
fetch_chunk/2Equivalent to fetch_chunk(Statement, ChunkSize, 5000).
fetch_chunk/3fetch a number of rows.
fetch_one/1Equivalent to fetch_one(Statement, 5000).
fetch_one/2fetch exactly one row of results.
foreach/3Equivalent to foreach(F, Sql, [], Connection, 5000).
foreach/4Equivalent to foreach(F, Sql, Args, Connection, 5000).
foreach/5Execute a function for all rows returned by the SQL query Sql.
get_autocommit/1Equivalent to get_autocommit(Connection, 5000).
get_autocommit/2Returns whether the database is in autocommit mode.
insert/2Equivalent to insert(Sql, Connection, 5000).
insert/3Insert records, returns the last inserted rowid.
is_encrypted/1Whether a database is encrypted.
map/3Equivalent to map(F, Sql, [], Connection, 5000).
map/4Equivalent to map(F, Sql, [], Connection, 5000).
map/5Map over all rows returned by the SQL query Sql.
open/1Equivalent to open(Filename, 5000).
open/2Open an unencrypted database connection.
open_encrypted/2Equivalent to open_encrypted(Filename, Key, 5000).
open_encrypted/3Open an encrypted database connection.
prepare/2Equivalent to prepare(Sql, Connection, Timeout).
prepare/3Prepare (that is, compile) an SQL statement.
prepare_bind/3Equivalent to prepare_bind(Sql, Values, Connection, 5000).
prepare_bind/4Prepare an SQL statement and bind values to it.
q/2Equivalent to q(Sql, [], Connection, 5000).
q/3Equivalent to q(Sql, Args, Connection, 5000).
q/4Prepare statement, bind args and return a list with tuples as result.
rekey/2Equivalent to rekey(Key, Connection, 5000).
rekey/3Change the database key.
reset/1Equivalent to reset(Statement, false, 5000).
reset/2Equivalent to reset(Statemennt, ClearValues, 5000).
reset/3Reset the prepared statement back to its initial state.
run/1Equivalent to run(Statement, 5000).
run/2run a prepared statement, ignoring any possible results.
set_update_hook/2Equivalent to set_update_hook(Pid, Connection, 5000).
set_update_hook/3Subscribe to notifications for row updates, insertions and deletions.

Function Details

bind/2

bind(Statement::statement(), Values::[bind_values()]) -> ok | sqlite_error()

Equivalent to bind(Statement, Args, 5000).

bind/3

bind(Statement::statement(), Values::[bind_values()], Timeout::timeout()) -> ok | sqlite_error()

Bind values to a prepared statement created by prepare/3. Note that you can also use prepare_bind/4 to prepare and bind a statement in one step.

nil will be interpreted as NULL. Use {'$blob', <<binary>>} for sqlite BLOBs. Since sqlite does not have a true boolean type, true and false are invalid; use 1 and 0, respectively.

All forms of bindings supported by sqlite3 are supported (see also sqlite3 docs):

Anonymous parameters of the form ? are discouraged; prefer named or numbered parameters.

Values is a list of values that are bound to these parameters. Values can either be a list of raw values or a list of tuples of the form {N, Value} or {name, Value}. Of course, something like {myblob, {'$blob', <<"blob">>}} is allowed as well.

changes/1

changes(Connection) -> any()

Equivalent to changes(Connection, 5000).

changes/2

changes(Connection::connection(), Timeout::timeout()) -> integer()

Return the number of the rows that have been modified, inserted, or deleted by the last statement (see the sqlite3 docs for further information).

close/1

close(Connection::connection()) -> ok | sqlite_error()

Equivalent to close(Connection, 5000).

close/2

close(Connection::connection(), Timeout::timeout()) -> ok | sqlite_error()

Close the database connection.

column_names/1

column_names(Statement::statement()) -> [binary()]

Equivalent to column_names(Statement, 5000).

column_names/2

column_names(Statement::statement(), Timeout::timeout()) -> [binary()]

Return the column names of the prepared statement.

column_types/1

column_types(Stmt::statement()) -> [binary()]

Equivalent to column_types(Statement, 5000).

column_types/2

column_types(X1::statement(), Timeout::timeout()) -> [binary()]

Return the declared column types of the prepared statement. Note that since sqlite3 is dynamically typed, actual column values need not necessarily conform to the declared type

exec/2

exec(Sql::sql(), Connection::connection()) -> ok | sqlite_error()

Equivalent to exec(Sql, Connection, 5000).

exec/3

exec(Sql::sql(), Connection::connection(), Timeout::timeout()) -> ok | sqlite_error()

exec(Sql::sql(), Params::[term()], Timeout::connection()) -> ok | sqlite_error()

Execute (simple or prepared) SQL statement without returning anything.

The second form of invocation (with Params) is equivalent to exec(Sql, Params, Connection, 5000).

exec/4

exec(Sql::sql(), Params::[term()], Connection::connection(), Timeout::timeout()) -> ok | sqlite_error()

Params: values that are bound to the SQL statement

Execute prepared SQL statement without returning anything.

fetch_all/1

fetch_all(Statement::statement()) -> [tuple()] | {error, term()}

Equivalent to fetch_all(Statement, 5000, 5000).

fetch_all/2

fetch_all(Statement::statement(), ChunkSize::pos_integer()) -> [tuple()] | {error, term()}

Equivalent to fetch_all(Statement, ChunkSize, 5000).

fetch_all/3

fetch_all(Statement::statement(), ChunkSize::pos_integer(), Timeout::timeout()) -> [row()] | sqlite_error()

Statement: a prepared sql statement created by prepare/3 or prepare_bind/4
ChunkSize: is a number of rows to be read from sqlite and sent to erlang in one bulk Decrease this value if rows are heavy. Default value is 5000 (DEFAULT_CHUNK_SIZE).
Timeout: is timeout per each request of one bulk

Fetch all records

fetch_chunk/2

fetch_chunk(Statement::statement(), ChunkSize::pos_integer()) -> {rows | '$done', [row()]} | sqlite_error()

Equivalent to fetch_chunk(Statement, ChunkSize, 5000).

fetch_chunk/3

fetch_chunk(Statement::statement(), ChunkSize::pos_integer(), Timeout::timeout()) -> {rows | '$done', [row()]} | sqlite_error()

Statement: a prepared sql statement created by prepare/3 or prepare_bind/4
ChunkSize: is a number of rows to be read from sqlite and sent to erlang
Timeout: timeout for the whole operation. Might need to be increased for very large chunks

returns: {rows, [...]} if more rows exist but where not fetched due to the ChunkSize limit; {'$done', [...]} if these where the last rows

fetch a number of rows. Can be called multiple times to fetch more rows.

fetch_one/1

fetch_one(Statement::statement()) -> {ok, nil} | {ok, row()} | sqlite_error()

Equivalent to fetch_one(Statement, 5000).

fetch_one/2

fetch_one(Statement::statement(), Timeout::timeout()) -> {ok, nil} | {ok, row()} | sqlite_error()

Statement: a prepared sql statement created by prepare/3 or prepare_bind/4

returns: {ok, X} if the statement was executed successfully where X is either a row in the shape of a tuple or nil if no rows where returned

fetch exactly one row of results. Returns ok if the result is empty.

foreach/3

foreach(F::foreach_function(), Sql::sql(), Connection::connection()) -> ok

throws sqlite_error()

Equivalent to foreach(F, Sql, [], Connection, 5000).

foreach/4

foreach(F::foreach_function(), Sql::sql(), Args::[bind_values()], Connection::connection()) -> ok

throws sqlite_error()

Equivalent to foreach(F, Sql, Args, Connection, 5000).

foreach/5

foreach(F::foreach_function(), Sql::sql(), Args::[bind_values()], Connection::connection(), Timeout::timeout()) -> ok

Sql: an SQL query
Args: values that are bound to Sql

throws sqlite_error()

Execute a function for all rows returned by the SQL query Sql.

get_autocommit/1

get_autocommit(Connection::connection()) -> boolean()

Equivalent to get_autocommit(Connection, 5000).

get_autocommit/2

get_autocommit(Connection::connection(), Timeout::timeout()) -> boolean()

Returns whether the database is in autocommit mode. Autocommit is normally enabled, except within transactions.

insert/2

insert(Sql::sql(), Connection::connection()) -> {ok, integer()} | sqlite_error()

Equivalent to insert(Sql, Connection, 5000).

insert/3

insert(Sql::sql(), Connection::connection(), Timeout::timeout()) -> {ok, integer()} | sqlite_error()

Insert records, returns the last inserted rowid. Sql can be any INSERT statement. If the table has a column of type INTEGER PRIMARY KEY, the returned rowid will equal that primary key. See also the sqlite3 docs for sqlite3_last_insert_rowid.

is_encrypted/1

is_encrypted(Connection::connection()) -> boolean()

Whether a database is encrypted. Returns true if the database connection is to an encrypted database, false if it's a plaintext database

map/3

map(F::map_function(Type), Sql::sql(), Connection::connection()) -> [Type]

throws sqlite_error()

Equivalent to map(F, Sql, [], Connection, 5000).

map/4

map(F::map_function(Type), Sql::sql(), Args::[bind_values()], Connection::connection()) -> [Type]

throws sqlite_error()

Equivalent to map(F, Sql, [], Connection, 5000).

map/5

map(F::map_function(Type), Sql::sql(), Args::[bind_values()], Connection::connection(), Timeout::timeout()) -> [Type]

Sql: an SQL query
Args: values that are bound to Sql

throws sqlite_error()

Map over all rows returned by the SQL query Sql.

open/1

open(Filename::iodata()) -> {ok, connection()} | sqlite_error()

Equivalent to open(Filename, 5000).

open/2

open(Filename::iodata(), Timeout::timeout()) -> {ok, connection()} | sqlite_error()

Open an unencrypted database connection. If Filename doesn't exist, it will be created. You can also open an in-memory database that will be destroyed after closing by giving :memory: as the Filename. URI filenames are allowed as well.

The database will be checked by testing whether sqlite_master is readable. Unreadable, corrupted or encrypted databases will return an error of the form {error, {baddb, _}}.

Since sqlcipher is just sqlite3 under the hood, these unencrypted databases are fully compatible with sqlite3.

open_encrypted/2

open_encrypted(Filename::iodata(), Key::iodata()) -> {ok, connection()} | sqlite_error()

Equivalent to open_encrypted(Filename, Key, 5000).

open_encrypted/3

open_encrypted(Filename::iodata(), Key::iodata(), Timeout::timeout()) -> {ok, connection()} | sqlite_error()

Open an encrypted database connection. If Filename doesn't exist, it will be created.

The database will be checked by testing whether sqlite_master is readable. Unreadable or corrupted databases as well as an incorrect Key will return an error of the form {error, {baddb, _}}.

Normally, the actual database key will be derived from Key using PBKDF2 key derivation by sqlcipher. However, it's possible to specify a raw byte sequence as a key. This key has to be hex-encoded and can be used by passing "x'A0B1C2(...)D3E4F5'" using a 64 character hex string for a resulting 32 byte key (256 bits). Finally, an exact database salt can be specified as well by passing a 96 character hex string (the last 32 characters will be used as the salt). If the salt is not explicitly provided, it will be generated randomly and stored in the first 16 bytes of the database.

Please refer to the sqlcipher documentation for further information about the generation and usage of encryption keys.

prepare/2

prepare(Sql::sql(), Connection::connection()) -> {ok, statement()} | sqlite_error()

Equivalent to prepare(Sql, Connection, Timeout).

prepare/3

prepare(Sql::sql(), C::connection(), Timeout::timeout()) -> {ok, statement()} | sqlite_error()

Prepare (that is, compile) an SQL statement. Value placeholder can then be bound using bind/3. Or, you can do both in one step using prepare_bind/4!

prepare_bind/3

prepare_bind(Sql::sql(), Values::[bind_values()], Connection::connection()) -> {ok, statement()} | sqlite_error()

Equivalent to prepare_bind(Sql, Values, Connection, 5000).

prepare_bind/4

prepare_bind(Sql::sql(), Values::[bind_values()], Connection::connection(), Timeout::timeout()) -> {ok, statement()} | sqlite_error()

Prepare an SQL statement and bind values to it. This is simply prepare/3 and bind/3 in a single step.

q/2

q(Sql::sql(), Connection::connection()) -> [tuple()]

throws sqlite_error()

Equivalent to q(Sql, [], Connection, 5000).

q/3

q(Sql::sql(), Args::[bind_values()], Connection::connection()) -> [tuple()]

throws sqlite_error()

Equivalent to q(Sql, Args, Connection, 5000).

q/4

q(Sql::sql(), Args::[bind_values()], Connection::connection(), Timeout::timeout()) -> [tuple()]

throws sqlite_error()

Prepare statement, bind args and return a list with tuples as result. Errors are thrown, not returned.

rekey/2

rekey(Key::iodata(), Connection::connection()) -> ok | sqlite_error()

Equivalent to rekey(Key, Connection, 5000).

rekey/3

rekey(Key::iodata(), Connection::connection(), Timeout::timeout()) -> ok | sqlite_error()

Change the database key. This function cannot be used to encrypt an unencrypted database and will return an error {error, {rekey_plaintext, _}} if called on one.

See also: open_encrypted/3.

reset/1

reset(Statement::statement()) -> ok | sqlite_error()

Equivalent to reset(Statement, false, 5000).

reset/2

reset(Statement::statement(), ClearValues::boolean() | timeout()) -> ok | sqlite_error()

Equivalent to reset(Statemennt, ClearValues, 5000).

reset/3

reset(Statement::statement(), ClearValues::boolean(), Timeout::timeout()) -> ok | sqlite_error()

ClearValues: whether to clear values bound to the statement

Reset the prepared statement back to its initial state. Once the statement has been reset, you can run it once more. By default, any values bound to the statement will be retained. Set ClearValues to true to change this.

run/1

run(Statement::statement()) -> ok | sqlite_error()

Equivalent to run(Statement, 5000).

run/2

run(Statement::statement(), Timeout::timeout()) -> ok | sqlite_error()

returns: ok if the query finishes without an error, whether or not it returns any rows.

run a prepared statement, ignoring any possible results. If you want to ensure that a query finishes correctly, returning exactly zero rows, use:

{ok, nil} = fetch_one(Statement, Timeout)

set_update_hook/2

set_update_hook(Pid::pid(), Connection::connection()) -> ok

Equivalent to set_update_hook(Pid, Connection, 5000).

set_update_hook/3

set_update_hook(Pid::pid(), X2::connection(), Timeout::timeout()) -> ok

Subscribe to notifications for row updates, insertions and deletions. Messages will come in the shape of {Action, Table :: string(), Id :: integer()}, where Action will be either insert, update or delete and Id will be the affected row id (i.e. the INTEGER PRIMARY KEY if the table has one).


Generated by EDoc