Cocos2dx Sqlite3を使ってみる

raharu(仮名)(プログラマー)
これがダイバージェンス1%の先の世界か。。。

こんにちわ、今週の休日は家に引きこもって自動エンコードバッチの修正をしていたraharuです。

今回はcocos2dxでsqlite3の使用をするという名目です。
まだ永続データの運用方法をちゃんと考えてないのですが、
とりあえず今回はSqliteでやってみようと思います。

※HellowWorldでもいいのですが今回はTopシーンを作成しています。

とりあず以下のソースを書いてみる

Top.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef __sqlitetest__Top__
#define __sqlitetest__Top__

#include <iostream>

#include "cocos2d.h"
#include "sqlite3.h"

class Top : public cocos2d::Layer
{

public:
    static cocos2d::Scene* createScene();
    virtual bool init();
    void menuCloseCallback(cocos2d::Ref* pSender);
    CREATE_FUNC(Top);

    //sqlite3
    sqlite3* useDataBase = NULL;
    char* errorMessage = NULL;

};

#endif /* defined(__sqlitetest__Top__) */

Top.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include "Top.h"

USING_NS_CC;

Scene* Top::createScene()
{
    auto scene = Scene::create();
    auto layer = Top::create();
    scene->addChild(layer);
    return scene;
}

// on "init" you need to initialize your instance
bool Top::init()
{
    if ( !Layer::init() ) return false;

    //DBファイルの保存先のパス
    auto filePath = FileUtils::getInstance()->getWritablePath();
    filePath.append("Test.db");

    //OPEN
    auto status = sqlite3_open(filePath.c_str(), &useDataBase);

    //ステータスが0以外の場合はエラーを表示
    if (status != SQLITE_OK){
        CCLOG("opne failed : %s", errorMessage);
    }else{
        CCLOG("open sucessed");
    }

    //テーブル作成
    auto create_sql = "CREATE TABLE user( id integer primary key autoincrement, name nvarchar(32), age int(2) )";
    status = sqlite3_exec(useDataBase, create_sql, NULL, NULL, &errorMessage );
    if( status != SQLITE_OK ) CCLOG("create table failed : %s", errorMessage);

    //インサート
    auto insert_sql = "INSERT INTO user(name, age) VALUES('raharu', 29)";
    status = sqlite3_exec(useDataBase, insert_sql , NULL, NULL, &errorMessage);

    //Close
    sqlite3_close(useDataBase);

    return true;
}

ビルドすると。。

1
2
3
4
5
6
7
Undefined symbols for architecture i386:
  "_sqlite3_exec", referenced from:
      Top::init() in Top.o
  "_sqlite3_open", referenced from:
      Top::init() in Top.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

こんなエラーがでました?

[Build Phases] > [Link Binaly With libraries]を開いて

f:id:raharu0425:20140414161323p:plain

[libsqlite3.0.dylib]を追加してあげます

f:id:raharu0425:20140414161346p:plain

これでビルド通るはずです。

保存先の確認

DBのファイルの保存先はfilePathここに入っていますので
ログにでも出力しておきます

1
2
3
4
5
//DBファイルの保存先のパス
auto filePath = FileUtils::getInstance()->getWritablePath();
filePath.append("Test.db");

CCLOG("%s", filePath.c_str());

Test.dbの保存パスが出力されたと思います。

Litaで確認する

http://www.dehats.com/drupal/?q=node/58

Download Nowをクリックしてインストールします。

f:id:raharu0425:20140414161858p:plain

さっきログに出力したパスを指定して入れた値が正常に入っているか確認します。

f:id:raharu0425:20140414162110p:plain

これで使えるようになりました。
アクションにSQLべたってのもなんなのでマッピングクラスでも作るのが良さそうです。