メモ
https://spiralsense.jp/blog/2016/09/06/sqlite3-c%e3%83%a9%e3%83%83%e3%83%91%e3%83%bc%e3%83%a9%e3%82%a4%e3%83%96%e3%83%a9%e3%83%aa%e3%80%8csqlitecpp%e3%80%8d%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9/spiralsense.jp
元記事消えちゃったので、失礼して復元
非常にシンプルに作られており、とても使い易いライブラリです。
cmakeでビルドする方法が記載されていますが、xcodeではもっと簡単にプロジェクトに組み込めます。
SQLiteCppフォルダをプロジェクトに配置し
SQLiteCpp/include をHeader Serch Pathsに追加して
SQLiteCpp/src/*.cpp、SQLiteCpp/sqlite3.cファイルすべてをCompile Sourcesに追加するだけです。
SQLiteCppの使い方
インスタンスの作り方
#include <SQLiteCpp/SQLiteCpp.h>
int main() {
try {
SQLite::Database db("filename");
}
catch (std::exception& e) {
std::cout << "exception: " << e.what() << std::endl;
}
return 0;
}コンストラクタやクエリは例外を投げるのでtry-catchした方がいいです。
コンストラクタは第4引数まで持ちます。
第一引数:ファイル名
第二引数:オープンタイプ
OPEN_READONLY : 読み込み専用
OPEN_READWRITE : 読み書き
OPEN_CREATE : なかったら作る
OPEN_URI : URIも許可する
複数のタイプを組み合わせることができます。(例:SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE)
デフォルト値: OPEN_READONLY
第三引数:データベースがロックされている時のタイムアウト時間[ms]
デフォルト値:0
第四引数: VFSの設定
独自のファイルシステムを指定する際に使う。
デフォルト値:空文字列
成功したかどうかさえわかれば良いタイプのクエリを送る(例: CREATE TABLE)
int nb = db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");返り値:SQL文で変更された行の数
返り値でSQLITE_OKはかえってきません。
内部でSQLITE_OKかどうかをチェックし、例外を投げる機構が作られてるので、OKチェックをしたい場合はtry-catchしてください。
トランザクションの作成
明示的にトランザクションを使う場合はTransactionクラスを使います。
SQLite::Transaction transaction(db);
// dbに関する操作
transaction.commit();
もしcommitせずにtransactionインスタンスが破棄された場合、デストラクタでロールバックが行われます。
データを取ってくるクエリ
Statementクラスを使います。
SQLite::Statement query(db, "SELECT * FROM test WHERE id >= ?");
query.bind(1, 0);
while (query.executeStep()){
int id = query.getColumn(0);
std::string text = query.getColumn(1);
std::cout << "row: " << id << ", " << text << std::endl;
}エラーをとりたい場合は同様にtry-catchします。
バインドはプレースホルダ「?」を使って行います。
プレースホルダインデックスは1から始まります。注意してください(本家sqlite3は0から)
getColumn関数は対応するインデックスのデータを取得しますが、返り値がColumnというデータラッパクラスです。
プリミティブ型になら何でもキャスト出来る型なので、インデックス等をよく確認するか、isIntegerメソッド等を利用するとデバッグに便利かもしれません。
非explicitキャスト演算子がオーバーロードされているため、以下の3文は等価です。
id = query.getColumn(0); id = static_cast<int>(query.getColumn(0)); id = (int)query.getColumn(0);
1行目が暗黙キャスト、2行目がC++風キャスト、3行目がC風キャスト。
すべて内部でgetIntメソッドを呼びます。
他の型も同様です。
また、bindは内部でprepareしてくれます。
内部で扱われてるsqlite_stmtラッパクラスのコンストラクタとデストラクタが、prepare-rest-finalizeをやってくれてるからです。