Fix crash when invalid parameter given
[platform/core/api/capability-manager.git] / src / sqlite_connection.cc
1 // Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "src/sqlite_connection.h"
6
7 #include <sqlite3.h>
8 #include <sys/types.h>
9 #include <unistd.h>
10
11 #include <boost/optional.hpp>
12
13 #include <string>
14 #include <utility>
15
16 #include "src/sqlite_statement.h"
17 #include "src/utils/logging.h"
18
19 namespace capmgr {
20
21 SQLiteConnection::SQLiteConnection(std::string path, bool readonly)
22     : path_(std::move(path)), db_(nullptr) {
23   if (!Connect(readonly))
24     LOG(ERROR) << "Failed to connect db";
25 }
26
27 SQLiteConnection::~SQLiteConnection() {
28   Disconnect();
29 }
30
31 bool SQLiteConnection::Connect(bool readonly) {
32   int flags;
33   if (readonly)
34     flags = SQLITE_OPEN_READONLY;
35   else
36     flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
37
38   sqlite3* db;
39   int r = sqlite3_open_v2(path_.c_str(), &db, flags, nullptr);
40   if (r != SQLITE_OK) {
41     LOG(ERROR) << "Failed to open sqlite3 db("
42                << path_ << "). Error code: " << r;
43     SetErrorCode(r);
44     sqlite3_close_v2(db);
45     return false;
46   }
47   r = sqlite3_exec(db, "PRAGMA foreign_keys=ON", nullptr, nullptr, nullptr);
48   if (r != SQLITE_OK)
49     LOG(ERROR) << "Failed to enable foreign key support: " << r;
50   db_ = db;
51   return true;
52 }
53
54 bool SQLiteConnection::Disconnect() {
55   if (db_) {
56     sqlite3_close_v2(db_);
57     db_ = nullptr;
58   }
59   return true;
60 }
61
62 bool SQLiteConnection::Execute(const std::string& command) {
63   if (!db_) {
64     LOG(ERROR) << "Invalid SQLite connection";
65     return false;
66   }
67
68   int r = sqlite3_exec(db_, command.c_str(), nullptr, nullptr, nullptr);
69   if (r != SQLITE_OK) {
70     LOG(ERROR) << "Execute command(" << command << ") failed: "
71                << GetErrorMessage();
72     SetErrorCode(r);
73     return false;
74   }
75   return true;
76 }
77
78 bool SQLiteConnection::BeginTransaction() {
79   return Execute("BEGIN EXCLUSIVE");
80 }
81
82 bool SQLiteConnection::CommitTransaction() {
83   return Execute("COMMIT");
84 }
85
86 bool SQLiteConnection::RollbackTransaction() {
87   return Execute("ROLLBACK");
88 }
89
90 std::string SQLiteConnection::GetErrorMessage() const {
91   return sqlite3_errmsg(db_);
92 }
93
94 std::shared_ptr<SQLStatement> SQLiteConnection::PrepareStatement(
95     const std::string& query) {
96   if (!db_) {
97     LOG(ERROR) << "Invalid SQLite connection";
98     return {};
99   }
100
101   sqlite3_stmt* stmt;
102   int r = sqlite3_prepare_v2(db_, query.c_str(), query.length(), &stmt,
103       nullptr);
104   if (r != SQLITE_OK) {
105     LOG(ERROR) << "sqlite3_prepare_v2() failed: " << GetErrorMessage();
106     return {};
107   }
108   return std::shared_ptr<SQLStatement>(new SQLiteStatement(this, stmt));
109 }
110
111 bool SQLiteConnection::IsValid() {
112   if (db_)
113     return true;
114   return false;
115 }
116
117 }  // namespace capmgr