Using SQLite

You can save and load game data easily by using the database in your game. In a smartphone application, the database called SQLite is usually used. SQLite is easy to use. However, you have to set a few things before using it. In this recipe, we will explain how to set up and use SQLite in Cocos2d-x.

Getting ready

Cocos2d-x doesn't have an SQLite library. You have to add SQLite's source code to Cocos2d-x.

You need to download the source code from the site http://sqlite.org/download.html. The latest version at the time of writing this book is version 3.8.10. You can download this version's .zip file and expand it. Then, you can add the resulting files to your project as shown in the following image:

Getting ready

In this recipe, we will create an original class called SQLiteManager. So, you have to add the SQLiteManager.h and SQLiteManager.cpp files to your project.

Then, if you build for Android, you have to edit proj.android/jni/Android.mk as follows:

LOCAL_SRC_FILES := hellocpp/main.cpp  
                   ../../Classes/AppDelegate.cpp  
                   ../../Classes/HelloWorldScene.cpp  
                   ../../Classes/SQLiteManager.cpp  
                   ../../Classes/sqlite/sqlite3.c

How to do it...

First, you have to edit the SQLiteManager.h file as follows:

#include "cocos2d.h" #include "sqlite/sqlite3.h"

class SQLiteManager {
private:
    SQLiteManager();
    static SQLiteManager* instance;
    sqlite3 *_db;
    bool open();
    void close();
public:
    virtual ~SQLiteManager();
    static SQLiteManager* getInstance();
    void insert(std::string key, std::string value);
    std::string select(std::string key);
};

Next, you have to edit the SQLiteManager.cpp file. This code is a little long. So, we will explain it step by step.

  1. Add the following code for the singleton class:
    SQLiteManager* SQLiteManager::instance = nullptr; 
    SQLiteManager::~SQLiteManager() { 
    }
    
    SQLiteManager::SQLiteManager()
    {
        if (this->open()) {
            sqlite3_stmt* stmt;
            // create table 
            std::string sql = "CREATE TABLE IF NOT EXISTS 
    data(key TEXT PRIMARY KEY,value TEXT);"; 
            if (sqlite3_prepare_v2(_db, sql.c_str(), -1, &stmt, 
    nullptr) == SQLITE_OK) { 
                if (sqlite3_step(stmt)!=SQLITE_DONE) { 
                    CCLOG("Error in CREATE TABLE"); 
                }
      } 
            sqlite3_reset(stmt); 
            sqlite3_finalize(stmt); 
            this->close(); 
       } 
    }
    
    SQLiteManager* SQLiteManager::getInstance() { 
        if (instance==nullptr) { 
            instance = new SQLiteManager(); 
        }
        return instance;
    }
  2. Add the method that opens and closes the database:
    bool SQLiteManager::open() 
    {
        std::string path = FileUtils::getInstance()- 
    >getWritablePath()+"test.sqlite"; 
        return sqlite3_open(path.c_str(), &_db)==SQLITE_OK; 
    }
    
    void SQLiteManager::close() 
    { 
        sqlite3_close(_db); 
    }
  3. Add the method that inserts data to the database:
    void SQLiteManager::insert(std::string key, std::string value)
    {
        this->open();
        // insert data
        sqlite3_stmt* stmt;
        std::string sql = "INSERT INTO data (key, value) VALUES(?, ?)";
        if (sqlite3_prepare_v2(_db, sql.c_str(), -1, &stmt, nullptr) == SQLITE_OK) {
            sqlite3_bind_text(stmt, 1, key.c_str(), -1, SQLITE_TRANSIENT);
            sqlite3_bind_text(stmt, 2, value.c_str(), -1, SQLITE_TRANSIENT);
            if (sqlite3_step(stmt)!=SQLITE_DONE) { 
                CCLOG("Error in INSERT 1, %s", 
                sqlite3_errmsg(_db)); 
            }
        }
        sqlite3_reset(stmt);
        sqlite3_finalize(stmt);
        this->close();
    }
  4. Add the method that selects data from the database:
    std::string SQLiteManager::select(std::string key){
        this->open(); 
    
        // select data 
        std::string value; 
        sqlite3_stmt* stmt; 
        std::string sql = "SELECT VALUE from data where key=?"; 
        if (sqlite3_prepare_v2(_db, sql.c_str(), -1, &stmt, 
        NULL) == SQLITE_OK) { 
            sqlite3_bind_text(stmt, 1, key.c_str(), -1, 
            SQLITE_TRANSIENT); 
            if (sqlite3_step(stmt) == SQLITE_ROW) { 
                const unsigned char* val = 
                sqlite3_column_text(stmt, 0); 
                value = std::string((char*)val); 
                CCLOG("key=%s, value=%s", key.c_str(), val); 
            } else {
                CCLOG("Error in SELECT, %s", 
                sqlite3_errmsg(_db));
            }
        } else {
            CCLOG("Error in SELECT, %s", sqlite3_errmsg(_db)); 
        } 
        sqlite3_reset(stmt); 
        sqlite3_finalize(stmt); 
        this->close(); 
        return value; 
    }
  5. Finally, here's how to use this class. To insert data, use the following code:
    SQLiteManager::getInstance()->insert("foo", "value1");

    To select data, use the following code:

    std::string value = SQLiteManager::getInstance()- 
    >select("foo");

How it works...

Firstly, in the constructor method of the SQLiteManager class, this class creates a table called data if it does not already exist. The data table is created in SQL as follows:

CREATE TABLE IF NOT EXISTS data(key TEXT PRIMARY KEY,value TEXT);

In order to use SQLite, you have to include sqlite3.h and use the sqlite3 API. This API is in the C language. If you would like to learn it, you should check the website http://sqlite.org/cintro.html.

We created our database called test.sqlite in the sandbox area of the application. If you want to change the location or the name, you should edit the open method.

std::string path = FileUtils::getInstance()->getWritablePath()+"test.sqlite";

You can insert data by using the insert method to specify the key and the value.

SQLiteManager::getInstance()->insert("foo", "value1");

Further, you can select the value by using the select method to specify the key.

std::string value = SQLiteManager::getInstance()->select("foo");

There's more...

In this recipe, we created the insert method and the select method. However, you can execute other SQL methods such as delete and replace. Further, you can make the database match your game. So, you will need to edit this class for your game.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.28.53