Sqlite

Use SQLite natively in Gren.

type Database

An opened SQLite database. This value is required to complete operations on that database.

type Location
= Memory
| File Path

Where a database is located when opened.

  • Memory opens the database in memory. When your program stops, any data written is lost.
  • File opens the database in a given Path in the file system.
type alias Options =
{ readOnly : Bool
, enableForeignKeyConstraints : Bool
, allowExtension : Bool
, timeout : Int
}

When opening the database, you can define a set of restrictions that apply for all queries and statements executed.

  • readOnly, when True, opens the database in read-only mode. All attempted modifications will fail.
  • allowExtension, when True, enables the loadExtension SQL function and the loadExtension() method.
  • enableForeignKeyConstraints, when True, foreign key constraints are enabled. This is recommended but can be disabled for compatibility with legacy database schemas. The enforcement of foreign key constraints can be enabled and disabled after opening the database using PRAGMA foreign_keys.
  • timeout is the busy timeout in milliseconds. This is the maximum amount of time that SQLite will wait for a database lock to be released before returning an error. 0 or negative number means no timeout.
defaultOptions : Options

A sensible set of default Options for a SQLite database.

{ readOnly = False
, enableForeignKeyConstraints = True
, allowExtension = False
, timeout = 5000
}
open : Permission -> Options -> Location -> Task Error Database

Open a database at the given Location if it already exists. If a database does not exist at the given location, this function creates a database at that location.

This is the only way to obtain the Database type that is required for nearly all functionality in the Sqlite family of modules.

close : Database -> Task Error {}

Close the given Database.

Query

type alias Query value =
{ query : String
, parameters : Array Value
, rowDecoder : Decoder value
}

A SQL query to get some data from a database. An example of how this can be used is below:

{ query = "SELECT name, email, age FROM users WHERE id = :user_id
, parameters = 
    [ Sqlite.Encode.Row.column "user_id" <| Encode.string "123"
    ]
, rowDecoder =
    Sqlite.Decode.Row.column "name" Decode.string <| \name ->
    Sqlite.Decode.Row.column "email" Decode.string <| \email ->
        Sqlite.Decode.Row.succeed { name = name, email = email }
}

For more information on encoding parameters, visit Sqlite.Encode.Row module documentation. For more information on decoding the returned rows, visit Sqlite.Decode.Row module documentation.

getOne : Database -> Query value -> Task Error value

Get a single value returned by a Query. This will fail if either no results or more than one result is returned.

getMaybeOne : Database -> Query value -> Task Error (Maybe value)

Get either Nothing (no result) or a single value returned by a Query.

getAll : Database -> Query value -> Task Error (Array value)

Get all values returned by a Query.

foldl : (a -> b -> b) -> b -> Database -> Query a -> Task Error b

Accumulate a new value by iterating over all results from a given Query, one row at a time.

Statement

type alias Statement = { statement : String, parameters : Array Value }

SQL that does not return any data from the database. An example of how this can be used is below:

{ statement = "INSERT INTO people (name, role) VALUES (:name, :role)"
, parameters =
    [ Sqlite.Encode.Row.column "name" <| Encode.string p.name
    , Sqlite.Encode.Row.column "role" <| Encode.string p.role
    ]
}

For more information on encoding parameters, visit Sqlite.Encode.Row module documentation.

type alias ExecutionSummary = { changes : Int, lastInsertRowid : Int }

A summary of how an execution changed the database.

  • changes is how many rows were inserted, updated, or removed.
  • lastInsertRowId is the ID of the last row inserted. This could be be negative if no row was inserted.
execute : Database -> Statement -> Task Error ExecutionSummary

Execute some given SQL.

executeAll :
Database
-> Array Statement
-> Task Error (Array ExecutionSummary)

Execute many statements sequentially.

executeForEach :
Database
-> { statement : String, parameters : value -> Array Value }
-> Array value
-> Task Error ExecutionSummary

Execute a single Statement for many sets of encoded parameters. This is very useful for inserting lots of rows into the database.

Sqlite.executeForEach db
    { statement = "INSERT INTO people (name) VALUES (:name)"
    , parameters = encoder
    }
    [ { name = "Joey" }
    , { name = "Robin" }
    , { name = "Justin" }
    ]
executeScript : Database -> String -> Task Error Database

Execute some arbitrary SQL. This is most helpful when you need to run more than one SQL statement, as execute, executeForAll, and executeForEach only allow a single SQL statement.

Backup

type Backup

A backup configuration for a database. This value can be created by running the backup function.

backup : Permission -> Path -> Database -> Backup

Produce a backup configuration for the given Database.

withBackupPageRate : Int -> Backup -> Backup

Configure the number of pages that are saved in each batch of the backup process. By default, the backup page rate is 100.

runBackup : Backup -> Task Error {}

Run a database Backup after it's been configured. The database can still be used safely during the backup process. However, if there are any mutations performed on the database outside of your Gren program, the backup process will restart.

Errors

type Error
= AbortError AbortError
| AuthError AuthError
| BusyError BusyError
| CantOpenError CantOpenError
| ConstraintError ConstraintError
| CorruptError CorruptError
| Error String
| IoError IoError
| LockedError LockedError
| MismatchError
| MisuseError
| NoLfsError
| NoMemError
| NotADbError
| NotFoundError
| NoticeError NoticeError
| PermError
| ProtocolError
| RangeError
| ReadOnlyError ReadOnlyError
| FullError
| InternalError
| InterruptError
| TooBigError
| NoResultsError
| SchemaError
| MultipleResultsError Int
| DecodingError Error

All possible errors that can happen when running functions in this module. Most of these come from the SQLite error documentation.

While any of these errors can happen when interacting with a SQLite database, some more commmon types of errors are below:

  • ConstraintError and its associated errors. These set of errors deal with any failed constraints, like primary keys, foreign keys, or column types.
  • NoResultsError and MultipleResultsError are isolated to the getOne function.
  • DecodingError when decoding data returned from a Query.
type AbortError
= GenericAbortError String
| RollbackAbortError
type AuthError
= GenericAuthError String
| UserAuthError
type BusyError
= GenericBusyError String
| RecoveryBusyError
| SnapshotBusyError
| TimeoutBusyError
type CantOpenError
= GenericCantOpenError String
| ConvPathCantOpenError
| DirtyWalCantOpenError
| FullPathCantOpenError
| IsDirCantOpenError
| NoTempDirCantOpenError
| SymLinkCantOpenError
type ConstraintError
= GenericConstraintError String
| CheckConstraintError
| CommitHookConstraintError
| DataTypeConstraintError
| ForeignKeyConstraintError
| FunctionConstraintError
| NotNullConstraintError
| PinnedConstraintError
| PrimaryKeyConstraintError
| RowIdConstraintError
| TriggerConstraintError
| UniqueConstraintError
| VTabConstraintError
type CorruptError
= GenericCorruptError String
| IndexCorruptError
| SequenceCorruptError
| VTabCorruptError
type IoError
= GenericIoError String
| AccessIoError
| AuthIoError
| BeginAtomicIoError
| BlockedIoError
| CheckReservedLockIoError
| CloseIoError
| CommitAtomicIoError
| ConvPathIoError
| CorruptFsIoError
| DataIoError
| DeleteIoError
| DeleteNoEntIoError
| DirectoryCloseIoError
| DirFSyncIoError
| FStatIoError
| FSyncIoError
| GetTempPathIoError
| LockIoError
| MMapIoError
| NoMemIoError
| RdLockIoError
| ReadIoError
| RollbackAtomicIoError
| SeekIoError
| ShmLockIoError
| ShmMapIoError
| ShmOpenIoError
| ShmSizeIoError
| ShortReadIoError
| TruncateIoError
| UnlockIoError
| VNodeIoError
| WriteIoError
type LockedError
= GenericLockedError String
| SharedCacheLockedError
| VTabLockedError
type NoticeError
= GenericNoticeError String
| RecoverRollbackNoticeError
| RecoverWalNoticeError
type ReadOnlyError
= GenericReadOnlyError String
| CantInitReadOnlyError
| CantLockReadOnlyError
| DbMovedReadOnlyError
| DirectoryReadOnlyError
| RecoveryReadOnlyError
| RollbackReadOnlyError
errorToString : Error -> String

Transform a given Error into a descriptive String.

Each error string for known SQLite errors contain the error code found at https://sqlite.org/rescode.html.More details on the errors can be found by their code on that page.

Utilities

inTransaction : Database -> Task Error a -> Task Error a

Run a Task (like statements or queries) in a transaction. This is equivalant to running some SQL like this:

BEGIN TRANSACTION
-- The given `Task` runs here
COMMIT

If the given Task has an error, COMMIT will instead be ROLLBACK, reverting any changes within the transaction.