SQLiteのユーザバージョンを利用する

昨日に続き、SQLiteの話題。SQLiteのリファレンス本をパラパラとめくっていたら、schema_version, user_versionなるPRAGMAコマンドを見つけた。これは一体何だろう?

schema_versionについてはこんな説明が載っていた。

データベースに変更が加えられるたびに加算されるバージョン番号を管理します。バージョン番号が加算されるのは、テーブルやインデックスの作成および削除、またALTER TABLEによるテーブル定義の更新時です。

SQLiteが内部的に管理する番号ということなので、これに依存した処理を記述するのは危険だけど、動作確認用としては便利そうだ。

一方、user_versionについては、その名前と上記の解説から予想されるように、ユーザが自由に使って良い番号だ。

ユーザーによって設定できるバージョン番号を管理します。PRAGMA schema_versionコマンドとは違い、SQLite内部では使用されません。

ガーン、今までバージョン番号管理用にわざわざテーブルを作って番号を保持しておき、これを参照することでALTER TABLE等の処理を呼び出していたけれど、そんな面倒な手続きは不要で、簡単にバージョン番号を利用出来る仕組みが用意されていたのだ。

期待通りの動作をするのか、早速テストしてみる。動作環境は昨日と同じSQLite.NETだ。

using (SQLiteConnection connection = new SQLiteConnection("Data Source=test.db"))
{
    connection.Open();
    using (SQLiteCommand command = new SQLiteCommand(connection))
    {
        command.CommandText = "CREATE TABLE IF NOT EXISTS Bar(id integer NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, Value INTEGER)";
        command.ExecuteNonQuery();

        // Before
        command.CommandText = "PRAGMA schema_version";
        Trace.WriteLine("schema_version (before):" + command.ExecuteScalar());
        command.CommandText = "PRAGMA user_version";
        Trace.WriteLine("user_version (before):" + command.ExecuteScalar());

        Trace.WriteLine("alter the table.");
        command.CommandText = "ALTER TABLE Bar ADD Name VARCHAR(8)";
        command.ExecuteNonQuery();

        // After
        command.CommandText = "PRAGMA schema_version";
        Trace.WriteLine("schema_version (after):" + command.ExecuteScalar());
        command.CommandText = "PRAGMA user_version";
        Trace.WriteLine("user_version (after):" + command.ExecuteScalar());

        // Update
        command.CommandText = "PRAGMA user_version = 1234";
        int updated = command.ExecuteNonQuery();
        command.CommandText = "PRAGMA user_version";
        Trace.WriteLine("user_version (updated):" + command.ExecuteScalar());
    }
}

実行結果は下記の通り。

schema_version (before):1
user_version (before):0
alter the table.
schema_version (after):2
user_version (after):0
user_version (updated):1234

動作は確かに上記の説明通り、ALTER TABLEの呼び出しによってschema versionの値は変わるけれどuser versionの値は変わらず、またuser versionには任意の値を保持出来ていた。

もしかすると、まだ他にも何か知らない便利コマンドが有るのかも知れない。リファレンスを真面目に読んで勉強しようと心に誓う夏の一日でした。

SQLite ポケットリファレンス

SQLite ポケットリファレンス

The user-version is not used internally by SQLite. It may be used by applications for any purpose

Pragma statements supported by SQLite



関連