From 0a7cbcee315f5c24df8f4554352b4ff8d4ca098c Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 14 Mar 2017 20:44:26 +0900 Subject: [PATCH 01/16] Add a schema sample xml Change-Id: Ie233bd104e6538d91857ba4468eaeff6c4e2c7ad Signed-off-by: Mu-Woong Lee --- schema/sample.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 schema/sample.xml diff --git a/schema/sample.xml b/schema/sample.xml new file mode 100644 index 0000000..6e67c38 --- /dev/null +++ b/schema/sample.xml @@ -0,0 +1,11 @@ + + + + http://tizen.org/privilege/location + http://tizen.org/privilege/internal/service + + + + + + -- 2.7.4 From a4402485c82fbe50366d4d096b2619b192a313d3 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 14 Mar 2017 20:47:08 +0900 Subject: [PATCH 02/16] Implement DatabaseManager in the server Change-Id: Ib88f7fd66583ce4632d52a003b169c9479d664b4 Signed-off-by: Mu-Woong Lee --- src/server/DatabaseManager.cpp | 111 +++++++++++++++++++++++++++++++++++++++++ src/server/DatabaseManager.h | 48 ++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 src/server/DatabaseManager.cpp create mode 100644 src/server/DatabaseManager.h diff --git a/src/server/DatabaseManager.cpp b/src/server/DatabaseManager.cpp new file mode 100644 index 0000000..bb5a3bb --- /dev/null +++ b/src/server/DatabaseManager.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "DatabaseManager.h" + +using namespace ctx; + +Database* DatabaseManager::__systemDatabase = NULL; +Database* DatabaseManager::__userDatabase = NULL; + +DatabaseManager::DatabaseManager() +{ +} + +bool DatabaseManager::openSystem() +{ + IF_FAIL_RETURN(!isSystemReady(), true); + + __systemDatabase = new(std::nothrow) PlatformDatabase(BASE_PATH); + IF_FAIL_RETURN_TAG(__systemDatabase, false, _E, "%s", CTX_ERROR_STR(E_NO_MEM)); + + if (!__systemDatabase->open()) { + _E("DB open failed"); + delete __systemDatabase; + __systemDatabase = NULL; + return false; + } + + _I("System DB opened"); + return true; +} + +bool DatabaseManager::openUser(uid_t uid) +{ + if (isUserReady()) { + _W("Closing the current DB"); + closeUser(); + } + + __userDatabase = new(std::nothrow) PlatformDatabase(BASE_PATH, uid); + IF_FAIL_RETURN_TAG(__userDatabase, false, _E, "%s", CTX_ERROR_STR(E_NO_MEM)); + + if (!__userDatabase->open()) { + _E("DB open failed"); + delete __userDatabase; + __userDatabase = NULL; + return false; + } + + _I("User DB opened"); + return true; +} + +void DatabaseManager::closeSystem() +{ + if (!__systemDatabase) + return; + + __systemDatabase->close(); + _I("System DB closed"); + + delete __systemDatabase; + __systemDatabase = NULL; + +} + +void DatabaseManager::closeUser() +{ + if (!__userDatabase) + return; + + __userDatabase->close(); + _I("User DB closed"); + + delete __userDatabase; + __userDatabase = NULL; +} + +bool DatabaseManager::isSystemReady() +{ + return (__systemDatabase != NULL); +} + +bool DatabaseManager::isUserReady() +{ + return (__userDatabase != NULL); +} + +Database& DatabaseManager::getSystem() +{ + return *__systemDatabase; +} + +Database& DatabaseManager::getUser() +{ + return *__userDatabase; +} diff --git a/src/server/DatabaseManager.h b/src/server/DatabaseManager.h new file mode 100644 index 0000000..b274443 --- /dev/null +++ b/src/server/DatabaseManager.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_STORE_DATABASE_MANAGER_H__ +#define __CONTEXT_STORE_DATABASE_MANAGER_H__ + +#include +#include + +namespace ctx { + + class DatabaseManager { + public: + static bool openSystem(); + static bool openUser(uid_t uid); + + static void closeSystem(); + static void closeUser(); + + static bool isSystemReady(); + static bool isUserReady(); + + static Database& getSystem(); + static Database& getUser(); + + private: + DatabaseManager(); + + static Database* __systemDatabase; + static Database* __userDatabase; + }; + +} + +#endif /* __CONTEXT_STORE_DATABASE_MANAGER_H__ */ -- 2.7.4 From 88dc1c784794d4854fae5a5b707beb15942e250d Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 14 Mar 2017 20:52:19 +0900 Subject: [PATCH 03/16] Implement SchemaLoader in the server Change-Id: I86e52eace38cdd0710e198712df1aa894bf68dd4 Signed-off-by: Mu-Woong Lee --- packaging/context-store.spec | 4 +- script/init.sql | 7 + src/server/SchemaLoader.cpp | 375 +++++++++++++++++++++++++++++++++++++++++++ src/server/SchemaLoader.h | 91 +++++++++++ 4 files changed, 476 insertions(+), 1 deletion(-) create mode 100644 script/init.sql create mode 100644 src/server/SchemaLoader.cpp create mode 100644 src/server/SchemaLoader.h diff --git a/packaging/context-store.spec b/packaging/context-store.spec index 573a430..5c4a488 100644 --- a/packaging/context-store.spec +++ b/packaging/context-store.spec @@ -61,7 +61,8 @@ make %{?_smp_mflags} %install %make_install - +mkdir -p %{buildroot}%{TZ_SYS_DATA}/%{name} +install -m 0644 script/init.sql %{buildroot}%{TZ_SYS_DATA}/%{name}/ %post /sbin/ldconfig @@ -89,6 +90,7 @@ popd %manifest packaging/%{name}.manifest %{_libdir}/lib%{name}-client-genuine.so* %{_libdir}/lib%{name}-server-genuine.so* +%{TZ_SYS_DATA}/%{name}/*.sql %files devel diff --git a/script/init.sql b/script/init.sql new file mode 100644 index 0000000..d0ec0c9 --- /dev/null +++ b/script/init.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS ContextStoreSchema ( + "uri" TEXT PRIMARY KEY, + "retention" INTEGER NOT NULL DEFAULT 0, + "limit" INTEGER NOT NULL DEFAULT 0, + "readPrivileges" TEXT NOT NULL, + "writePrivileges" TEXT NOT NULL +); diff --git a/src/server/SchemaLoader.cpp b/src/server/SchemaLoader.cpp new file mode 100644 index 0000000..6185762 --- /dev/null +++ b/src/server/SchemaLoader.cpp @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include "DatabaseManager.h" +#include "SchemaLoader.h" + +/* Schema XML example: + + + + + http://tizen.org/privilege/healthinfo + http://tizen.org/privilege/internal/service + + + + + + + */ + +#define URI_REGEX(CATEGORY) R"~(^http:\/\/[\w-]+(\.[\w-]+)*\/)~" CATEGORY R"~(\/[\w-]+(\.[\w-]+)*(\/[\w-]+(\.[\w-]+)*)*$)~" +#define COL_REGEX "^[A-Za-z]+\\w*$" + +#define CHK_NAME(NODE, NAME) (!xmlStrcmp(NODE->name, (const xmlChar*)(NAME))) + +using namespace ctx; + +static std::string __getXmlAttribute(xmlNode* node, const char* name) +{ + xmlChar* prop = xmlGetProp(node, reinterpret_cast(name)); + std::string out; + if (prop) { + out = reinterpret_cast(prop); + xmlFree(prop); + } + return out; +} + +static std::string __getXmlContent(xmlNode* node) +{ + xmlChar* content = xmlNodeGetContent(node); + _D("%s", content); + std::string out; + if (content) { + out = reinterpret_cast(content); + xmlFree(content); + } + return out; +} + +Schema::Schema() : + retention(0), + limit(0) +{ +} + +bool Schema::valid() +{ + if (retention > MAX_RETENTION || limit > MAX_LIMIT) + return false; + + if (retention == 0 && limit == 0) + return false; + + if (attributes.empty()) + return false; + + std::regex uriRegex(URI_REGEX("contextstore"), std::regex::optimize); + if (!std::regex_match(uri, uriRegex)) + return false; + + std::regex privilegeRegex(URI_REGEX("privilege"), std::regex::optimize); + for (auto& privil : readPrivileges) { + if (!std::regex_match(privil, privilegeRegex)) + return false; + } + + for (auto& privil : writePrivileges) { + if (!std::regex_match(privil, privilegeRegex)) + return false; + } + + std::regex columnNameRegex(COL_REGEX, std::regex::optimize); + for (auto& attr: attributes) { + if (!std::regex_match(attr.first, columnNameRegex)) + return false; + } + + return true; +} + +SchemaLoader::SchemaLoader() +{ +} + +SchemaLoader::~SchemaLoader() +{ +} + +bool SchemaLoader::load() +{ + bool result = true; + __getDatabase().beginTransaction(); + + if (!__createMetadataTables()) { + _E("Metadata table creation failed"); + result = false; + } + + try { + if (result && !__loadSchemaDir(__getSchemaDir())) { + _W("Schema loading failed"); + result = false; + } + } catch (std::regex_error& e) { + _E("%s", e.what()); + result = false; + } + + __getDatabase().endTransaction(); + return result; +} + +bool SchemaLoader::__createMetadataTables() +{ + std::string path = PathUtil::getSystemPath(TZ_SYS_DATA, BASE_PATH "/init.sql"); + IF_FAIL_RETURN(!path.empty(), false); + + std::ifstream inFile(path); + std::stringstream buffer; + buffer << inFile.rdbuf(); + + return __getDatabase().execute(buffer.str(), NULL); +} + +bool SchemaLoader::__loadSchemaDir(const std::string& dirPath) +{ + DIR* dir = NULL; + struct dirent entry; + struct dirent *result = NULL; + + dir = opendir(dirPath.c_str()); + IF_FAIL_RETURN_TAG(dir, false, _E, "Failed to open: %s", dirPath.c_str()); + + std::regex xmlFileRegex("^.*\\.(xml|XML)$", std::regex::optimize); + + while (true) { + if (readdir_r(dir, &entry, &result) != 0) + continue; + + if (result == NULL) + break; + + std::string filename = entry.d_name; + + if (!std::regex_match(filename, xmlFileRegex)) + continue; + + __parseSchemaFile(dirPath + "/" + filename); + } + + closedir(dir); + return true; +} + +void SchemaLoader::__parseSchemaFile(const std::string& filePath) +{ + _D("Parsing %s", filePath.c_str()); + + xmlDoc *doc = xmlReadFile(filePath.c_str(), NULL, 0); + IF_FAIL_VOID_TAG(doc, _W, "Could not parse %s", filePath.c_str()); + + xmlNode *node = xmlDocGetRootElement(doc); + + if (!node || !CHK_NAME(node, "ContextStore")) { + _W("Not a ContextStore schema XML"); + xmlFreeDoc(doc); + return; + } + + for (node = node->children; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE) + continue; + + if (!CHK_NAME(node, "Schema")) { + _D("Skip '%s'", node->name); + continue; + } + + Schema schema; + if (__parseSchema(node, schema)) { + __insertMetadata(schema); + __createStoreTable(schema); + } + } + + xmlFreeDoc(doc); + return; +} + +bool SchemaLoader::__parseSchema(xmlNode* node, Schema& schema) +{ + std::string retention = __getXmlAttribute(node, "retention"); + std::string limit = __getXmlAttribute(node, "limit"); + schema.uri = __getXmlAttribute(node, "uri"); + + for (node = node->children; node != NULL; node = node->next) { + if (node->type != XML_ELEMENT_NODE) + continue; + + if (CHK_NAME(node, "Privilege")) + __parsePrivilege(node, schema); + else if (CHK_NAME(node, "Attribute")) + __parseAttribute(node, schema); + } + + if (!retention.empty()) + schema.retention = std::atoi(retention.c_str()); + + if (!limit.empty()) + schema.limit = std::atoi(limit.c_str()); + + return schema.valid(); +} + +void SchemaLoader::__parsePrivilege(xmlNode* node, Schema& schema) +{ + std::string access = __getXmlAttribute(node, "access"); + std::string privil = __getXmlContent(node); + + if (access == "Read") + schema.readPrivileges.push_back(privil); + else if (access == "Write") + schema.writePrivileges.push_back(privil); +} + +void SchemaLoader::__parseAttribute(xmlNode* node, Schema& schema) +{ + std::string name = __getXmlAttribute(node, "name"); + std::string type = __getXmlAttribute(node, "type"); + + IF_FAIL_VOID(!name.empty()); + + if (type == "Integer") + schema.attributes.push_back(std::make_pair(name, Schema::AttributeType::INTEGER)); + else if (type == "Real") + schema.attributes.push_back(std::make_pair(name, Schema::AttributeType::REAL)); + else if (type == "Text") + schema.attributes.push_back(std::make_pair(name, Schema::AttributeType::TEXT)); +} + +void SchemaLoader::__insertMetadata(Schema& schema) +{ + char* updateSql = NULL; + char* insertSql = NULL; + int length = 0; + + std::string readPrivil; + std::string writePrivil; + + for (auto& item : schema.readPrivileges) { + readPrivil.append(item); + readPrivil.append(PRIVILEGE_DELIM); + } + + for (auto& item : schema.writePrivileges) { + writePrivil.append(item); + writePrivil.append(PRIVILEGE_DELIM); + } + + length = asprintf(&updateSql, + "UPDATE ContextStoreSchema" + " SET uri='%s', retention=%u, \"limit\"=%u, readPrivileges='%s', writePrivileges='%s'" + " WHERE uri='%s'", + schema.uri.c_str(), schema.retention, schema.limit, readPrivil.c_str(), writePrivil.c_str(), + schema.uri.c_str()); + if (length <= 0) { + _E("Memory allocation failed"); + return; + } + + length = asprintf(&insertSql, + "INSERT OR IGNORE INTO ContextStoreSchema" + " (uri, retention, \"limit\", readPrivileges, writePrivileges)" + " VALUES ('%s', %u, %u, '%s', '%s')", + schema.uri.c_str(), schema.retention, schema.limit, readPrivil.c_str(), writePrivil.c_str()); + if (length <= 0) { + g_free(updateSql); + _E("Memory allocation failed"); + return; + } + + __getDatabase().execute(updateSql, NULL); + __getDatabase().execute(insertSql, NULL); + + g_free(updateSql); + g_free(insertSql); +} + +void SchemaLoader::__createStoreTable(Schema& schema) +{ + std::string attr = + COL_TIMESTAMP " DATETIME DEFAULT CURRENT_TIMESTAMP," + COL_OWNER_ID " TEXT NOT NULL DEFAULT ''"; + + for (auto& item : schema.attributes) { + attr = attr + "," + item.first; + switch (item.second) { + case Schema::AttributeType::INTEGER: + attr = attr + " INTEGER NOT NULL DEFAULT 0"; + break; + case Schema::AttributeType::REAL: + attr = attr + " REAL NOT NULL DEFAULT 0"; + break; + default: + attr = attr + " TEXT NOT NULL DEFAULT ''"; + break; + } + } + + std::string query = + "CREATE TABLE IF NOT EXISTS [" + schema.uri + "] (" + attr + ")"; + + __getDatabase().execute(query.c_str(), NULL); +} + + +SystemSchemaLoader::SystemSchemaLoader() +{ +} + +Database& SystemSchemaLoader::__getDatabase() +{ + return DatabaseManager::getSystem(); +} + +std::string SystemSchemaLoader::__getSchemaDir() +{ + return PathUtil::getSystemPath(TZ_SYS_DATA, BASE_PATH "/system"); +} + + +UserSchemaLoader::UserSchemaLoader() +{ +} + +Database& UserSchemaLoader::__getDatabase() +{ + return DatabaseManager::getUser(); +} + +std::string UserSchemaLoader::__getSchemaDir() +{ + return PathUtil::getSystemPath(TZ_SYS_DATA, BASE_PATH "/user"); +} diff --git a/src/server/SchemaLoader.h b/src/server/SchemaLoader.h new file mode 100644 index 0000000..4b08934 --- /dev/null +++ b/src/server/SchemaLoader.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_STORE_SCHEMA_LOADER_H__ +#define __CONTEXT_STORE_SCHEMA_LOADER_H__ + +#include +#include +#include +#include +#include +#include + +namespace ctx { + + class Schema { + public: + enum class AttributeType { + UNDEFINED = 0, + INTEGER = 1, + REAL = 2, + TEXT = 3 + }; + + Schema(); + bool valid(); + + std::string uri; + unsigned int retention; + unsigned int limit; + std::vector readPrivileges; + std::vector writePrivileges; + std::vector> attributes; + }; + + class SchemaLoader { + public: + virtual ~SchemaLoader(); + + bool load(); + + private: + bool __createMetadataTables(); + bool __loadSchemaDir(const std::string& dirPath); + void __parseSchemaFile(const std::string& filePath); + bool __parseSchema(xmlNode* node, Schema& schema); + void __parsePrivilege(xmlNode* node, Schema& schema); + void __parseAttribute(xmlNode* node, Schema& schema); + void __insertMetadata(Schema& schema); + void __createStoreTable(Schema& schema); + + virtual std::string __getSchemaDir() = 0; + virtual Database& __getDatabase() = 0; + + protected: + SchemaLoader(); + }; + + class SystemSchemaLoader : public SchemaLoader { + public: + SystemSchemaLoader(); + + private: + std::string __getSchemaDir(); + Database& __getDatabase(); + }; + + class UserSchemaLoader : public SchemaLoader { + public: + UserSchemaLoader(); + + private: + std::string __getSchemaDir(); + Database& __getDatabase(); + }; +} + +#endif /* __CONTEXT_STORE_SCHEMA_LOADER_H__ */ -- 2.7.4 From 48d1ecc062c7f6c413a0f2abbed0465f3e6d0cad Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 14 Mar 2017 20:55:52 +0900 Subject: [PATCH 04/16] Implement StoreManager & store handle classes in the server Change-Id: Idcb901e3d7fa4b6bfdb753d428b7ad06c0668c9f Signed-off-by: Mu-Woong Lee --- src/server/Store.cpp | 97 ++++++++++++++++++++++++++++ src/server/Store.h | 74 +++++++++++++++++++++ src/server/StoreManager.cpp | 152 ++++++++++++++++++++++++++++++++++++++++++++ src/server/StoreManager.h | 51 +++++++++++++++ src/server/SystemStore.cpp | 53 +++++++++++++++ src/server/SystemStore.h | 40 ++++++++++++ src/server/UserStore.cpp | 56 ++++++++++++++++ src/server/UserStore.h | 40 ++++++++++++ 8 files changed, 563 insertions(+) create mode 100644 src/server/Store.cpp create mode 100644 src/server/Store.h create mode 100644 src/server/StoreManager.cpp create mode 100644 src/server/StoreManager.h create mode 100644 src/server/SystemStore.cpp create mode 100644 src/server/SystemStore.h create mode 100644 src/server/UserStore.cpp create mode 100644 src/server/UserStore.h diff --git a/src/server/Store.cpp b/src/server/Store.cpp new file mode 100644 index 0000000..1bd089b --- /dev/null +++ b/src/server/Store.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Store.h" + +using namespace ctx; + +Store::Metadata::Metadata() : + retention(0), + limit(0) +{ +} + +Store::Store() +{ +} + +Store::~Store() +{ +} + +bool Store::permitted(ContextStoreClient& client) +{ + return __readable(client) || __writable(client); +} + +const std::string& Store::getPath() +{ + return metadata.path; +} + +int Store::insert(ContextStoreClient& client, const std::string& columns, std::vector& tuples) +{ + //TODO: handling owner's ID + //TODO: delete expired data + if (!__writable(client)) + return E_ACCESS; + + _D("Inserting %u tuples of (%s) to %s", tuples.size(), columns.c_str(), metadata.uri.c_str()); + + int error = __getDatabase().insert(metadata.uri, columns, tuples) ? E_NONE : E_PARAM; + return error; +} + +int Store::retrieve(ContextStoreClient& client, + const std::string& projection, const std::string& selection, + const std::string& sortOrder, unsigned int limit, std::vector* tuples) +{ + if (!__readable(client)) + return E_ACCESS; + + _D("Retrieving (%s) from %s", projection.c_str(), metadata.uri.c_str()); + + std::string query = "SELECT " + projection + " FROM [" + metadata.uri + "]"; + if (!selection.empty()) + query = query + " WHERE " + selection; + if (!sortOrder.empty()) + query = query + " ORDER BY " + sortOrder; + if (limit > 0) + query = query + " LIMIT " + std::to_string(limit); + + if (!__getDatabase().execute(query, tuples)) + return E_PARAM; + + return E_NONE; +} + +int Store::remove(ContextStoreClient& client, const std::string selection) +{ + //TODO: handling owner's ID + if (!__writable(client)) + return E_ACCESS; + + _D("Removing from %s", metadata.uri.c_str()); + + std::string query = "DELETE FROM [" + metadata.uri + "]"; + if (!selection.empty()) + query = query + " WHERE " + selection; + + if (!__getDatabase().execute(query, NULL)) + return E_PARAM; + + return E_NONE; +} diff --git a/src/server/Store.h b/src/server/Store.h new file mode 100644 index 0000000..c51778a --- /dev/null +++ b/src/server/Store.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_STORE_STORE_H__ +#define __CONTEXT_STORE_STORE_H__ + +#include +#include +#include +#include +#include + +namespace ctx { + + class ContextStoreClient; + + class Store { + public: + class Metadata { + public: + Metadata(); + + std::string path; + std::string uri; + unsigned int retention; + unsigned int limit; + std::vector readPrivileges; + std::vector writePrivileges; + }; + + virtual ~Store(); + + bool permitted(ContextStoreClient& client); + + const std::string& getPath(); + + int insert(ContextStoreClient& client, const std::string& columns, std::vector& tuples); + + int retrieve(ContextStoreClient& client, + const std::string& projection, const std::string& selection, + const std::string& sortOrder, unsigned int limit, + std::vector* tuples); + + int remove(ContextStoreClient& client, const std::string selection); + + protected: + Store(); + + Metadata metadata; + + private: + virtual bool __readable(ContextStoreClient& client) = 0; + virtual bool __writable(ContextStoreClient& client) = 0; + virtual Database& __getDatabase() = 0; + + friend class StoreManager; + }; + +} + +#endif /* __CONTEXT_STORE_STORE_H__ */ diff --git a/src/server/StoreManager.cpp b/src/server/StoreManager.cpp new file mode 100644 index 0000000..9c36f95 --- /dev/null +++ b/src/server/StoreManager.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DatabaseManager.h" +#include "UserStore.h" +#include "SystemStore.h" +#include "StoreManager.h" + +#define CACHE_SIZE 3 + +using namespace ctx; + +StoreManager::StoreManager() +{ +} + +StoreManager::~StoreManager() +{ +} + +Store* StoreManager::__findStore(std::list& stores, const std::string& uri) +{ + for (auto& store : stores) { + if (store->metadata.uri != uri) + continue; + + _D("Cache hit!"); + return store; + } + + return NULL; +} + +std::vector __tokenize(std::string& in, const char* delim) +{ + std::vector tokens; + std::size_t begin = 0; + std::size_t end = in.find(delim, 0); + + while (end != std::string::npos) { + tokens.push_back(in.substr(begin, end - begin)); + begin = end + 1; + end = in.find(delim, begin); + } + + return tokens; +} + +template +Store* StoreManager::__createStore(Database& database, std::list& stores, const std::string& uri) +{ + std::string query = + "SELECT retention, \"limit\", readPrivileges, writePrivileges" + " FROM ContextStoreSchema" + " WHERE uri='" + uri + "'"; + + std::vector tuples; + if (!database.execute(query, COL_INT64 COL_INT64 COL_STRING COL_STRING, NULL, &tuples)) { + _E("DB search failed"); + return NULL; + } + if (tuples.empty()) { + _W("Not found"); + return NULL; + } + + int64_t retention = 0; + int64_t limit = 0; + std::string readPrivil; + std::string writePrivil; + + tuples[0]->getAt(0, &retention); + tuples[0]->getAt(1, &limit); + tuples[0]->getAt(2, &readPrivil); + tuples[0]->getAt(3, &writePrivil); + + delete tuples[0]; + + _D("URI: %s, Retention: %u, Limit: %u", uri.c_str(), static_cast(retention), static_cast(limit)); + _D("Read: %s", readPrivil.c_str()); + _D("Write: %s", writePrivil.c_str()); + + StoreType* store = new(std::nothrow) StoreType(); + IF_FAIL_RETURN_TAG(store, NULL, _E, "Memory allocation failed"); + + store->metadata.uri = uri; + store->metadata.retention= static_cast(retention); + store->metadata.limit = static_cast(limit); + store->metadata.readPrivileges = __tokenize(readPrivil, PRIVILEGE_DELIM); + store->metadata.writePrivileges = __tokenize(writePrivil, PRIVILEGE_DELIM); + + stores.push_front(store); + if (stores.size() > CACHE_SIZE) { + delete stores.back(); + stores.pop_back(); + } + + return store; +} + +void StoreManager::flushUserCache() +{ + for (auto& store : __userStores) { + delete store; + } + __userStores.clear(); +} + +void StoreManager::flushSystemCache() +{ + for (auto& store : __systemStores) { + delete store; + } + __systemStores.clear(); +} + +Store* StoreManager::getUserStore(const std::string& uri) +{ + _D("Checking the user DB"); + Store* store = __findStore(__userStores, uri); + if (store) + return store; + + store = __createStore(DatabaseManager::getUser(), __userStores, uri); + if (store) + return store; + + return getSystemStore(uri); +} + +Store* StoreManager::getSystemStore(const std::string& uri) +{ + _D("Checking the system DB"); + Store* store = __findStore(__systemStores, uri); + if (store) + return store; + + return __createStore(DatabaseManager::getSystem(), __systemStores, uri); +} diff --git a/src/server/StoreManager.h b/src/server/StoreManager.h new file mode 100644 index 0000000..f8d8e63 --- /dev/null +++ b/src/server/StoreManager.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_STORE_STORE_MANAGER_H__ +#define __CONTEXT_STORE_STORE_MANAGER_H__ + +#include +#include + +namespace ctx { + + class Store; + class Database; + + class StoreManager { + public: + StoreManager(); + ~StoreManager(); + + Store* getUserStore(const std::string& uri); + Store* getSystemStore(const std::string& uri); + + void flushUserCache(); + void flushSystemCache(); + + private: + Store* __findStore(std::list& stores, const std::string& uri); + + template + Store* __createStore(Database& database, std::list& stores, const std::string& uri); + + std::list __userStores; + std::list __systemStores; + }; + +} + +#endif /* __CONTEXT_STORE_STORE_MANAGER_H__ */ diff --git a/src/server/SystemStore.cpp b/src/server/SystemStore.cpp new file mode 100644 index 0000000..9bf5fb7 --- /dev/null +++ b/src/server/SystemStore.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ContextStoreClient.h" +#include "DatabaseManager.h" +#include "SystemStore.h" + +using namespace ctx; + +SystemStore::SystemStore() +{ +} + +SystemStore::~SystemStore() +{ +} + +bool SystemStore::__readable(ContextStoreClient& client) +{ + if (!client.hasPrivileges(metadata.readPrivileges)) + return false; + + return true; +} + +bool SystemStore::__writable(ContextStoreClient& client) +{ + if (!client.isSystem()) + return false; + + if (!client.hasPrivileges(metadata.writePrivileges)) + return false; + + return true; +} + +Database& SystemStore::__getDatabase() +{ + return DatabaseManager::getSystem(); +} diff --git a/src/server/SystemStore.h b/src/server/SystemStore.h new file mode 100644 index 0000000..12b6865 --- /dev/null +++ b/src/server/SystemStore.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_STORE_SYSTEM_STORE_H__ +#define __CONTEXT_STORE_SYSTEM_STORE_H__ + +#include "Store.h" + +namespace ctx { + + class SystemStore : public Store { + public: + ~SystemStore(); + + private: + SystemStore(); + + bool __readable(ContextStoreClient& client); + bool __writable(ContextStoreClient& client); + Database& __getDatabase(); + + friend class StoreManager; + }; + +} + +#endif /* __CONTEXT_STORE_SYSTEM_STORE_H__ */ diff --git a/src/server/UserStore.cpp b/src/server/UserStore.cpp new file mode 100644 index 0000000..e636190 --- /dev/null +++ b/src/server/UserStore.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ContextStoreClient.h" +#include "DatabaseManager.h" +#include "UserStore.h" + +using namespace ctx; + +UserStore::UserStore() +{ +} + +UserStore::~UserStore() +{ +} + +bool UserStore::__readable(ContextStoreClient& client) +{ + if (client.isSystem()) + return false; + + if (!client.hasPrivileges(metadata.readPrivileges)) + return false; + + return true; +} + +bool UserStore::__writable(ContextStoreClient& client) +{ + if (client.isSystem()) + return false; + + if (!client.hasPrivileges(metadata.writePrivileges)) + return false; + + return true; +} + +Database& UserStore::__getDatabase() +{ + return DatabaseManager::getUser(); +} diff --git a/src/server/UserStore.h b/src/server/UserStore.h new file mode 100644 index 0000000..0ff8896 --- /dev/null +++ b/src/server/UserStore.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_STORE_USER_STORE_H__ +#define __CONTEXT_STORE_USER_STORE_H__ + +#include "Store.h" + +namespace ctx { + + class UserStore : public Store { + public: + ~UserStore(); + + private: + UserStore(); + + bool __readable(ContextStoreClient& client); + bool __writable(ContextStoreClient& client); + Database& __getDatabase(); + + friend class StoreManager; + }; + +} + +#endif /* __CONTEXT_STORE_USER_STORE_H__ */ -- 2.7.4 From 0ba8ec22afcf314b87dcdc701ab37c147dfbed47 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 14 Mar 2017 20:58:23 +0900 Subject: [PATCH 05/16] Implement ContextStoreService & ContextStoreClient Change-Id: I6cfe0a430aa6abbebf5ef86ee3b1198990a67f1f Signed-off-by: Mu-Woong Lee --- include/ContextStoreService.h | 7 +++ src/server/ContextStoreClient.cpp | 126 ++++++++++++++++++++++++++++++++++++- src/server/ContextStoreClient.h | 14 +++++ src/server/ContextStoreService.cpp | 38 ++++++++++- 4 files changed, 181 insertions(+), 4 deletions(-) diff --git a/include/ContextStoreService.h b/include/ContextStoreService.h index ca384dc..828424e 100644 --- a/include/ContextStoreService.h +++ b/include/ContextStoreService.h @@ -24,6 +24,8 @@ namespace ctx { + class StoreManager; + class EXPORT_API ContextStoreService : public ServiceBase { public: ContextStoreService(GDBusConnection* conn); @@ -31,6 +33,8 @@ namespace ctx { bool isUserService(); + StoreManager& getStoreManager(); + protected: bool prepare(); void cleanup(); @@ -39,6 +43,9 @@ namespace ctx { void onUserActivated(); void onUserDeactivated(); + + private: + StoreManager* __storeManager; }; } diff --git a/src/server/ContextStoreClient.cpp b/src/server/ContextStoreClient.cpp index 6f64c7f..3d72f19 100644 --- a/src/server/ContextStoreClient.cpp +++ b/src/server/ContextStoreClient.cpp @@ -14,8 +14,11 @@ * limitations under the License. */ -#include +#include #include +#include "ContextStoreService.h" +#include "Store.h" +#include "StoreManager.h" #include "ContextStoreClient.h" using namespace ctx; @@ -31,10 +34,129 @@ ContextStoreClient::~ContextStoreClient() void ContextStoreClient::onMethodCalled(MethodCall* methodCall) { - // 'methodCall' should be deleted. + try { + __verifyUid(methodCall->getUid()); + std::string uri = __getStoreUri(methodCall->getParam()); + Store* store = __getStore(uri); + + if (methodCall->getMethodName() == METHOD_GET_ACCESS) { + __getAccess(*store, *methodCall); + } else if (methodCall->getMethodName() == METHOD_INSERT) { + __insert(*store, *methodCall); + } else if (methodCall->getMethodName() == METHOD_RETRIEVE) { + __retrieve(*store, *methodCall); + } else if (methodCall->getMethodName() == METHOD_REMOVE) { + __remove(*store, *methodCall); + } + } catch (int error) { + methodCall->reply(error); + } + delete methodCall; } void ContextStoreClient::onDisconnected() { } + +void ContextStoreClient::__verifyUid(uid_t uid) +{ + if (!isSystemUid(uid) && uid != ServiceBase::getActiveUser()) { + _E("Invalid Uid: %u != %u (ActiveUser)", uid, ServiceBase::getActiveUser()); + throw static_cast(E_ACCESS); + } +} + +std::string ContextStoreClient::__getStoreUri(GVariant* param) +{ + const char* uri = NULL; + g_variant_get_child(param, IDX_URI, "&s", &uri); + if (!uri) { + _E("Invalid URI"); + throw static_cast(E_PARAM); + } + return uri; +} + +StoreManager& ContextStoreClient::__getStoreManager() +{ + return static_cast(getHostService()).getStoreManager(); +} + +Store* ContextStoreClient::__getStore(const std::string& uri) +{ + Store* store = NULL; + + if (isSystem()) { + store = __getStoreManager().getSystemStore(uri); + } else { + store = __getStoreManager().getUserStore(uri); + } + + if (!store) { + _W("Getting store failed"); + throw static_cast(E_PARAM); + } + + return store; +} + +void ContextStoreClient::__getAccess(Store& store, MethodCall& methodCall) +{ + if (!store.permitted(*this)) + throw static_cast(E_ACCESS); + + methodCall.reply(g_variant_new("(s)", store.getPath().c_str())); +} + +void ContextStoreClient::__insert(Store& store, MethodCall& methodCall) +{ + const char* uri = NULL; + const char* cols = NULL; + GVariant* vals = NULL; + + g_variant_get(methodCall.getParam(), "(&s&sv)", &uri, &cols, &vals); + if (!cols || !vals) { + if (vals) g_variant_unref(vals); + throw static_cast(E_PARAM); + } + + std::vector tuples = Tuple::buildFrom(vals); + if (tuples.empty()) { + throw static_cast(E_PARAM); + } + + methodCall.reply(store.insert(*this, cols, tuples)); +} + +void ContextStoreClient::__retrieve(Store& store, MethodCall& methodCall) +{ + const char* uri = NULL; + const char* projection = NULL; + const char* selection = NULL; + const char* sortOrder = NULL; + uint32_t limit = 0; + + g_variant_get(methodCall.getParam(), "(&s&s&s&su)", &uri, &projection, &selection, &sortOrder, &limit); + if (!projection || !selection || !sortOrder) + throw static_cast(E_PARAM); + + std::vector tuples; + int error = store.retrieve(*this, projection, selection, sortOrder, limit, &tuples); + if (error != E_NONE) + throw error; + + methodCall.reply(g_variant_new("(v)", Tuple::toGVariant(tuples))); +} + +void ContextStoreClient::__remove(Store& store, MethodCall& methodCall) +{ + const char* uri = NULL; + const char* selection = NULL; + + g_variant_get(methodCall.getParam(), "(&s&s)", &uri, &selection); + if (!selection) + throw static_cast(E_PARAM); + + methodCall.reply(store.remove(*this, selection)); +} diff --git a/src/server/ContextStoreClient.h b/src/server/ContextStoreClient.h index 0f51a77..a106acd 100644 --- a/src/server/ContextStoreClient.h +++ b/src/server/ContextStoreClient.h @@ -21,6 +21,9 @@ namespace ctx { + class StoreManager; + class Store; + class ContextStoreClient : public ClientBase { public: ContextStoreClient(ServiceBase* hostService, const std::string& busName); @@ -28,6 +31,17 @@ namespace ctx { void onMethodCalled(MethodCall* methodCall); void onDisconnected(); + + private: + void __verifyUid(uid_t uid); + std::string __getStoreUri(GVariant* param); + StoreManager& __getStoreManager(); + Store* __getStore(const std::string& uri); + + void __getAccess(Store& store, MethodCall& methodCall); + void __insert(Store& store, MethodCall& methodCall); + void __retrieve(Store& store, MethodCall& methodCall); + void __remove(Store& store, MethodCall& methodCall); }; } diff --git a/src/server/ContextStoreService.cpp b/src/server/ContextStoreService.cpp index c8dce21..e4162e1 100644 --- a/src/server/ContextStoreService.cpp +++ b/src/server/ContextStoreService.cpp @@ -17,11 +17,15 @@ #include #include #include "ContextStoreClient.h" +#include "StoreManager.h" +#include "DatabaseManager.h" +#include "SchemaLoader.h" using namespace ctx; ContextStoreService::ContextStoreService(GDBusConnection* conn) : - ServiceBase(conn, CTX_CONTEXT_STORE, CTX_CONTEXT_STORE_SPEC) + ServiceBase(conn, CTX_CONTEXT_STORE, CTX_CONTEXT_STORE_SPEC), + __storeManager(NULL) { } @@ -36,12 +40,21 @@ bool ContextStoreService::isUserService() bool ContextStoreService::prepare() { - /* Service-specific initialization tasks */ + if (!DatabaseManager::openSystem()) + return false; + + SystemSchemaLoader schemaLoader; + schemaLoader.load(); return true; } void ContextStoreService::cleanup() { + delete __storeManager; + __storeManager = NULL; + + DatabaseManager::closeUser(); + DatabaseManager::closeSystem(); } ClientBase* ContextStoreService::createClient(const std::string& busName) @@ -51,8 +64,29 @@ ClientBase* ContextStoreService::createClient(const std::string& busName) void ContextStoreService::onUserActivated() { + if (!DatabaseManager::openUser(getActiveUser())) + return; + + UserSchemaLoader schemaLoader; + schemaLoader.load(); } void ContextStoreService::onUserDeactivated() { + DatabaseManager::closeUser(); +} + +StoreManager& ContextStoreService::getStoreManager() +{ + if (__storeManager) + return *__storeManager; + + __storeManager = new(std::nothrow) StoreManager(); + + while (__storeManager == NULL) { + _W("Memory allocation failed"); + __storeManager = new(std::nothrow) StoreManager(); + } + + return *__storeManager; } -- 2.7.4 From 9e7ad557894537aca6097c1c9840608b39a59187 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 14 Mar 2017 21:46:16 +0900 Subject: [PATCH 06/16] Rename a pamareter to be consistant through the APIs Change-Id: I5338edc46a0f2bbde50badb1cb2e1ab51a6a6f80 Signed-off-by: Mu-Woong Lee --- include/ContextStore.h | 2 +- src/client-dummy/ContextStore.cpp | 2 +- src/client/ContextStore.cpp | 2 +- src/client/PlatformManagedStore.cpp | 4 ++-- src/client/PlatformManagedStore.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/ContextStore.h b/include/ContextStore.h index 214c988..cf6c098 100644 --- a/include/ContextStore.h +++ b/include/ContextStore.h @@ -30,7 +30,7 @@ namespace ctx { virtual int insert(const std::string& columns, Tuple* record); virtual int insert(const std::string& columns, std::vector& records); - virtual int retrieve(const ContextStoreSearchQuery& query, std::vector& result); + virtual int retrieve(const ContextStoreSearchQuery& query, std::vector& records); virtual int remove(const std::string& selection); protected: diff --git a/src/client-dummy/ContextStore.cpp b/src/client-dummy/ContextStore.cpp index 3ac2af0..3f14d37 100644 --- a/src/client-dummy/ContextStore.cpp +++ b/src/client-dummy/ContextStore.cpp @@ -37,7 +37,7 @@ int ContextStore::insert(const std::string& columns, std::vector& record return E_SUPPORT; } -int ContextStore::retrieve(const ContextStoreSearchQuery& query, std::vector& result) +int ContextStore::retrieve(const ContextStoreSearchQuery& query, std::vector& records) { return E_SUPPORT; } diff --git a/src/client/ContextStore.cpp b/src/client/ContextStore.cpp index 3ac2af0..3f14d37 100644 --- a/src/client/ContextStore.cpp +++ b/src/client/ContextStore.cpp @@ -37,7 +37,7 @@ int ContextStore::insert(const std::string& columns, std::vector& record return E_SUPPORT; } -int ContextStore::retrieve(const ContextStoreSearchQuery& query, std::vector& result) +int ContextStore::retrieve(const ContextStoreSearchQuery& query, std::vector& records) { return E_SUPPORT; } diff --git a/src/client/PlatformManagedStore.cpp b/src/client/PlatformManagedStore.cpp index ed913af..57f41c4 100644 --- a/src/client/PlatformManagedStore.cpp +++ b/src/client/PlatformManagedStore.cpp @@ -59,7 +59,7 @@ int PlatformManagedStore::insert(const std::string& columns, std::vector return __proxy->call(METHOD_INSERT, param); } -int PlatformManagedStore::retrieve(const ContextStoreSearchQuery& query, std::vector& result) +int PlatformManagedStore::retrieve(const ContextStoreSearchQuery& query, std::vector& records) { IF_FAIL_RETURN(query.valid(), E_PARAM); @@ -74,7 +74,7 @@ int PlatformManagedStore::retrieve(const ContextStoreSearchQuery& query, std::ve GVariant* vals = NULL; g_variant_get(outParam, "(v)", &vals); - result = Tuple::buildFrom(vals); + records = Tuple::buildFrom(vals); return E_NONE; } diff --git a/src/client/PlatformManagedStore.h b/src/client/PlatformManagedStore.h index c5d0786..77c3d38 100644 --- a/src/client/PlatformManagedStore.h +++ b/src/client/PlatformManagedStore.h @@ -34,7 +34,7 @@ namespace ctx { int insert(const std::string& columns, Tuple* record); int insert(const std::string& columns, std::vector& records); - int retrieve(const ContextStoreSearchQuery& query, std::vector& result); + int retrieve(const ContextStoreSearchQuery& query, std::vector& records); int remove(const std::string& selection); private: -- 2.7.4 From c2cc395595a65655a09c5206b0823ac0c296cd36 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 16 Mar 2017 15:26:52 +0900 Subject: [PATCH 07/16] Rename the pkg config template file Change-Id: I91a9526adeb9baacfe9d5b1dfca89faca87cd59c Signed-off-by: Mu-Woong Lee --- context-store.pc.in => pkg-config.pc.in | 0 src/client-dummy/CMakeLists.txt | 2 +- src/server-dummy/CMakeLists.txt | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename context-store.pc.in => pkg-config.pc.in (100%) diff --git a/context-store.pc.in b/pkg-config.pc.in similarity index 100% rename from context-store.pc.in rename to pkg-config.pc.in diff --git a/src/client-dummy/CMakeLists.txt b/src/client-dummy/CMakeLists.txt index f247700..1e5e9f4 100644 --- a/src/client-dummy/CMakeLists.txt +++ b/src/client-dummy/CMakeLists.txt @@ -24,7 +24,7 @@ SET(PC_REQUIRED ${DEPS}) SET(PC_LDFLAGS -l${target}) CONFIGURE_FILE( - ${CMAKE_SOURCE_DIR}/${PROJECT_NAME}.pc.in + ${CMAKE_SOURCE_DIR}/pkg-config.pc.in ${CMAKE_SOURCE_DIR}/${target}.pc @ONLY ) diff --git a/src/server-dummy/CMakeLists.txt b/src/server-dummy/CMakeLists.txt index d5a3a4d..1f0fdc0 100644 --- a/src/server-dummy/CMakeLists.txt +++ b/src/server-dummy/CMakeLists.txt @@ -24,7 +24,7 @@ SET(PC_REQUIRED ${DEPS}) SET(PC_LDFLAGS -l${target}) CONFIGURE_FILE( - ${CMAKE_SOURCE_DIR}/${PROJECT_NAME}.pc.in + ${CMAKE_SOURCE_DIR}/pkg-config.pc.in ${CMAKE_SOURCE_DIR}/${target}.pc @ONLY ) -- 2.7.4 From dd771220622302d6c0e6d11387698b10b5c7203e Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 16 Mar 2017 17:46:06 +0900 Subject: [PATCH 08/16] Disable redundant virtual packages Change-Id: Id77460862b678d34797c0f6a4be54eecb6499dc4 Signed-off-by: Mu-Woong Lee --- packaging/context-store.spec | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packaging/context-store.spec b/packaging/context-store.spec index 5c4a488..7b27165 100644 --- a/packaging/context-store.spec +++ b/packaging/context-store.spec @@ -14,9 +14,6 @@ BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(context-common-server) BuildRequires: pkgconfig(context-common-client) -Provides: %{name}-profile_tv = %{version}-%{release} -Provides: %{name}-profile_ivi = %{version}-%{release} -Provides: %{name}-profile_common = %{version}-%{release} %description Tizen Context Store Service @@ -26,8 +23,11 @@ Tizen Context Store Service Summary: Genuine Context Store service server and client libraries Requires: %{name} = %{version}-%{release} Requires: context-service -Provides: %{name}-profile_mobile = %{version}-%{release} -Provides: %{name}-profile_wearable = %{version}-%{release} +#Provides: %{name}-profile_common = %{version}-%{release} +#Provides: %{name}-profile_mobile = %{version}-%{release} +#Provides: %{name}-profile_wearable = %{version}-%{release} +#Provides: %{name}-profile_tv = %{version}-%{release} +#Provides: %{name}-profile_ivi = %{version}-%{release} %global __provides_exclude ^.*-genuine\\.so.*$ %description genuine -- 2.7.4 From 8b46e8a9e34b243267c84750a30a19e184da1c7a Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 16 Mar 2017 20:04:32 +0900 Subject: [PATCH 09/16] Set the default limit parameter of selection queries Change-Id: I1965cb8970d1c12417cbf479b3e055656a794776 Signed-off-by: Mu-Woong Lee --- src/client/ContextStoreSearchQuery.cpp | 6 ++++-- src/shared/ContextStoreTypesPrivate.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/client/ContextStoreSearchQuery.cpp b/src/client/ContextStoreSearchQuery.cpp index e1161b6..cc606c8 100644 --- a/src/client/ContextStoreSearchQuery.cpp +++ b/src/client/ContextStoreSearchQuery.cpp @@ -20,7 +20,7 @@ using namespace ctx; ContextStoreSearchQuery::ContextStoreSearchQuery() : - __limit(0) + __limit(DEFAULT_QUERY_LIMIT) { } @@ -84,6 +84,8 @@ unsigned int ContextStoreSearchQuery::getLimit() const bool ContextStoreSearchQuery::valid() const { - // TODO + if (__projection.empty()) + return false; + return true; } diff --git a/src/shared/ContextStoreTypesPrivate.h b/src/shared/ContextStoreTypesPrivate.h index 786fec0..1d3a5b8 100644 --- a/src/shared/ContextStoreTypesPrivate.h +++ b/src/shared/ContextStoreTypesPrivate.h @@ -62,4 +62,6 @@ #define COL_TIMESTAMP "__timestamp" #define COL_OWNER_ID "__ownerId" +#define DEFAULT_QUERY_LIMIT 10 + #endif -- 2.7.4 From 73ab667ec0b2409421fe73f706b4b487acaa500d Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 16 Mar 2017 21:02:55 +0900 Subject: [PATCH 10/16] Code skeleton of the query validity checker Change-Id: I90c2607563dd19b5b2555abacbbe5f58b5a995fe Signed-off-by: Mu-Woong Lee --- src/server/ContextStoreClient.cpp | 30 ++++++++++++++++-- src/server/QueryChecker.cpp | 57 +++++++++++++++++++++++++++++++++++ src/server/QueryChecker.h | 40 ++++++++++++++++++++++++ src/server/SchemaLoader.cpp | 1 - src/shared/ContextStoreTypesPrivate.h | 2 ++ 5 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 src/server/QueryChecker.cpp create mode 100644 src/server/QueryChecker.h diff --git a/src/server/ContextStoreClient.cpp b/src/server/ContextStoreClient.cpp index 3d72f19..096f35e 100644 --- a/src/server/ContextStoreClient.cpp +++ b/src/server/ContextStoreClient.cpp @@ -19,10 +19,13 @@ #include "ContextStoreService.h" #include "Store.h" #include "StoreManager.h" +#include "QueryChecker.h" #include "ContextStoreClient.h" using namespace ctx; +static QueryChecker __queryChecker; + ContextStoreClient::ContextStoreClient(ServiceBase* hostService, const std::string& busName) : ClientBase(hostService, busName) { @@ -50,6 +53,9 @@ void ContextStoreClient::onMethodCalled(MethodCall* methodCall) } } catch (int error) { methodCall->reply(error); + } catch (std::exception& e) { + _E("Exception: %s", e.what()); + methodCall->reply(E_FAILED); } delete methodCall; @@ -71,10 +77,10 @@ std::string ContextStoreClient::__getStoreUri(GVariant* param) { const char* uri = NULL; g_variant_get_child(param, IDX_URI, "&s", &uri); - if (!uri) { - _E("Invalid URI"); + + if (!uri) throw static_cast(E_PARAM); - } + return uri; } @@ -87,6 +93,9 @@ Store* ContextStoreClient::__getStore(const std::string& uri) { Store* store = NULL; + if (!__queryChecker.validateUri(uri)) + throw static_cast(E_PARAM); + if (isSystem()) { store = __getStoreManager().getSystemStore(uri); } else { @@ -121,6 +130,9 @@ void ContextStoreClient::__insert(Store& store, MethodCall& methodCall) throw static_cast(E_PARAM); } + if (!__queryChecker.validateProjection(cols)) + throw static_cast(E_PARAM); + std::vector tuples = Tuple::buildFrom(vals); if (tuples.empty()) { throw static_cast(E_PARAM); @@ -141,6 +153,15 @@ void ContextStoreClient::__retrieve(Store& store, MethodCall& methodCall) if (!projection || !selection || !sortOrder) throw static_cast(E_PARAM); + if (!__queryChecker.validateProjection(projection)) + throw static_cast(E_PARAM); + + if (!__queryChecker.validateSelection(selection)) + throw static_cast(E_PARAM); + + if (!__queryChecker.validateSortOrder(sortOrder)) + throw static_cast(E_PARAM); + std::vector tuples; int error = store.retrieve(*this, projection, selection, sortOrder, limit, &tuples); if (error != E_NONE) @@ -158,5 +179,8 @@ void ContextStoreClient::__remove(Store& store, MethodCall& methodCall) if (!selection) throw static_cast(E_PARAM); + if (!__queryChecker.validateSelection(selection)) + throw static_cast(E_PARAM); + methodCall.reply(store.remove(*this, selection)); } diff --git a/src/server/QueryChecker.cpp b/src/server/QueryChecker.cpp new file mode 100644 index 0000000..20a8bed --- /dev/null +++ b/src/server/QueryChecker.cpp @@ -0,0 +1,57 @@ + +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "QueryChecker.h" + +using namespace ctx; + +QueryChecker::QueryChecker() +{ +} + +QueryChecker::~QueryChecker() +{ +} + +bool QueryChecker::validateUri(const std::string& uri) +{ + static std::regex uriRegex(URI_REGEX("contextstore"), std::regex::optimize); + if (!std::regex_match(uri, uriRegex)) { + _E("Invalid parameter"); + return false; + } + return true; +} + +bool QueryChecker::validateProjection(const std::string& projection) +{ + // TODO + return true; +} + +bool QueryChecker::validateSelection(const std::string& selection) +{ + // TODO + return true; +} + +bool QueryChecker::validateSortOrder(const std::string& sortOrder) +{ + // TODO + return true; +} diff --git a/src/server/QueryChecker.h b/src/server/QueryChecker.h new file mode 100644 index 0000000..eaaf932 --- /dev/null +++ b/src/server/QueryChecker.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_STORE_QUERY_CHECKER_H__ +#define __CONTEXT_STORE_QUERY_CHECKER_H__ + +#include + +namespace ctx { + + class QueryChecker { + public: + QueryChecker(); + ~QueryChecker(); + + bool validateUri(const std::string& uri); + + bool validateProjection(const std::string& projection); + + bool validateSelection(const std::string& selection); + + bool validateSortOrder(const std::string& sortOrder); + }; + +} + +#endif /* __CONTEXT_STORE_QUERY_CHECKER_H__ */ diff --git a/src/server/SchemaLoader.cpp b/src/server/SchemaLoader.cpp index 6185762..b1b01bd 100644 --- a/src/server/SchemaLoader.cpp +++ b/src/server/SchemaLoader.cpp @@ -38,7 +38,6 @@ */ -#define URI_REGEX(CATEGORY) R"~(^http:\/\/[\w-]+(\.[\w-]+)*\/)~" CATEGORY R"~(\/[\w-]+(\.[\w-]+)*(\/[\w-]+(\.[\w-]+)*)*$)~" #define COL_REGEX "^[A-Za-z]+\\w*$" #define CHK_NAME(NODE, NAME) (!xmlStrcmp(NODE->name, (const xmlChar*)(NAME))) diff --git a/src/shared/ContextStoreTypesPrivate.h b/src/shared/ContextStoreTypesPrivate.h index 1d3a5b8..7daa99f 100644 --- a/src/shared/ContextStoreTypesPrivate.h +++ b/src/shared/ContextStoreTypesPrivate.h @@ -64,4 +64,6 @@ #define DEFAULT_QUERY_LIMIT 10 +#define URI_REGEX(CATEGORY) R"~(^http:\/\/[\w-]+(\.[\w-]+)*\/)~" CATEGORY R"~(\/[\w-]+(\.[\w-]+)*(\/[\w-]+(\.[\w-]+)*)*$)~" + #endif -- 2.7.4 From cc3bf40f11898ba807b169a43daf73eb86ee0632 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Mon, 20 Mar 2017 00:01:06 +0900 Subject: [PATCH 11/16] Rearrange header directory structure w.r.t. context-common Change-Id: I561191d1ca2aeeae827c58837cd7213d62949693 Signed-off-by: Mu-Woong Lee --- CMakeLists.txt | 18 ++++++++++++------ packaging/context-store.spec | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d15b53..1905668 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,9 +3,10 @@ PROJECT(context-store) INCLUDE(GNUInstallDirs) SET(DEPS "glib-2.0 gio-2.0 dlog capi-base-common") -SET(INCDIR "context-service") +SET(INCDIR "${CMAKE_INSTALL_INCLUDEDIR}/context-service") INCLUDE_DIRECTORIES( + ${CMAKE_INSTALL_PREFIX}/${INCDIR}/private ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src/shared ) @@ -16,14 +17,19 @@ SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC -Wl,--as-needed -Wl, SET(VERSION ${FULLVER}) SET(PREFIX ${CMAKE_INSTALL_PREFIX}) -SET(PC_INCLUDE "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/${INCDIR}") -SET(PC_LIBDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") -SET(PC_CFLAGS -I\${includedir}/${INCDIR}) +SET(PC_INCLUDE "${CMAKE_INSTALL_PREFIX}/${INCDIR}") +SET(PC_LIBDIR "${CMAKE_INSTALL_LIBDIR}") INSTALL( + FILES ${CMAKE_SOURCE_DIR}/include/ContextStoreService.h + DESTINATION ${INCDIR}/private +) +INSTALL( DIRECTORY ${CMAKE_SOURCE_DIR}/include/ - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${INCDIR} - FILES_MATCHING PATTERN "*.h" + DESTINATION ${INCDIR} + FILES_MATCHING + PATTERN "*.h" + PATTERN "ContextStoreService.h" EXCLUDE ) ADD_SUBDIRECTORY(src/client-dummy) diff --git a/packaging/context-store.spec b/packaging/context-store.spec index 7b27165..bc513fe 100644 --- a/packaging/context-store.spec +++ b/packaging/context-store.spec @@ -95,4 +95,5 @@ popd %files devel %{_includedir}/context-service/*.h +%{_includedir}/context-service/*/*.h %{_libdir}/pkgconfig/*.pc -- 2.7.4 From 813f1aaf1f951d8e89ec02b224b6728b839aba36 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Sat, 18 Mar 2017 07:20:08 -0700 Subject: [PATCH 12/16] Separate SchemaChecker from Schema to reuse regex while parsing schema files Change-Id: I81735406af570af5902905f739c362fcf6ffdf28 Signed-off-by: Mu-Woong Lee --- src/server/Schema.cpp | 25 ++++++++++++++++ src/server/Schema.h | 48 ++++++++++++++++++++++++++++++ src/server/SchemaChecker.cpp | 61 ++++++++++++++++++++++++++++++++++++++ src/server/SchemaChecker.h | 41 ++++++++++++++++++++++++++ src/server/SchemaLoader.cpp | 70 ++++++++++++++++---------------------------- src/server/SchemaLoader.h | 25 ++++------------ 6 files changed, 205 insertions(+), 65 deletions(-) create mode 100644 src/server/Schema.cpp create mode 100644 src/server/Schema.h create mode 100644 src/server/SchemaChecker.cpp create mode 100644 src/server/SchemaChecker.h diff --git a/src/server/Schema.cpp b/src/server/Schema.cpp new file mode 100644 index 0000000..6e548e2 --- /dev/null +++ b/src/server/Schema.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Schema.h" + +using namespace ctx; + +Schema::Schema() : + retention(0), + limit(0) +{ +} diff --git a/src/server/Schema.h b/src/server/Schema.h new file mode 100644 index 0000000..ac74b04 --- /dev/null +++ b/src/server/Schema.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_STORE_SCHEMA_H__ +#define __CONTEXT_STORE_SCHEMA_H__ + +#include +#include +#include +#include + +namespace ctx { + + class Schema { + public: + enum class AttributeType { + UNDEFINED = 0, + INTEGER = 1, + REAL = 2, + TEXT = 3 + }; + + Schema(); + + std::string uri; + unsigned int retention; + unsigned int limit; + std::vector readPrivileges; + std::vector writePrivileges; + std::vector> attributes; + }; + +} + +#endif diff --git a/src/server/SchemaChecker.cpp b/src/server/SchemaChecker.cpp new file mode 100644 index 0000000..3a7a165 --- /dev/null +++ b/src/server/SchemaChecker.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Schema.h" +#include "SchemaChecker.h" + +#define COL_REGEX "^[A-Za-z]+\\w*$" + +using namespace ctx; + +SchemaChecker::SchemaChecker() : + __uriRegex(URI_REGEX("contextstore"), std::regex::optimize), + __privilegeRegex(URI_REGEX("privilege"), std::regex::optimize), + __columnNameRegex(COL_REGEX, std::regex::optimize) +{ +} + +bool SchemaChecker::validate(const Schema& schema) +{ + if (schema.retention > MAX_RETENTION || schema.limit > MAX_LIMIT) + return false; + + if (schema.retention == 0 && schema.limit == 0) + return false; + + if (schema.attributes.empty()) + return false; + + if (!std::regex_match(schema.uri, __uriRegex)) + return false; + + for (auto& privil : schema.readPrivileges) { + if (!std::regex_match(privil, __privilegeRegex)) + return false; + } + + for (auto& privil : schema.writePrivileges) { + if (!std::regex_match(privil, __privilegeRegex)) + return false; + } + + for (auto& attr: schema.attributes) { + if (!std::regex_match(attr.first, __columnNameRegex)) + return false; + } + + return true; +} diff --git a/src/server/SchemaChecker.h b/src/server/SchemaChecker.h new file mode 100644 index 0000000..c01ee03 --- /dev/null +++ b/src/server/SchemaChecker.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_STORE_SCHEMA_CHECKER_H__ +#define __CONTEXT_STORE_SCHEMA_CHECKER_H__ + +#include +#include + +namespace ctx { + + class Schema; + + class SchemaChecker { + public: + SchemaChecker(); + + bool validate(const Schema& schema); + + private: + std::regex __uriRegex; + std::regex __privilegeRegex; + std::regex __columnNameRegex; + }; + +} + +#endif diff --git a/src/server/SchemaLoader.cpp b/src/server/SchemaLoader.cpp index b1b01bd..4343456 100644 --- a/src/server/SchemaLoader.cpp +++ b/src/server/SchemaLoader.cpp @@ -15,12 +15,15 @@ */ #include +#include #include #include #include #include #include #include "DatabaseManager.h" +#include "Schema.h" +#include "SchemaChecker.h" #include "SchemaLoader.h" /* Schema XML example: @@ -38,8 +41,6 @@ */ -#define COL_REGEX "^[A-Za-z]+\\w*$" - #define CHK_NAME(NODE, NAME) (!xmlStrcmp(NODE->name, (const xmlChar*)(NAME))) using namespace ctx; @@ -67,53 +68,14 @@ static std::string __getXmlContent(xmlNode* node) return out; } -Schema::Schema() : - retention(0), - limit(0) -{ -} - -bool Schema::valid() -{ - if (retention > MAX_RETENTION || limit > MAX_LIMIT) - return false; - - if (retention == 0 && limit == 0) - return false; - - if (attributes.empty()) - return false; - - std::regex uriRegex(URI_REGEX("contextstore"), std::regex::optimize); - if (!std::regex_match(uri, uriRegex)) - return false; - - std::regex privilegeRegex(URI_REGEX("privilege"), std::regex::optimize); - for (auto& privil : readPrivileges) { - if (!std::regex_match(privil, privilegeRegex)) - return false; - } - - for (auto& privil : writePrivileges) { - if (!std::regex_match(privil, privilegeRegex)) - return false; - } - - std::regex columnNameRegex(COL_REGEX, std::regex::optimize); - for (auto& attr: attributes) { - if (!std::regex_match(attr.first, columnNameRegex)) - return false; - } - - return true; -} - -SchemaLoader::SchemaLoader() +SchemaLoader::SchemaLoader() : + __schemaChecker(NULL) { } SchemaLoader::~SchemaLoader() { + delete __schemaChecker; } bool SchemaLoader::load() @@ -239,7 +201,10 @@ bool SchemaLoader::__parseSchema(xmlNode* node, Schema& schema) if (!limit.empty()) schema.limit = std::atoi(limit.c_str()); - return schema.valid(); + SchemaChecker* checker = __getSchemaChecker(); + IF_FAIL_RETURN(checker, false); + + return checker->validate(schema); } void SchemaLoader::__parsePrivilege(xmlNode* node, Schema& schema) @@ -268,6 +233,21 @@ void SchemaLoader::__parseAttribute(xmlNode* node, Schema& schema) schema.attributes.push_back(std::make_pair(name, Schema::AttributeType::TEXT)); } +SchemaChecker* SchemaLoader::__getSchemaChecker() +{ + if (__schemaChecker) + return __schemaChecker; + + try { + __schemaChecker = new SchemaChecker; + } catch (std::exception& e) { + _E("Exception: %s", e.what()); + return NULL; + } + + return __schemaChecker; +} + void SchemaLoader::__insertMetadata(Schema& schema) { char* updateSql = NULL; diff --git a/src/server/SchemaLoader.h b/src/server/SchemaLoader.h index 4b08934..59fdac0 100644 --- a/src/server/SchemaLoader.h +++ b/src/server/SchemaLoader.h @@ -17,7 +17,6 @@ #ifndef __CONTEXT_STORE_SCHEMA_LOADER_H__ #define __CONTEXT_STORE_SCHEMA_LOADER_H__ -#include #include #include #include @@ -26,25 +25,8 @@ namespace ctx { - class Schema { - public: - enum class AttributeType { - UNDEFINED = 0, - INTEGER = 1, - REAL = 2, - TEXT = 3 - }; - - Schema(); - bool valid(); - - std::string uri; - unsigned int retention; - unsigned int limit; - std::vector readPrivileges; - std::vector writePrivileges; - std::vector> attributes; - }; + class Schema; + class SchemaChecker; class SchemaLoader { public: @@ -61,10 +43,13 @@ namespace ctx { void __parseAttribute(xmlNode* node, Schema& schema); void __insertMetadata(Schema& schema); void __createStoreTable(Schema& schema); + SchemaChecker* __getSchemaChecker(); virtual std::string __getSchemaDir() = 0; virtual Database& __getDatabase() = 0; + SchemaChecker* __schemaChecker; + protected: SchemaLoader(); }; -- 2.7.4 From 9b46bc66d52f1a0451010252f208b6f77f5bf0f3 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Thu, 23 Mar 2017 20:01:17 +0900 Subject: [PATCH 13/16] Rename the packages to clearly denote their roles Change-Id: I585585d93edd3fa4581febd72fbbbe5b0c79d1f1 Signed-off-by: Mu-Woong Lee --- packaging/context-store.spec | 67 ++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/packaging/context-store.spec b/packaging/context-store.spec index bc513fe..87f390d 100644 --- a/packaging/context-store.spec +++ b/packaging/context-store.spec @@ -1,5 +1,5 @@ Name: context-store -Summary: Tizen Context Store +Summary: Context store service server and client libraries Version: 0.0.1 Release: 1 Group: Service Framework/Context @@ -15,34 +15,33 @@ BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(context-common-server) BuildRequires: pkgconfig(context-common-client) +Requires: %{name}-dummy = %{version}-%{release} +Requires: context-service +%global __provides_exclude ^.*-genuine\\.so.*$ + %description -Tizen Context Store Service +This package provides fully functional libraries of the context store service, +which is a part of the Tizen Contextual service framework. +The libraries replace the dummy libraries installed by %{name}-dummy. -%package genuine -Summary: Genuine Context Store service server and client libraries -Requires: %{name} = %{version}-%{release} -Requires: context-service -#Provides: %{name}-profile_common = %{version}-%{release} -#Provides: %{name}-profile_mobile = %{version}-%{release} -#Provides: %{name}-profile_wearable = %{version}-%{release} -#Provides: %{name}-profile_tv = %{version}-%{release} -#Provides: %{name}-profile_ivi = %{version}-%{release} -%global __provides_exclude ^.*-genuine\\.so.*$ +%package dummy +Summary: Context store service 'dummy' libraries -%description genuine -Binary replacement for context-store. -This genuine context-store package contains actually working shared objects -of the both server and client sides of the context-store service. +%description dummy +This package provides dummy libraries of the context store service, +which is a part of the Tizen Contextual service framework. +Installing %{name} replaces these dummy libraries with the actually functional libraries. %package devel -Summary: Tizen Context Store Service API +Summary: Headers of the context store service server and client libraries Group: Service Framework/Context -Requires: %{name} = %{version}-%{release} +Requires: %{name}-dummy = %{version}-%{release} %description devel -Tizen Context Store Service API +This package provides headers of the context store service libraries, +which is a part of the Tizen Contextual service framework. %prep @@ -64,20 +63,8 @@ make %{?_smp_mflags} mkdir -p %{buildroot}%{TZ_SYS_DATA}/%{name} install -m 0644 script/init.sql %{buildroot}%{TZ_SYS_DATA}/%{name}/ -%post -/sbin/ldconfig - -%files -%manifest packaging/%{name}.manifest -%{_libdir}/lib%{name}-client.so* -%{_libdir}/lib%{name}-server.so* -%license LICENSE - -%preun genuine -echo "You need to reinstall %{name} to keep using the APIs after uninstalling this." - -%post genuine +%post pushd %{_libdir} ln -sf lib%{name}-client-genuine.so.%{version} lib%{name}-client.so.%{version} ln -sf lib%{name}-server-genuine.so.%{version} lib%{name}-server.so.%{version} @@ -86,11 +73,25 @@ chsmack -a "_" lib%{name}-server.so.%{version} popd /sbin/ldconfig -%files genuine +%preun +echo "You need to reinstall %{name}-dummy to keep using the APIs after uninstalling this." + +%files %manifest packaging/%{name}.manifest %{_libdir}/lib%{name}-client-genuine.so* %{_libdir}/lib%{name}-server-genuine.so* %{TZ_SYS_DATA}/%{name}/*.sql +%license LICENSE + + +%post dummy +/sbin/ldconfig + +%files dummy +%manifest packaging/%{name}.manifest +%{_libdir}/lib%{name}-client.so* +%{_libdir}/lib%{name}-server.so* +%license LICENSE %files devel -- 2.7.4 From 63f67a7df54b35ba2707b54757eceaf53b1a9124 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Fri, 24 Mar 2017 22:00:00 +0900 Subject: [PATCH 14/16] Add APIs for client application & daemons, and the other services in contextd Change-Id: I0176c6eb838508dd3cccc277902a7b0aeacaab8f Signed-off-by: Mu-Woong Lee --- CMakeLists.txt | 8 - include/ContextStoreSearchQuery.h | 57 --- include/context_store_internal.h | 100 ++++++ include/{ => private}/ContextStoreService.h | 1 - include/private/ContextStoreSideGate.h | 48 +++ script/init.sql | 1 + src/client-dummy/CMakeLists.txt | 2 + src/client-dummy/ContextStoreSearchQuery.cpp | 85 ----- src/client-dummy/context_store.cpp | 152 ++++++++ src/client/CMakeLists.txt | 2 + src/client/ContextStore.cpp | 34 +- {include => src/client}/ContextStore.h | 24 +- src/client/ContextStoreManager.cpp | 12 +- {include => src/client}/ContextStoreManager.h | 11 +- src/client/ContextStoreSearchQuery.cpp | 91 ----- src/client/PlatformManagedStore.cpp | 23 +- src/client/PlatformManagedStore.h | 6 +- src/client/context_store.cpp | 382 +++++++++++++++++++++ src/server-dummy/CMakeLists.txt | 2 + .../ContextStoreSideGate.cpp} | 27 +- src/server/CMakeLists.txt | 2 + src/server/ContextStoreClient.cpp | 5 +- src/server/ContextStoreService.cpp | 4 + src/server/ContextStoreSideGate.cpp | 50 +++ src/server/SchemaLoader.cpp | 39 ++- src/server/Store.cpp | 8 +- src/server/Store.h | 4 +- src/server/StoreManager.cpp | 38 +- src/shared/ContextStoreTypesPrivate.h | 10 +- .../ContextStoreUtil.cpp} | 22 +- .../shared/ContextStoreUtil.h | 12 +- 31 files changed, 938 insertions(+), 324 deletions(-) delete mode 100644 include/ContextStoreSearchQuery.h create mode 100644 include/context_store_internal.h rename include/{ => private}/ContextStoreService.h (97%) create mode 100644 include/private/ContextStoreSideGate.h delete mode 100644 src/client-dummy/ContextStoreSearchQuery.cpp create mode 100644 src/client-dummy/context_store.cpp rename {include => src/client}/ContextStore.h (71%) rename {include => src/client}/ContextStoreManager.h (87%) delete mode 100644 src/client/ContextStoreSearchQuery.cpp create mode 100644 src/client/context_store.cpp rename src/{client-dummy/ContextStore.cpp => server-dummy/ContextStoreSideGate.cpp} (50%) create mode 100644 src/server/ContextStoreSideGate.cpp rename src/{client-dummy/ContextStoreManager.cpp => shared/ContextStoreUtil.cpp} (61%) rename include/ContextStoreTypes.h => src/shared/ContextStoreUtil.h (74%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1905668..8dbfdf0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,6 @@ SET(INCDIR "${CMAKE_INSTALL_INCLUDEDIR}/context-service") INCLUDE_DIRECTORIES( ${CMAKE_INSTALL_PREFIX}/${INCDIR}/private - ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src/shared ) @@ -21,15 +20,8 @@ SET(PC_INCLUDE "${CMAKE_INSTALL_PREFIX}/${INCDIR}") SET(PC_LIBDIR "${CMAKE_INSTALL_LIBDIR}") INSTALL( - FILES ${CMAKE_SOURCE_DIR}/include/ContextStoreService.h - DESTINATION ${INCDIR}/private -) -INSTALL( DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION ${INCDIR} - FILES_MATCHING - PATTERN "*.h" - PATTERN "ContextStoreService.h" EXCLUDE ) ADD_SUBDIRECTORY(src/client-dummy) diff --git a/include/ContextStoreSearchQuery.h b/include/ContextStoreSearchQuery.h deleted file mode 100644 index c279676..0000000 --- a/include/ContextStoreSearchQuery.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __CONTEXT_STORE_SEARCH_QUERY_H__ -#define __CONTEXT_STORE_SEARCH_QUERY_H__ - -#include -#include - -namespace ctx { - - class EXPORT_API ContextStoreSearchQuery { - public: - ContextStoreSearchQuery(); - ContextStoreSearchQuery( - const std::string& projection, - const std::string& selection, - const std::string& sortOrder, - unsigned int limit); - - ~ContextStoreSearchQuery(); - - ContextStoreSearchQuery& setProjection(const std::string& projection); - ContextStoreSearchQuery& setSelection(const std::string& selection); - ContextStoreSearchQuery& setSortOrder(const std::string& sortOrder); - ContextStoreSearchQuery& setLimit(unsigned int limit); - - const std::string& getProjection() const; - const std::string& getSelection() const; - const std::string& getSortOrder() const; - unsigned int getLimit() const; - - bool valid() const; - - private: - std::string __projection; - std::string __selection; - std::string __sortOrder; - unsigned int __limit; - }; - -} - -#endif /* __CONTEXT_STORE_SEARCH_QUERY_H__ */ diff --git a/include/context_store_internal.h b/include/context_store_internal.h new file mode 100644 index 0000000..8e8c972 --- /dev/null +++ b/include/context_store_internal.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CAPI_CONTEXT_STORE_INTERNAL_H__ +#define __CAPI_CONTEXT_STORE_INTERNAL_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Handles */ +typedef struct _ctx_store_handle_s* ctx_store_h; + +typedef struct _ctx_store_record_s* ctx_store_record_h; + +typedef struct _ctx_store_cursor_s* ctx_store_cursor_h; + + +/* Store object creation */ +int ctx_store_create(const char* uri, ctx_store_h* store); + +int ctx_store_destroy(ctx_store_h store); + + +/* Data CRUD */ +int ctx_store_insert(ctx_store_h store, ctx_store_record_h record); + +int ctx_store_lazy_insert(ctx_store_h store, ctx_store_record_h record); + +int ctx_store_lazy_insert_flush(ctx_store_h store); + +int ctx_store_lazy_insert_reset(ctx_store_h store); + +int ctx_store_retrieve(ctx_store_h store, + const char* projection, const char* selection, + const char* sort_order, unsigned int limit, + ctx_store_cursor_h* cursor); + +int ctx_store_remove(ctx_store_h store, const char* selection); + + +/* Tuple */ +int ctx_store_record_create(ctx_store_record_h* record); + +int ctx_store_record_destroy(ctx_store_record_h record); + +int ctx_store_record_set_int64(ctx_store_record_h record, const char* key, int64_t value); + +int ctx_store_record_set_double(ctx_store_record_h record, const char* key, double value); + +int ctx_store_record_set_string(ctx_store_record_h, const char* key, const char* value); + + +/* Cursor */ +int ctx_store_cursor_destroy(ctx_store_cursor_h cursor); + +/* Cursor: Navigation */ +int ctx_store_cursor_get_count(ctx_store_cursor_h cursor, unsigned int* count); + +int ctx_store_cursor_get_position(ctx_store_cursor_h cursor, unsigned int* position); + +int ctx_store_cursor_set_position(ctx_store_cursor_h cursor, unsigned int position); + +int ctx_store_cursor_first(ctx_store_cursor_h cursor); + +int ctx_store_cursor_last(ctx_store_cursor_h cursor); + +int ctx_store_cursor_next(ctx_store_cursor_h cursor); + +int ctx_store_cursor_prev(ctx_store_cursor_h cursor); + +/* Cursor: Extraction */ +int ctx_store_cursor_get_int64(ctx_store_cursor_h cursor, const char* key, int64_t* value); + +int ctx_store_cursor_get_double(ctx_store_cursor_h cursor, const char* key, double* value); + +int ctx_store_cursor_get_string(ctx_store_cursor_h cursor, const char* key, char** value); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/include/ContextStoreService.h b/include/private/ContextStoreService.h similarity index 97% rename from include/ContextStoreService.h rename to include/private/ContextStoreService.h index 828424e..b056583 100644 --- a/include/ContextStoreService.h +++ b/include/private/ContextStoreService.h @@ -20,7 +20,6 @@ /* This header SHOULD NOT be included by other headers in this directory. */ #include -#include namespace ctx { diff --git a/include/private/ContextStoreSideGate.h b/include/private/ContextStoreSideGate.h new file mode 100644 index 0000000..7e870d7 --- /dev/null +++ b/include/private/ContextStoreSideGate.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTEXT_STORE_SIDE_GATE_H__ +#define __CONTEXT_STORE_SIDE_GATE_H__ + +#include + +namespace ctx { + + class ContextStoreService; + + class EXPORT_API ContextStoreSideGate { + public: + ~ContextStoreSideGate(); + + int insert(const std::string& columns, std::vector& tuples); + + static ContextStoreSideGate getUserStore(const std::string& uri); + static ContextStoreSideGate getSystemStore(const std::string& uri); + + private: + ContextStoreSideGate(const std::string& uri, bool isSystem); + + std::string __uri; + bool __isSystem; + + static ContextStoreService* __hostService; + + friend class ContextStoreService; + }; + +} + +#endif diff --git a/script/init.sql b/script/init.sql index d0ec0c9..80dd7bf 100644 --- a/script/init.sql +++ b/script/init.sql @@ -1,5 +1,6 @@ CREATE TABLE IF NOT EXISTS ContextStoreSchema ( "uri" TEXT PRIMARY KEY, + "columns" TEXT NOT NULL, "retention" INTEGER NOT NULL DEFAULT 0, "limit" INTEGER NOT NULL DEFAULT 0, "readPrivileges" TEXT NOT NULL, diff --git a/src/client-dummy/CMakeLists.txt b/src/client-dummy/CMakeLists.txt index 1e5e9f4..c5865b0 100644 --- a/src/client-dummy/CMakeLists.txt +++ b/src/client-dummy/CMakeLists.txt @@ -2,6 +2,8 @@ SET(target "${PROJECT_NAME}-client") SET(DEPS "${DEPS} context-common-client") +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + FILE(GLOB_RECURSE SRCS *.cpp) MESSAGE("Sources: ${SRCS}") diff --git a/src/client-dummy/ContextStoreSearchQuery.cpp b/src/client-dummy/ContextStoreSearchQuery.cpp deleted file mode 100644 index bda66fe..0000000 --- a/src/client-dummy/ContextStoreSearchQuery.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -using namespace ctx; - -ContextStoreSearchQuery::ContextStoreSearchQuery() : - __limit(0) -{ -} - -ContextStoreSearchQuery::ContextStoreSearchQuery(const std::string& projection, - const std::string& selection, const std::string& sortOrder, - unsigned int limit) : - __limit(0) -{ -} - -ContextStoreSearchQuery::~ContextStoreSearchQuery() -{ -} - -ContextStoreSearchQuery& ContextStoreSearchQuery::setProjection(const std::string& projection) -{ - __projection = projection; - return *this; -} - -ContextStoreSearchQuery& ContextStoreSearchQuery::setSelection(const std::string& selection) -{ - __selection = selection; - return *this; -} - -ContextStoreSearchQuery& ContextStoreSearchQuery::setSortOrder(const std::string& sortOrder) -{ - __sortOrder = sortOrder; - return *this; -} - -ContextStoreSearchQuery& ContextStoreSearchQuery::setLimit(unsigned int limit) -{ - __limit = limit; - return *this; -} - -const std::string& ContextStoreSearchQuery::getProjection() const -{ - return __projection; -} - -const std::string& ContextStoreSearchQuery::getSelection() const -{ - return __selection; -} - -const std::string& ContextStoreSearchQuery::getSortOrder() const -{ - return __sortOrder; -} - -unsigned int ContextStoreSearchQuery::getLimit() const -{ - return __limit; -} - -bool ContextStoreSearchQuery::valid() const -{ - return false; -} diff --git a/src/client-dummy/context_store.cpp b/src/client-dummy/context_store.cpp new file mode 100644 index 0000000..7669bd6 --- /dev/null +++ b/src/client-dummy/context_store.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +typedef struct _ctx_store_handle_s { + int dummy; +} ctx_store_handle_s; + +typedef struct _ctx_store_record_s { + int dummy; +} ctx_store_record_s; + +typedef struct _ctx_store_cursor_s { + int dummy; +} ctx_store_cursor_s; + +EXPORT_API int ctx_store_create(const char* uri, ctx_store_h* store) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_destroy(ctx_store_h store) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_insert(ctx_store_h store, ctx_store_record_h record) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_lazy_insert(ctx_store_h store, ctx_store_record_h record) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_lazy_insert_flush(ctx_store_h store) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_lazy_insert_reset(ctx_store_h store) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_retrieve(ctx_store_h store, const char* projection, + const char* selection, const char* sort_order, unsigned int limit, + ctx_store_cursor_h* cursor) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_remove(ctx_store_h store, const char* selection) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_record_create(ctx_store_record_h* record) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_record_destroy(ctx_store_record_h record) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_record_set_int64(ctx_store_record_h record, const char* key, int64_t value) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_record_set_double(ctx_store_record_h record, const char* key, double value) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_record_set_string(ctx_store_record_h record, const char* key, const char* value) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_cursor_destroy(ctx_store_cursor_h cursor) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_cursor_get_count(ctx_store_cursor_h cursor, unsigned int* count) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_cursor_get_position(ctx_store_cursor_h cursor, unsigned int* position) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_cursor_set_position(ctx_store_cursor_h cursor, unsigned int position) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_cursor_first(ctx_store_cursor_h cursor) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_cursor_last(ctx_store_cursor_h cursor) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_cursor_next(ctx_store_cursor_h cursor) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_cursor_prev(ctx_store_cursor_h cursor) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_cursor_get_int64(ctx_store_cursor_h cursor, const char* key, int64_t* value) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_cursor_get_double(ctx_store_cursor_h cursor, const char* key, double* value) +{ + return E_SUPPORT; +} + +EXPORT_API int ctx_store_cursor_get_string(ctx_store_cursor_h cursor, const char* key, char** value) +{ + return E_SUPPORT; +} diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 8f551d7..cce6a58 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -2,6 +2,8 @@ SET(target "${PROJECT_NAME}-client-genuine") SET(DEPS "${DEPS} context-common-client") +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + FILE(GLOB_RECURSE SRCS *.cpp ../shared/*.cpp) MESSAGE("Sources: ${SRCS}") diff --git a/src/client/ContextStore.cpp b/src/client/ContextStore.cpp index 3f14d37..8f906f9 100644 --- a/src/client/ContextStore.cpp +++ b/src/client/ContextStore.cpp @@ -14,11 +14,20 @@ * limitations under the License. */ +#include #include -#include +#include "ContextStore.h" using namespace ctx; +ContextStoreSearchQuery::ContextStoreSearchQuery(const char* proj, const char* sel, const char* srt, unsigned int lim) : + projection(proj ? proj : EMPTY_STR), + selection(sel ? sel : EMPTY_STR), + sortOrder(srt ? srt : EMPTY_STR), + limit(lim) +{ +} + ContextStore::ContextStore() { } @@ -46,3 +55,26 @@ int ContextStore::remove(const std::string& selection) { return E_SUPPORT; } + +DataType ContextStore::getColumnType(const std::string& columnName) +{ + size_t pos = __columns.find(columnName); + IF_FAIL_RETURN(pos != std::string::npos, DataType::UNKNOWN); + + DataType type = DataType::UNKNOWN; + + try { + char typeChar = __columns.at(pos + columnName.size() + 1); + if (typeChar == *COL_INT64) { + type = DataType::INT64; + } else if (typeChar == *COL_DOUBLE) { + type = DataType::DOUBLE; + } else if (typeChar == *COL_STRING) { + type = DataType::STRING; + } + } catch (std::exception& e) { + _E("%s", e.what()); + } + + return type; +} diff --git a/include/ContextStore.h b/src/client/ContextStore.h similarity index 71% rename from include/ContextStore.h rename to src/client/ContextStore.h index cf6c098..ccef9ea 100644 --- a/include/ContextStore.h +++ b/src/client/ContextStore.h @@ -19,12 +19,26 @@ #include #include -#include -#include +#include namespace ctx { - class EXPORT_API ContextStore { + enum class DataType { + UNKNOWN = 0, + INT64 = 1, + DOUBLE, + STRING + }; + + struct ContextStoreSearchQuery { + std::string projection; + std::string selection; + std::string sortOrder; + unsigned int limit; + ContextStoreSearchQuery(const char* proj, const char* sel, const char* srt, unsigned int lim); + }; + + class ContextStore { public: virtual ~ContextStore(); @@ -33,8 +47,12 @@ namespace ctx { virtual int retrieve(const ContextStoreSearchQuery& query, std::vector& records); virtual int remove(const std::string& selection); + DataType getColumnType(const std::string& columnName); + protected: ContextStore(); + + std::string __columns; }; } diff --git a/src/client/ContextStoreManager.cpp b/src/client/ContextStoreManager.cpp index 9dcca7c..9f135a1 100644 --- a/src/client/ContextStoreManager.cpp +++ b/src/client/ContextStoreManager.cpp @@ -16,8 +16,8 @@ #include #include -#include #include "PlatformManagedStore.h" +#include "ContextStoreManager.h" using namespace ctx; @@ -70,3 +70,13 @@ int ContextStoreManager::getStore(const std::string& uri, ContextStore** store) *store = _store; return E_NONE; } + +int ContextStoreManager::reloadUser() +{ + return __getServiceProxy()->call(METHOD_RELOAD_USER, NULL); +} + +int ContextStoreManager::reloadSystem() +{ + return __getServiceProxy()->call(METHOD_RELOAD_SYSTEM, NULL); +} diff --git a/include/ContextStoreManager.h b/src/client/ContextStoreManager.h similarity index 87% rename from include/ContextStoreManager.h rename to src/client/ContextStoreManager.h index 60f2a3e..1c978d2 100644 --- a/include/ContextStoreManager.h +++ b/src/client/ContextStoreManager.h @@ -18,17 +18,22 @@ #define __CONTEXT_STORE_MANAGER_H__ #include -#include -#include +#include namespace ctx { - class EXPORT_API ContextStoreManager { + class ContextStore; + + class ContextStoreManager { public: ContextStoreManager(); ~ContextStoreManager(); int getStore(const std::string& uri, ContextStore** contextStore); + + int reloadUser(); + + int reloadSystem(); }; } diff --git a/src/client/ContextStoreSearchQuery.cpp b/src/client/ContextStoreSearchQuery.cpp deleted file mode 100644 index cc606c8..0000000 --- a/src/client/ContextStoreSearchQuery.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -using namespace ctx; - -ContextStoreSearchQuery::ContextStoreSearchQuery() : - __limit(DEFAULT_QUERY_LIMIT) -{ -} - -ContextStoreSearchQuery::ContextStoreSearchQuery(const std::string& projection, - const std::string& selection, const std::string& sortOrder, - unsigned int limit) : - __projection(projection), - __selection(selection), - __sortOrder(sortOrder), - __limit(limit) -{ -} - -ContextStoreSearchQuery::~ContextStoreSearchQuery() -{ -} - -ContextStoreSearchQuery& ContextStoreSearchQuery::setProjection(const std::string& projection) -{ - __projection = projection; - return *this; -} - -ContextStoreSearchQuery& ContextStoreSearchQuery::setSelection(const std::string& selection) -{ - __selection = selection; - return *this; -} - -ContextStoreSearchQuery& ContextStoreSearchQuery::setSortOrder(const std::string& sortOrder) -{ - __sortOrder = sortOrder; - return *this; -} - -ContextStoreSearchQuery& ContextStoreSearchQuery::setLimit(unsigned int limit) -{ - __limit = limit; - return *this; -} - -const std::string& ContextStoreSearchQuery::getProjection() const -{ - return __projection; -} - -const std::string& ContextStoreSearchQuery::getSelection() const -{ - return __selection; -} - -const std::string& ContextStoreSearchQuery::getSortOrder() const -{ - return __sortOrder; -} - -unsigned int ContextStoreSearchQuery::getLimit() const -{ - return __limit; -} - -bool ContextStoreSearchQuery::valid() const -{ - if (__projection.empty()) - return false; - - return true; -} diff --git a/src/client/PlatformManagedStore.cpp b/src/client/PlatformManagedStore.cpp index 57f41c4..295c878 100644 --- a/src/client/PlatformManagedStore.cpp +++ b/src/client/PlatformManagedStore.cpp @@ -29,9 +29,19 @@ PlatformManagedStore::~PlatformManagedStore() int PlatformManagedStore::init(const std::string& uri) { - int error = __proxy->call(METHOD_GET_ACCESS, g_variant_new("(s)", uri.c_str())); __uri = uri; - return error; + GVariant* outParam = NULL; + int error = __proxy->call(METHOD_GET_ACCESS, g_variant_new("(s)", uri.c_str()), &outParam); + IF_FAIL_RETURN(error == E_NONE, error); + + const char* columns = NULL; + g_variant_get(outParam, "(&s)", &columns); + + __columns = (columns ? columns : EMPTY_STR); + + g_variant_unref(outParam); + + return E_NONE; } int PlatformManagedStore::insert(const std::string& columns, Tuple* record) @@ -61,11 +71,11 @@ int PlatformManagedStore::insert(const std::string& columns, std::vector int PlatformManagedStore::retrieve(const ContextStoreSearchQuery& query, std::vector& records) { - IF_FAIL_RETURN(query.valid(), E_PARAM); + IF_FAIL_RETURN(!query.projection.empty(), E_PARAM); GVariant* param = g_variant_new("(ssssu)", __uri.c_str(), - query.getProjection().c_str(), query.getSelection().c_str(), - query.getSortOrder().c_str(), static_cast(query.getLimit())); + query.projection.c_str(), query.selection.c_str(), + query.sortOrder.c_str(), static_cast(query.limit)); GVariant* outParam = NULL; int error = __proxy->call(METHOD_RETRIEVE, param, &outParam); @@ -75,6 +85,9 @@ int PlatformManagedStore::retrieve(const ContextStoreSearchQuery& query, std::ve g_variant_get(outParam, "(v)", &vals); records = Tuple::buildFrom(vals); + + g_variant_unref(outParam); + return E_NONE; } diff --git a/src/client/PlatformManagedStore.h b/src/client/PlatformManagedStore.h index 77c3d38..4ba7d89 100644 --- a/src/client/PlatformManagedStore.h +++ b/src/client/PlatformManagedStore.h @@ -14,14 +14,14 @@ * limitations under the License. */ -#ifndef __CONTEXT_STORE_PLATFORM_MANAGED_STORE_H__ -#define __CONTEXT_STORE_PLATFORM_MANAGED_STORE_H__ +#ifndef __CONTEXT_PLATFORM_MANAGED_STORE_H__ +#define __CONTEXT_PLATFORM_MANAGED_STORE_H__ #include #include #include -#include #include +#include "ContextStore.h" namespace ctx { diff --git a/src/client/context_store.cpp b/src/client/context_store.cpp new file mode 100644 index 0000000..2907759 --- /dev/null +++ b/src/client/context_store.cpp @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include "ContextStore.h" +#include "ContextStoreManager.h" + +#define COMMA "," + +using namespace ctx; + +typedef struct _ctx_store_handle_s { + std::string uri; + ContextStore* proxy; +} ctx_store_handle_s; + +union DataValue { + int64_t i64; + double dbl; + char* str; +}; + +typedef struct _ctx_store_record_s { + std::map> attributes; +} ctx_store_record_s; + +typedef struct _ctx_store_cursor_s { + size_t index; + std::vector keys; + std::vector tuples; +} ctx_store_cursor_s; + +static ContextStoreManager __storeManager; + +EXPORT_API int ctx_store_create(const char* uri, ctx_store_h* store) +{ + IF_FAIL_RETURN(uri && store, E_PARAM); + + ContextStore* proxy; + int error = __storeManager.getStore(uri, &proxy); + IF_FAIL_RETURN(error == E_NONE, error); + + ctx_store_h handle = new(std::nothrow) ctx_store_handle_s; + if (!handle) { + delete proxy; + return E_NO_MEM; + } + + handle->uri = uri; + handle->proxy = proxy; + *store = handle; + + return E_NONE; +} + +EXPORT_API int ctx_store_destroy(ctx_store_h store) +{ + IF_FAIL_RETURN(store, E_NONE); + + delete store->proxy; + delete store; + + return E_NONE; +} + +EXPORT_API int ctx_store_insert(ctx_store_h store, ctx_store_record_h record) +{ + IF_FAIL_RETURN(store && record, E_PARAM); + + std::string columns; + Tuple::Builder builder; + + for (auto& iter : record->attributes) { + if (store->proxy->getColumnType(iter.first) != iter.second.first) { + return E_PARAM; + } + columns.append(iter.first).append(COMMA); + if (iter.second.first == DataType::INT64) { + builder.add(iter.second.second.i64); + } else if (iter.second.first == DataType::DOUBLE) { + builder.add(iter.second.second.dbl); + } else { + builder.add(iter.second.second.str); + } + } + + IF_FAIL_RETURN(!columns.empty(), E_PARAM); + columns.pop_back(); + + Tuple* tuple = builder.build(); + IF_FAIL_RETURN(tuple, E_FAILED); + + return store->proxy->insert(columns, tuple); +} + +EXPORT_API int ctx_store_lazy_insert(ctx_store_h store, ctx_store_record_h record) +{ + // TODO + return E_SUPPORT; +} + +EXPORT_API int ctx_store_lazy_insert_flush(ctx_store_h store) +{ + // TODO + return E_SUPPORT; +} + +EXPORT_API int ctx_store_lazy_insert_reset(ctx_store_h store) +{ + // TODO + return E_SUPPORT; +} + +EXPORT_API int ctx_store_retrieve(ctx_store_h store, const char* projection, + const char* selection, const char* sort_order, unsigned int limit, + ctx_store_cursor_h* cursor) +{ + IF_FAIL_RETURN(store && projection && cursor, E_PARAM); + + ctx_store_cursor_s* csr = new(std::nothrow) ctx_store_cursor_s; + IF_FAIL_RETURN(csr, E_NO_MEM); + + std::vector tuples; + ContextStoreSearchQuery query(projection, selection, sort_order, limit); + + int error = store->proxy->retrieve(query, tuples); + if (error != E_NONE) { + delete csr; + return error; + } + + csr->index = 0; + csr->keys = util::tokenizeString(query.projection, ", "); + csr->tuples = tuples; + + *cursor = csr; + + return E_NONE; +} + +EXPORT_API int ctx_store_remove(ctx_store_h store, const char* selection) +{ + IF_FAIL_RETURN(store && selection, E_PARAM); + + return store->proxy->remove(selection); +} + +EXPORT_API int ctx_store_record_create(ctx_store_record_h* record) +{ + IF_FAIL_RETURN(record, E_PARAM); + + ctx_store_record_h handle = new(std::nothrow) ctx_store_record_s; + IF_FAIL_RETURN(handle, E_NO_MEM); + + *record = handle; + + return E_NONE; +} + +EXPORT_API int ctx_store_record_destroy(ctx_store_record_h record) +{ + IF_FAIL_RETURN(record, E_NONE); + + for (auto& iter : record->attributes) { + if (iter.second.first == DataType::STRING) + g_free(iter.second.second.str); + } + + delete record; + + return E_NONE; +} + +static void __removeFromRecord(ctx_store_record_h record, const char* key) +{ + auto iter = record->attributes.find(key); + if (iter == record->attributes.end()) + return; + + if (iter->second.first == DataType::STRING) + g_free(iter->second.second.str); + + record->attributes.erase(iter); +} + +EXPORT_API int ctx_store_record_set_int64(ctx_store_record_h record, const char* key, int64_t value) +{ + IF_FAIL_RETURN(record && key, E_PARAM); + + __removeFromRecord(record, key); + + DataValue v; + v.i64 = value; + record->attributes[key] = std::make_pair(DataType::INT64, v); + + return E_NONE; +} + +EXPORT_API int ctx_store_record_set_double(ctx_store_record_h record, const char* key, double value) +{ + IF_FAIL_RETURN(record && key, E_PARAM); + + __removeFromRecord(record, key); + + DataValue v; + v.dbl = value; + record->attributes[key] = std::make_pair(DataType::DOUBLE, v); + + return E_NONE; +} + +EXPORT_API int ctx_store_record_set_string(ctx_store_record_h record, const char* key, const char* value) +{ + IF_FAIL_RETURN(record && key && value, E_PARAM); + + __removeFromRecord(record, key); + + DataValue v; + v.str = g_strdup(value); + IF_FAIL_RETURN(v.str, E_NO_MEM); + + record->attributes[key] = std::make_pair(DataType::STRING, v); + + return E_NONE; +} + +EXPORT_API int ctx_store_cursor_destroy(ctx_store_cursor_h cursor) +{ + IF_FAIL_RETURN(cursor, E_NONE); + + for (auto& tuple : cursor->tuples) { + delete tuple; + } + + delete cursor; + + return E_NONE; +} + +EXPORT_API int ctx_store_cursor_get_count(ctx_store_cursor_h cursor, unsigned int* count) +{ + IF_FAIL_RETURN(cursor && count, E_PARAM); + + *count = cursor->tuples.size(); + + return E_NONE; +} + +EXPORT_API int ctx_store_cursor_get_position(ctx_store_cursor_h cursor, unsigned int* position) +{ + IF_FAIL_RETURN(cursor && position, E_PARAM); + + *position = cursor->index; + + return E_NONE; +} + +EXPORT_API int ctx_store_cursor_set_position(ctx_store_cursor_h cursor, unsigned int position) +{ + IF_FAIL_RETURN(cursor && position < cursor->tuples.size(), E_PARAM); + + cursor->index = position; + + return E_NONE; +} + +EXPORT_API int ctx_store_cursor_first(ctx_store_cursor_h cursor) +{ + IF_FAIL_RETURN(cursor, E_PARAM); + + cursor->index = 0; + + return E_NONE; +} + +EXPORT_API int ctx_store_cursor_last(ctx_store_cursor_h cursor) +{ + IF_FAIL_RETURN(cursor, E_PARAM); + + cursor->index = cursor->tuples.size() - 1; + + return E_NONE; +} + +EXPORT_API int ctx_store_cursor_next(ctx_store_cursor_h cursor) +{ + IF_FAIL_RETURN(cursor, E_PARAM); + IF_FAIL_RETURN(cursor->index + 1 < cursor->tuples.size(), E_NO_DATA); + + cursor->index += 1; + + return E_NONE; +} + +EXPORT_API int ctx_store_cursor_prev(ctx_store_cursor_h cursor) +{ + IF_FAIL_RETURN(cursor, E_PARAM); + IF_FAIL_RETURN(cursor->index != 0, E_NO_DATA); + + cursor->index -= 1; + + return E_NONE; +} + +static unsigned int __getIndexOf(ctx_store_cursor_h cursor, const std::string& key) +{ + unsigned int i; + for (i = 0; i < cursor->keys.size(); ++i) { + if (cursor->keys[i] == key) + return i; + } + return i; +} + +EXPORT_API int ctx_store_cursor_get_int64(ctx_store_cursor_h cursor, const char* key, int64_t* value) +{ + IF_FAIL_RETURN(cursor && key && value, E_PARAM); + + unsigned int idx = __getIndexOf(cursor, key); + const char* valueStr = NULL; + + if (!cursor->tuples[cursor->index]->getAt(idx, &valueStr)) + return E_PARAM; + + //TODO: Type checking & locale-invariant? + *value = std::atoll(valueStr); + + return E_NONE; +} + +EXPORT_API int ctx_store_cursor_get_double(ctx_store_cursor_h cursor, const char* key, double* value) +{ + //TODO: check whether a number with many digits can be handled. + IF_FAIL_RETURN(cursor && key && value, E_PARAM); + + unsigned int idx = __getIndexOf(cursor, key); + const char* valueStr = NULL; + + if (!cursor->tuples[cursor->index]->getAt(idx, &valueStr)) + return E_PARAM; + + //TODO: Type checking & locale-invariant? + *value = std::atof(valueStr); + + return E_NONE; +} + +EXPORT_API int ctx_store_cursor_get_string(ctx_store_cursor_h cursor, const char* key, char** value) +{ + IF_FAIL_RETURN(cursor && key && value, E_PARAM); + + unsigned int idx = __getIndexOf(cursor, key); + const char* valueStr = NULL; + + if (!cursor->tuples[cursor->index]->getAt(idx, &valueStr)) + return E_PARAM; + + char* buf = g_strdup(valueStr); + IF_FAIL_RETURN(buf, E_NO_MEM); + + *value = buf; + + return E_NONE; +} diff --git a/src/server-dummy/CMakeLists.txt b/src/server-dummy/CMakeLists.txt index 1f0fdc0..efc6f22 100644 --- a/src/server-dummy/CMakeLists.txt +++ b/src/server-dummy/CMakeLists.txt @@ -2,6 +2,8 @@ SET(target "${PROJECT_NAME}-server") SET(DEPS "${DEPS} context-common-server") +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include/private) + FILE(GLOB_RECURSE SRCS *.cpp) MESSAGE("Sources: ${SRCS}") diff --git a/src/client-dummy/ContextStore.cpp b/src/server-dummy/ContextStoreSideGate.cpp similarity index 50% rename from src/client-dummy/ContextStore.cpp rename to src/server-dummy/ContextStoreSideGate.cpp index 3f14d37..c965543 100644 --- a/src/client-dummy/ContextStore.cpp +++ b/src/server-dummy/ContextStoreSideGate.cpp @@ -14,35 +14,36 @@ * limitations under the License. */ -#include -#include +#include +#include using namespace ctx; -ContextStore::ContextStore() -{ -} +ContextStoreService* ContextStoreSideGate::__hostService = NULL; -ContextStore::~ContextStore() +ContextStoreSideGate::ContextStoreSideGate(const std::string& uri, bool isSystem) : + __uri(uri), + __isSystem(isSystem) { } -int ContextStore::insert(const std::string& columns, Tuple* record) +ContextStoreSideGate::~ContextStoreSideGate() { - return E_SUPPORT; } -int ContextStore::insert(const std::string& columns, std::vector& records) +int ContextStoreSideGate::insert(const std::string& columns, std::vector& tuples) { return E_SUPPORT; } -int ContextStore::retrieve(const ContextStoreSearchQuery& query, std::vector& records) +ContextStoreSideGate ContextStoreSideGate::getUserStore(const std::string& uri) { - return E_SUPPORT; + ContextStoreSideGate sideGate(uri, false); + return sideGate; } -int ContextStore::remove(const std::string& selection) +ContextStoreSideGate ContextStoreSideGate::getSystemStore(const std::string& uri) { - return E_SUPPORT; + ContextStoreSideGate sideGate(uri, true); + return sideGate; } diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 64a741f..bd50a93 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -2,6 +2,8 @@ SET(target "${PROJECT_NAME}-server-genuine") SET(DEPS "${DEPS} context-common-server") +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include/private) + FILE(GLOB_RECURSE SRCS *.cpp ../shared/*.cpp) MESSAGE("Sources: ${SRCS}") diff --git a/src/server/ContextStoreClient.cpp b/src/server/ContextStoreClient.cpp index 096f35e..a89af10 100644 --- a/src/server/ContextStoreClient.cpp +++ b/src/server/ContextStoreClient.cpp @@ -52,6 +52,7 @@ void ContextStoreClient::onMethodCalled(MethodCall* methodCall) __remove(*store, *methodCall); } } catch (int error) { + _W("Catch: %s", CTX_ERROR_STR(error)); methodCall->reply(error); } catch (std::exception& e) { _E("Exception: %s", e.what()); @@ -115,7 +116,7 @@ void ContextStoreClient::__getAccess(Store& store, MethodCall& methodCall) if (!store.permitted(*this)) throw static_cast(E_ACCESS); - methodCall.reply(g_variant_new("(s)", store.getPath().c_str())); + methodCall.reply(g_variant_new("(s)", store.getColumns().c_str())); } void ContextStoreClient::__insert(Store& store, MethodCall& methodCall) @@ -166,6 +167,8 @@ void ContextStoreClient::__retrieve(Store& store, MethodCall& methodCall) int error = store.retrieve(*this, projection, selection, sortOrder, limit, &tuples); if (error != E_NONE) throw error; + if (tuples.empty()) + throw static_cast(E_NO_DATA); methodCall.reply(g_variant_new("(v)", Tuple::toGVariant(tuples))); } diff --git a/src/server/ContextStoreService.cpp b/src/server/ContextStoreService.cpp index e4162e1..00993fd 100644 --- a/src/server/ContextStoreService.cpp +++ b/src/server/ContextStoreService.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include "ContextStoreClient.h" #include "StoreManager.h" @@ -27,6 +28,7 @@ ContextStoreService::ContextStoreService(GDBusConnection* conn) : ServiceBase(conn, CTX_CONTEXT_STORE, CTX_CONTEXT_STORE_SPEC), __storeManager(NULL) { + ContextStoreSideGate::__hostService = this; } ContextStoreService::~ContextStoreService() @@ -74,6 +76,8 @@ void ContextStoreService::onUserActivated() void ContextStoreService::onUserDeactivated() { DatabaseManager::closeUser(); + if (__storeManager) + __storeManager->flushUserCache(); } StoreManager& ContextStoreService::getStoreManager() diff --git a/src/server/ContextStoreSideGate.cpp b/src/server/ContextStoreSideGate.cpp new file mode 100644 index 0000000..a3f4e36 --- /dev/null +++ b/src/server/ContextStoreSideGate.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +using namespace ctx; + +ContextStoreService* ContextStoreSideGate::__hostService = NULL; + +ContextStoreSideGate::ContextStoreSideGate(const std::string& uri, bool isSystem) : + __uri(uri), + __isSystem(isSystem) +{ +} + +ContextStoreSideGate::~ContextStoreSideGate() +{ +} + +int ContextStoreSideGate::insert(const std::string& columns, std::vector& tuples) +{ + //TODO: Switch to the thread-default mainloop, get the Store object, and insert. + return E_SUPPORT; +} + +ContextStoreSideGate ContextStoreSideGate::getUserStore(const std::string& uri) +{ + ContextStoreSideGate sideGate(uri, false); + return sideGate; +} + +ContextStoreSideGate ContextStoreSideGate::getSystemStore(const std::string& uri) +{ + ContextStoreSideGate sideGate(uri, true); + return sideGate; +} diff --git a/src/server/SchemaLoader.cpp b/src/server/SchemaLoader.cpp index 4343456..146ed54 100644 --- a/src/server/SchemaLoader.cpp +++ b/src/server/SchemaLoader.cpp @@ -254,9 +254,26 @@ void SchemaLoader::__insertMetadata(Schema& schema) char* insertSql = NULL; int length = 0; + std::string columns; std::string readPrivil; std::string writePrivil; + for (auto& attr : schema.attributes) { + columns.append(attr.first); + switch (attr.second) { + case Schema::AttributeType::INTEGER: + columns.append(" " COL_INT64 COLUMN_DELIM); + break; + case Schema::AttributeType::REAL: + columns.append(" " COL_DOUBLE COLUMN_DELIM); + break; + case Schema::AttributeType::TEXT: + default: + columns.append(" " COL_STRING COLUMN_DELIM); + break; + } + } + for (auto& item : schema.readPrivileges) { readPrivil.append(item); readPrivil.append(PRIVILEGE_DELIM); @@ -269,10 +286,10 @@ void SchemaLoader::__insertMetadata(Schema& schema) length = asprintf(&updateSql, "UPDATE ContextStoreSchema" - " SET uri='%s', retention=%u, \"limit\"=%u, readPrivileges='%s', writePrivileges='%s'" + " SET uri='%s', columns='%s', retention=%u, \"limit\"=%u, readPrivileges='%s', writePrivileges='%s'" " WHERE uri='%s'", - schema.uri.c_str(), schema.retention, schema.limit, readPrivil.c_str(), writePrivil.c_str(), - schema.uri.c_str()); + schema.uri.c_str(), columns.c_str(), schema.retention, schema.limit, + readPrivil.c_str(), writePrivil.c_str(), schema.uri.c_str()); if (length <= 0) { _E("Memory allocation failed"); return; @@ -280,9 +297,10 @@ void SchemaLoader::__insertMetadata(Schema& schema) length = asprintf(&insertSql, "INSERT OR IGNORE INTO ContextStoreSchema" - " (uri, retention, \"limit\", readPrivileges, writePrivileges)" - " VALUES ('%s', %u, %u, '%s', '%s')", - schema.uri.c_str(), schema.retention, schema.limit, readPrivil.c_str(), writePrivil.c_str()); + " (uri, columns, retention, \"limit\", readPrivileges, writePrivileges)" + " VALUES ('%s', '%s', %u, %u, '%s', '%s')", + schema.uri.c_str(), columns.c_str(), schema.retention, schema.limit, + readPrivil.c_str(), writePrivil.c_str()); if (length <= 0) { g_free(updateSql); _E("Memory allocation failed"); @@ -303,16 +321,17 @@ void SchemaLoader::__createStoreTable(Schema& schema) COL_OWNER_ID " TEXT NOT NULL DEFAULT ''"; for (auto& item : schema.attributes) { - attr = attr + "," + item.first; + attr.append(",").append(item.first); switch (item.second) { case Schema::AttributeType::INTEGER: - attr = attr + " INTEGER NOT NULL DEFAULT 0"; + attr.append(" INTEGER NOT NULL DEFAULT 0"); break; case Schema::AttributeType::REAL: - attr = attr + " REAL NOT NULL DEFAULT 0"; + attr.append(" REAL NOT NULL DEFAULT 0"); break; + case Schema::AttributeType::TEXT: default: - attr = attr + " TEXT NOT NULL DEFAULT ''"; + attr.append(" TEXT NOT NULL DEFAULT ''"); break; } } diff --git a/src/server/Store.cpp b/src/server/Store.cpp index 1bd089b..ef765be 100644 --- a/src/server/Store.cpp +++ b/src/server/Store.cpp @@ -37,9 +37,9 @@ bool Store::permitted(ContextStoreClient& client) return __readable(client) || __writable(client); } -const std::string& Store::getPath() +const std::string& Store::getColumns() { - return metadata.path; + return metadata.columns; } int Store::insert(ContextStoreClient& client, const std::string& columns, std::vector& tuples) @@ -52,6 +52,10 @@ int Store::insert(ContextStoreClient& client, const std::string& columns, std::v _D("Inserting %u tuples of (%s) to %s", tuples.size(), columns.c_str(), metadata.uri.c_str()); int error = __getDatabase().insert(metadata.uri, columns, tuples) ? E_NONE : E_PARAM; + for (auto& tuple : tuples) { + delete tuple; + } + tuples.clear(); return error; } diff --git a/src/server/Store.h b/src/server/Store.h index c51778a..0000146 100644 --- a/src/server/Store.h +++ b/src/server/Store.h @@ -33,8 +33,8 @@ namespace ctx { public: Metadata(); - std::string path; std::string uri; + std::string columns; unsigned int retention; unsigned int limit; std::vector readPrivileges; @@ -45,7 +45,7 @@ namespace ctx { bool permitted(ContextStoreClient& client); - const std::string& getPath(); + const std::string& getColumns(); int insert(ContextStoreClient& client, const std::string& columns, std::vector& tuples); diff --git a/src/server/StoreManager.cpp b/src/server/StoreManager.cpp index 9c36f95..5a6cee0 100644 --- a/src/server/StoreManager.cpp +++ b/src/server/StoreManager.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include "DatabaseManager.h" #include "UserStore.h" #include "SystemStore.h" @@ -29,6 +30,8 @@ StoreManager::StoreManager() StoreManager::~StoreManager() { + flushUserCache(); + flushSystemCache(); } Store* StoreManager::__findStore(std::list& stores, const std::string& uri) @@ -44,31 +47,16 @@ Store* StoreManager::__findStore(std::list& stores, const std::string& u return NULL; } -std::vector __tokenize(std::string& in, const char* delim) -{ - std::vector tokens; - std::size_t begin = 0; - std::size_t end = in.find(delim, 0); - - while (end != std::string::npos) { - tokens.push_back(in.substr(begin, end - begin)); - begin = end + 1; - end = in.find(delim, begin); - } - - return tokens; -} - template Store* StoreManager::__createStore(Database& database, std::list& stores, const std::string& uri) { std::string query = - "SELECT retention, \"limit\", readPrivileges, writePrivileges" + "SELECT columns, retention, \"limit\", readPrivileges, writePrivileges" " FROM ContextStoreSchema" " WHERE uri='" + uri + "'"; std::vector tuples; - if (!database.execute(query, COL_INT64 COL_INT64 COL_STRING COL_STRING, NULL, &tuples)) { + if (!database.execute(query, COL_STRING COL_INT64 COL_INT64 COL_STRING COL_STRING, NULL, &tuples)) { _E("DB search failed"); return NULL; } @@ -77,19 +65,22 @@ Store* StoreManager::__createStore(Database& database, std::list& stores return NULL; } + std::string columns; int64_t retention = 0; int64_t limit = 0; std::string readPrivil; std::string writePrivil; - tuples[0]->getAt(0, &retention); - tuples[0]->getAt(1, &limit); - tuples[0]->getAt(2, &readPrivil); - tuples[0]->getAt(3, &writePrivil); + tuples[0]->getAt(0, &columns); + tuples[0]->getAt(1, &retention); + tuples[0]->getAt(2, &limit); + tuples[0]->getAt(3, &readPrivil); + tuples[0]->getAt(4, &writePrivil); delete tuples[0]; _D("URI: %s, Retention: %u, Limit: %u", uri.c_str(), static_cast(retention), static_cast(limit)); + _D("Columns: %s", columns.c_str()); _D("Read: %s", readPrivil.c_str()); _D("Write: %s", writePrivil.c_str()); @@ -97,10 +88,11 @@ Store* StoreManager::__createStore(Database& database, std::list& stores IF_FAIL_RETURN_TAG(store, NULL, _E, "Memory allocation failed"); store->metadata.uri = uri; + store->metadata.columns = columns; store->metadata.retention= static_cast(retention); store->metadata.limit = static_cast(limit); - store->metadata.readPrivileges = __tokenize(readPrivil, PRIVILEGE_DELIM); - store->metadata.writePrivileges = __tokenize(writePrivil, PRIVILEGE_DELIM); + store->metadata.readPrivileges = util::tokenizeString(readPrivil, PRIVILEGE_DELIM); + store->metadata.writePrivileges = util::tokenizeString(writePrivil, PRIVILEGE_DELIM); stores.push_front(store); if (stores.size() > CACHE_SIZE) { diff --git a/src/shared/ContextStoreTypesPrivate.h b/src/shared/ContextStoreTypesPrivate.h index 7daa99f..9dbd2d0 100644 --- a/src/shared/ContextStoreTypesPrivate.h +++ b/src/shared/ContextStoreTypesPrivate.h @@ -19,13 +19,16 @@ #include #include -#include #define CTX_CONTEXT_STORE "ContextStore" #define CTX_CONTEXT_STORE_SPEC \ + "" \ + "" \ + "" \ + "" \ "" \ " " \ - " " \ + " " \ "" \ "" \ " " \ @@ -45,6 +48,8 @@ " " \ "" +#define METHOD_RELOAD_USER "ReloadUser" +#define METHOD_RELOAD_SYSTEM "ReloadSystem" #define METHOD_GET_ACCESS "GetAccess" #define METHOD_INSERT "Insert" #define METHOD_RETRIEVE "Retrieve" @@ -56,6 +61,7 @@ #define MAX_RETENTION 8760 // one year #define MAX_LIMIT 100000 #define PRIVILEGE_DELIM ";" +#define COLUMN_DELIM ";" #define BASE_PATH "context-store" diff --git a/src/client-dummy/ContextStoreManager.cpp b/src/shared/ContextStoreUtil.cpp similarity index 61% rename from src/client-dummy/ContextStoreManager.cpp rename to src/shared/ContextStoreUtil.cpp index 9178735..5d6d5f2 100644 --- a/src/client-dummy/ContextStoreManager.cpp +++ b/src/shared/ContextStoreUtil.cpp @@ -14,20 +14,22 @@ * limitations under the License. */ -#include -#include +#include "ContextStoreTypesPrivate.h" +#include "ContextStoreUtil.h" using namespace ctx; -ContextStoreManager::ContextStoreManager() +std::vector util::tokenizeString(std::string& in, const char* delim) { -} + std::vector tokens; + std::size_t begin = 0; + std::size_t end = in.find(delim, 0); -ContextStoreManager::~ContextStoreManager() -{ -} + while (end != std::string::npos) { + tokens.push_back(in.substr(begin, end - begin)); + begin = end + 1; + end = in.find(delim, begin); + } -int ContextStoreManager::getStore(const std::string& uri, ContextStore** store) -{ - return E_SUPPORT; + return tokens; } diff --git a/include/ContextStoreTypes.h b/src/shared/ContextStoreUtil.h similarity index 74% rename from include/ContextStoreTypes.h rename to src/shared/ContextStoreUtil.h index 03bd8b5..52348e8 100644 --- a/include/ContextStoreTypes.h +++ b/src/shared/ContextStoreUtil.h @@ -14,10 +14,16 @@ * limitations under the License. */ -#ifndef __CONTEXT_STORE_TYPES_H__ -#define __CONTEXT_STORE_TYPES_H__ +#ifndef __CONTEXT_STORE_UTIL_H__ +#define __CONTEXT_STORE_UTIL_H__ -#include +#include +#include +namespace ctx { namespace util { + + std::vector tokenizeString(std::string& in, const char* delim); + +} } #endif -- 2.7.4 From 36345f0e7fc6f77e6c101270fab8518c3ade6114 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 28 Mar 2017 22:10:04 +0900 Subject: [PATCH 15/16] Replace obsoleted util headers Change-Id: Ib239fff20cbd3163cee14786a6ac6237696b6858 Signed-off-by: Mu-Woong Lee --- src/client/context_store.cpp | 1 - src/server/SchemaLoader.cpp | 8 ++++---- src/server/StoreManager.cpp | 1 - src/shared/ContextStoreTypesPrivate.h | 2 +- src/shared/ContextStoreUtil.cpp | 35 ----------------------------------- src/shared/ContextStoreUtil.h | 29 ----------------------------- 6 files changed, 5 insertions(+), 71 deletions(-) delete mode 100644 src/shared/ContextStoreUtil.cpp delete mode 100644 src/shared/ContextStoreUtil.h diff --git a/src/client/context_store.cpp b/src/client/context_store.cpp index 2907759..0451aab 100644 --- a/src/client/context_store.cpp +++ b/src/client/context_store.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include "ContextStore.h" #include "ContextStoreManager.h" diff --git a/src/server/SchemaLoader.cpp b/src/server/SchemaLoader.cpp index 146ed54..edb205f 100644 --- a/src/server/SchemaLoader.cpp +++ b/src/server/SchemaLoader.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include "DatabaseManager.h" #include "Schema.h" #include "SchemaChecker.h" @@ -104,7 +104,7 @@ bool SchemaLoader::load() bool SchemaLoader::__createMetadataTables() { - std::string path = PathUtil::getSystemPath(TZ_SYS_DATA, BASE_PATH "/init.sql"); + std::string path = util::getSystemPath(TZ_SYS_DATA, BASE_PATH "/init.sql"); IF_FAIL_RETURN(!path.empty(), false); std::ifstream inFile(path); @@ -354,7 +354,7 @@ Database& SystemSchemaLoader::__getDatabase() std::string SystemSchemaLoader::__getSchemaDir() { - return PathUtil::getSystemPath(TZ_SYS_DATA, BASE_PATH "/system"); + return util::getSystemPath(TZ_SYS_DATA, BASE_PATH "/system"); } @@ -369,5 +369,5 @@ Database& UserSchemaLoader::__getDatabase() std::string UserSchemaLoader::__getSchemaDir() { - return PathUtil::getSystemPath(TZ_SYS_DATA, BASE_PATH "/user"); + return util::getSystemPath(TZ_SYS_DATA, BASE_PATH "/user"); } diff --git a/src/server/StoreManager.cpp b/src/server/StoreManager.cpp index 5a6cee0..9119884 100644 --- a/src/server/StoreManager.cpp +++ b/src/server/StoreManager.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#include #include "DatabaseManager.h" #include "UserStore.h" #include "SystemStore.h" diff --git a/src/shared/ContextStoreTypesPrivate.h b/src/shared/ContextStoreTypesPrivate.h index 9dbd2d0..3651bb8 100644 --- a/src/shared/ContextStoreTypesPrivate.h +++ b/src/shared/ContextStoreTypesPrivate.h @@ -18,7 +18,7 @@ #define __CONTEXT_STORE_TYPES_PRIVATE_H__ #include -#include +#include #define CTX_CONTEXT_STORE "ContextStore" #define CTX_CONTEXT_STORE_SPEC \ diff --git a/src/shared/ContextStoreUtil.cpp b/src/shared/ContextStoreUtil.cpp deleted file mode 100644 index 5d6d5f2..0000000 --- a/src/shared/ContextStoreUtil.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ContextStoreTypesPrivate.h" -#include "ContextStoreUtil.h" - -using namespace ctx; - -std::vector util::tokenizeString(std::string& in, const char* delim) -{ - std::vector tokens; - std::size_t begin = 0; - std::size_t end = in.find(delim, 0); - - while (end != std::string::npos) { - tokens.push_back(in.substr(begin, end - begin)); - begin = end + 1; - end = in.find(delim, begin); - } - - return tokens; -} diff --git a/src/shared/ContextStoreUtil.h b/src/shared/ContextStoreUtil.h deleted file mode 100644 index 52348e8..0000000 --- a/src/shared/ContextStoreUtil.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __CONTEXT_STORE_UTIL_H__ -#define __CONTEXT_STORE_UTIL_H__ - -#include -#include - -namespace ctx { namespace util { - - std::vector tokenizeString(std::string& in, const char* delim); - -} } - -#endif -- 2.7.4 From ad36a56c48088eb77f32a1e8bd01ba5ef6f284b2 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Mon, 3 Apr 2017 16:53:02 +0900 Subject: [PATCH 16/16] Apply the updated Tuple & Database interfaces Change-Id: Iae7af355b36ab506ee695ce01065995586b198fa Signed-off-by: Mu-Woong Lee --- include/private/ContextStoreSideGate.h | 2 +- src/client/ContextStore.cpp | 6 +++--- src/client/ContextStore.h | 6 +++--- src/client/PlatformManagedStore.cpp | 21 +++++++++++---------- src/client/PlatformManagedStore.h | 6 +++--- src/client/context_store.cpp | 21 ++++++++++----------- src/server-dummy/ContextStoreSideGate.cpp | 2 +- src/server/ContextStoreClient.cpp | 4 ++-- src/server/ContextStoreSideGate.cpp | 2 +- src/server/Store.cpp | 7 ++----- src/server/Store.h | 4 ++-- src/server/StoreManager.cpp | 4 +--- 12 files changed, 40 insertions(+), 45 deletions(-) diff --git a/include/private/ContextStoreSideGate.h b/include/private/ContextStoreSideGate.h index 7e870d7..777f6c5 100644 --- a/include/private/ContextStoreSideGate.h +++ b/include/private/ContextStoreSideGate.h @@ -27,7 +27,7 @@ namespace ctx { public: ~ContextStoreSideGate(); - int insert(const std::string& columns, std::vector& tuples); + int insert(const std::string& columns, std::vector>& tuples); static ContextStoreSideGate getUserStore(const std::string& uri); static ContextStoreSideGate getSystemStore(const std::string& uri); diff --git a/src/client/ContextStore.cpp b/src/client/ContextStore.cpp index 8f906f9..1e4d4a9 100644 --- a/src/client/ContextStore.cpp +++ b/src/client/ContextStore.cpp @@ -36,17 +36,17 @@ ContextStore::~ContextStore() { } -int ContextStore::insert(const std::string& columns, Tuple* record) +int ContextStore::insert(const std::string& columns, std::shared_ptr record) { return E_SUPPORT; } -int ContextStore::insert(const std::string& columns, std::vector& records) +int ContextStore::insert(const std::string& columns, std::vector>& records) { return E_SUPPORT; } -int ContextStore::retrieve(const ContextStoreSearchQuery& query, std::vector& records) +int ContextStore::retrieve(const ContextStoreSearchQuery& query, std::vector>* records) { return E_SUPPORT; } diff --git a/src/client/ContextStore.h b/src/client/ContextStore.h index ccef9ea..01b8458 100644 --- a/src/client/ContextStore.h +++ b/src/client/ContextStore.h @@ -42,9 +42,9 @@ namespace ctx { public: virtual ~ContextStore(); - virtual int insert(const std::string& columns, Tuple* record); - virtual int insert(const std::string& columns, std::vector& records); - virtual int retrieve(const ContextStoreSearchQuery& query, std::vector& records); + virtual int insert(const std::string& columns, std::shared_ptr record); + virtual int insert(const std::string& columns, std::vector>& records); + virtual int retrieve(const ContextStoreSearchQuery& query, std::vector>* records); virtual int remove(const std::string& selection); DataType getColumnType(const std::string& columnName); diff --git a/src/client/PlatformManagedStore.cpp b/src/client/PlatformManagedStore.cpp index 295c878..81491c7 100644 --- a/src/client/PlatformManagedStore.cpp +++ b/src/client/PlatformManagedStore.cpp @@ -44,10 +44,9 @@ int PlatformManagedStore::init(const std::string& uri) return E_NONE; } -int PlatformManagedStore::insert(const std::string& columns, Tuple* record) +int PlatformManagedStore::insert(const std::string& columns, std::shared_ptr record) { if (columns.empty() || record == NULL) { - delete record; return E_PARAM; } @@ -55,12 +54,9 @@ int PlatformManagedStore::insert(const std::string& columns, Tuple* record) return __proxy->call(METHOD_INSERT, param); } -int PlatformManagedStore::insert(const std::string& columns, std::vector& records) +int PlatformManagedStore::insert(const std::string& columns, std::vector>& records) { if (columns.empty() || records.empty()) { - for (auto& tuple : records) { - delete tuple; - } records.clear(); return E_PARAM; } @@ -69,9 +65,9 @@ int PlatformManagedStore::insert(const std::string& columns, std::vector return __proxy->call(METHOD_INSERT, param); } -int PlatformManagedStore::retrieve(const ContextStoreSearchQuery& query, std::vector& records) +int PlatformManagedStore::retrieve(const ContextStoreSearchQuery& query, std::vector>* records) { - IF_FAIL_RETURN(!query.projection.empty(), E_PARAM); + IF_FAIL_RETURN(!query.projection.empty() && records, E_PARAM); GVariant* param = g_variant_new("(ssssu)", __uri.c_str(), query.projection.c_str(), query.selection.c_str(), @@ -84,11 +80,16 @@ int PlatformManagedStore::retrieve(const ContextStoreSearchQuery& query, std::ve GVariant* vals = NULL; g_variant_get(outParam, "(v)", &vals); - records = Tuple::buildFrom(vals); + try { + *records = Tuple::buildFrom(vals); + } catch (std::exception& e) { + _E("Exception: %s", e.what()); + error = E_FAILED; + } g_variant_unref(outParam); - return E_NONE; + return error; } int PlatformManagedStore::remove(const std::string& selection) diff --git a/src/client/PlatformManagedStore.h b/src/client/PlatformManagedStore.h index 4ba7d89..a47943d 100644 --- a/src/client/PlatformManagedStore.h +++ b/src/client/PlatformManagedStore.h @@ -32,9 +32,9 @@ namespace ctx { int init(const std::string& uri); - int insert(const std::string& columns, Tuple* record); - int insert(const std::string& columns, std::vector& records); - int retrieve(const ContextStoreSearchQuery& query, std::vector& records); + int insert(const std::string& columns, std::shared_ptr record); + int insert(const std::string& columns, std::vector>& records); + int retrieve(const ContextStoreSearchQuery& query, std::vector>* records); int remove(const std::string& selection); private: diff --git a/src/client/context_store.cpp b/src/client/context_store.cpp index 0451aab..376da75 100644 --- a/src/client/context_store.cpp +++ b/src/client/context_store.cpp @@ -44,7 +44,7 @@ typedef struct _ctx_store_record_s { typedef struct _ctx_store_cursor_s { size_t index; std::vector keys; - std::vector tuples; + std::vector> tuples; } ctx_store_cursor_s; static ContextStoreManager __storeManager; @@ -104,10 +104,12 @@ EXPORT_API int ctx_store_insert(ctx_store_h store, ctx_store_record_h record) IF_FAIL_RETURN(!columns.empty(), E_PARAM); columns.pop_back(); - Tuple* tuple = builder.build(); - IF_FAIL_RETURN(tuple, E_FAILED); - - return store->proxy->insert(columns, tuple); + try { + auto tuple = builder.build(); + return store->proxy->insert(columns, tuple); + } catch (std::exception& e) { + return E_FAILED; + } } EXPORT_API int ctx_store_lazy_insert(ctx_store_h store, ctx_store_record_h record) @@ -137,10 +139,10 @@ EXPORT_API int ctx_store_retrieve(ctx_store_h store, const char* projection, ctx_store_cursor_s* csr = new(std::nothrow) ctx_store_cursor_s; IF_FAIL_RETURN(csr, E_NO_MEM); - std::vector tuples; + std::vector> tuples; ContextStoreSearchQuery query(projection, selection, sort_order, limit); - int error = store->proxy->retrieve(query, tuples); + int error = store->proxy->retrieve(query, &tuples); if (error != E_NONE) { delete csr; return error; @@ -245,10 +247,7 @@ EXPORT_API int ctx_store_cursor_destroy(ctx_store_cursor_h cursor) { IF_FAIL_RETURN(cursor, E_NONE); - for (auto& tuple : cursor->tuples) { - delete tuple; - } - + cursor->tuples.clear(); delete cursor; return E_NONE; diff --git a/src/server-dummy/ContextStoreSideGate.cpp b/src/server-dummy/ContextStoreSideGate.cpp index c965543..0240651 100644 --- a/src/server-dummy/ContextStoreSideGate.cpp +++ b/src/server-dummy/ContextStoreSideGate.cpp @@ -31,7 +31,7 @@ ContextStoreSideGate::~ContextStoreSideGate() { } -int ContextStoreSideGate::insert(const std::string& columns, std::vector& tuples) +int ContextStoreSideGate::insert(const std::string& columns, std::vector>& tuples) { return E_SUPPORT; } diff --git a/src/server/ContextStoreClient.cpp b/src/server/ContextStoreClient.cpp index a89af10..444852e 100644 --- a/src/server/ContextStoreClient.cpp +++ b/src/server/ContextStoreClient.cpp @@ -134,7 +134,7 @@ void ContextStoreClient::__insert(Store& store, MethodCall& methodCall) if (!__queryChecker.validateProjection(cols)) throw static_cast(E_PARAM); - std::vector tuples = Tuple::buildFrom(vals); + std::vector> tuples = Tuple::buildFrom(vals); if (tuples.empty()) { throw static_cast(E_PARAM); } @@ -163,7 +163,7 @@ void ContextStoreClient::__retrieve(Store& store, MethodCall& methodCall) if (!__queryChecker.validateSortOrder(sortOrder)) throw static_cast(E_PARAM); - std::vector tuples; + std::vector> tuples; int error = store.retrieve(*this, projection, selection, sortOrder, limit, &tuples); if (error != E_NONE) throw error; diff --git a/src/server/ContextStoreSideGate.cpp b/src/server/ContextStoreSideGate.cpp index a3f4e36..415087b 100644 --- a/src/server/ContextStoreSideGate.cpp +++ b/src/server/ContextStoreSideGate.cpp @@ -31,7 +31,7 @@ ContextStoreSideGate::~ContextStoreSideGate() { } -int ContextStoreSideGate::insert(const std::string& columns, std::vector& tuples) +int ContextStoreSideGate::insert(const std::string& columns, std::vector>& tuples) { //TODO: Switch to the thread-default mainloop, get the Store object, and insert. return E_SUPPORT; diff --git a/src/server/Store.cpp b/src/server/Store.cpp index ef765be..a7ff134 100644 --- a/src/server/Store.cpp +++ b/src/server/Store.cpp @@ -42,7 +42,7 @@ const std::string& Store::getColumns() return metadata.columns; } -int Store::insert(ContextStoreClient& client, const std::string& columns, std::vector& tuples) +int Store::insert(ContextStoreClient& client, const std::string& columns, std::vector>& tuples) { //TODO: handling owner's ID //TODO: delete expired data @@ -52,16 +52,13 @@ int Store::insert(ContextStoreClient& client, const std::string& columns, std::v _D("Inserting %u tuples of (%s) to %s", tuples.size(), columns.c_str(), metadata.uri.c_str()); int error = __getDatabase().insert(metadata.uri, columns, tuples) ? E_NONE : E_PARAM; - for (auto& tuple : tuples) { - delete tuple; - } tuples.clear(); return error; } int Store::retrieve(ContextStoreClient& client, const std::string& projection, const std::string& selection, - const std::string& sortOrder, unsigned int limit, std::vector* tuples) + const std::string& sortOrder, unsigned int limit, std::vector>* tuples) { if (!__readable(client)) return E_ACCESS; diff --git a/src/server/Store.h b/src/server/Store.h index 0000146..d2edfc6 100644 --- a/src/server/Store.h +++ b/src/server/Store.h @@ -47,12 +47,12 @@ namespace ctx { const std::string& getColumns(); - int insert(ContextStoreClient& client, const std::string& columns, std::vector& tuples); + int insert(ContextStoreClient& client, const std::string& columns, std::vector>& tuples); int retrieve(ContextStoreClient& client, const std::string& projection, const std::string& selection, const std::string& sortOrder, unsigned int limit, - std::vector* tuples); + std::vector>* tuples); int remove(ContextStoreClient& client, const std::string selection); diff --git a/src/server/StoreManager.cpp b/src/server/StoreManager.cpp index 9119884..1c3b900 100644 --- a/src/server/StoreManager.cpp +++ b/src/server/StoreManager.cpp @@ -54,7 +54,7 @@ Store* StoreManager::__createStore(Database& database, std::list& stores " FROM ContextStoreSchema" " WHERE uri='" + uri + "'"; - std::vector tuples; + std::vector> tuples; if (!database.execute(query, COL_STRING COL_INT64 COL_INT64 COL_STRING COL_STRING, NULL, &tuples)) { _E("DB search failed"); return NULL; @@ -76,8 +76,6 @@ Store* StoreManager::__createStore(Database& database, std::list& stores tuples[0]->getAt(3, &readPrivil); tuples[0]->getAt(4, &writePrivil); - delete tuples[0]; - _D("URI: %s, Retention: %u, Limit: %u", uri.c_str(), static_cast(retention), static_cast(limit)); _D("Columns: %s", columns.c_str()); _D("Read: %s", readPrivil.c_str()); -- 2.7.4