* limitations under the License.
*/
+#include <algorithm>
+
#include "db_manager.h"
#include "log.h"
+#include "tac_common.h"
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "DOTNET_INSTALLER_PLUGIN"
-sqlite3* dbCreate(std::string path)
+static int dbIntegrityCheckCb(void *user_data, int argc, char **argv, char **not_used)
+{
+ bool* is_db_corrupted = static_cast<bool*>(user_data);
+ std::string result_DB_check = argv[0];
+ std::transform(result_DB_check.begin(), result_DB_check.end(), result_DB_check.begin(), ::tolower);
+ if(result_DB_check != "ok") {
+ *is_db_corrupted = true;
+ _ERR("DB integrity check failed");
+ return -1;
+ }
+ _INFO("DB integrity result : %s", argv[0]);
+ return 0;
+}
+
+sqlite3* dbCreate(std::string path, std::string query)
{
sqlite3 *sqlite = NULL;
+ bool is_db_corrupted = false;
int ret = sqlite3_open(path.c_str(), &sqlite);
if (ret != SQLITE_OK) {
- _ERR("Sqlite error : [%d] : path [%s]", ret, path.c_str());
- return NULL;
+ _INFO("DB file is corrupted, start to recover corrupted db");
+ if (restoreTACDB() != TAC_ERROR_NONE) {
+ _ERR("Sqlite error : [%d, %s]", ret, path.c_str());
+ return NULL;
+ }
+ return dbCreate(path, query);
}
ret = sqlite3_exec(sqlite, "PRAGMA journal_mode = PERSIST", NULL, NULL, NULL);
if (ret != SQLITE_OK) {
- _ERR("Sqlite error : [%d]", ret);
- return NULL;
+ _ERR("Sqlite error : [%d, %s]", ret, path.c_str());
+ sqlite3_close(sqlite);
+ sqlite = NULL;
+ return sqlite;
}
- ret = sqlite3_exec(sqlite, CREATE_TAC_DB_TABLE, NULL, NULL, NULL);
+ ret = sqlite3_exec(sqlite, query.c_str(), NULL, NULL, NULL);
if (ret != SQLITE_OK) {
- _ERR("Sqlite error : [%d] : path [%s]", ret, path.c_str());
- return NULL;
+ _ERR("Sqlite error : [%d, %s]", ret, path.c_str());
+ sqlite3_close(sqlite);
+ sqlite = NULL;
+ return sqlite;
+ }
+ ret = sqlite3_exec(sqlite, "PRAGMA integrity_check", dbIntegrityCheckCb, &is_db_corrupted, NULL);
+ if (ret == SQLITE_CORRUPT || is_db_corrupted) {
+ _INFO("DB file is corrupted, start to recover corrupted db");
+ if (restoreTACDB() != TAC_ERROR_NONE) {
+ _ERR("Sqlite error : [%d, %s]", ret, path.c_str());
+ sqlite3_close(sqlite);
+ sqlite = NULL;
+ return sqlite;
+ }
+ return dbCreate(path, query);
}
return sqlite;
}
-bool dbOpen(sqlite3 *tac_db, std::string path)
+sqlite3* dbOpen(std::string path)
{
- if (!tac_db) {
- int ret = sqlite3_open(path.c_str(), &tac_db);
- if (ret != SQLITE_OK) {
- _ERR("Sqlite error : [%d] : path [%s]", ret, path.c_str());
- return false;
+ sqlite3 *sqlite = NULL;
+ bool is_db_corrupted = false;
+ int ret = sqlite3_open(path.c_str(), &sqlite);
+ if (ret != SQLITE_OK) {
+ _INFO("DB file is corrupted, start to recover corrupted db");
+ if (restoreTACDB() != TAC_ERROR_NONE) {
+ _ERR("Sqlite error : [%d, %s]", ret, path.c_str());
+ return NULL;
+ }
+ return dbOpen(path);
+ }
+ ret = sqlite3_exec(sqlite, "PRAGMA integrity_check", dbIntegrityCheckCb, &is_db_corrupted, NULL);
+ if (ret == SQLITE_CORRUPT || is_db_corrupted) {
+ _INFO("DB file is corrupted, start to recover corrupted db");
+ if (restoreTACDB() != TAC_ERROR_NONE) {
+ _ERR("Sqlite error : [%d, %s]", ret, path.c_str());
+ sqlite3_close(sqlite);
+ sqlite = NULL;
+ return sqlite;
}
+ return dbOpen(path);
}
- return true;
+ return sqlite;
}
void dbFinalize(sqlite3_stmt *stmt)
}
}
-void dbClose(sqlite3 *tac_db)
+void dbClose(sqlite3 *sqlite)
{
- if (tac_db) {
- sqlite3_exec(tac_db, "COMMIT;", NULL, NULL, NULL);
- sqlite3_close(tac_db);
- tac_db = NULL;
+ if (sqlite) {
+ sqlite3_exec(sqlite, "COMMIT;", NULL, NULL, NULL);
+ sqlite3_close(sqlite);
+ sqlite = NULL;
}
}
-void dbRollback(sqlite3 *tac_db)
+void dbRollback(sqlite3 *sqlite)
{
- if (tac_db) {
- sqlite3_exec(tac_db, "ROLLBACK;", NULL, NULL, NULL);
- sqlite3_close(tac_db);
- tac_db = NULL;
+ if (sqlite) {
+ sqlite3_exec(sqlite, "ROLLBACK;", NULL, NULL, NULL);
+ sqlite3_close(sqlite);
+ sqlite = NULL;
}
}
-bool dbUpdate(sqlite3 *tac_db, std::string path, std::string query)
+bool dbUpdate(sqlite3 *sqlite, std::string path, std::string query)
{
sqlite3_stmt *stmt = NULL;
- if (!dbOpen(tac_db, path)) {
- return false;
- }
- int ret = sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
- ret = sqlite3_prepare(tac_db, query.c_str(), QUERY_MAX_LEN , &stmt, NULL);
+ int ret = sqlite3_exec(sqlite, "BEGIN;", NULL, NULL, NULL);
+ ret = sqlite3_prepare(sqlite, query.c_str(), query.size(), &stmt, NULL);
if (ret != SQLITE_OK) {
- _ERR("Sqlite error : [%s, %s]", query.c_str(), sqlite3_errmsg(tac_db));
- dbClose(tac_db);
+ _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
+ dbClose(sqlite);
return false;
}
ret = sqlite3_step(stmt);
if (ret != SQLITE_DONE && ret != SQLITE_ROW && ret != SQLITE_OK) {
- _ERR("Sqlite error [%d]", ret);
+ _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
dbFinalize(stmt);
- dbClose(tac_db);
+ dbClose(sqlite);
return false;
}
dbFinalize(stmt);
return true;
}
-bool dbInsert(sqlite3 *tac_db, std::string path, std::string query)
+bool dbInsert(sqlite3 *sqlite, std::string path, std::string query)
{
sqlite3_stmt *stmt = NULL;
- if (!dbOpen(tac_db, path)) {
- return false;
- }
- int ret = sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
- ret = sqlite3_prepare(tac_db, query.c_str(), QUERY_MAX_LEN , &stmt, NULL);
+ int ret = sqlite3_exec(sqlite, "BEGIN;", NULL, NULL, NULL);
+ ret = sqlite3_prepare(sqlite, query.c_str(), query.size(), &stmt, NULL);
if (ret != SQLITE_OK) {
- _ERR("Sqlite error : [%s,%s]", query.c_str(), sqlite3_errmsg(tac_db));
- dbClose(tac_db);
+ _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
+ dbClose(sqlite);
return false;
}
ret = sqlite3_step(stmt);
if (ret != SQLITE_DONE && ret != SQLITE_ROW && ret != SQLITE_OK) {
- _ERR("Sqlite error [%d]", ret);
+ _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
dbFinalize(stmt);
- dbClose(tac_db);
+ dbClose(sqlite);
return false;
}
dbFinalize(stmt);
return true;
}
-std::vector<std::string> dbSelect(sqlite3 *tac_db, std::string path, std::string query)
+std::vector<std::string> dbSelect(sqlite3 *sqlite, std::string path, std::string query)
{
std::vector<std::string> updateDB;
sqlite3_stmt* stmt = NULL;
const char* str = NULL;
- if (!dbOpen(tac_db, path)) {
- return updateDB;
- }
- int ret = sqlite3_prepare_v2(tac_db, query.c_str(), strlen(query.c_str()), &stmt, NULL);
+ int ret = sqlite3_prepare_v2(sqlite, query.c_str(), query.size(), &stmt, NULL);
if (ret != SQLITE_OK) {
- _ERR("Sqlite error : [%s,%s]", query.c_str(), sqlite3_errmsg(tac_db));
- dbClose(tac_db);
+ _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
+ dbClose(sqlite);
return updateDB;
}
while (sqlite3_step(stmt) == SQLITE_ROW) {
str = (const char *) sqlite3_column_text(stmt, 2);
- _DBG("Nuget : %s", (!str || !strlen(str)) ? NULL : strdup(str));
updateDB.push_back((!str || !strlen(str)) ? NULL : strdup(str));
}
dbFinalize(stmt);
return updateDB;
}
-bool dbDelete(sqlite3 *tac_db, std::string path, std::string query)
+bool dbDelete(sqlite3 *sqlite, std::string path, std::string query)
{
sqlite3_stmt *stmt = NULL;
- if (!dbOpen(tac_db, path)) {
- return false;
- }
- int ret = sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
- ret = sqlite3_prepare(tac_db, query.c_str(), QUERY_MAX_LEN , &stmt, NULL);
+ int ret = sqlite3_exec(sqlite, "BEGIN;", NULL, NULL, NULL);
+ ret = sqlite3_prepare(sqlite, query.c_str(), query.size(), &stmt, NULL);
if (ret != SQLITE_OK) {
- _ERR("Sqlite error : [%s,%s]", query.c_str(), sqlite3_errmsg(tac_db));
- dbClose(tac_db);
+ _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
+ dbClose(sqlite);
return false;
}
ret = sqlite3_step(stmt);
if (ret != SQLITE_DONE && ret != SQLITE_ROW && ret != SQLITE_OK) {
- _ERR("Sqlite error [%d]", ret);
+ _ERR("Sqlite error : [%d, %s]", ret, sqlite3_errmsg(sqlite));
dbFinalize(stmt);
- dbClose(tac_db);
+ dbClose(sqlite);
return false;
}
dbFinalize(stmt);