概要
「SQLiteをはじめたいけど、始め方が分からない…」
このブログでは、
・SQLiteのプロジェクト導入
・sqlの実行
をするところまで解説し、そんなお悩みに答えたいと思います。
サンプル
SQLiteのプロジェクト導入
すごく簡単です。
1. sqliteのダウンロード
2. プロジェクトへの追加
3. コーディング
の3stepです。(だいたいそうか笑
sqliteのダウンロード
よりダウンロードします。
今回はamalgamation (一番上のリンク)をダウンロードしました。執筆時点では3.8.8.3が最新です。
※amalgamationは混合とかって意味らしいです。
注意!
もしupdate文を打つ際にlimitもしくはorder byを使用する予定がある方はamalgamationではなく生のソースコードをダウンロードしてコンパイルして入れてください。
それに関してはこちらのエントリで。
また、生のソースからの入れ方については当記事では説明しておりません。
プロジェクトへの追加
以下3つのファイルを追加します。
・sqlite3.c
・sqlite3.h
・sqlite3ext.h
ここまでで導入は終わりです。簡単でしょう?
コーディング
では実際にソースを書いてみましょう。
最終系はこんな感じです。
string dbName = "test.db";
auto filePath = FileUtils::getInstance()->getWritablePath() + dbName;
auto status = sqlite3_open(filePath.c_str(), &db);
if(status != SQLITE_OK)
{
CCLOG("error for opening db.");
}
else
{
CCLOG("open successed!");
}
// create table
auto create_table = "create table user (id integer, age integer)";
status = sqlite3_exec(db, create_table, nullptr, nullptr, &errorMessage);
if(status != SQLITE_OK) CCLOG("create: %s", errorMessage);
// insert row
auto insert = "insert into user(id, age) values (1, 15)";
status = sqlite3_exec(db, insert, nullptr, nullptr, &errorMessage);
if(status != SQLITE_OK) CCLOG("insert: %s", errorMessage);
// update row
auto update = "update user set age = 20 where id = 1";
status = sqlite3_exec(db, update, nullptr, nullptr, &errorMessage);
if(status != SQLITE_OK) CCLOG("update: %s", errorMessage);
// select row(s)
auto select = "select * from user where id = 1";
status = sqlite3_exec(db, select, callback, nullptr, &errorMessage);
if(status != SQLITE_OK) CCLOG("select: %s", errorMessage);
sqlite3_close(db);
出力
cocos2d: open successed!
id = 1
age = 20
解説
上記のコードを読んで理解出来る人は多分解説はいらないと思います。
L1〜L2 DBの場所を用意
L4〜L12 databaseをopen
L14〜L17 userテーブルの作成
L19〜L22 userにデータをinsert
L24〜L27 userデータをupdate
L29〜31 userデータをselect
L34 最後は必ずdatabaseをclose
さて、selectのexecの第3引数だけcallbackが指定されています。
コールバックは以下の様になっています。
static int callback(void *_, int argc, char **argv, char **columnName){
for(int i=0; i < argc; i++)
printf("%s = %s\n", columnName[i], argv[i] ? argv[i] : "null");
return SQLITE_OK;
}
第一引数:今回使っていませんが、呼び出し元のインスタンスが入っています。
第二引数:カラム数
第三引数:データの値の配列
第四引数:カラム名
callback以外にないのか?
さて、先ほどの書き方で少し問題が出てきます。
callback関数が別関数になってしまっているので処理が煩雑になりがちです。
もう一つの書き方を紹介します。
sqlite3_stmt* statement = nullptr;
auto select = "select * from user where id = 1";
if(sqlite3_prepare_v2(db, select, -1, &statement, nullptr) != SQLITE_OK) CCLOG("prepare: %s", errorMessage);
else
{
if (sqlite3_step(statement) == SQLITE_ROW)
{
for (int i = 0; i < sqlite3_column_count(statement); i++)
{
string name = sqlite3_column_name(statement, i);
int columnType = sqlite3_column_type(statement, i);
if (columnType == SQLITE_INTEGER)
{
CCLOG("%s = %d", name.c_str(), sqlite3_column_int(statement, i));
continue;
}
}
}
}
sqlite3_reset(statement);
sqlite3_finalize(statement);
出力は先ほどと同じです。
L1 状態を表す変数statementを用意
L3 sqlをコンパイル
L6 sqlite3_stepでsqlを実行
L7 sqlite3_column_countでカラム数を取得
L10 sqlite3_column_nameでi番目のカラム名を取得
L11 sqlite3_column_typeでカラムのタイプ(int, char...)を取得
L12 sqlite3_column_*で各タイプの値の取得
このような形になります。
誰かのお役に立てば。
コメント