--- /dev/null
+// Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/db_manager.h"
+
+#include <string>
+#include <memory>
+#include <vector>
+
+#include "common/capability.h"
+#include "common/sql_connection.h"
+#include "common/sql_statement.h"
+#include "common/sqlite_connection.h"
+#include "common/utils/logging.h"
+
+namespace {
+
+const char kDBPath[] = "/run/capmgr/capmgr.db";
+const char kQueryInitDevicesTable[] =
+ "CREATE TABLE IF NOT EXISTS devices (\n"
+ " device_id TEXT,\n"
+ " address TEXT,\n"
+ " model_name TEXT,\n"
+ " device_name TEXT,\n"
+ " platform_ver TEXT,\n"
+ " profile TEXT,\n"
+ " sw_ver TEXT,\n"
+ " PRIMARY KEY (device_id))";
+const char kQueryInitCapsTable[] =
+ "CREATE TABLE IF NOT EXISTS capabilities (\n"
+ " device_id TEXT,\n"
+ " operation TEXT,\n"
+ " uri TEXT,\n"
+ " mime TEXT,\n"
+ " appid TEXT,\n"
+ " pkgid TEXT,\n"
+ " PRIMARY KEY (device_id, operation, uri, mime, appid),\n"
+ " FOREIGN KEY (device_id)\n"
+ " REFERENCES devices (device_id) ON DELETE CASCADE)";
+const char kQueryInsertDev[] =
+ "INSERT INTO devices (device_id, address, model_name, device_name,"
+ " platform_ver, profile, sw_ver) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?)";
+const char kQueryDeleteDev[] =
+ "DELETE FROM devices WHERE device_id=?";
+const char kQueryInsertCap[] =
+ "INSERT INTO capabilities (device_id, operation, uri, mime, appid, pkgid) "
+ "VALUES (?, ?, ?, ?, ?, ?)";
+const char kQueryDeleteCap[] =
+ "DELETE FROM capabilities WHERE device_id=? AND operation=? AND uri=? AND "
+ " mime=? AND appid=?";
+
+} // namespace
+
+namespace capmgr {
+
+bool DBManager::InsertDevice(const RemoteDevice& device) {
+ auto guard = Instance().sql_conn_->GetTransactionGuard();
+ std::shared_ptr<SQLStatement> stmt = Instance().sql_conn_->PrepareStatement(
+ kQueryInsertDev);
+ if (!stmt) {
+ LOG(ERROR) << "Failed to prepare statement";
+ return false;
+ }
+
+ int idx = 1;
+ if (!stmt->BindString(idx++, device.device_id()))
+ return false;
+ if (!stmt->BindString(idx++, device.address()))
+ return false;
+ if (!stmt->BindString(idx++, device.model_name()))
+ return false;
+ if (!stmt->BindString(idx++, device.device_name()))
+ return false;
+ if (!stmt->BindString(idx++, device.platform_ver()))
+ return false;
+ if (!stmt->BindString(idx++, device.profile()))
+ return false;
+ if (!stmt->BindString(idx++, device.sw_ver()))
+ return false;
+
+ if (stmt->Step() != SQLStatement::StepResult::DONE) {
+ LOG(ERROR) << "Failed to insert device info into db";
+ return false;
+ }
+
+ return true;
+}
+
+bool DBManager::DeleteDevice(const RemoteDevice& device) {
+ auto guard = Instance().sql_conn_->GetTransactionGuard();
+ std::shared_ptr<SQLStatement> stmt = Instance().sql_conn_->PrepareStatement(
+ kQueryDeleteDev);
+ if (!stmt) {
+ LOG(ERROR) << "Failed to prepare statement";
+ return false;
+ }
+
+ if (!stmt->BindString(1, device.device_id()))
+ return false;
+
+ if (stmt->Step() != SQLStatement::StepResult::DONE) {
+ LOG(ERROR) << "Failed to delete device info from db";
+ return false;
+ }
+
+ return true;
+}
+
+bool DBManager::InsertCapability(const std::string& device_id,
+ const Capability& cap) {
+ auto guard = Instance().sql_conn_->GetTransactionGuard();
+ std::shared_ptr<SQLStatement> stmt = Instance().sql_conn_->PrepareStatement(
+ kQueryInsertCap);
+ if (!stmt) {
+ LOG(ERROR) << "Failed to prepare statement";
+ return false;
+ }
+
+ int idx = 1;
+ if (!stmt->BindString(idx++, device_id))
+ return false;
+ if (!stmt->BindString(idx++, cap.operation()))
+ return false;
+ if (!stmt->BindString(idx++, cap.uri()))
+ return false;
+ if (!stmt->BindString(idx++, cap.mime()))
+ return false;
+ if (!stmt->BindString(idx++, cap.appid()))
+ return false;
+ if (!stmt->BindString(idx++, cap.pkgid()))
+ return false;
+
+ if (stmt->Step() != SQLStatement::StepResult::DONE) {
+ LOG(ERROR) << "Failed to add capability to db";
+ return false;
+ }
+
+ return true;
+}
+
+bool DBManager::InsertCapabilities(const std::string& device_id,
+ const std::vector<Capability>& caps) {
+ auto guard = Instance().sql_conn_->GetTransactionGuard();
+ std::shared_ptr<SQLStatement> stmt = Instance().sql_conn_->PrepareStatement(
+ kQueryInsertCap);
+
+ for (const auto& cap : caps) {
+ int idx = 1;
+ if (!stmt->BindString(idx++, device_id))
+ return false;
+ if (!stmt->BindString(idx++, cap.operation()))
+ return false;
+ if (!stmt->BindString(idx++, cap.uri()))
+ return false;
+ if (!stmt->BindString(idx++, cap.mime()))
+ return false;
+ if (!stmt->BindString(idx++, cap.appid()))
+ return false;
+ if (!stmt->BindString(idx++, cap.pkgid()))
+ return false;
+
+ if (stmt->Step() != SQLStatement::StepResult::DONE) {
+ LOG(ERROR) << "Failed to insert capability into db";
+ return false;
+ }
+ if (!stmt->Reset()) {
+ LOG(ERROR) << "Failed to reset statement";
+ return false;
+ }
+ stmt->Clear();
+ }
+
+ return true;
+}
+
+bool DBManager::DeleteCapability(const std::string& device_id,
+ const Capability& cap) {
+ auto guard = Instance().sql_conn_->GetTransactionGuard();
+ std::shared_ptr<SQLStatement> stmt = Instance().sql_conn_->PrepareStatement(
+ kQueryDeleteCap);
+ if (!stmt) {
+ LOG(ERROR) << "Failed to prepare statement";
+ return false;
+ }
+
+ int idx = 1;
+ if (!stmt->BindString(idx++, device_id))
+ return false;
+ if (!stmt->BindString(idx++, cap.operation()))
+ return false;
+ if (!stmt->BindString(idx++, cap.uri()))
+ return false;
+ if (!stmt->BindString(idx++, cap.mime()))
+ return false;
+ if (!stmt->BindString(idx++, cap.appid()))
+ return false;
+
+ if (stmt->Step() != SQLStatement::StepResult::DONE) {
+ LOG(ERROR) << "Failed to delete capability from db";
+ return false;
+ }
+
+ return true;
+}
+
+DBManager& DBManager::Instance() {
+ static DBManager instance(kDBPath);
+ return instance;
+}
+
+DBManager::DBManager(const std::string& path) {
+ sql_conn_ = std::unique_ptr<SQLConnection>(new SQLiteConnection(path, false));
+ if (!InitTable(sql_conn_))
+ LOG(ERROR) << "Failed to initialize table";
+}
+
+DBManager::~DBManager() {
+}
+
+bool DBManager::InitTable(const std::unique_ptr<SQLConnection>& conn) {
+ std::shared_ptr<SQLStatement> stmt = conn->PrepareStatement(
+ kQueryInitDevicesTable);
+ if (!stmt) {
+ LOG(ERROR) << "Failed to prepare statement";
+ return false;
+ }
+ if (stmt->Step() != SQLStatement::StepResult::DONE) {
+ LOG(ERROR) << "Failed to create devices table";
+ return false;
+ }
+
+ stmt = conn->PrepareStatement(kQueryInitCapsTable);
+ if (!stmt) {
+ LOG(ERROR) << "Failed to prepare statement";
+ return false;
+ }
+ if (stmt->Step() != SQLStatement::StepResult::DONE) {
+ LOG(ERROR) << "Failed to create capabilities table";
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace capmgr