Sqlcx (sqlcx v1.2.0) View Source

Sqlcx gives you a way to create and query SQLCipher (encrypted SQLite) databases.

Basic Example

iex> {:ok, db} = Sqlcx.open(":memory:")
iex> Sqlcx.exec(db, "CREATE TABLE t (a INTEGER, b INTEGER, c INTEGER)")
:ok
iex> Sqlcx.exec(db, "INSERT INTO t VALUES (1, 2, 3)")
:ok
iex> Sqlcx.query(db, "SELECT * FROM t")
{:ok, [[a: 1, b: 2, c: 3]]}
iex> Sqlcx.query(db, "SELECT * FROM t", into: %{})
{:ok, [%{a: 1, b: 2, c: 3}]}

Configuration

Sqlcx uses the Erlang library esqlcipher which accepts a timeout parameter for almost all interactions with the database. The default value for this timeout is 5000 ms. Many functions in Sqlcx accept a :db_timeout option that is passed on to the esqlcipher calls and also defaults to 5000 ms. If required, this default value can be overridden globally with the following in your config.exs:

config :sqlcx, db_timeout: 10_000 # or other positive integer number of ms

Another esqlcipher parameter is :db_chunk_size. This is a count of rows to read from native sqlcipher and send to erlang process in one bulk. For example, consider a table mytable that has 1000 rows. We make the query to get all rows with db_chunk_size: 500 parameter:

Sqlcx.query(db, "select * from mytable", db_chunk_size: 500)

in this case all rows will be passed from native sqlcipher OS thread to the erlang process in two passes. Each pass will contain 500 rows. This parameter decrease overhead of transmitting rows from native OS sqlcipher thread to the erlang process by chunking list of result rows. Please, decrease this value if rows are heavy. Default value is 5000. If you’re in doubt what to do with this parameter, just leave it as is. The default value will be ok in almost all cases.

config :sqlcx, db_chunk_size: 500 # if most of the database rows are heavy

Link to this section Summary

Functions

Create a new table name where table_opts is a list of table constraints and cols is a keyword list of columns. The following table constraints are supported: :temp and :primary_key. Example

Send a raw SQL statement to the database

Sets a PID to receive notifications about table updates.

Runs fun inside a transaction. If fun returns without raising an exception, the transaction will be commited via commit. Otherwise, rollback will be called.

Link to this section Types

Specs

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

Specs

sqlite_error() :: {:error, {:sqlite_error, charlist()}}

Specs

string_or_charlist() :: string_or_charlist()

Link to this section Functions

Specs

close(connection(), Keyword.t()) :: :ok
Link to this function

create_table(db, name, table_opts \\ [], cols, call_opts \\ [])

View Source

Create a new table name where table_opts is a list of table constraints and cols is a keyword list of columns. The following table constraints are supported: :temp and :primary_key. Example:

[:temp, {:primary_key, [:id]}]

Columns can be passed as:

  • name: :type
  • name: {:type, constraints}

where constraints is a list of column constraints. The following column constraints are supported: :primary_key, :not_null and :autoincrement. Example:

id: :integer, name: {:text, [:not_null]}

Link to this function

exec(db, sql, opts \\ [])

View Source

Specs

Send a raw SQL statement to the database

This function is intended for running fully-complete SQL statements. No query preparation, or binding of values takes place. This is generally useful for things like re-playing a SQL export back into the database.

Link to this function

is_encrypted(connection)

View Source

Specs

is_encrypted(connection()) :: boolean()

Specs

open(string_or_charlist(), Keyword.t()) ::
  {:ok, connection()} | {:error, {atom(), charlist()}}

Specs

Link to this function

query(db, sql, opts \\ [])

View Source

Specs

query(connection(), string_or_charlist(), [Sqlcx.Query.query_option()]) ::
  {:ok, [keyword()]} | {:error, term()}

A shortcut to Sqlcx.Query.query/3

Link to this function

query!(db, sql, opts \\ [])

View Source

Specs

A shortcut to Sqlcx.Query.query!/3

Link to this function

query_rows(db, sql, opts \\ [])

View Source

Specs

query_rows(connection(), string_or_charlist(), [Sqlcx.Query.query_option()]) ::
  {:ok, %{}} | sqlite_error()

A shortcut to Sqlcx.Query.query_rows/3

Link to this function

query_rows!(db, sql, opts \\ [])

View Source

Specs

A shortcut to Sqlcx.Query.query_rows!/3

Link to this function

rekey(db, password, opts \\ [])

View Source

Specs

rekey(connection(), String.t(), Keyword.t()) :: :ok | sqlite_error()
Link to this function

rekey!(db, password, opts \\ [])

View Source

Specs

rekey!(connection(), String.t(), Keyword.t()) :: :ok
Link to this function

set_update_hook(db, pid, opts \\ [])

View Source

Specs

set_update_hook(connection(), pid(), Keyword.t()) :: :ok | {:error, term()}

Sets a PID to receive notifications about table updates.

Messages will come in the shape of: {action, table, rowid}

  • action -> :insert | :update | :delete
  • table -> charlist of the table name. Example: 'posts'
  • rowid -> internal immutable rowid index of the row.
           This is *NOT* the `id` or `primary key` of the row.
    See the official docs.
Link to this function

with_db(path, fun, opts \\ [])

View Source
Link to this function

with_transaction(db, fun, opts \\ [])

View Source

Specs

with_transaction(connection(), (connection() -> any()), Keyword.t()) :: any()

Runs fun inside a transaction. If fun returns without raising an exception, the transaction will be commited via commit. Otherwise, rollback will be called.

## Examples

iex> {:ok, db} = Sqlcx.open(":memory:")
iex> Sqlcx.with_transaction(db, fn(db) ->
...>   Sqlcx.exec(db, "create table foo(id integer)")
...>   Sqlcx.exec(db, "insert into foo (id) values(42)")
...> end)
iex> Sqlcx.query(db, "select * from foo")
{:ok, [[{:id, 42}]]}