Add DBManager class
authorSangyoon Jang <jeremy.jang@samsung.com>
Thu, 21 Jun 2018 07:49:40 +0000 (16:49 +0900)
committer장상윤/Tizen Platform Lab(SR)/Engineer/삼성전자 <jeremy.jang@samsung.com>
Mon, 9 Jul 2018 08:06:58 +0000 (17:06 +0900)
DBManager does operations for capmgr db.

Change-Id: Idd6b37c47f71161e5625c54e4a1151331b93d803
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
src/common/db_manager.cc [new file with mode: 0644]
src/common/db_manager.h [new file with mode: 0644]
src/common/sqlite_connection.cc

diff --git a/src/common/db_manager.cc b/src/common/db_manager.cc
new file mode 100644 (file)
index 0000000..4b1c8d5
--- /dev/null
@@ -0,0 +1,247 @@
+// 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
diff --git a/src/common/db_manager.h b/src/common/db_manager.h
new file mode 100644 (file)
index 0000000..ca521ba
--- /dev/null
@@ -0,0 +1,43 @@
+// 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.
+
+#ifndef COMMON_DB_MANAGER_H_
+#define COMMON_DB_MANAGER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "common/capability.h"
+#include "common/remote_device.h"
+
+namespace capmgr {
+
+class Capability;
+class SQLConnection;
+
+class DBManager {
+ public:
+  static bool InsertDevice(const RemoteDevice& device);
+  static bool DeleteDevice(const RemoteDevice& device);
+  static bool InsertCapability(const std::string& device_id,
+      const Capability& cap);
+  static bool InsertCapabilities(const std::string& device_id,
+      const std::vector<Capability>& caps);
+  static bool DeleteCapability(const std::string& device_id,
+      const Capability& cap);
+
+ private:
+  explicit DBManager(const std::string& path);
+  ~DBManager();
+
+  static DBManager& Instance();
+  static bool InitTable(const std::unique_ptr<SQLConnection>& conn);
+
+  std::unique_ptr<SQLConnection> sql_conn_;
+};
+
+}  // namespace capmgr
+
+#endif  // COMMON_DB_MANAGER_H_
index 89ac08ef18049a370cb902be08595f0ae579f201..44dbde93804bf47bcb7477406297772afd267a53 100644 (file)
@@ -44,6 +44,9 @@ bool SQLiteConnection::Connect(bool readonly) {
     sqlite3_close_v2(db);
     return false;
   }
+  r = sqlite3_exec(db, "PRAGMA foreign_keys=ON", nullptr, nullptr, nullptr);
+  if (r != SQLITE_OK)
+    LOG(ERROR) << "Failed to enable foreign key support: " << r;
   db_ = db;
   return true;
 }