Docsの目次

SQLの事前検査

Nagi 0.2.0の std.db.sqlite は、通常checkで直接literalから作る Query を必須にします。SQL構文・schemaの検査は明示オプションで有効にする別段階です。公開済み0.1.xの機能へ遡及適用しません。SQLiteと移行を参照してください。

このページの目次

使い方

schema.sql に配備するschemaのDDL snapshotを保存します。

CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL);

app.nagi の直接Query constructorは、schemaの名前・返却列・bind数を検査できます。

import std.db.sqlite as sqlite
class User:
    id: i64
    name: str
async def find(tx: view[sqlite.Tx], id: i64) -> Result[User?, sqlite.Failure]:
    return await sqlite.query[User](tx, sqlite.literal("SELECT id, name FROM users WHERE id = ?"), sqlite.bind_i64(sqlite.parameters(), id))
nagic check app.nagi --sql-schema schema.sql --sql-dialect sqlite

naem は未定義列、SELECT id はUserのname不足として拒否します。診断はSQLを書いた元Nagi/Low moduleの行を示します。projectでは nagic check --project ./app --sql-schema ./app/schema.sql --sql-dialect sqlite を使います。schemaの相対pathは実行時current working directoryを基準にします。二つのSQLオプションは組で指定し、checkだけに使えます。nagi.tomlやeditorの自動有効化はありません。

検査するもの

対象 確認する内容
sqlite.query/all の直接literal Query 単一readonly文、table/column名、必要row field
sqlite.exec の直接literal Query 一文・返却列なし・schema参照。DDLもprepare-onlyで実行しない
直接 parameters() と bind_* のbuilder列 SQLの匿名 ? 個数との一致
Query/Parametersが変数や関数経由で構造不明 当該siteをruntime検査として表示。static検査成功へ数えない

canonical stdlib:std.db.sqlite として解決された呼出しだけが対象です。同名ユーザー関数をSQLと推測しません。列順・alias・余分な列は許します。numbered ?1 とnamed placeholderは標準APIの制約で拒否します。SQL parserをcheckerへ複製せず、opt-in engineとruntimeがSQLiteのauthorizer・prepare metadataでshapeを検査します。

Query変数はliteralから作った値として通常checkを通りますが、このcollectorはdataflowを追ってSQLを推測しません。直接constructorでもParameters変数なら bind unchecked です。実値型・NULL・数値範囲は常にruntimeに残します。例えば 'oops' AS id は必要列を返しても、i64のdecode成功を保証しません。手書きnative FromRow本体は解析しません。

DDL/bootstrapはtrusted管理処理です。queryを実行してschemaを推測せず、execのCREATE TABLEで検査schemaを変更しません。request用動的文字列factoryはありません。旧Db/db_*はSQL検査に入る前に具体的migration診断で拒否します。

安全性と保証の限界

検査用SQLiteは別workerのmemory DBです。通常CREATE TABLE・INDEX・VIEWを使うDDL snapshotを読み込みます。任意migration、ATTACH/DETACH、PRAGMA、外部file操作、extension、TEMP・virtual table・trigger・transaction・CREATE TABLE AS SELECTは拒否します。関数allowlistを使い、random・日時関数・DEFAULT CURRENT_TIMESTAMPは対象外です。

schemaは2 MiB・1024文、各SQLは256 KiBまでで、列数や式の深さにも上限があります。別worker processを5秒の期限で監視し、上限・期限違反は検査Errです。全siteを明示した一つのschemaへ照合し、複数Poolの配備先や権限・tenant predicate・実DBの状態を保証しません。

SQLiteを含めずにコンパイラをビルドする

opt-in engineは既定Cargo feature sql-check に含まれます。

cargo build --release --locked -p nagic --no-default-features

engineなしでもliteral Queryの通常checkとbuildは使えます。SQL検査オプションはfeatureが必要というErrになります。アプリ側SQLite runtimeとは別設定です。

Nagi 0.2.0 · Docsこのページのソース