Sqlcx.Server (sqlcx v2.0.0-rc.1) View Source
Sqlcx.Server provides a GenServer to wrap an sqlcipher db. This makes it easy to share a SQLCipher database between multiple processes without worrying about concurrency issues (although sqlite handles concurrency natively as well). You can also register the process with a name so you can query by name later.
Unsupervised Example
iex> {:ok, pid} = Sqlcx.Server.start_link(":memory:", [name: :example])
iex> Sqlcx.Server.exec(pid, "CREATE TABLE t (a INTEGER, b INTEGER)")
:ok
iex> Sqlcx.Server.exec(pid, "INSERT INTO t (a, b) VALUES (1, 1), (2, 2), (3, 3)")
:ok
iex> Sqlcx.Server.query(pid, "SELECT * FROM t WHERE b = 2")
{:ok, [[2, 2]]}
iex> Sqlcx.Server.query(:example, "SELECT * FROM t ORDER BY a LIMIT 1", into: %{})
{:ok, [%{"a" => 1, "b" => 1}]}
iex> Sqlcx.Server.query_rows(:example, "SELECT * FROM t ORDER BY a LIMIT 2")
{:ok, [%{a: 1, b: 1}, %{a: 2, b: 2}]}
iex> Sqlcx.Server.prepare(:example, "SELECT * FROM t")
{:ok, %{column_names: ["a", "b"], column_types: ["INTEGER", "INTEGER"]}}
# Subsequent queries using this exact statement will now operate more efficiently
# because this statement has been cached.
iex> Sqlcx.Server.prepare(:example, "INVALID SQL")
{:error, {:sqlite_error, 'near "INVALID": syntax error'}}
iex> Sqlcx.Server.stop(:example)
:ok
iex> :timer.sleep(10) # wait for the process to exit asynchronously
iex> Process.alive?(pid)
false
Supervised Example
import Supervisor.Spec
children = [
worker(Sqlcx.Server, ["priv/my_db.db", [name: :my_db])
]
Supervisor.start_link(children, strategy: :one_for_one)
Link to this section Summary
Functions
Same as Sqlcx.changes/2
but using the shared db connection saved in the GenServer state.
Returns a specification to start this module under a supervisor.
Same as Sqlcx.exec/3
but using the shared db connection saved in the GenServer state.
Callback implementation for GenServer.init/1
.
Prepares a SQL statement for future use.
Same as Sqlcx.query/3
but using the shared db connection saved in the GenServer state.
Same as Sqlcx.query_rows/3
but using the shared db connection saved in the GenServer state.
Change the password used to encrypt the database.
Same as Sqlcx.set_update_hook/3
but using the shared db connection saved in the GenServer state.
Starts a SQLCipher Server (GenServer) instance.
Stops the server and closes the database connection.
Link to this section Types
Specs
init_options() :: [ db_timeout: timeout(), db_chunk_size: pos_integer(), db_password: String.t() | {:raw, binary()} ]
Specs
query_options() :: [ bind: [Sqlcx.Statement.bind_value()], into: Collectable.t(), db_timeout: timeout(), db_chunk_size: pos_integer(), call_timeout: timeout() ]
Specs
server_id() :: GenServer.server()
Specs
server_options() :: [ db_timeout: timeout(), db_chunk_size: pos_integer(), db_password: String.t() | {:raw, binary()}, stmt_cache_size: non_neg_integer() ]
Specs
state() :: {Sqlcx.connection(), Sqlcx.Server.StatementCache.t(), [db_timeout: timeout(), db_chunk_size: pos_integer()]}
Specs
Link to this section Functions
Specs
changes(server_id(), timeout_options()) :: non_neg_integer()
Same as Sqlcx.changes/2
but using the shared db connection saved in the GenServer state.
Returns the results of Sqlcx.changes/2
.
Returns a specification to start this module under a supervisor.
See Supervisor
.
Specs
exec(server_id(), String.t(), timeout_options()) :: :ok | Sqlcx.error()
Same as Sqlcx.exec/3
but using the shared db connection saved in the GenServer state.
Returns the results of Sqlcx.exec/3
.
Specs
init({String.t(), non_neg_integer(), init_options()}) :: {:ok, state()} | {:stop, {id :: atom(), reason :: charlist()}}
Callback implementation for GenServer.init/1
.
Specs
prepare(server_id(), String.t(), timeout_options()) :: {:ok, %{column_names: [String.t()], column_types: [String.t()]}} | Sqlcx.error()
Prepares a SQL statement for future use.
This causes a call to sqlite3_prepare_v2
to be executed in the Server process. To protect the reference to the corresponding
sqlite3_stmt
struct from misuse in other
processes, that reference is not passed back. Instead, prepared statements are
cached in the Server process. If a subsequent call to query/3
or query_rows/3
is made with a matching SQL statement, the prepared statement is reused.
Prepared statements are purged from the cache when the cache exceeds a preset limit (32 statements by default).
Note that binding parameters to a statement is only possible using query/3
or query_rows/3
. These functions also use the cache, so a statement that has
been prepare
d before will be run from the cache.
Returns summary information about the prepared statement.
{:ok, %{column_names: ["foo", "bar",... ], column_types: ["INTEGER", ...]}}
on success or {:error, {:id, 'message'}}
if the statement could not be prepared.
Specs
query(server_id(), String.t(), query_options()) :: {:ok, [keyword()]} | Sqlcx.error()
Same as Sqlcx.query/3
but using the shared db connection saved in the GenServer state.
Returns the results of Sqlcx.query/3
.
Specs
query_rows(server_id(), String.t(), query_options()) :: {:ok, %{}} | Sqlcx.error()
Same as Sqlcx.query_rows/3
but using the shared db connection saved in the GenServer state.
Returns the results of Sqlcx.query_rows/3
.
Specs
rekey(server_id(), String.t(), timeout_options()) :: :ok | Sqlcx.error()
Change the password used to encrypt the database.
Specs
set_update_hook(server_id(), pid(), timeout_options()) :: :ok | Sqlcx.error()
Same as Sqlcx.set_update_hook/3
but using the shared db connection saved in the GenServer state.
Returns the results of Sqlcx.set_update_hook/3
.
Specs
start_link(String.t(), server_options()) :: GenServer.on_start()
Starts a SQLCipher Server (GenServer) instance.
In addition to the options that are typically provided to GenServer.start_link/3
,
you can also specify:
db_password:
optional password used for opening an encrypted database. SeeSqlcx.open/2
for details.stmt_cache_size:
to override the default limit (32) of statements that are cached when callingprepare/3
.db_timeout:
to override:esqlcipher
's default timeout of 5000 ms for interactions with the database. This can also be set inconfig.exs
asconfig :sqlcx, db_timeout: 5_000
.db_chunk_size:
to override:esqlcipher
's default chunk_size of 5000 rows to read from native sqlite and send to erlang process in one bulk. This can also be set inconfig.exs
asconfig :sqlcx, db_chunk_size: 5_000
.
Specs
stop(server_id()) :: :ok
Stops the server and closes the database connection.