本文へ移動
Hikari リファレンス

std:db/sqlite リファレンス

import sqlite := "std:db/sqlite" で取得する SQLite ドライバーモジュール。open で Db ハンドルを得て query / exec / transaction を行う (契約は std:db)。

Db

ExactlyOnce(Db)

SQLite データベース接続のハンドル。ExactlyOnce の多重度型で、close が Consuming
メソッドである。閉じ忘れは接続の漏れなので、未消費のまま有効範囲を出ると
never-consumed の診断になる。

>>> import sqlite := "std:db/sqlite"
>>> db := sqlite.open("app.db")!.unwrap!
>>> db.close()!

Tx

AtMostOnce(Tx)

トランザクションのハンドル。AtMostOnce の多重度型だが Consuming メソッドは持たない
— 封印するのは transaction の側で、ブロックの結果により commit / rollback を決める。
ゆえにブロックが受け取るのは貸し出された Borrowed(Tx) である。

>>> import sqlite := "std:db/sqlite"
>>> handler := { tx: sqlite.Tx | tx }

open

open(path)
open: { String | Effect(Future(Result(Db)), Fs) }

DB ファイルを開き (不在なら作成) Db ハンドルを得る。\":memory:\" も可。

効果ハンドラーの操作である。handle の操作スロットに open と書いて横取りできる(language-spec.md §17.9)。

>>> db := sqlite.open(":memory:")!
>>> db.close()!

Db メソッド

close

db.close()
close: Consuming({ Effect(Future(Result(Unit)), Fs) })

接続を閉じて封印する。以降のメソッド呼び出しは Error。

効果ハンドラーの操作である。handle の操作スロットに close と書いて横取りできる(language-spec.md §17.9)。

>>> db := sqlite.open(":memory:")!
>>> db.close()!

exec

db.exec(sql, params)
exec: { String, List(Any) | Effect(Future(Result({ changes: Int, last_insert_rowid: Int |})), Fs) }

INSERT / UPDATE / DDL を実行し {changes, last_insert_rowid} を得る。

効果ハンドラーの操作である。handle の操作スロットに exec と書いて横取りできる(language-spec.md §17.9)。

>>> r := db.exec("insert into t (x) values (?)", [1])!
>>> print r.unwrap!.changes

query

db.query(sql, params)
query: { String, List(Any) | Effect(Future(Result(List(Any))), Fs) }

SELECT を実行し行 record の List を得る。列値は Some(v)、NULL は None。

効果ハンドラーの操作である。handle の操作スロットに query と書いて横取りできる(language-spec.md §17.9)。

>>> rows := db.query("select name, age from users where age > ?", [20])!
>>> print rows.unwrap!.length!

transaction

db.transaction(block)
transaction: { EffectConduit({ Borrowed(Tx) | Result(a) }) | Effect(Future(Result(a)), Fs) }

block をトランザクションで評価する。Ok → commit、Err / panic → rollback。

効果ハンドラーの操作である。handle の操作スロットに transaction と書いて横取りできる(language-spec.md §17.9)。

>>> (db.transaction { tx | tx.exec("insert into t values (1)")!?; Ok(()) })!

Tx メソッド

exec

tx.exec(sql, params)
exec: { String, List(Any) | Effect(Future(Result({ changes: Int, last_insert_rowid: Int |})), Fs) }

トランザクションの中で INSERT / UPDATE / DDL を実行する。形と戻りは db.exec と
同じ。block の中は tx 経由が正道である — 同じ Db への直接の exec は接続の解放を待ち、
待ち時間を超えると busy になる。

効果ハンドラーの操作である。handle の操作スロットに exec と書いて横取りできる(language-spec.md §17.9)。

>>> tx.exec("update users set age = age + 1 where name = ?", ["Alice"])!?

query

tx.query(sql, params)
query: { String, List(Any) | Effect(Future(Result(List(Any))), Fs) }

トランザクションの中で SELECT を実行する。形と戻りは db.query と同じ。
block の中は tx 経由が正道である。

効果ハンドラーの操作である。handle の操作スロットに query と書いて横取りできる(language-spec.md §17.9)。

>>> rows := tx.query("select id from users where name = ?", ["Alice"])!?