sqlite3の実装をやっています。
C++では当然Objective-C用のFMDBが使えないので、
C言語に近いところでの操作が必要になります。
sqlite3自体は、
http://www.sqlite.org/download.html
からダウンロードしてプロジェクトに加えます。
で、いろいろとやって、とうとうSelect文を実行する段階に。
しかし、sqlite3の関数を探してみても、クエリの結果から値を取り出す際に、
下記関数のような、コラムのindexで指定するものしか見当たりませんでした。
sqlite3_column_int(sqlite3_stmt *stmt, int i)
この方法だと、Objective-Cから移植する際に面倒くさいので、
無理矢理カラム名からやる様にしてみました。
std::vector<cocos2d::Value> allRecord = std::vector<cocos2d::Value>();
sqlite3 *db = this->getDB();
if (!db) {
return allRecord;
}
sqlite3_stmt *stmt = NULL;
std::string sql = "SELECT * FROM table1";
if (sqlite3_prepare_v2(db, // db
sql.c_str(), //sql
-1, //バイト長
&stmt, //ステートメントハンドル
NULL) == SQLITE_OK) {
//indexとcolumn nameの対応
std::map<std::string, int> map;
while (sqlite3_step(stmt) == SQLITE_ROW) {
if (map.size() == 0) {
for (int columnIdx = 0; columnIdx < sqlite3_column_count(stmt); columnIdx++) {
dict[sqlite3_column_name(stmt, columnIdx)]=columnIdx;
}
}
std::vector<cocos2d::Value> records = std::vector<cocos2d::Value>();
//0
records.push_back(Value(sqlite3_column_int(stmt, map["id"])));
//1
const unsigned char *str = sqlite3_column_text(stmt, map["name"]);
if(str){
records.push_back(Value(""));
}else{
records.push_back(Value(str));
}
allRecord.push_back(Value(records));
}
}
sqlite3_reset(stmt);
sqlite3_finalize(stmt);
sqlite3_close(db);
return allRecord;
*getDBは、DBファイルを指定したsqlite3変数を返す自作のメソッドです。
*データは、"id"と"name"の2列です。
*それぞれの行ごとの配列(Vector)と、それをまとめる配列の二次元配列にしています。
何をしているかというと、
mapにインデックス番号とカラム名を関連づけて保存し、
そこからカラム名を使ってインデックスを指定できるようにしただけです。
他にもいい方法があるかもしれませんが、自分にはこれで十分でした。
以上です。
0 件のコメント:
コメントを投稿