前提条件
プレビュー機能を使用する拡張機能は、vsql_allow_preview_extensions が ON の場合にのみインストールできます:
SET GLOBAL が拒否される理由を含む詳細については、プレビュー層の有効化を参照してください。
また、動作する Rust 拡張機能のセットアップも必要です — Rust で拡張機能を作成するのチュートリアルで、ツールチェーン、cargo-vsql、および最初の extension! ブロックについて説明しています。
Rust SDK がラップするもの
残りのプレビュー機能 —
auth、mysql_services、session_var、statement_event、カスタムインデックス機能、および列ストレージ ABI — は現時点では C++ のみです。これらのいずれかが必要な場合は、C++ SDK を使用してください。
登録パターン
各機能をstatic として宣言し、extension! の requires: セクションで参照によって列挙します — これは C++ SDK の .with() に相当する Rust の方法です:
static は必須です — サーバーは拡張機能の全生存期間にわたって機能へのポインタを保持します。
ステータス変数
status_var 機能は、拡張機能が所有するカウンターを SHOW GLOBAL STATUS を通じて公開します。拡張機能は 'static なアトミック値としてストレージを所有し、それらに書き込みます。サーバーは、ステータス変数がクエリされるたびにポインタ経由で読み取ります。
各変数を StatusVarSpec として宣言します — AtomicI64 に裏付けられた Int、または SDK の AtomicF64 に裏付けられた Double です(Rust の標準ライブラリにはアトミックな f64 がないため、SDK が new、load、store を備えたものを提供しています):
INSTALL EXTENSION の後、変数は拡張機能名をプレフィックスとして表示されます:
システム変数
sys_var 機能は、拡張機能が所有する MySQL システム変数を登録します。3 つの型がサポートされます:Bool、Int(min/max の境界付き)、および Str です。すべての spec は、名前、コメント、デフォルト値、およびオプションの on_change コールバックを持ちます。
名前と文字列のデフォルト値は &'static CStr の値です — C 文字列リテラル(c"enabled")として記述してください:
funcs: セクションは、空の場合でも requires: の前に存在しなければなりません。
インストール後、変数は拡張機能名をプレフィックスとして参照できます:
変更への反応
on_change は生の C コールバックであり、変数が設定された後にサーバーによって呼び出されます。サーバーはグローバルなシステム変数ロックを保持したままこれを呼び出すため、処理は短く保ち、パニックさせないでください — ここでのパニックは FFI 境界を越えます。コールバックは生の ABI レイヤーから *const vef_sys_var_change_t を受け取ります:
on_change: Some(on_enabled_change) として spec に組み込みます。
拡張機能コードからの読み書き
SysVarCapability は、サーバーを介したプログラム的アクセスのための get() および set() も公開しています(そのため範囲の検証と永続化はサーバーが処理します)。set() は永続化を選択する scope 引数を取ります:null は実行中の値のみを変更するため、再起動時に元に戻ります。"PERSIST" は実行中の値を変更し、永続化された設定にも書き込みます。"PERSIST_ONLY" は実行中の値に触れずに永続化された設定に書き込むため、次回の再起動時に適用されます。どちらも NUL 終端の C 文字列を取る unsafe な FFI メソッドであり、どちらも反転した C の慣習を使用します:Some(false) は成功、Some(true) はサーバーがエラーを報告したこと、None は機能が利用不可であることを意味します。get が成功した場合、サーバーは malloc された文字列を書き込みます。これは C の free() で解放する必要があります。vsql_sys_var の例に、free の extern 宣言と safety コメントを含む完全なパターンが示されています。
スレッドワーカー
thread_worker 機能は、あなたが提供する関数をサーバー管理のバックグラウンドスレッドで実行します。サーバーはロード時に制御システム変数を登録します。それが ON の間、あなたの作業関数は定期タイマー、ファイルディスクリプタの準備完了、または有効化/無効化の遷移に応じて呼び出されます。
作業関数は通常の安全な Rust です:
ThreadWorkerCapability::new は、作業関数、スレッド名のサフィックス、初期スリープ間隔、およびオプションの制御変数名のオーバーライドを取ります。オーバーライドが None の場合、制御変数は {suffix}_enabled という名前になり、拡張機能のプレフィックスの下に登録されます:
ウェイクアップ
WakeupReason は、サーバーが呼び出した理由を示します:Enable、Periodic、PollFd、または Disable です。戻り値によって次回のウェイクアップを調整します:
NextWakeup::unchanged()— 現在のスリープ間隔と poll fd を維持します。NextWakeup::after(duration)—durationの後に再度起動します。poll_fdフィールドに 0 より大きいファイルディスクリプタを設定すると、それが読み取り可能になったときにも起動します。-1を設定すると、以前に設定したものをクリアします。
Duration は「変更なし」に帰着します — 基盤となる C ABI が 0 をその意味に予約しているため、即時のウェイクアップは表現できません。
作業関数がパニックした場合、SDK は FFI 境界でそのパニックを捕捉し、その呼び出しが NextWakeup::unchanged() を返したものとして扱います — ワーカーは実行を継続します。
handle パラメータを SqlQueryCapability::open に渡すと、ワーカー内から SQL を実行できます。
SQL クエリ
sql_query 機能は、thread_worker のコールバックから SQL セッションを開きます。これにより、バックグラウンドワーカーは、自身がロードされているサーバーに対してステートメントを実行できます。ThreadWorkerCapability と一緒に宣言し、ワーカーが受け取る ThreadHandle でセッションを開きます:
SqlQueryCapability::open(handle) は、機能に値が設定されていない場合(プレビューがオフ、または要求されていない)、ABI が古すぎる場合、あるいはサーバーがセッションを開けなかった場合に None を返します。結果を使用する前に確認してください。
Session には、ステートメントを実行する 2 つの方法があります:
execute(sql)は結果セット全体をバッファリングし、QueryResultを返します。next_row()がNoneを返すまで繰り返し呼び出します。各Rowはget_int(i)、get_str(i)、get_real(i)、またはget_bytes(i)で列を読み取ります。get_bytes/get_strは、SQLNULLまたは範囲外のインデックスに対してNoneを返します(get_strは UTF-8 でないバイトに対してもNoneを返します)。get_int/get_realはまず列をテキストとして解析するため、解析できないテキストに対してもNoneを返します。execute自体は、セットアップの失敗(セッションがない、またはメモリ不足)の場合にのみNoneを返します。for_each(sql, |row: Row<'_>| { ... })は、結果セット全体をバッファリングする代わりに、行をクロージャにストリーミングします。返されるQueryResultは診断情報のみを持ち、反復処理するバッファリングされた行はありません。また、セットアップの失敗時にはNoneを返します。
has_error() と error()(errno、severity、sqlstate、message を持つ Option<Diag>)を確認してください。warnings() は、結果に付随するすべての警告とノートを返します。
Session と QueryResult は、それぞれドロップ時に基盤となるハンドルを閉じます。自分で呼び出す close メソッドはありません。
キーリングアクセス
keyring 機能は、MySQL keyring コンポーネントに格納されたシークレット — API キー、暗号化キー、テーブルに置くべきでないあらゆるもの — を読み書きします。keyring コンポーネント(例:component_keyring_file)は、Keyring Component Installation で説明されているように、コンポーネントマニフェストとその構成ファイルを通じてサーバー起動時にロードされている必要があります。INSTALL COMPONENT では利用可能になりません。コンポーネントがない場合、すべての読み書きは KeyringError::NoComponent で失敗します。
read(data_id, auth_id, buf) は、渡されたバッファを埋め、シークレットの長さとともに Ok(Some(n)) を返します。data_id の下にシークレットが存在しない場合は Ok(None) を返します — これはエラーではなく通常の結果です。write(data_id, auth_id, data) は成功時に Ok(()) を返します。auth_id は所有ユーザーです。特定のユーザーに関連付けられていない内部キーには None を渡します。
どちらも失敗時に Err(KeyringError) を返します:CapabilityUnavailable(機能が一度も接続されていない)、NoComponent(サーバーに keyring コンポーネントがない)、または Other です。
keyring にはサイズを調べる手段がありません。read に渡したバッファより大きいシークレットは Ok(None) として返り、キーが存在しない場合と区別できません。格納する見込みの最大のシークレットに合わせてバッファのサイズを決めてください。
次のステップ
プレビュー機能(C++)
完全な機能インデックス、プレビュー層、および C++ のみの機能:auth、
mysql_services、session_var、statement_event、カスタムインデックス機能、
列ストレージ。
Rust API リファレンス
InValue、VdfReturn、extension!、func!、custom_type! — すべてのフィールド。