Support for TLC(Tizen Library cache) (#260)
[platform/core/dotnet/launcher.git] / NativeLauncher / util / db_manager.cc
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "log.h"
18 #include "db_manager.h"
19
20 #include <algorithm>
21
22 #ifdef  LOG_TAG
23 #undef  LOG_TAG
24 #endif
25 #define LOG_TAG "DOTNET_INSTALLER_PLUGIN"
26
27 static int dbIntegrityCheckCb(void *user_data, int argc, char **argv, char **not_used)
28 {
29         bool* is_db_corrupted = static_cast<bool*>(user_data);
30         std::string result_DB_check = argv[0];
31         std::transform(result_DB_check.begin(), result_DB_check.end(), result_DB_check.begin(), ::tolower);
32         if (result_DB_check != "ok") {
33                 *is_db_corrupted = true;
34                 _ERR("DB integrity check failed");
35                 return -1;
36         }
37         _INFO("DB integrity result : %s", argv[0]);
38         return 0;
39 }
40
41 sqlite3* dbCreate(std::string path, std::string query)
42 {
43         sqlite3 *sqlite = NULL;
44         bool is_db_corrupted = false;
45         int ret = sqlite3_open(path.c_str(), &sqlite);
46         if (ret != SQLITE_OK) {
47                 _INFO("DB file is corrupted, start to recover corrupted db");
48                 return sqlite;
49         }
50         ret = sqlite3_exec(sqlite, "PRAGMA journal_mode = PERSIST", NULL, NULL, NULL);
51         if (ret != SQLITE_OK) {
52                 _ERR("Sqlite error : [%d, %s]", ret, path.c_str());
53                 sqlite3_close(sqlite);
54                 sqlite = NULL;
55                 return sqlite;
56         }
57         ret = sqlite3_exec(sqlite, query.c_str(), NULL, NULL, NULL);
58         if (ret != SQLITE_OK) {
59                 _ERR("Sqlite error : [%d, %s]", ret, path.c_str());
60                 sqlite3_close(sqlite);
61                 sqlite = NULL;
62                 return sqlite;
63         }
64         ret = sqlite3_exec(sqlite, "PRAGMA integrity_check", dbIntegrityCheckCb, &is_db_corrupted, NULL);
65         if (ret == SQLITE_CORRUPT || is_db_corrupted) {
66                 _INFO("DB file is corrupted, start to recover corrupted db");
67                 sqlite3_close(sqlite);
68                 sqlite = NULL;
69                 return sqlite;
70         }
71         return sqlite;
72 }
73
74 sqlite3* dbOpen(std::string path)
75 {
76         sqlite3 *sqlite = NULL;
77         bool is_db_corrupted = false;
78         int ret = sqlite3_open(path.c_str(), &sqlite);
79         if (ret != SQLITE_OK) {
80                 _INFO("DB file is corrupted, start to recover corrupted db");
81                 return sqlite;
82         }
83         ret = sqlite3_exec(sqlite, "PRAGMA integrity_check", dbIntegrityCheckCb, &is_db_corrupted, NULL);
84         if (ret == SQLITE_CORRUPT || is_db_corrupted) {
85                 _INFO("DB file is corrupted, start to recover corrupted db");
86                 sqlite3_close(sqlite);
87                 sqlite = NULL;
88                 return sqlite;
89         }
90         return sqlite;
91 }
92
93 void dbFinalize(sqlite3_stmt *stmt)
94 {
95         if (stmt) {
96                 sqlite3_finalize(stmt);
97                 stmt = NULL;
98         }
99 }
100
101 void dbClose(sqlite3 *sqlite)
102 {
103         if (sqlite) {
104                 sqlite3_exec(sqlite, "COMMIT;", NULL, NULL, NULL);
105                 sqlite3_close(sqlite);
106                 sqlite = NULL;
107         }
108 }
109
110 void dbRollback(sqlite3 *sqlite)
111 {
112         if (sqlite) {
113                 sqlite3_exec(sqlite, "ROLLBACK;", NULL, NULL, NULL);
114                 sqlite3_close(sqlite);
115                 sqlite = NULL;
116         }
117 }
118
119 bool dbUpdate(sqlite3 *sqlite, std::string path, std::string query)
120 {
121         sqlite3_stmt *stmt = NULL;
122         int ret = sqlite3_exec(sqlite, "BEGIN;", NULL, NULL, NULL);
123         ret = sqlite3_prepare(sqlite, query.c_str(), query.size(), &stmt, NULL);
124         if (ret != SQLITE_OK) {
125                 _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
126                 dbClose(sqlite);
127                 return false;
128         }
129         ret = sqlite3_step(stmt);
130         if (ret != SQLITE_DONE && ret != SQLITE_ROW && ret != SQLITE_OK) {
131                 _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
132                 dbFinalize(stmt);
133                 dbClose(sqlite);
134                 return false;
135         }
136         dbFinalize(stmt);
137         return true;
138 }
139
140 bool dbInsert(sqlite3 *sqlite, std::string path, std::string query)
141 {
142         sqlite3_stmt *stmt = NULL;
143         int ret = sqlite3_exec(sqlite, "BEGIN;", NULL, NULL, NULL);
144         ret = sqlite3_prepare(sqlite, query.c_str(), query.size(), &stmt, NULL);
145         if (ret != SQLITE_OK) {
146                 _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
147                 dbClose(sqlite);
148                 return false;
149         }
150         ret = sqlite3_step(stmt);
151         if (ret != SQLITE_DONE && ret != SQLITE_ROW && ret != SQLITE_OK) {
152                 _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
153                 dbFinalize(stmt);
154                 dbClose(sqlite);
155                 return false;
156         }
157         dbFinalize(stmt);
158         return true;
159 }
160
161 std::vector<std::string> dbSelect(sqlite3 *sqlite, std::string path, std::string query)
162 {
163         std::vector<std::string> updateDB;
164         sqlite3_stmt* stmt = NULL;
165         const char* str = NULL;
166         int ret = sqlite3_prepare_v2(sqlite, query.c_str(), query.size(), &stmt, NULL);
167         if (ret != SQLITE_OK) {
168                 _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
169                 dbClose(sqlite);
170                 return updateDB;
171         }
172         while (sqlite3_step(stmt) == SQLITE_ROW) {
173                 str = (const char *) sqlite3_column_text(stmt, 2);
174                 updateDB.push_back((!str || !strlen(str)) ? NULL : strdup(str));
175         }
176         dbFinalize(stmt);
177         return updateDB;
178 }
179
180 bool dbDelete(sqlite3 *sqlite, std::string path, std::string query)
181 {
182         sqlite3_stmt *stmt = NULL;
183         int ret = sqlite3_exec(sqlite, "BEGIN;", NULL, NULL, NULL);
184         ret = sqlite3_prepare(sqlite, query.c_str(), query.size(), &stmt, NULL);
185         if (ret != SQLITE_OK) {
186                 _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
187                 dbClose(sqlite);
188                 return false;
189         }
190         ret = sqlite3_step(stmt);
191         if (ret != SQLITE_DONE && ret != SQLITE_ROW && ret != SQLITE_OK) {
192                 _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
193                 dbFinalize(stmt);
194                 dbClose(sqlite);
195                 return false;
196         }
197         dbFinalize(stmt);
198         return true;
199 }