This is my first time using an sqlite database, I just want to make sure this way works and I haven’t missed something obvious in what I’m trying to do here:
#ifndef PROJ_ANDROID_STUDIO_CCLOADER_H
#define PROJ_ANDROID_STUDIO_CCLOADER_H
#include "cocos2d.h"
#include "../Libraries/sqlite3.h"
using namespace std;
USING_NS_CC;
NS_CC_BEGIN
class DataScene : public Scene {
protected:
static sqlite3* _database;
public:
typedef Scene super;
static sqlite3* getDatabase();
virtual void onEnter() override ;
virtual void onExit() override ;
};
NS_CC_END
#endif //PROJ_ANDROID_STUDIO_CCLOADER_H
And in the source file:
#include "CCDataScene.h"
#include "../CatAndToast/CatAndToastConfig.h"
using namespace std;
NS_CC_BEGIN
sqlite3* DataScene::_database = nullptr;
sqlite3* DataScene::getDatabase() {
return _database;
}
void DataScene::onEnter() {
string path = FileUtils::getInstance()->getWritablePath() + DB_NAME;
string sql;
auto result = sqlite3_open(path.c_str(), &_database);
if (result != SQLITE_OK) {
CCLOG("open database failed, error: %d", result);
CC_ASSERT(false);
}
super::onEnter();
}
void DataScene::onExit() {
super::onExit();
sqlite3_close(_database);
_database = nullptr;
}
NS_CC_END
Advantages of this:
–It’s better than just opening and closing the database connection in whatever function needs the database, because I don’t have the risk of then calling another function that opens a concurrent connection.
–It’s better than a true singleton, because I don’t have to remember to open and close the database connection. I just have to run a DataScene, and as long I’m in one, the database is there, and as soon as I’m not in one, the database is gone.
–Making the database connection a static variable avoids breaking the Liskov Substitution Principle with a messy dynamic_cast<DataScene*>(Director::getInstance()->getRunningScene())->getDatabase()
. This way, I’ll just always know that if I’m not in a DataScene, DataScene::getDatabase()
will return null, and there’s no need to get the DataScene object and treat it as such.