14faa1673Sopenharmony_ci/*
24faa1673Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
34faa1673Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44faa1673Sopenharmony_ci * you may not use this file except in compliance with the License.
54faa1673Sopenharmony_ci * You may obtain a copy of the License at
64faa1673Sopenharmony_ci *
74faa1673Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84faa1673Sopenharmony_ci *
94faa1673Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104faa1673Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114faa1673Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124faa1673Sopenharmony_ci * See the License for the specific language governing permissions and
134faa1673Sopenharmony_ci * limitations under the License.
144faa1673Sopenharmony_ci */
154faa1673Sopenharmony_ci
164faa1673Sopenharmony_ci#include "sqlite_helper.h"
174faa1673Sopenharmony_ci#include "sandbox_manager_log.h"
184faa1673Sopenharmony_ci
194faa1673Sopenharmony_cinamespace OHOS {
204faa1673Sopenharmony_cinamespace AccessControl {
214faa1673Sopenharmony_cinamespace SandboxManager {
224faa1673Sopenharmony_cinamespace {
234faa1673Sopenharmony_cistatic constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, ACCESSCONTROL_DOMAIN_SANDBOXMANAGER, "SqliteHelper"};
244faa1673Sopenharmony_ci}
254faa1673Sopenharmony_ci
264faa1673Sopenharmony_ciSqliteHelper::SqliteHelper(const std::string &dbName, const std::string &dbPath, int32_t version)
274faa1673Sopenharmony_ci    : dbName_(dbName), dbPath_(dbPath), currentVersion_(version), db_(nullptr)
284faa1673Sopenharmony_ci{}
294faa1673Sopenharmony_ci
304faa1673Sopenharmony_ciSqliteHelper::~SqliteHelper()
314faa1673Sopenharmony_ci{}
324faa1673Sopenharmony_ci
334faa1673Sopenharmony_civoid SqliteHelper::Open()
344faa1673Sopenharmony_ci{
354faa1673Sopenharmony_ci    if (db_ != nullptr) {
364faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_WARN(LABEL, "db s already open");
374faa1673Sopenharmony_ci        return;
384faa1673Sopenharmony_ci    }
394faa1673Sopenharmony_ci    if (dbName_.empty() || dbPath_.empty() || currentVersion_ < 0) {
404faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_ERROR(LABEL, "param invalid, dbName: %{public}s, "
414faa1673Sopenharmony_ci            "dbPath: %{public}s, currentVersion: %{public}d",
424faa1673Sopenharmony_ci            dbName_.c_str(), dbPath_.c_str(), currentVersion_);
434faa1673Sopenharmony_ci        return;
444faa1673Sopenharmony_ci    }
454faa1673Sopenharmony_ci    std::string fileName = dbPath_ + dbName_;
464faa1673Sopenharmony_ci    int32_t res = sqlite3_open(fileName.c_str(), &db_);
474faa1673Sopenharmony_ci    if (res != SQLITE_OK) {
484faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_ERROR(LABEL, "Failed to open db: %{public}s", sqlite3_errmsg(db_));
494faa1673Sopenharmony_ci        return;
504faa1673Sopenharmony_ci    }
514faa1673Sopenharmony_ci
524faa1673Sopenharmony_ci    int32_t version = GetVersion();
534faa1673Sopenharmony_ci    if (version == currentVersion_) {
544faa1673Sopenharmony_ci        return;
554faa1673Sopenharmony_ci    }
564faa1673Sopenharmony_ci
574faa1673Sopenharmony_ci    BeginTransaction();
584faa1673Sopenharmony_ci    if (version == 0) {
594faa1673Sopenharmony_ci        OnCreate();
604faa1673Sopenharmony_ci    } else {
614faa1673Sopenharmony_ci        if (version < currentVersion_) {
624faa1673Sopenharmony_ci            OnUpdate();
634faa1673Sopenharmony_ci        }
644faa1673Sopenharmony_ci    }
654faa1673Sopenharmony_ci    SetVersion();
664faa1673Sopenharmony_ci    CommitTransaction();
674faa1673Sopenharmony_ci}
684faa1673Sopenharmony_ci
694faa1673Sopenharmony_civoid SqliteHelper::Close()
704faa1673Sopenharmony_ci{
714faa1673Sopenharmony_ci    if (db_ == nullptr) {
724faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
734faa1673Sopenharmony_ci        return;
744faa1673Sopenharmony_ci    }
754faa1673Sopenharmony_ci    int32_t ret = sqlite3_close(db_);
764faa1673Sopenharmony_ci    if (ret != SQLITE_OK) {
774faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_WARN(LABEL, "sqlite3_close error, ret=%{public}d", ret);
784faa1673Sopenharmony_ci        return;
794faa1673Sopenharmony_ci    }
804faa1673Sopenharmony_ci    db_ = nullptr;
814faa1673Sopenharmony_ci}
824faa1673Sopenharmony_ci
834faa1673Sopenharmony_ciint32_t SqliteHelper::BeginTransaction() const
844faa1673Sopenharmony_ci{
854faa1673Sopenharmony_ci    if (db_ == nullptr) {
864faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
874faa1673Sopenharmony_ci        return GENERAL_ERROR;
884faa1673Sopenharmony_ci    }
894faa1673Sopenharmony_ci    char* errorMessage = nullptr;
904faa1673Sopenharmony_ci    int32_t result = 0;
914faa1673Sopenharmony_ci    int32_t ret = sqlite3_exec(db_, "BEGIN;", nullptr, nullptr, &errorMessage);
924faa1673Sopenharmony_ci    if (ret != SQLITE_OK) {
934faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", errorMessage);
944faa1673Sopenharmony_ci        result = GENERAL_ERROR;
954faa1673Sopenharmony_ci    }
964faa1673Sopenharmony_ci    sqlite3_free(errorMessage);
974faa1673Sopenharmony_ci    return result;
984faa1673Sopenharmony_ci}
994faa1673Sopenharmony_ci
1004faa1673Sopenharmony_ciint32_t SqliteHelper::CommitTransaction() const
1014faa1673Sopenharmony_ci{
1024faa1673Sopenharmony_ci    if (db_ == nullptr) {
1034faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
1044faa1673Sopenharmony_ci        return GENERAL_ERROR;
1054faa1673Sopenharmony_ci    }
1064faa1673Sopenharmony_ci    char* errorMessage = nullptr;
1074faa1673Sopenharmony_ci    int32_t result = 0;
1084faa1673Sopenharmony_ci    int32_t ret = sqlite3_exec(db_, "COMMIT;", nullptr, nullptr, &errorMessage);
1094faa1673Sopenharmony_ci    if (ret != SQLITE_OK) {
1104faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", errorMessage);
1114faa1673Sopenharmony_ci        result = GENERAL_ERROR;
1124faa1673Sopenharmony_ci    }
1134faa1673Sopenharmony_ci    sqlite3_free(errorMessage);
1144faa1673Sopenharmony_ci    return result;
1154faa1673Sopenharmony_ci}
1164faa1673Sopenharmony_ci
1174faa1673Sopenharmony_ciint32_t SqliteHelper::RollbackTransaction() const
1184faa1673Sopenharmony_ci{
1194faa1673Sopenharmony_ci    if (db_ == nullptr) {
1204faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
1214faa1673Sopenharmony_ci        return GENERAL_ERROR;
1224faa1673Sopenharmony_ci    }
1234faa1673Sopenharmony_ci    int32_t result = 0;
1244faa1673Sopenharmony_ci    char* errorMessage = nullptr;
1254faa1673Sopenharmony_ci    int32_t ret = sqlite3_exec(db_, "ROLLBACK;", nullptr, nullptr, &errorMessage);
1264faa1673Sopenharmony_ci    if (ret != SQLITE_OK) {
1274faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", errorMessage);
1284faa1673Sopenharmony_ci        result = GENERAL_ERROR;
1294faa1673Sopenharmony_ci    }
1304faa1673Sopenharmony_ci    sqlite3_free(errorMessage);
1314faa1673Sopenharmony_ci    return result;
1324faa1673Sopenharmony_ci}
1334faa1673Sopenharmony_ci
1344faa1673Sopenharmony_ciStatement SqliteHelper::Prepare(const std::string &sql) const
1354faa1673Sopenharmony_ci{
1364faa1673Sopenharmony_ci    return Statement(db_, sql);
1374faa1673Sopenharmony_ci}
1384faa1673Sopenharmony_ci
1394faa1673Sopenharmony_ciint32_t SqliteHelper::ExecuteSql(const std::string &sql) const
1404faa1673Sopenharmony_ci{
1414faa1673Sopenharmony_ci    if (db_ == nullptr) {
1424faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
1434faa1673Sopenharmony_ci        return GENERAL_ERROR;
1444faa1673Sopenharmony_ci    }
1454faa1673Sopenharmony_ci    char* errorMessage = nullptr;
1464faa1673Sopenharmony_ci    int32_t result = 0;
1474faa1673Sopenharmony_ci    int32_t res = sqlite3_exec(db_, sql.c_str(), nullptr, nullptr, &errorMessage);
1484faa1673Sopenharmony_ci    if (res != SQLITE_OK) {
1494faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", errorMessage);
1504faa1673Sopenharmony_ci        result = GENERAL_ERROR;
1514faa1673Sopenharmony_ci    }
1524faa1673Sopenharmony_ci    sqlite3_free(errorMessage);
1534faa1673Sopenharmony_ci    return result;
1544faa1673Sopenharmony_ci}
1554faa1673Sopenharmony_ci
1564faa1673Sopenharmony_ciint32_t SqliteHelper::GetVersion() const
1574faa1673Sopenharmony_ci{
1584faa1673Sopenharmony_ci    if (db_ == nullptr) {
1594faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
1604faa1673Sopenharmony_ci        return GENERAL_ERROR;
1614faa1673Sopenharmony_ci    }
1624faa1673Sopenharmony_ci    auto statement = Prepare(PRAGMA_VERSION_COMMAND);
1634faa1673Sopenharmony_ci    int32_t version = 0;
1644faa1673Sopenharmony_ci    while (statement.Step() == Statement::State::ROW) {
1654faa1673Sopenharmony_ci        version = statement.GetColumnInt(0);
1664faa1673Sopenharmony_ci    }
1674faa1673Sopenharmony_ci    SANDBOXMANAGER_LOG_INFO(LABEL, "version: %{public}d", version);
1684faa1673Sopenharmony_ci    return version;
1694faa1673Sopenharmony_ci}
1704faa1673Sopenharmony_ci
1714faa1673Sopenharmony_civoid SqliteHelper::SetVersion() const
1724faa1673Sopenharmony_ci{
1734faa1673Sopenharmony_ci    if (db_ == nullptr) {
1744faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
1754faa1673Sopenharmony_ci        return;
1764faa1673Sopenharmony_ci    }
1774faa1673Sopenharmony_ci    auto statement = Prepare(PRAGMA_VERSION_COMMAND + " = " + std::to_string(currentVersion_));
1784faa1673Sopenharmony_ci    statement.Step();
1794faa1673Sopenharmony_ci}
1804faa1673Sopenharmony_ci
1814faa1673Sopenharmony_cistd::string SqliteHelper::SpitError() const
1824faa1673Sopenharmony_ci{
1834faa1673Sopenharmony_ci    if (db_ == nullptr) {
1844faa1673Sopenharmony_ci        SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
1854faa1673Sopenharmony_ci        return "";
1864faa1673Sopenharmony_ci    }
1874faa1673Sopenharmony_ci    return sqlite3_errmsg(db_);
1884faa1673Sopenharmony_ci}
1894faa1673Sopenharmony_ci} // namespace SandboxManager
1904faa1673Sopenharmony_ci} // namespace AccessControl
1914faa1673Sopenharmony_ci} // namespace OHOS
192