#include "common/app_db.h"
-#include <app_preference.h>
+// #define USE_APP_PREFERENCE;
+#ifdef USE_APP_PREFERENCE
+ #include <app_preference.h>
+#else
+ #include "common/app_db_sqlite.h"
+
+ #include <unistd.h>
+ #include <sqlite3.h>
+ #include <app.h>
+#endif
+
#include <memory>
#include "common/string_utils.h"
+#include "common/logger.h"
namespace wrt {
namespace {
+#ifdef USE_APP_PREFERENCE
const char* kSectionPrefix = "_SECT_";
const char* kSectionSuffix = "_SECT_";
+#else
+ const char* kCreateDbQuery = "CREATE TABLE IF NOT EXISTS appdb ("
+ "section TEXT, "
+ "key TEXT, "
+ "value TEXT,"
+ "PRIMARY KEY(section, key));";
+#endif
} // namespace
+#ifdef USE_APP_PREFERENCE
+
class PreferenceAppDB : public AppDB {
public:
PreferenceAppDB();
preference_remove(combined_key.c_str());
}
+#else // end of USE_APP_PREFERENCE
+
+SqliteDB::SqliteDB(const std::string& app_data_path)
+ : app_data_path_(app_data_path),
+ sqldb_(NULL) {
+ if (app_data_path_.empty()) {
+ std::unique_ptr<char, decltype(std::free)*>
+ path {app_get_data_path(), std::free};
+ if (path.get() != NULL)
+ app_data_path_ = path.get();
+ }
+ Initialize();
+}
+
+SqliteDB::~SqliteDB() {
+ if (sqldb_ != NULL) {
+ sqlite3_close(sqldb_);
+ sqldb_ = NULL;
+ }
+}
+
+void SqliteDB::Initialize() {
+ if (app_data_path_.empty()) {
+ LOGGER(ERROR) << "app data path was empty";
+ return;
+ }
+ std::string db_path = app_data_path_ + "/.appdb.db";
+ int ret = sqlite3_open(db_path.c_str(), &sqldb_);
+ if (ret != SQLITE_OK) {
+ LOGGER(ERROR) << "Fail to open app db :" << sqlite3_errmsg(sqldb_);
+ sqldb_ = NULL;
+ return;
+ }
+ sqlite3_busy_handler(sqldb_, [](void *, int count) {
+ if (count < 5) {
+ LOGGER(ERROR) << "App db was busy, Wait the lock count(" << count << ")";
+ usleep(100000*(count+1));
+ return 1;
+ } else {
+ LOGGER(ERROR) << "App db was busy, Fail to access";
+ return 0;
+ }
+ }, NULL);
+
+ char *errmsg = NULL;
+ ret = sqlite3_exec(sqldb_, kCreateDbQuery, NULL, NULL, &errmsg);
+ if (ret != SQLITE_OK) {
+ LOGGER(ERROR) << "Error to create appdb : " << (errmsg ? errmsg : "");
+ if (errmsg)
+ sqlite3_free(errmsg);
+ }
+}
+
+bool SqliteDB::HasKey(const std::string& section,
+ const std::string& key) const {
+ char *buffer = NULL;
+ sqlite3_stmt *stmt = NULL;
+ bool result = false;
+
+ int ret = 0;
+ buffer = sqlite3_mprintf(
+ "select count(*) from appdb where section = %Q and key = %Q",
+ section.c_str(),
+ key.c_str());
+ if (buffer == NULL) {
+ LOGGER(ERROR) << "error to make query";
+ return false;
+ }
+
+ std::unique_ptr<char, decltype(sqlite3_free)*>
+ scoped_data {buffer, sqlite3_free};
+
+ ret = sqlite3_prepare(sqldb_, buffer, strlen(buffer), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGGER(ERROR) << "Fail to prepare query : " << sqlite3_errmsg(sqldb_);
+ return false;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ROW) {
+ int value = sqlite3_column_int(stmt, 0);
+ result = value > 0;
+ }
+
+ sqlite3_finalize(stmt);
+ return result;
+}
+
+std::string SqliteDB::Get(const std::string& section,
+ const std::string& key) const {
+ char *buffer = NULL;
+ sqlite3_stmt *stmt = NULL;
+ std::string result;
+
+ int ret = 0;
+ buffer = sqlite3_mprintf(
+ "select value from appdb where section = %Q and key = %Q",
+ section.c_str(),
+ key.c_str());
+ if (buffer == NULL) {
+ LOGGER(ERROR) << "error to make query";
+ return result;
+ }
+
+ std::unique_ptr<char, decltype(sqlite3_free)*>
+ scoped_data {buffer, sqlite3_free};
+
+ ret = sqlite3_prepare(sqldb_, buffer, strlen(buffer), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGGER(ERROR) << "Fail to prepare query : " << sqlite3_errmsg(sqldb_);
+ return result;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ROW) {
+ result = std::string(
+ reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
+ }
+
+ sqlite3_finalize(stmt);
+ return result;
+}
+
+void SqliteDB::Set(const std::string& section,
+ const std::string& key,
+ const std::string& value) {
+ char *buffer = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ int ret = 0;
+ buffer = sqlite3_mprintf(
+ "replace into appdb (section, key, value) values (?, ?, ?);");
+ if (buffer == NULL) {
+ LOGGER(ERROR) << "error to make query";
+ return;
+ }
+
+ std::unique_ptr<char, decltype(sqlite3_free)*>
+ scoped_data {buffer, sqlite3_free};
+
+ ret = sqlite3_prepare(sqldb_, buffer, strlen(buffer), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGGER(ERROR) << "Fail to prepare query : " << sqlite3_errmsg(sqldb_);
+ return;
+ }
+
+ std::unique_ptr<sqlite3_stmt, decltype(sqlite3_finalize)*>
+ scoped_stmt {stmt, sqlite3_finalize};
+
+ ret = sqlite3_bind_text(stmt,
+ 1,
+ section.c_str(),
+ section.length(),
+ SQLITE_STATIC);
+ if (ret != SQLITE_OK) {
+ LOGGER(ERROR) << "Fail to prepare query bind argument : "
+ << sqlite3_errmsg(sqldb_);
+ return;
+ }
+ ret = sqlite3_bind_text(stmt,
+ 2,
+ key.c_str(),
+ key.length(),
+ SQLITE_STATIC);
+ if (ret != SQLITE_OK) {
+ LOGGER(ERROR) << "Fail to prepare query bind argument : "
+ << sqlite3_errmsg(sqldb_);
+ return;
+ }
+ ret = sqlite3_bind_text(stmt,
+ 3,
+ value.c_str(),
+ value.length(),
+ SQLITE_STATIC);
+ if (ret != SQLITE_OK) {
+ LOGGER(ERROR) << "Fail to prepare query bind argument : "
+ << sqlite3_errmsg(sqldb_);
+ return;
+ }
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_DONE) {
+ LOGGER(ERROR) << "Fail to insert data : " << sqlite3_errmsg(sqldb_);
+ }
+}
+
+void SqliteDB::Remove(const std::string& section,
+ const std::string& key) {
+ char *buffer = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ buffer = sqlite3_mprintf(
+ "delete from appdb where section = %Q and key = %Q",
+ section.c_str(),
+ key.c_str());
+
+ if (buffer == NULL) {
+ LOGGER(ERROR) << "error to make query";
+ return;
+ }
+
+ std::unique_ptr<char, decltype(sqlite3_free)*>
+ scoped_data {buffer, sqlite3_free};
+
+ char *errmsg = NULL;
+ int ret = sqlite3_exec(sqldb_, buffer, NULL, NULL, &errmsg);
+ if (ret != SQLITE_OK) {
+ LOGGER(ERROR) << "Error to delete value : " << (errmsg ? errmsg : "");
+ if (errmsg)
+ sqlite3_free(errmsg);
+ }
+}
+
+void SqliteDB::GetKeys(const std::string& section,
+ std::list<std::string>* keys) const {
+ char *buffer = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ int ret = 0;
+ buffer = sqlite3_mprintf(
+ "select key from appdb where section = %Q",
+ section.c_str());
+ if (buffer == NULL) {
+ LOGGER(ERROR) << "error to make query";
+ return;
+ }
+
+ std::unique_ptr<char, decltype(sqlite3_free)*>
+ scoped_data {buffer, sqlite3_free};
+
+ ret = sqlite3_prepare(sqldb_, buffer, strlen(buffer), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGGER(ERROR) << "Fail to prepare query : " << sqlite3_errmsg(sqldb_);
+ return;
+ }
+
+ ret = sqlite3_step(stmt);
+ while (ret == SQLITE_ROW) {
+ const char* value =
+ reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
+ keys->push_back(std::string(value));
+ ret = sqlite3_step(stmt);
+ }
+
+ sqlite3_finalize(stmt);
+ return;
+}
+
+#endif // end of else
AppDB* AppDB::GetInstance() {
+#ifdef USE_APP_PREFERENCE
static PreferenceAppDB instance;
+#else
+ static SqliteDB instance;
+#endif
return &instance;
}
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "common/app_db.h"\r
+\r
+#include <string>\r
+#include <list>\r
+\r
+class sqlite3;\r
+\r
+namespace wrt {\r
+class SqliteDB : public AppDB {\r
+ public:\r
+ explicit SqliteDB(const std::string& app_data_path = std::string());\r
+ ~SqliteDB();\r
+ virtual bool HasKey(const std::string& section,\r
+ const std::string& key) const;\r
+ virtual std::string Get(const std::string& section,\r
+ const std::string& key) const;\r
+ virtual void Set(const std::string& section,\r
+ const std::string& key,\r
+ const std::string& value);\r
+ virtual void GetKeys(const std::string& section,\r
+ std::list<std::string>* keys) const;\r
+ virtual void Remove(const std::string& section,\r
+ const std::string& key);\r
+\r
+ private:\r
+ void Initialize();\r
+ std::string app_data_path_;\r
+ sqlite3* sqldb_;\r
+};\r
+\r
+} // namespace wrt\r
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <limits.h>\r
+\r
+#include <string>\r
+#include <iostream>\r
+\r
+#include "common/app_db_sqlite.h"\r
+#include "gtest/gtest.h"\r
+\r
+namespace wrt {\r
+\r
+namespace {\r
+ const char* kLongValue =\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897";\r
+ const char* kLongKey =\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897"\r
+ "01234567891123456789212345678931234567894123456789512345678961234567897";\r
+} // namespace\r
+\r
+// Tests AppDB class\r
+\r
+TEST(AppDBSqliteTest, Positive) {\r
+ SqliteDB db("/tmp/");\r
+ db.Set("test", "key1", "value1");\r
+ EXPECT_EQ(true, db.HasKey("test", "key1"));\r
+ db.Remove("test", "key1");\r
+ EXPECT_EQ(false, db.HasKey("test", "key1"));\r
+\r
+ db.Set("test", "key1", "value1");\r
+ EXPECT_EQ(std::string("value1"), db.Get("test", "key1"));\r
+\r
+ db.Set("test", "key1", "value1-1");\r
+ EXPECT_EQ(std::string("value1-1"), db.Get("test", "key1"));\r
+\r
+ db.Set("test", "longvalue", kLongValue);\r
+ EXPECT_EQ(std::string(kLongValue), db.Get("test", "longvalue"));\r
+\r
+ db.Set("test", kLongKey, "longkey");\r
+ EXPECT_EQ("longkey", db.Get("test", kLongKey));\r
+}\r
+\r
+} // namespace wrt\r