【Flutter】SQLiteでのDebugのTips
使用するライブラリ
sqflite
を使用したデバッグ方法の解説
sqflite
を使用した開発では、問題が発生した時のデバッグが重要です。この記事では、sqflite
のデバッグ方法について、具体的な実装例を交えながら解説していきます。
デバッグログの実装方法
SQLite のデバッグで最も効果的な方法の一つが、SqfliteDatabaseFactoryLogger
を使用したログ出力です。
// データベースの操作をログ出力するための実装例
// ロガーの設定とデータベースの初期化
var factoryWithLogs = SqfliteDatabaseFactoryLogger(databaseFactory,
options:
SqfliteLoggerOptions(type: SqfliteDatabaseFactoryLoggerType.all));
// データベースの作成とテーブル定義
var db = await factoryWithLogs.openDatabase(
join(await getDatabasesPath(), 'todo_database.db'),
options: OpenDatabaseOptions(
version: 1,
onCreate: (db, version) {
return db.execute(
'CREATE TABLE todos(id INTEGER PRIMARY KEY, title TEXT, done INTEGER)',
);
},
),
);
このコードを実行すると、以下のような詳細なログが出力されます:
flutter: openDatabase:({path: /Users/省略/Library/Developer/CoreSimulator/Devices/59A21D49-BCBD-493D-B172-66CBB63A44D2/data/Containers/Data/Application/88204291-0ACE-41A1-92DA-269D2F94076B/Documents/todo_database.db, options: {readOnly: false, singleInstance
flutter: query(query:({db: 1, sql: PRAGMA user_version, result: [{user_version: 0}], sw: 0:00:00.008604}))
flutter: execute(execute:({db: 1, sql: BEGIN EXCLUSIVE, result: {transactionId: 1}, sw: 0:00:00.001032}))
flutter: query(query:({db: 1, txn: 1, sql: PRAGMA user_version, result: [{user_version: 0}], sw: 0:00:00.000144}))
flutter: execute(execute:({db: 1, txn: 1, sql: CREATE TABLE todos(id INTEGER PRIMARY KEY, title TEXT, done INTEGER), sw: 0:00:00.000218}))
flutter: execute(execute:({db: 1, txn: 1, sql: PRAGMA user_version = 1, sw: 0:00:00.000128}))
flutter: execute(execute:({db: 1, txn: 1, sql: COMMIT, sw: 0:00:00.000478}))
flutter: query(query:({db: 1, sql: SELECT * FROM todos, result: [], sw: 0:00:00.273168}))
ログの詳細内容
1. データベースのオープン
// データベースファイルのパスを指定してデータベースをオープン
openDatabase:({
path: '/Users/.../todo_database.db',
options: {readOnly: false, singleInstance}
})
指定されたパスに Todo アプリケーション用の SQLite データベースを作成し、読み書き可能な状態でオープンしています。
2. データベースのバージョン確認
// データベースのユーザーバージョンを確認
PRAGMA user_version
// 結果: {user_version: 0}
新規作成されたデータベースのため、バージョンは 0 となっています。
PRAGMA(プラグマ)とは、SQLite の設定を変更・確認するための特別なコマンドです。
3. トランザクションの開始
// 排他的なトランザクションを開始
BEGIN EXCLUSIVE
データベースの一貫性を保つため、排他的なトランザクションを開始しています。
BEGIN EXCLUSIVE(排他的トランザクション開始)とは、他のプロセスがデータベースに書き込めないようにロックする
4. テーブルの作成
// Todosテーブルの作成
CREATE TABLE todos(
id INTEGER PRIMARY KEY, // 一意のID
title TEXT, // Todoのタイトル
done INTEGER // 完了状態(0:未完了, 1:完了)
)
5. バージョン管理
// データベースのバージョンを1に更新
PRAGMA user_version = 1
テーブル作成後、データベースのバージョンを 1 に更新しています。
6. トランザクションの確定
// トランザクションをコミット
COMMIT
すべての変更を確定させています。
7. データの取得
// todosテーブルから全データを取得
SELECT * FROM todos
// 結果: [] (新規作成のため、データは空)
実行時間の分析
各操作の実行時間(sw: ソフトウェアタイマー)を見ると:
- バージョン確認: 0.008604 秒
- トランザクション開始: 0.001032 秒
- テーブル作成: 0.000218 秒
- データ取得: 0.273168 秒
今回作成したアプリで hogehoge を入力して、insert
query
を実行すると、
flutter: insert(insert:({db: 1, sql: INSERT OR REPLACE INTO todos (title, done) VALUES (?, ?), arguments: [hogehoge, 0], result: 1, sw: 0:00:00.003601}))
flutter: query(query:({db: 1, sql: SELECT * FROM todos, result: [{id: 1, title: hogehoge, done: 0}], sw: 0:00:00.000425}))
と出力され、どのような CRUD 処理を実行したか、処理後にどんな結果が得られたかがログで出力されます。
データベースの内容確認
テーブル構造の確認
データベースの状態を確認したい場合、以下のコードで既存のテーブル情報を取得できます:
// sqlite_masterテーブルの確認
print(await db.query("sqlite_master"));
ログ
[{type: table, name: todos, tbl_name: todos, rootpage: 2, sal: CREATE TABLE todos(id INTEGER PRIMARY KEY, title TEXT, done
INTEGER)}]
テーブルの内容確認
特定のテーブルの中身を確認したい場合は、以下のように実装します:
// テーブルの内容を出力
print(await db.query("todos"));
ログ
雑に入力した TODO リストが出力されました。
[id: 1, title: ちいかわかわいい, done: 1}, {id: 2, title: ちいかわかわいい, done: 1}, {id: 3, title: ちいかわかわいい, done: 1}, {id: 4, title: ちいかわかわいい, done: 1}, {id: 5, title: ちいかわかわいい, done: 1}]
まとめ
SQLite のデバッグでは、ログ出力とデータベースの状態確認が重要です。この記事で紹介した手法を組み合わせることで、効率的なデバッグが可能になります。
以下は、今回作成したサンプルコードです。
参照
Discussion