Implement ContextStoreService & ContextStoreClient 10/118910/2
authorMu-Woong Lee <muwoong.lee@samsung.com>
Tue, 14 Mar 2017 11:58:23 +0000 (20:58 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Tue, 14 Mar 2017 13:10:10 +0000 (06:10 -0700)
Change-Id: I6cfe0a430aa6abbebf5ef86ee3b1198990a67f1f
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
include/ContextStoreService.h
src/server/ContextStoreClient.cpp
src/server/ContextStoreClient.h
src/server/ContextStoreService.cpp

index ca384dc..828424e 100644 (file)
@@ -24,6 +24,8 @@
 
 namespace ctx {
 
+       class StoreManager;
+
        class EXPORT_API ContextStoreService : public ServiceBase {
        public:
                ContextStoreService(GDBusConnection* conn);
@@ -31,6 +33,8 @@ namespace ctx {
 
                bool isUserService();
 
+               StoreManager& getStoreManager();
+
        protected:
                bool prepare();
                void cleanup();
@@ -39,6 +43,9 @@ namespace ctx {
 
                void onUserActivated();
                void onUserDeactivated();
+
+       private:
+               StoreManager* __storeManager;
        };
 
 }
index 6f64c7f..3d72f19 100644 (file)
  * limitations under the License.
  */
 
-#include <ServiceBase.h>
+#include <Tuple.h>
 #include <MethodCall.h>
+#include "ContextStoreService.h"
+#include "Store.h"
+#include "StoreManager.h"
 #include "ContextStoreClient.h"
 
 using namespace ctx;
@@ -31,10 +34,129 @@ ContextStoreClient::~ContextStoreClient()
 
 void ContextStoreClient::onMethodCalled(MethodCall* methodCall)
 {
-       // 'methodCall' should be deleted.
+       try {
+               __verifyUid(methodCall->getUid());
+               std::string uri = __getStoreUri(methodCall->getParam());
+               Store* store = __getStore(uri);
+
+               if (methodCall->getMethodName() == METHOD_GET_ACCESS) {
+                       __getAccess(*store, *methodCall);
+               } else if (methodCall->getMethodName() == METHOD_INSERT) {
+                       __insert(*store, *methodCall);
+               } else if (methodCall->getMethodName() == METHOD_RETRIEVE) {
+                       __retrieve(*store, *methodCall);
+               } else if (methodCall->getMethodName() == METHOD_REMOVE) {
+                       __remove(*store, *methodCall);
+               }
+       } catch (int error) {
+               methodCall->reply(error);
+       }
+
        delete methodCall;
 }
 
 void ContextStoreClient::onDisconnected()
 {
 }
+
+void ContextStoreClient::__verifyUid(uid_t uid)
+{
+       if (!isSystemUid(uid) && uid != ServiceBase::getActiveUser()) {
+               _E("Invalid Uid: %u != %u (ActiveUser)", uid, ServiceBase::getActiveUser());
+               throw static_cast<int>(E_ACCESS);
+       }
+}
+
+std::string ContextStoreClient::__getStoreUri(GVariant* param)
+{
+       const char* uri = NULL;
+       g_variant_get_child(param, IDX_URI, "&s", &uri);
+       if (!uri) {
+               _E("Invalid URI");
+               throw static_cast<int>(E_PARAM);
+       }
+       return uri;
+}
+
+StoreManager& ContextStoreClient::__getStoreManager()
+{
+       return static_cast<ContextStoreService&>(getHostService()).getStoreManager();
+}
+
+Store* ContextStoreClient::__getStore(const std::string& uri)
+{
+       Store* store = NULL;
+
+       if (isSystem()) {
+               store = __getStoreManager().getSystemStore(uri);
+       } else {
+               store = __getStoreManager().getUserStore(uri);
+       }
+
+       if (!store) {
+               _W("Getting store failed");
+               throw static_cast<int>(E_PARAM);
+       }
+
+       return store;
+}
+
+void ContextStoreClient::__getAccess(Store& store, MethodCall& methodCall)
+{
+       if (!store.permitted(*this))
+               throw static_cast<int>(E_ACCESS);
+
+       methodCall.reply(g_variant_new("(s)", store.getPath().c_str()));
+}
+
+void ContextStoreClient::__insert(Store& store, MethodCall& methodCall)
+{
+       const char* uri = NULL;
+       const char* cols = NULL;
+       GVariant* vals = NULL;
+
+       g_variant_get(methodCall.getParam(), "(&s&sv)", &uri, &cols, &vals);
+       if (!cols || !vals) {
+               if (vals) g_variant_unref(vals);
+               throw static_cast<int>(E_PARAM);
+       }
+
+       std::vector<Tuple*> tuples = Tuple::buildFrom(vals);
+       if (tuples.empty()) {
+               throw static_cast<int>(E_PARAM);
+       }
+
+       methodCall.reply(store.insert(*this, cols, tuples));
+}
+
+void ContextStoreClient::__retrieve(Store& store, MethodCall& methodCall)
+{
+       const char* uri = NULL;
+       const char* projection = NULL;
+       const char* selection = NULL;
+       const char* sortOrder = NULL;
+       uint32_t limit = 0;
+
+       g_variant_get(methodCall.getParam(), "(&s&s&s&su)", &uri, &projection, &selection, &sortOrder, &limit);
+       if (!projection || !selection || !sortOrder)
+               throw static_cast<int>(E_PARAM);
+
+       std::vector<Tuple*> tuples;
+       int error = store.retrieve(*this, projection, selection, sortOrder, limit, &tuples);
+       if (error != E_NONE)
+               throw error;
+
+       methodCall.reply(g_variant_new("(v)", Tuple::toGVariant(tuples)));
+}
+
+void ContextStoreClient::__remove(Store& store, MethodCall& methodCall)
+{
+       const char* uri = NULL;
+       const char* selection = NULL;
+
+       g_variant_get(methodCall.getParam(), "(&s&s)", &uri, &selection);
+       if (!selection)
+               throw static_cast<int>(E_PARAM);
+
+       methodCall.reply(store.remove(*this, selection));
+}
index 0f51a77..a106acd 100644 (file)
@@ -21,6 +21,9 @@
 
 namespace ctx {
 
+       class StoreManager;
+       class Store;
+
        class ContextStoreClient : public ClientBase {
        public:
                ContextStoreClient(ServiceBase* hostService, const std::string& busName);
@@ -28,6 +31,17 @@ namespace ctx {
 
                void onMethodCalled(MethodCall* methodCall);
                void onDisconnected();
+
+       private:
+               void __verifyUid(uid_t uid);
+               std::string __getStoreUri(GVariant* param);
+               StoreManager& __getStoreManager();
+               Store* __getStore(const std::string& uri);
+
+               void __getAccess(Store& store, MethodCall& methodCall);
+               void __insert(Store& store, MethodCall& methodCall);
+               void __retrieve(Store& store, MethodCall& methodCall);
+               void __remove(Store& store, MethodCall& methodCall);
        };
 
 }
index c8dce21..e4162e1 100644 (file)
 #include <ContextStoreTypesPrivate.h>
 #include <ContextStoreService.h>
 #include "ContextStoreClient.h"
+#include "StoreManager.h"
+#include "DatabaseManager.h"
+#include "SchemaLoader.h"
 
 using namespace ctx;
 
 ContextStoreService::ContextStoreService(GDBusConnection* conn) :
-       ServiceBase(conn, CTX_CONTEXT_STORE, CTX_CONTEXT_STORE_SPEC)
+       ServiceBase(conn, CTX_CONTEXT_STORE, CTX_CONTEXT_STORE_SPEC),
+       __storeManager(NULL)
 {
 }
 
@@ -36,12 +40,21 @@ bool ContextStoreService::isUserService()
 
 bool ContextStoreService::prepare()
 {
-       /* Service-specific initialization tasks */
+       if (!DatabaseManager::openSystem())
+               return false;
+
+       SystemSchemaLoader schemaLoader;
+       schemaLoader.load();
        return true;
 }
 
 void ContextStoreService::cleanup()
 {
+       delete __storeManager;
+       __storeManager = NULL;
+
+       DatabaseManager::closeUser();
+       DatabaseManager::closeSystem();
 }
 
 ClientBase* ContextStoreService::createClient(const std::string& busName)
@@ -51,8 +64,29 @@ ClientBase* ContextStoreService::createClient(const std::string& busName)
 
 void ContextStoreService::onUserActivated()
 {
+       if (!DatabaseManager::openUser(getActiveUser()))
+               return;
+
+       UserSchemaLoader schemaLoader;
+       schemaLoader.load();
 }
 
 void ContextStoreService::onUserDeactivated()
 {
+       DatabaseManager::closeUser();
+}
+
+StoreManager& ContextStoreService::getStoreManager()
+{
+       if (__storeManager)
+               return *__storeManager;
+
+       __storeManager = new(std::nothrow) StoreManager();
+
+       while (__storeManager == NULL) {
+               _W("Memory allocation failed");
+               __storeManager = new(std::nothrow) StoreManager();
+       }
+
+       return *__storeManager;
 }