+/*
+ * 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 <ContextStoreService.h>
+#include <ContextStore.h>
+#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<std::shared_ptr<Tuple>> __tuples;
+
+public:
+ InsertionTask(ContextStoreService* svc, const std::string& uri, bool isSystem,
+ const std::string& columns, std::vector<std::shared_ptr<Tuple>>& 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<StoreTask*>(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> tuple)
+{
+ std::vector<std::shared_ptr<Tuple>> tuples;
+ tuples.push_back(tuple);
+ return insert(columns, tuples);
+}
+
+int ContextStore::insert(const std::string& columns, std::vector<std::shared_ptr<Tuple>>& 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;
+}