Sqlite

Value

Represents a value that can be stored in a Sqlite database.

[
    Null,
    Real F64,
    Integer I64,
    String Str,
    Bytes (List U8),
]

ErrCode

Represents various error codes that can be returned by Sqlite.

[
    Error, # SQL error or missing database
    Internal, # Internal logic error in Sqlite
    Perm, # Access permission denied
    Abort, # Callback routine requested an abort
    Busy, # The database file is locked
    Locked, # A table in the database is locked
    NoMem, # A malloc() failed
    ReadOnly, # Attempt to write a readonly database
    Interrupt, # Operation terminated by sqlite3_interrupt(
    IOErr, # Some kind of disk I/O error occurred
    Corrupt, # The database disk image is malformed
    NotFound, # Unknown opcode in sqlite3_file_control()
    Full, # Insertion failed because database is full
    CanNotOpen, # Unable to open the database file
    Protocol, # Database lock protocol error
    Empty, # Database is empty
    Schema, # The database schema changed
    TooBig, # String or BLOB exceeds size limit
    Constraint, # Abort due to constraint violation
    Mismatch, # Data type mismatch
    Misuse, # Library used incorrectly
    NoLfs, # Uses OS features not supported on host
    AuthDenied, # Authorization denied
    Format, # Auxiliary database format error
    OutOfRange, # 2nd parameter to sqlite3_bind out of range
    NotADatabase, # File opened that is not a database file
    Notice, # Notifications from sqlite3_log()
    Warning, # Warnings from sqlite3_log()
    Row, # sqlite3_step() has another row ready
    Done, # sqlite3_step() has finished executing
    Unknown I64, # error code not known
]

Binding

Bind a name and a value to pass to the Sqlite database.

{
    name : Str,
    value : SqliteValue,
}

Stmt

Represents a prepared statement that can be executed many times.

prepare! : { path : Str, query : Str } => Result Stmt [SqliteErr ErrCode Str]

Prepare a Stmt for execution at a later time.

This is useful when you have a query that will be called many times, as it is more efficient than preparing the query each time it is called. This is usually done in init! with the prepared Stmt stored in the model.

prepared_query = Sqlite.prepare!({
    path : "path/to/database.db",
    query : "SELECT * FROM todos;",
})?

Sqlite.query_many_prepared!({
    stmt: prepared_query,
    bindings: [],
    rows: { Sqlite.decode_record <-
        id: Sqlite.i64("id"),
        task: Sqlite.str("task"),
    },
})

execute! : { path : Str, query : Str, bindings : List Binding } => Result {} [ SqliteErr ErrCode Str, UnhandledRows ]

Execute a SQL statement that doesn't return any rows (like INSERT, UPDATE, DELETE).

Example:

Sqlite.execute!({
    path: "path/to/database.db",
    query: "INSERT INTO users (first, last) VALUES (:first, :last);",
    bindings: [
        { name: ":first", value: String("John") },
        { name: ":last", value: String("Smith") },
    ],
})?

execute_prepared! : { stmt : Stmt, bindings : List Binding } => Result {} [ SqliteErr ErrCode Str, UnhandledRows ]

Execute a prepared SQL statement that doesn't return any rows.

This is more efficient than execute! when running the same query multiple times as it reuses the prepared statement.

query! : { path : Str, query : Str, bindings : List Binding, row : SqlDecode a (RowCountErr err) } => Result a (SqlDecodeErr (RowCountErr err))

Execute a SQL query and decode exactly one row into a value.

Example:

# count the number of rows in the `users` table
count = Sqlite.query!({
    path: db_path,
    query: "SELECT COUNT(*) as \"count\" FROM users;",
    bindings: [],
    row: Sqlite.u64("count"),
})?

query_prepared! : { stmt : Stmt, bindings : List Binding, row : SqlDecode a (RowCountErr err) } => Result a (SqlDecodeErr (RowCountErr err))

Execute a prepared SQL query and decode exactly one row into a value.

This is more efficient than query! when running the same query multiple times as it reuses the prepared statement.

query_many! : { path : Str, query : Str, bindings : List Binding, rows : SqlDecode a err } => Result (List a) (SqlDecodeErr err)

Execute a SQL query and decode multiple rows into a list of values.

Example:

rows = Sqlite.query_many!({
    path: "path/to/database.db",
    query: "SELECT * FROM todos;",
    bindings: [],
    rows: { Sqlite.decode_record <-
        id: Sqlite.i64("id"),
        task: Sqlite.str("task"),
    },
})?

query_many_prepared! : { stmt : Stmt, bindings : List Binding, rows : SqlDecode a err } => Result (List a) (SqlDecodeErr err)

Execute a prepared SQL query and decode multiple rows into a list of values.

This is more efficient than query_many! when running the same query multiple times as it reuses the prepared statement.

decode_record : SqlDecode a err, SqlDecode b err, (a, b -> c) -> SqlDecode c err

Decode a Sqlite row into a record by combining decoders.

Example:

{ Sqlite.decode_record <-
    id: Sqlite.i64("id"),
    task: Sqlite.str("task"),
}

map_value : SqlDecode a err, (a -> b) -> SqlDecode b err

Transform the output of a decoder by applying a function to the decoded value.

Example:

Sqlite.i64("id") |> Sqlite.map_value(Num.to_str)

tagged_value : Str -> SqlDecode Value []

Decode a Value keeping it tagged. This is useful when data could be many possible types.

For example here we build a decoder that decodes the rows into a list of records with id and mixed_data fields:

rows = Sqlite.query_many!({
    path: "path/to/database.db",
    query: "SELECT id, mix_data FROM users;",
    bindings: [],
    rows: { Sqlite.decode_record <-
        id: Sqlite.i64("id"),
        mix_data: Sqlite.tagged_value("mixed_data"),
    },
})?

str : Str -> SqlDecode Str UnexpectedTypeErr

Decode a Value to a Str.

For example here we build a decoder that decodes the rows into a list of records with id and name fields:

rows = Sqlite.query_many!({
    path: "path/to/database.db",
    query: "SELECT id, name FROM users;",
    bindings: [],
    rows: { Sqlite.decode_record <-
        id: Sqlite.i64("id"),
        task: Sqlite.str("name"),
    },
})?

bytes : Str -> SqlDecode (List U8) UnexpectedTypeErr

Decode a Value to a List U8.

i64 : Str -> SqlDecode I64 [FailedToDecodeInteger []]UnexpectedTypeErr

Decode a Value to a I64.

For example here we build a decoder that decodes the rows into a list of records with id and name fields:

rows = Sqlite.query_many!({
    path: "path/to/database.db",
    query: "SELECT id, name FROM users;",
    bindings: [],
    rows: { Sqlite.decode_record <-
        id: Sqlite.i64("id"),
        task: Sqlite.str("name"),
    },
})?

i32 : Str -> SqlDecode I32 [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a I32.

i16 : Str -> SqlDecode I16 [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a I16.

i8 : Str -> SqlDecode I8 [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a I8.

u64 : Str -> SqlDecode U64 [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a U64.

u32 : Str -> SqlDecode U32 [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a U32.

u16 : Str -> SqlDecode U16 [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a U16.

u8 : Str -> SqlDecode U8 [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a U8.

f64 : Str -> SqlDecode F64 [FailedToDecodeReal []]UnexpectedTypeErr

Decode a Value to a F64.

f32 : Str -> SqlDecode F32 [FailedToDecodeReal []]UnexpectedTypeErr

Decode a Value to a F32.

Nullable a : [ NotNull a, Null ]

Represents a nullable value that can be stored in a Sqlite database.

nullable_str : Str -> SqlDecode (Nullable Str) UnexpectedTypeErr

Decode a Value to a Nullable Str.

nullable_bytes : Str -> SqlDecode (Nullable (List U8)) UnexpectedTypeErr

Decode a Value to a Nullable (List U8).

nullable_i64 : Str -> SqlDecode (Nullable I64) [FailedToDecodeInteger []]UnexpectedTypeErr

Decode a Value to a Nullable I64.

nullable_i32 : Str -> SqlDecode (Nullable I32) [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a Nullable I32.

nullable_i16 : Str -> SqlDecode (Nullable I16) [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a Nullable I16.

nullable_i8 : Str -> SqlDecode (Nullable I8) [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a Nullable I8.

nullable_u64 : Str -> SqlDecode (Nullable U64) [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a Nullable U64.

nullable_u32 : Str -> SqlDecode (Nullable U32) [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a Nullable U32.

nullable_u16 : Str -> SqlDecode (Nullable U16) [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a Nullable U16.

nullable_u8 : Str -> SqlDecode (Nullable U8) [FailedToDecodeInteger [OutOfBounds]]UnexpectedTypeErr

Decode a Value to a Nullable U8.

nullable_f64 : Str -> SqlDecode (Nullable F64) [FailedToDecodeReal []]UnexpectedTypeErr

Decode a Value to a Nullable F64.

nullable_f32 : Str -> SqlDecode (Nullable F32) [FailedToDecodeReal []]UnexpectedTypeErr

Decode a Value to a Nullable F32.

errcode_to_str : ErrCode -> Str

Convert a ErrCode to a pretty string for display purposes.