From 63f67a7df54b35ba2707b54757eceaf53b1a9124 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Fri, 24 Mar 2017 22:00:00 +0900 Subject: [PATCH 01/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 02/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 03/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 From 5773e0bc3ebef7fdf056782febe8c6699a4f749d Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Wed, 5 Apr 2017 14:07:53 +0900 Subject: [PATCH 04/16] Remove redundant exception handlings Change-Id: I3c8c004a63e4ac093b91f3ec1f84b53a816e93fc Signed-off-by: Mu-Woong Lee --- src/client/ContextStore.cpp | 2 +- src/client/PlatformManagedStore.cpp | 2 +- src/client/context_store.cpp | 2 +- src/server/ContextStoreClient.cpp | 5 +---- src/server/ContextStoreService.cpp | 9 ++------- src/server/DatabaseManager.cpp | 6 ++---- src/server/SchemaLoader.cpp | 20 +++++--------------- src/server/StoreManager.cpp | 4 +--- 8 files changed, 14 insertions(+), 36 deletions(-) diff --git a/src/client/ContextStore.cpp b/src/client/ContextStore.cpp index 1e4d4a9..9539b27 100644 --- a/src/client/ContextStore.cpp +++ b/src/client/ContextStore.cpp @@ -72,7 +72,7 @@ DataType ContextStore::getColumnType(const std::string& columnName) } else if (typeChar == *COL_STRING) { type = DataType::STRING; } - } catch (std::exception& e) { + } catch (const std::exception& e) { _E("%s", e.what()); } diff --git a/src/client/PlatformManagedStore.cpp b/src/client/PlatformManagedStore.cpp index 81491c7..ace3f7e 100644 --- a/src/client/PlatformManagedStore.cpp +++ b/src/client/PlatformManagedStore.cpp @@ -82,7 +82,7 @@ int PlatformManagedStore::retrieve(const ContextStoreSearchQuery& query, std::ve try { *records = Tuple::buildFrom(vals); - } catch (std::exception& e) { + } catch (const std::exception& e) { _E("Exception: %s", e.what()); error = E_FAILED; } diff --git a/src/client/context_store.cpp b/src/client/context_store.cpp index 376da75..9aeffe5 100644 --- a/src/client/context_store.cpp +++ b/src/client/context_store.cpp @@ -107,7 +107,7 @@ EXPORT_API int ctx_store_insert(ctx_store_h store, ctx_store_record_h record) try { auto tuple = builder.build(); return store->proxy->insert(columns, tuple); - } catch (std::exception& e) { + } catch (const std::exception& e) { return E_FAILED; } } diff --git a/src/server/ContextStoreClient.cpp b/src/server/ContextStoreClient.cpp index 444852e..9985854 100644 --- a/src/server/ContextStoreClient.cpp +++ b/src/server/ContextStoreClient.cpp @@ -51,12 +51,9 @@ void ContextStoreClient::onMethodCalled(MethodCall* methodCall) } else if (methodCall->getMethodName() == METHOD_REMOVE) { __remove(*store, *methodCall); } - } catch (int error) { + } catch (const int error) { _W("Catch: %s", CTX_ERROR_STR(error)); methodCall->reply(error); - } catch (std::exception& e) { - _E("Exception: %s", e.what()); - methodCall->reply(E_FAILED); } delete methodCall; diff --git a/src/server/ContextStoreService.cpp b/src/server/ContextStoreService.cpp index 00993fd..2c138e8 100644 --- a/src/server/ContextStoreService.cpp +++ b/src/server/ContextStoreService.cpp @@ -61,7 +61,7 @@ void ContextStoreService::cleanup() ClientBase* ContextStoreService::createClient(const std::string& busName) { - return new(std::nothrow) ContextStoreClient(this, busName); + return new ContextStoreClient(this, busName); } void ContextStoreService::onUserActivated() @@ -85,12 +85,7 @@ StoreManager& ContextStoreService::getStoreManager() if (__storeManager) return *__storeManager; - __storeManager = new(std::nothrow) StoreManager(); - - while (__storeManager == NULL) { - _W("Memory allocation failed"); - __storeManager = new(std::nothrow) StoreManager(); - } + __storeManager = new StoreManager(); return *__storeManager; } diff --git a/src/server/DatabaseManager.cpp b/src/server/DatabaseManager.cpp index bb5a3bb..acc51c1 100644 --- a/src/server/DatabaseManager.cpp +++ b/src/server/DatabaseManager.cpp @@ -30,8 +30,7 @@ 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)); + __systemDatabase = new PlatformDatabase(BASE_PATH); if (!__systemDatabase->open()) { _E("DB open failed"); @@ -51,8 +50,7 @@ bool DatabaseManager::openUser(uid_t uid) closeUser(); } - __userDatabase = new(std::nothrow) PlatformDatabase(BASE_PATH, uid); - IF_FAIL_RETURN_TAG(__userDatabase, false, _E, "%s", CTX_ERROR_STR(E_NO_MEM)); + __userDatabase = new PlatformDatabase(BASE_PATH, uid); if (!__userDatabase->open()) { _E("DB open failed"); diff --git a/src/server/SchemaLoader.cpp b/src/server/SchemaLoader.cpp index edb205f..252bcfa 100644 --- a/src/server/SchemaLoader.cpp +++ b/src/server/SchemaLoader.cpp @@ -88,13 +88,8 @@ bool SchemaLoader::load() result = false; } - try { - if (result && !__loadSchemaDir(__getSchemaDir())) { - _W("Schema loading failed"); - result = false; - } - } catch (std::regex_error& e) { - _E("%s", e.what()); + if (result && !__loadSchemaDir(__getSchemaDir())) { + _W("Schema loading failed"); result = false; } @@ -238,12 +233,7 @@ SchemaChecker* SchemaLoader::__getSchemaChecker() if (__schemaChecker) return __schemaChecker; - try { - __schemaChecker = new SchemaChecker; - } catch (std::exception& e) { - _E("Exception: %s", e.what()); - return NULL; - } + __schemaChecker = new SchemaChecker; return __schemaChecker; } @@ -291,7 +281,7 @@ void SchemaLoader::__insertMetadata(Schema& schema) 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"); + _E_ALLOC; return; } @@ -303,7 +293,7 @@ void SchemaLoader::__insertMetadata(Schema& schema) readPrivil.c_str(), writePrivil.c_str()); if (length <= 0) { g_free(updateSql); - _E("Memory allocation failed"); + _E_ALLOC; return; } diff --git a/src/server/StoreManager.cpp b/src/server/StoreManager.cpp index 1c3b900..3ee0012 100644 --- a/src/server/StoreManager.cpp +++ b/src/server/StoreManager.cpp @@ -81,9 +81,7 @@ Store* StoreManager::__createStore(Database& database, std::list& stores _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"); - + StoreType* store = new StoreType(); store->metadata.uri = uri; store->metadata.columns = columns; store->metadata.retention= static_cast(retention); -- 2.7.4 From 436660e635d3f97afe805745da3ca7cf0cc74f25 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Wed, 5 Apr 2017 16:26:30 +0900 Subject: [PATCH 05/16] Fix the build script typos and nonconventional so symlink packaging Change-Id: Ib214509b414ff868c44b41595beb9383e07d17ad Signed-off-by: Mu-Woong Lee --- CMakeLists.txt | 2 +- packaging/context-store.spec | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dbfdf0..ecf914f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ INCLUDE_DIRECTORIES( ADD_DEFINITIONS(-O2 -Wall -fPIC -fdata-sections -ffunction-sections -fvisibility=hidden) ADD_DEFINITIONS(-DLOG_TAG="CONTEXT-STORE") -SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC -Wl,--as-needed -Wl,--gc-section -Wl,--print-gc-section") +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC -Wl,--as-needed -Wl,--gc-sections -Wl,--print-gc-sections") SET(VERSION ${FULLVER}) SET(PREFIX ${CMAKE_INSTALL_PREFIX}) diff --git a/packaging/context-store.spec b/packaging/context-store.spec index 87f390d..daa3159 100644 --- a/packaging/context-store.spec +++ b/packaging/context-store.spec @@ -78,8 +78,8 @@ echo "You need to reinstall %{name}-dummy to keep using the APIs after uninstall %files %manifest packaging/%{name}.manifest -%{_libdir}/lib%{name}-client-genuine.so* -%{_libdir}/lib%{name}-server-genuine.so* +%{_libdir}/lib%{name}-client-genuine.so.* +%{_libdir}/lib%{name}-server-genuine.so.* %{TZ_SYS_DATA}/%{name}/*.sql %license LICENSE @@ -89,12 +89,14 @@ echo "You need to reinstall %{name}-dummy to keep using the APIs after uninstall %files dummy %manifest packaging/%{name}.manifest -%{_libdir}/lib%{name}-client.so* -%{_libdir}/lib%{name}-server.so* +%{_libdir}/lib%{name}-client.so.* +%{_libdir}/lib%{name}-server.so.* %license LICENSE %files devel %{_includedir}/context-service/*.h %{_includedir}/context-service/*/*.h +%{_libdir}/lib%{name}-client.so +%{_libdir}/lib%{name}-server.so %{_libdir}/pkgconfig/*.pc -- 2.7.4 From 3ac630067a319f5b776649742eb276b6edd58fee Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 11 Apr 2017 11:03:37 +0900 Subject: [PATCH 06/16] Initialize __storeManager from the constructor of ContextStoreService Change-Id: I4ee56652bcdd491ddf8da82ef082c37d887ff711 Signed-off-by: Mu-Woong Lee --- src/server-dummy/ContextStoreService.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server-dummy/ContextStoreService.cpp b/src/server-dummy/ContextStoreService.cpp index d5ef3b2..bbaa957 100644 --- a/src/server-dummy/ContextStoreService.cpp +++ b/src/server-dummy/ContextStoreService.cpp @@ -20,7 +20,8 @@ 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) { throw std::runtime_error("Context Store is not supported"); } -- 2.7.4 From 98b065e5f4de9ab6f063c7447708f758536dda1d Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 11 Apr 2017 13:51:25 +0900 Subject: [PATCH 07/16] Version 0.1.0 Change-Id: I6c5af17ad35e2440dbfcfc94564a3df5ffdbbd3d Signed-off-by: Mu-Woong Lee --- packaging/context-store.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/context-store.spec b/packaging/context-store.spec index daa3159..3ef4d07 100644 --- a/packaging/context-store.spec +++ b/packaging/context-store.spec @@ -1,6 +1,6 @@ Name: context-store Summary: Context store service server and client libraries -Version: 0.0.1 +Version: 0.1.0 Release: 1 Group: Service Framework/Context License: Apache-2.0 -- 2.7.4 From 8b84f5e0b6f333603f8f0b6836f0b8fd98100850 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Wed, 12 Apr 2017 13:27:27 +0900 Subject: [PATCH 08/16] Remove redundant try-catch for Tuple::buildFrom() Change-Id: I1efe8b7453e7d37eda63a633b0a845c7bb12fd03 Signed-off-by: Mu-Woong Lee --- src/client/PlatformManagedStore.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/client/PlatformManagedStore.cpp b/src/client/PlatformManagedStore.cpp index ace3f7e..f0ae6be 100644 --- a/src/client/PlatformManagedStore.cpp +++ b/src/client/PlatformManagedStore.cpp @@ -80,12 +80,7 @@ int PlatformManagedStore::retrieve(const ContextStoreSearchQuery& query, std::ve GVariant* vals = NULL; g_variant_get(outParam, "(v)", &vals); - try { - *records = Tuple::buildFrom(vals); - } catch (const std::exception& e) { - _E("Exception: %s", e.what()); - error = E_FAILED; - } + *records = Tuple::buildFrom(vals); g_variant_unref(outParam); -- 2.7.4 From 5a4caf494d3770d875086fdfc0257926edce7ac9 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Wed, 12 Apr 2017 20:36:21 +0900 Subject: [PATCH 09/16] Simplify include directory setting Change-Id: Ia739ed45cf6262ebd9a736c8e32e11f8e50f68ba Signed-off-by: Mu-Woong Lee --- CMakeLists.txt | 2 ++ src/client-dummy/CMakeLists.txt | 2 -- src/client/CMakeLists.txt | 2 -- src/server-dummy/CMakeLists.txt | 2 -- src/server/CMakeLists.txt | 2 -- 5 files changed, 2 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ecf914f..1509749 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,8 @@ SET(INCDIR "${CMAKE_INSTALL_INCLUDEDIR}/context-service") INCLUDE_DIRECTORIES( ${CMAKE_INSTALL_PREFIX}/${INCDIR}/private ${CMAKE_SOURCE_DIR}/src/shared + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/include/private ) ADD_DEFINITIONS(-O2 -Wall -fPIC -fdata-sections -ffunction-sections -fvisibility=hidden) diff --git a/src/client-dummy/CMakeLists.txt b/src/client-dummy/CMakeLists.txt index c5865b0..1e5e9f4 100644 --- a/src/client-dummy/CMakeLists.txt +++ b/src/client-dummy/CMakeLists.txt @@ -2,8 +2,6 @@ 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/CMakeLists.txt b/src/client/CMakeLists.txt index cce6a58..8f551d7 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -2,8 +2,6 @@ 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/server-dummy/CMakeLists.txt b/src/server-dummy/CMakeLists.txt index efc6f22..1f0fdc0 100644 --- a/src/server-dummy/CMakeLists.txt +++ b/src/server-dummy/CMakeLists.txt @@ -2,8 +2,6 @@ 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/server/CMakeLists.txt b/src/server/CMakeLists.txt index bd50a93..64a741f 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -2,8 +2,6 @@ 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}") -- 2.7.4 From 442c3de6870ca2b285aca3a4798cd7025ba7e116 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Fri, 14 Apr 2017 17:49:09 +0900 Subject: [PATCH 10/16] Add compile options to suppress verbose messages and enable colored diagnostics Change-Id: I515c4c8e4758447464f0c99486ffb3822fca8d14 Signed-off-by: Mu-Woong Lee --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1509749..1e02fb3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,8 +13,10 @@ INCLUDE_DIRECTORIES( ) ADD_DEFINITIONS(-O2 -Wall -fPIC -fdata-sections -ffunction-sections -fvisibility=hidden) +ADD_DEFINITIONS(-fdiagnostics-color) ADD_DEFINITIONS(-DLOG_TAG="CONTEXT-STORE") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC -Wl,--as-needed -Wl,--gc-sections -Wl,--print-gc-sections") +SET(CMAKE_VERBOSE_MAKEFILE OFF) SET(VERSION ${FULLVER}) SET(PREFIX ${CMAKE_INSTALL_PREFIX}) -- 2.7.4 From b3513f8f0cbfff7c09453f2481a859eb0c5e9a6d Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Mon, 24 Apr 2017 19:39:36 +0900 Subject: [PATCH 11/16] server: use the util::getFiles() helper instead of readdir_r() Change-Id: I40439c07fd5a775eb63ded93281d0357119bc6d9 Signed-off-by: Mu-Woong Lee --- src/server/SchemaLoader.cpp | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/server/SchemaLoader.cpp b/src/server/SchemaLoader.cpp index 252bcfa..0e513e4 100644 --- a/src/server/SchemaLoader.cpp +++ b/src/server/SchemaLoader.cpp @@ -16,10 +16,9 @@ #include #include +#include #include #include -#include -#include #include #include "DatabaseManager.h" #include "Schema.h" @@ -111,31 +110,26 @@ bool SchemaLoader::__createMetadataTables() bool SchemaLoader::__loadSchemaDir(const std::string& dirPath) { - DIR* dir = NULL; - struct dirent entry; - struct dirent *result = NULL; + auto fileNames = util::getFiles(dirPath); - dir = opendir(dirPath.c_str()); - IF_FAIL_RETURN_TAG(dir, false, _E, "Failed to open: %s", dirPath.c_str()); + if (fileNames.empty()) + return false; - std::regex xmlFileRegex("^.*\\.(xml|XML)$", std::regex::optimize); + for (auto& name : fileNames) { + size_t pos = name.find_last_of('.'); - while (true) { - if (readdir_r(dir, &entry, &result) != 0) + if (pos == std::string::npos) continue; - if (result == NULL) - break; - - std::string filename = entry.d_name; + std::string extension = name.substr(pos); + std::transform(extension.begin(), extension.end(), extension.begin(), ::toupper); - if (!std::regex_match(filename, xmlFileRegex)) + if (extension != ".XML") continue; - __parseSchemaFile(dirPath + "/" + filename); + __parseSchemaFile(dirPath + "/" + name); } - closedir(dir); return true; } -- 2.7.4 From c0349646ee9452aa29ef81076bfed8df73ac23f0 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Mon, 24 Apr 2017 20:07:11 +0900 Subject: [PATCH 12/16] Update the URI format to be aligned with other context URIs Change-Id: I0458ab649109ff6e8fa3283e3a5b8c0d0159c7aa Signed-off-by: Mu-Woong Lee --- schema/sample.xml | 2 +- src/server/QueryChecker.cpp | 2 +- src/server/SchemaChecker.cpp | 2 +- src/server/SchemaLoader.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/schema/sample.xml b/schema/sample.xml index 6e67c38..d7e30ab 100644 --- a/schema/sample.xml +++ b/schema/sample.xml @@ -1,6 +1,6 @@ - + http://tizen.org/privilege/location http://tizen.org/privilege/internal/service diff --git a/src/server/QueryChecker.cpp b/src/server/QueryChecker.cpp index 20a8bed..b5658e9 100644 --- a/src/server/QueryChecker.cpp +++ b/src/server/QueryChecker.cpp @@ -30,7 +30,7 @@ QueryChecker::~QueryChecker() bool QueryChecker::validateUri(const std::string& uri) { - static std::regex uriRegex(URI_REGEX("contextstore"), std::regex::optimize); + static std::regex uriRegex(URI_REGEX("context\/record"), std::regex::optimize); if (!std::regex_match(uri, uriRegex)) { _E("Invalid parameter"); return false; diff --git a/src/server/SchemaChecker.cpp b/src/server/SchemaChecker.cpp index 3a7a165..ecc19cc 100644 --- a/src/server/SchemaChecker.cpp +++ b/src/server/SchemaChecker.cpp @@ -22,7 +22,7 @@ using namespace ctx; SchemaChecker::SchemaChecker() : - __uriRegex(URI_REGEX("contextstore"), std::regex::optimize), + __uriRegex(URI_REGEX("context\/record"), std::regex::optimize), __privilegeRegex(URI_REGEX("privilege"), std::regex::optimize), __columnNameRegex(COL_REGEX, std::regex::optimize) { diff --git a/src/server/SchemaLoader.cpp b/src/server/SchemaLoader.cpp index 0e513e4..69bcce7 100644 --- a/src/server/SchemaLoader.cpp +++ b/src/server/SchemaLoader.cpp @@ -29,7 +29,7 @@ - + http://tizen.org/privilege/healthinfo http://tizen.org/privilege/internal/service -- 2.7.4 From 946f53ecc00d2acdc34e802efeec8a805291a6eb Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Wed, 29 Mar 2017 21:29:02 +0900 Subject: [PATCH 13/16] Implement QueryChecker to prevent SQL injections Change-Id: If625674bd7710d3d769e28687e333fa6d9f5f4ac Signed-off-by: Mu-Woong Lee --- src/server/ContextStoreClient.cpp | 14 ++--- src/server/QueryChecker.cpp | 102 +++++++++++++++++++++++++++++++--- src/server/QueryChecker.h | 18 ++++-- src/server/SchemaChecker.cpp | 6 +- src/shared/ContextStoreTypesPrivate.h | 2 + 5 files changed, 116 insertions(+), 26 deletions(-) diff --git a/src/server/ContextStoreClient.cpp b/src/server/ContextStoreClient.cpp index 9985854..3727343 100644 --- a/src/server/ContextStoreClient.cpp +++ b/src/server/ContextStoreClient.cpp @@ -24,8 +24,6 @@ using namespace ctx; -static QueryChecker __queryChecker; - ContextStoreClient::ContextStoreClient(ServiceBase* hostService, const std::string& busName) : ClientBase(hostService, busName) { @@ -91,7 +89,7 @@ Store* ContextStoreClient::__getStore(const std::string& uri) { Store* store = NULL; - if (!__queryChecker.validateUri(uri)) + if (!QueryChecker::validateUri(uri)) throw static_cast(E_PARAM); if (isSystem()) { @@ -128,7 +126,7 @@ void ContextStoreClient::__insert(Store& store, MethodCall& methodCall) throw static_cast(E_PARAM); } - if (!__queryChecker.validateProjection(cols)) + if (!QueryChecker::validateColumns(cols)) throw static_cast(E_PARAM); std::vector> tuples = Tuple::buildFrom(vals); @@ -151,13 +149,13 @@ void ContextStoreClient::__retrieve(Store& store, MethodCall& methodCall) if (!projection || !selection || !sortOrder) throw static_cast(E_PARAM); - if (!__queryChecker.validateProjection(projection)) + if (!QueryChecker::validateProjection(projection)) throw static_cast(E_PARAM); - if (!__queryChecker.validateSelection(selection)) + if (!QueryChecker::validateSelection(selection)) throw static_cast(E_PARAM); - if (!__queryChecker.validateSortOrder(sortOrder)) + if (!QueryChecker::validateSortOrder(sortOrder)) throw static_cast(E_PARAM); std::vector> tuples; @@ -179,7 +177,7 @@ void ContextStoreClient::__remove(Store& store, MethodCall& methodCall) if (!selection) throw static_cast(E_PARAM); - if (!__queryChecker.validateSelection(selection)) + 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 index b5658e9..5c1172c 100644 --- a/src/server/QueryChecker.cpp +++ b/src/server/QueryChecker.cpp @@ -1,4 +1,3 @@ - /* * Copyright (c) 2017 Samsung Electronics Co., Ltd. * @@ -18,40 +17,125 @@ #include #include "QueryChecker.h" +#define COLUMN_REGEX R"~(^ *[A-Za-z]\w* *$)~" +#define AGGR_REGEX R"~(^ *[A-Za-z]+\([A-Za-z]\w*\) *$)~" +#define QUOTED_REGEX R"~(\'.*?\')~" +#define NUMBER_REGEX R"~(^ *\-?[0-9]+(\.[0-9]+)? *$)~" +#define ORDER_REGEX R"~( +[Aa]|([Dd][Ee])([Ss][Cc]) *$)~" + using namespace ctx; -QueryChecker::QueryChecker() +static bool __isColumnName(const std::string& column) +{ + static std::regex colRegex(COLUMN_REGEX, std::regex::optimize); + return std::regex_match(column, colRegex); +} + +static bool __isAggregation(const std::string& aggr) { + static std::regex aggrRegex(AGGR_REGEX, std::regex::optimize); + return std::regex_match(aggr, aggrRegex); } -QueryChecker::~QueryChecker() +static bool __isNumber(const std::string& number) +{ + static std::regex numberRegex(NUMBER_REGEX, std::regex::optimize); + return std::regex_match(number, numberRegex); +} + +QueryChecker::QueryChecker() { } bool QueryChecker::validateUri(const std::string& uri) { - static std::regex uriRegex(URI_REGEX("context\/record"), std::regex::optimize); - if (!std::regex_match(uri, uriRegex)) { - _E("Invalid parameter"); + static std::regex uriRegex(STORE_URI_REGEX, std::regex::optimize); + + if (!std::regex_match(uri, uriRegex)) return false; + + return true; +} + +bool QueryChecker::validateColumns(const std::string& columns) +{ + std::vector tokens = util::tokenizeString(columns, ","); + + for (auto& token : tokens) { + if (!__isColumnName(token)) return false; } + return true; } bool QueryChecker::validateProjection(const std::string& projection) { - // TODO + std::vector tokens = util::tokenizeString(projection, ","); + + for (auto& token : tokens) { + if (!__isColumnName(token) && !__isAggregation(token)) return false; + } + return true; } bool QueryChecker::validateSelection(const std::string& selection) { - // TODO + if (selection.empty()) + return true; + + static std::regex quotedStrRegex(QUOTED_REGEX, std::regex::optimize); + + std::string stripped = std::regex_replace(selection, quotedStrRegex, " "); + std::vector tokens = util::tokenizeString(stripped, " ()!<>="); + + for (auto& token : tokens) { + if (!__isColumnName(token) && !__isNumber(token)) return false; + } + + return true; +} + +bool QueryChecker::validateGrouping(const std::string& grouping) +{ + if (grouping.empty()) + return true; + + return validateColumns(grouping); +} + +bool QueryChecker::validateHaving(const std::string& having) +{ + if (having.empty()) + return true; + + std::vector tokens = util::tokenizeString(having, "!<>="); + + if (tokens.size() != 2) + return false; + + if (!__isAggregation(tokens[0])) + return false; + + if (!__isNumber(tokens[1])) + return false; + return true; } bool QueryChecker::validateSortOrder(const std::string& sortOrder) { - // TODO + if (sortOrder.empty()) + return true; + + static std::regex orderRegex(ORDER_REGEX, std::regex::optimize); + + std::vector tokens = util::tokenizeString(sortOrder, ","); + + for (auto& token : tokens) { + token = std::regex_replace(token, orderRegex, EMPTY_STR); + if (!__isColumnName(token) && !__isAggregation(token)) return false; + } + return true; } diff --git a/src/server/QueryChecker.h b/src/server/QueryChecker.h index eaaf932..43c80ec 100644 --- a/src/server/QueryChecker.h +++ b/src/server/QueryChecker.h @@ -23,16 +23,22 @@ namespace ctx { class QueryChecker { public: - QueryChecker(); - ~QueryChecker(); + static bool validateUri(const std::string& uri); + + static bool validateColumns(const std::string& columns); + + static bool validateProjection(const std::string& projection); - bool validateUri(const std::string& uri); + static bool validateSelection(const std::string& selection); - bool validateProjection(const std::string& projection); + static bool validateGrouping(const std::string& grouping); - bool validateSelection(const std::string& selection); + static bool validateHaving(const std::string& having); - bool validateSortOrder(const std::string& sortOrder); + static bool validateSortOrder(const std::string& sortOrder); + + private: + QueryChecker(); }; } diff --git a/src/server/SchemaChecker.cpp b/src/server/SchemaChecker.cpp index ecc19cc..f45797c 100644 --- a/src/server/SchemaChecker.cpp +++ b/src/server/SchemaChecker.cpp @@ -17,13 +17,13 @@ #include "Schema.h" #include "SchemaChecker.h" -#define COL_REGEX "^[A-Za-z]+\\w*$" +#define COL_REGEX "^[A-Za-z]\\w*$" using namespace ctx; SchemaChecker::SchemaChecker() : - __uriRegex(URI_REGEX("context\/record"), std::regex::optimize), - __privilegeRegex(URI_REGEX("privilege"), std::regex::optimize), + __uriRegex(STORE_URI_REGEX, std::regex::optimize), + __privilegeRegex(PRIVILEGE_REGEX, std::regex::optimize), __columnNameRegex(COL_REGEX, std::regex::optimize) { } diff --git a/src/shared/ContextStoreTypesPrivate.h b/src/shared/ContextStoreTypesPrivate.h index 3651bb8..a8601a7 100644 --- a/src/shared/ContextStoreTypesPrivate.h +++ b/src/shared/ContextStoreTypesPrivate.h @@ -71,5 +71,7 @@ #define DEFAULT_QUERY_LIMIT 10 #define URI_REGEX(CATEGORY) R"~(^http:\/\/[\w-]+(\.[\w-]+)*\/)~" CATEGORY R"~(\/[\w-]+(\.[\w-]+)*(\/[\w-]+(\.[\w-]+)*)*$)~" +#define STORE_URI_REGEX URI_REGEX("context\\/record") +#define PRIVILEGE_REGEX URI_REGEX("privilege") #endif -- 2.7.4 From eded089d0c8b30a67cd25c1a9dceb51942346633 Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 25 Apr 2017 12:22:19 +0900 Subject: [PATCH 14/16] client: remove the enum class DataType It is declared in Tuple.h now. Change-Id: I2b0c86e55f936a222020c7fce599fc925b802722 Signed-off-by: Mu-Woong Lee --- src/client/ContextStore.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/client/ContextStore.h b/src/client/ContextStore.h index 01b8458..a713392 100644 --- a/src/client/ContextStore.h +++ b/src/client/ContextStore.h @@ -23,13 +23,6 @@ namespace ctx { - enum class DataType { - UNKNOWN = 0, - INT64 = 1, - DOUBLE, - STRING - }; - struct ContextStoreSearchQuery { std::string projection; std::string selection; -- 2.7.4 From 9064cbfa401bbda7b63908330c2af6b689f0953e Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 25 Apr 2017 17:32:09 +0900 Subject: [PATCH 15/16] client: merge PlatformManagedStore into ContextStore and rename it to StoreProxy ContextStore does not support other types of stores except the platform-managed one. Thus the class hierarchy of ContextStore & PlatformManagedStore classes are not necessary. Change-Id: Ifd7b69624df98bd96be1b641b51f5dce87f65672 Signed-off-by: Mu-Woong Lee --- src/client/ContextStore.cpp | 80 ---------------------- src/client/ContextStore.h | 53 -------------- .../{PlatformManagedStore.cpp => StoreProxy.cpp} | 61 +++++++++++++---- .../{PlatformManagedStore.h => StoreProxy.h} | 28 +++++--- ...ntextStoreManager.cpp => StoreProxyManager.cpp} | 22 +++--- .../{ContextStoreManager.h => StoreProxyManager.h} | 16 ++--- src/client/context_store.cpp | 12 ++-- 7 files changed, 92 insertions(+), 180 deletions(-) delete mode 100644 src/client/ContextStore.cpp delete mode 100644 src/client/ContextStore.h rename src/client/{PlatformManagedStore.cpp => StoreProxy.cpp} (50%) rename src/client/{PlatformManagedStore.h => StoreProxy.h} (66%) rename src/client/{ContextStoreManager.cpp => StoreProxyManager.cpp} (70%) rename src/client/{ContextStoreManager.h => StoreProxyManager.h} (72%) diff --git a/src/client/ContextStore.cpp b/src/client/ContextStore.cpp deleted file mode 100644 index 9539b27..0000000 --- a/src/client/ContextStore.cpp +++ /dev/null @@ -1,80 +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 -#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() -{ -} - -ContextStore::~ContextStore() -{ -} - -int ContextStore::insert(const std::string& columns, std::shared_ptr record) -{ - return E_SUPPORT; -} - -int ContextStore::insert(const std::string& columns, std::vector>& records) -{ - return E_SUPPORT; -} - -int ContextStore::retrieve(const ContextStoreSearchQuery& query, std::vector>* records) -{ - return E_SUPPORT; -} - -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 (const std::exception& e) { - _E("%s", e.what()); - } - - return type; -} diff --git a/src/client/ContextStore.h b/src/client/ContextStore.h deleted file mode 100644 index a713392..0000000 --- a/src/client/ContextStore.h +++ /dev/null @@ -1,53 +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_H__ -#define __CONTEXT_STORE_H__ - -#include -#include -#include - -namespace ctx { - - 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(); - - 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); - - protected: - ContextStore(); - - std::string __columns; - }; - -} - -#endif /* __CONTEXT_STORE_H__ */ diff --git a/src/client/PlatformManagedStore.cpp b/src/client/StoreProxy.cpp similarity index 50% rename from src/client/PlatformManagedStore.cpp rename to src/client/StoreProxy.cpp index f0ae6be..4324244 100644 --- a/src/client/PlatformManagedStore.cpp +++ b/src/client/StoreProxy.cpp @@ -14,24 +14,34 @@ * limitations under the License. */ -#include "PlatformManagedStore.h" +#include +#include +#include "StoreProxy.h" using namespace ctx; -PlatformManagedStore::PlatformManagedStore(ServiceProxy* proxy) : - __proxy(proxy) +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) { } -PlatformManagedStore::~PlatformManagedStore() +StoreProxy::StoreProxy(ServiceProxy* serviceProxy) : + __serviceProxy(serviceProxy) { } -int PlatformManagedStore::init(const std::string& uri) +StoreProxy::~StoreProxy() +{ +} + +int StoreProxy::init(const std::string& uri) { __uri = uri; GVariant* outParam = NULL; - int error = __proxy->call(METHOD_GET_ACCESS, g_variant_new("(s)", uri.c_str()), &outParam); + int error = __serviceProxy->call(METHOD_GET_ACCESS, g_variant_new("(s)", uri.c_str()), &outParam); IF_FAIL_RETURN(error == E_NONE, error); const char* columns = NULL; @@ -44,17 +54,17 @@ int PlatformManagedStore::init(const std::string& uri) return E_NONE; } -int PlatformManagedStore::insert(const std::string& columns, std::shared_ptr record) +int StoreProxy::insert(const std::string& columns, std::shared_ptr record) { if (columns.empty() || record == NULL) { return E_PARAM; } GVariant* param = g_variant_new("(ssv)", __uri.c_str(), columns.c_str(), Tuple::toGVariant(record)); - return __proxy->call(METHOD_INSERT, param); + return __serviceProxy->call(METHOD_INSERT, param); } -int PlatformManagedStore::insert(const std::string& columns, std::vector>& records) +int StoreProxy::insert(const std::string& columns, std::vector>& records) { if (columns.empty() || records.empty()) { records.clear(); @@ -62,10 +72,10 @@ int PlatformManagedStore::insert(const std::string& columns, std::vectorcall(METHOD_INSERT, param); + return __serviceProxy->call(METHOD_INSERT, param); } -int PlatformManagedStore::retrieve(const ContextStoreSearchQuery& query, std::vector>* records) +int StoreProxy::retrieve(const ContextStoreSearchQuery& query, std::vector>* records) { IF_FAIL_RETURN(!query.projection.empty() && records, E_PARAM); @@ -74,7 +84,7 @@ int PlatformManagedStore::retrieve(const ContextStoreSearchQuery& query, std::ve query.sortOrder.c_str(), static_cast(query.limit)); GVariant* outParam = NULL; - int error = __proxy->call(METHOD_RETRIEVE, param, &outParam); + int error = __serviceProxy->call(METHOD_RETRIEVE, param, &outParam); IF_FAIL_RETURN_TAG(error == E_NONE, error, _E, "%s", CTX_ERROR_STR(error)); GVariant* vals = NULL; @@ -87,7 +97,30 @@ int PlatformManagedStore::retrieve(const ContextStoreSearchQuery& query, std::ve return error; } -int PlatformManagedStore::remove(const std::string& selection) +int StoreProxy::remove(const std::string& selection) +{ + return __serviceProxy->call(METHOD_REMOVE, g_variant_new("(ss)", __uri.c_str(), selection.c_str())); +} + +DataType StoreProxy::getColumnType(const std::string& columnName) { - return __proxy->call(METHOD_REMOVE, g_variant_new("(ss)", __uri.c_str(), selection.c_str())); + 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 (const std::exception& e) { + _E("%s", e.what()); + } + + return type; } diff --git a/src/client/PlatformManagedStore.h b/src/client/StoreProxy.h similarity index 66% rename from src/client/PlatformManagedStore.h rename to src/client/StoreProxy.h index a47943d..5bec474 100644 --- a/src/client/PlatformManagedStore.h +++ b/src/client/StoreProxy.h @@ -14,21 +14,30 @@ * limitations under the License. */ -#ifndef __CONTEXT_PLATFORM_MANAGED_STORE_H__ -#define __CONTEXT_PLATFORM_MANAGED_STORE_H__ +#ifndef __CONTEXT_STORE_PROXY_H__ +#define __CONTEXT_STORE_PROXY_H__ +#include +#include #include #include #include #include -#include "ContextStore.h" namespace ctx { - class PlatformManagedStore : public ContextStore { + 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 StoreProxy { public: - PlatformManagedStore(ServiceProxy* proxy); - ~PlatformManagedStore(); + StoreProxy(ServiceProxy* serviceProxy); + ~StoreProxy(); int init(const std::string& uri); @@ -37,11 +46,14 @@ namespace ctx { int retrieve(const ContextStoreSearchQuery& query, std::vector>* records); int remove(const std::string& selection); + DataType getColumnType(const std::string& columnName); + private: - ServiceProxy* __proxy; + ServiceProxy* __serviceProxy; std::string __uri; + std::string __columns; }; } -#endif /* __CONTEXT_STORE_PLATFORM_MANAGED_STORE_H__ */ +#endif /* __CONTEXT_STORE_PROXY_H__ */ diff --git a/src/client/ContextStoreManager.cpp b/src/client/StoreProxyManager.cpp similarity index 70% rename from src/client/ContextStoreManager.cpp rename to src/client/StoreProxyManager.cpp index 9f135a1..cf8e02a 100644 --- a/src/client/ContextStoreManager.cpp +++ b/src/client/StoreProxyManager.cpp @@ -16,8 +16,8 @@ #include #include -#include "PlatformManagedStore.h" -#include "ContextStoreManager.h" +#include "StoreProxy.h" +#include "StoreProxyManager.h" using namespace ctx; @@ -27,9 +27,9 @@ static ServiceProxy* __getServiceProxy() return &proxy; } -static ContextStore* __createPlatformManagedStore(const std::string& uri, int* error) +static StoreProxy* __createStoreProxy(const std::string& uri, int* error) { - PlatformManagedStore* store = new(std::nothrow) PlatformManagedStore(__getServiceProxy()); + StoreProxy* store = new(std::nothrow) StoreProxy(__getServiceProxy()); if (!store) { *error = E_NO_MEM; @@ -48,35 +48,35 @@ static ContextStore* __createPlatformManagedStore(const std::string& uri, int* e return store; } -ContextStoreManager::ContextStoreManager() +StoreProxyManager::StoreProxyManager() { } -ContextStoreManager::~ContextStoreManager() +StoreProxyManager::~StoreProxyManager() { } -int ContextStoreManager::getStore(const std::string& uri, ContextStore** store) +int StoreProxyManager::getStore(const std::string& uri, StoreProxy** store) { IF_FAIL_RETURN(store, E_PARAM); _D("Getting the store %s", uri.c_str()); int error = E_NONE; - ContextStore* _store = NULL; + StoreProxy* _store = NULL; - _store = __createPlatformManagedStore(uri, &error); + _store = __createStoreProxy(uri, &error); IF_FAIL_RETURN(_store, error); *store = _store; return E_NONE; } -int ContextStoreManager::reloadUser() +int StoreProxyManager::reloadUser() { return __getServiceProxy()->call(METHOD_RELOAD_USER, NULL); } -int ContextStoreManager::reloadSystem() +int StoreProxyManager::reloadSystem() { return __getServiceProxy()->call(METHOD_RELOAD_SYSTEM, NULL); } diff --git a/src/client/ContextStoreManager.h b/src/client/StoreProxyManager.h similarity index 72% rename from src/client/ContextStoreManager.h rename to src/client/StoreProxyManager.h index 1c978d2..ceed080 100644 --- a/src/client/ContextStoreManager.h +++ b/src/client/StoreProxyManager.h @@ -14,22 +14,22 @@ * limitations under the License. */ -#ifndef __CONTEXT_STORE_MANAGER_H__ -#define __CONTEXT_STORE_MANAGER_H__ +#ifndef __CONTEXT_STORE_PROXY_MANAGER_H__ +#define __CONTEXT_STORE_PROXY_MANAGER_H__ #include #include namespace ctx { - class ContextStore; + class StoreProxy; - class ContextStoreManager { + class StoreProxyManager { public: - ContextStoreManager(); - ~ContextStoreManager(); + StoreProxyManager(); + ~StoreProxyManager(); - int getStore(const std::string& uri, ContextStore** contextStore); + int getStore(const std::string& uri, StoreProxy** contextStore); int reloadUser(); @@ -38,4 +38,4 @@ namespace ctx { } -#endif /* __CONTEXT_STORE_MANAGER_H__ */ +#endif /* __CONTEXT_STORE_PROXY_MANAGER_H__ */ diff --git a/src/client/context_store.cpp b/src/client/context_store.cpp index 9aeffe5..2a8c635 100644 --- a/src/client/context_store.cpp +++ b/src/client/context_store.cpp @@ -19,8 +19,8 @@ #include #include #include -#include "ContextStore.h" -#include "ContextStoreManager.h" +#include "StoreProxy.h" +#include "StoreProxyManager.h" #define COMMA "," @@ -28,7 +28,7 @@ using namespace ctx; typedef struct _ctx_store_handle_s { std::string uri; - ContextStore* proxy; + StoreProxy* proxy; } ctx_store_handle_s; union DataValue { @@ -47,14 +47,14 @@ typedef struct _ctx_store_cursor_s { std::vector> tuples; } ctx_store_cursor_s; -static ContextStoreManager __storeManager; +static StoreProxyManager __storeProxyManager; 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); + StoreProxy* proxy; + int error = __storeProxyManager.getStore(uri, &proxy); IF_FAIL_RETURN(error == E_NONE, error); ctx_store_h handle = new(std::nothrow) ctx_store_handle_s; -- 2.7.4 From a93fc19b0610eff8c8ea266d225e591ba461248d Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Tue, 25 Apr 2017 19:31:01 +0900 Subject: [PATCH 16/16] server: add the record insertion API for other services in the context framework Change-Id: I79ede86b7164e3b14a79ed9573f32eab92094db1 Signed-off-by: Mu-Woong Lee --- .../{ContextStoreSideGate.h => ContextStore.h} | 20 ++- .../{ContextStoreSideGate.cpp => ContextStore.cpp} | 22 +-- src/server/ContextStore.cpp | 151 +++++++++++++++++++++ src/server/ContextStoreService.cpp | 4 +- src/server/ContextStoreSideGate.cpp | 50 ------- src/server/Store.cpp | 9 ++ src/server/Store.h | 2 + 7 files changed, 188 insertions(+), 70 deletions(-) rename include/private/{ContextStoreSideGate.h => ContextStore.h} (60%) rename src/server-dummy/{ContextStoreSideGate.cpp => ContextStore.cpp} (54%) create mode 100644 src/server/ContextStore.cpp delete mode 100644 src/server/ContextStoreSideGate.cpp diff --git a/include/private/ContextStoreSideGate.h b/include/private/ContextStore.h similarity index 60% rename from include/private/ContextStoreSideGate.h rename to include/private/ContextStore.h index 777f6c5..947d675 100644 --- a/include/private/ContextStoreSideGate.h +++ b/include/private/ContextStore.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef __CONTEXT_STORE_SIDE_GATE_H__ -#define __CONTEXT_STORE_SIDE_GATE_H__ +#ifndef __CONTEXT_STORE_H__ +#define __CONTEXT_STORE_H__ #include @@ -23,17 +23,23 @@ namespace ctx { class ContextStoreService; - class EXPORT_API ContextStoreSideGate { + class EXPORT_API ContextStore { public: - ~ContextStoreSideGate(); + ~ContextStore(); + + int insert(const std::string& columns, std::shared_ptr tuple); int insert(const std::string& columns, std::vector>& tuples); - static ContextStoreSideGate getUserStore(const std::string& uri); - static ContextStoreSideGate getSystemStore(const std::string& uri); + // This tries to get the user-level store corresponding to the uri first, + // but if no store exists, it goes down to get the system-level store of the given uri. + static ContextStore getUserStore(const std::string& uri); + + // This directly goes to the system level and gets the system-level store of the given uri. + static ContextStore getSystemStore(const std::string& uri); private: - ContextStoreSideGate(const std::string& uri, bool isSystem); + ContextStore(const std::string& uri, bool isSystem); std::string __uri; bool __isSystem; diff --git a/src/server-dummy/ContextStoreSideGate.cpp b/src/server-dummy/ContextStore.cpp similarity index 54% rename from src/server-dummy/ContextStoreSideGate.cpp rename to src/server-dummy/ContextStore.cpp index 0240651..6b8e6b7 100644 --- a/src/server-dummy/ContextStoreSideGate.cpp +++ b/src/server-dummy/ContextStore.cpp @@ -15,35 +15,35 @@ */ #include -#include +#include using namespace ctx; -ContextStoreService* ContextStoreSideGate::__hostService = NULL; +ContextStoreService* ContextStore::__hostService = NULL; -ContextStoreSideGate::ContextStoreSideGate(const std::string& uri, bool isSystem) : +ContextStore::ContextStore(const std::string& uri, bool isSystem) : __uri(uri), __isSystem(isSystem) { } -ContextStoreSideGate::~ContextStoreSideGate() +ContextStore::~ContextStore() { } -int ContextStoreSideGate::insert(const std::string& columns, std::vector>& tuples) +int ContextStore::insert(const std::string& columns, std::vector>& tuples) { return E_SUPPORT; } -ContextStoreSideGate ContextStoreSideGate::getUserStore(const std::string& uri) +ContextStore ContextStore::getUserStore(const std::string& uri) { - ContextStoreSideGate sideGate(uri, false); - return sideGate; + ContextStore store(uri, false); + return store; } -ContextStoreSideGate ContextStoreSideGate::getSystemStore(const std::string& uri) +ContextStore ContextStore::getSystemStore(const std::string& uri) { - ContextStoreSideGate sideGate(uri, true); - return sideGate; + ContextStore store(uri, true); + return store; } diff --git a/src/server/ContextStore.cpp b/src/server/ContextStore.cpp new file mode 100644 index 0000000..fdec8e6 --- /dev/null +++ b/src/server/ContextStore.cpp @@ -0,0 +1,151 @@ +/* + * 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 "StoreManager.h" +#include "Store.h" + +#define ROOT_UID 0 + +using namespace ctx; + + +class StoreTask { +private: + ContextStoreService* __hostService; + std::string __uri; + bool __isSystem; + +protected: + StoreTask(ContextStoreService* svc, const std::string& uri, bool isSystem) : + __hostService(svc), + __uri(uri), + __isSystem(isSystem) + { + } + + Store* getStore() + { + StoreManager& manager = __hostService->getStoreManager(); + + if (__isSystem) + return manager.getSystemStore(__uri); + else if (__hostService->getActiveUser() != ROOT_UID) + return manager.getUserStore(__uri); + + _W("No active user"); + return NULL; + } + +public: + virtual ~StoreTask() {} + virtual void run() = 0; +}; + + +class InsertionTask : public StoreTask { +private: + std::string __columns; + std::vector> __tuples; + +public: + InsertionTask(ContextStoreService* svc, const std::string& uri, bool isSystem, + const std::string& columns, std::vector>& tuples) : + StoreTask(svc, uri, isSystem), + __columns(columns), + __tuples(tuples) + { + } + + void run() + { + Store* store = getStore(); + IF_FAIL_VOID_TAG(store, _E, "Failed to find the store"); + + int err = store->insert(__columns, __tuples); + IF_FAIL_VOID_TAG(err == E_NONE, _E, "Execution failed"); + } +}; + + +static gboolean __runTask(gpointer data) +{ + StoreTask* task = static_cast(data); + task->run(); + delete task; + return G_SOURCE_REMOVE; +} + +static bool __pushTask(ContextStoreService* hostService, StoreTask* task) +{ + GMainContext* mainContext = hostService->getMainContext(); + IF_FAIL_RETURN_TAG(mainContext, false, _E, "Service not ready"); + + GSource* gSrc = g_idle_source_new(); + IF_FAIL_RETURN_TAG(gSrc, false, _E, E_STR_ALLOC); + + g_source_set_callback(gSrc, __runTask, task, NULL); + g_source_attach(gSrc, mainContext); + g_source_unref(gSrc); + + return true; +} + + +ContextStoreService* ContextStore::__hostService = NULL; + +ContextStore::ContextStore(const std::string& uri, bool isSystem) : + __uri(uri), + __isSystem(isSystem) +{ +} + +ContextStore::~ContextStore() +{ +} + +int ContextStore::insert(const std::string& columns, std::shared_ptr tuple) +{ + std::vector> tuples; + tuples.push_back(tuple); + return insert(columns, tuples); +} + +int ContextStore::insert(const std::string& columns, std::vector>& tuples) +{ + _D("[%s] %s, #records = %d", __isSystem ? "system" : "user", __uri.c_str(), tuples.size()); + + StoreTask* task = new InsertionTask(__hostService, __uri, __isSystem, columns, tuples); + + if (__pushTask(__hostService, task)) + return E_NONE; + + delete task; + return E_FAILED; +} + +ContextStore ContextStore::getUserStore(const std::string& uri) +{ + ContextStore store(uri, false); + return store; +} + +ContextStore ContextStore::getSystemStore(const std::string& uri) +{ + ContextStore store(uri, true); + return store; +} diff --git a/src/server/ContextStoreService.cpp b/src/server/ContextStoreService.cpp index 2c138e8..35c73a0 100644 --- a/src/server/ContextStoreService.cpp +++ b/src/server/ContextStoreService.cpp @@ -15,7 +15,7 @@ */ #include -#include +#include #include #include "ContextStoreClient.h" #include "StoreManager.h" @@ -28,7 +28,7 @@ ContextStoreService::ContextStoreService(GDBusConnection* conn) : ServiceBase(conn, CTX_CONTEXT_STORE, CTX_CONTEXT_STORE_SPEC), __storeManager(NULL) { - ContextStoreSideGate::__hostService = this; + ContextStore::__hostService = this; } ContextStoreService::~ContextStoreService() diff --git a/src/server/ContextStoreSideGate.cpp b/src/server/ContextStoreSideGate.cpp deleted file mode 100644 index 415087b..0000000 --- a/src/server/ContextStoreSideGate.cpp +++ /dev/null @@ -1,50 +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; - -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/Store.cpp b/src/server/Store.cpp index a7ff134..d05d3c8 100644 --- a/src/server/Store.cpp +++ b/src/server/Store.cpp @@ -56,6 +56,15 @@ int Store::insert(ContextStoreClient& client, const std::string& columns, std::v return error; } +int Store::insert(const std::string& columns, std::vector>& tuples) +{ + _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; + 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) diff --git a/src/server/Store.h b/src/server/Store.h index d2edfc6..42304f4 100644 --- a/src/server/Store.h +++ b/src/server/Store.h @@ -49,6 +49,8 @@ namespace ctx { int insert(ContextStoreClient& client, const std::string& columns, std::vector>& tuples); + int insert(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, -- 2.7.4