* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "profile_database.h"
#include <cstdio>
#include <mutex>
#include <unistd.h>
#include "calllog_common.h"
#include "common.h"
#include "contacts_account.h"
#include "contacts_columns.h"
#include "contacts_common.h"
#include "contacts_type.h"
#include "hilog_wrapper.h"
namespace OHOS {
namespace Contacts {
std::shared_ptr<ProfileDatabase> ProfileDatabase::profileDatabase_ = nullptr;
std::shared_ptr<OHOS::NativeRdb::RdbStore> ProfileDatabase::store_ = nullptr;
static std::string g_databaseName;
namespace {
std::mutex g_mtx;
}
ProfileDatabase::ProfileDatabase()
{
int errCode = OHOS::NativeRdb::E_OK;
int getDataBasePathErrCode = OHOS::NativeRdb::E_OK;
g_databaseName = OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(
ContactsPath::RDB_PATH, "profile.db", getDataBasePathErrCode);
OHOS::NativeRdb::RdbStoreConfig config(g_databaseName);
HILOG_INFO("ProfileDatabase ts = %{public}lld", (long long) time(NULL));
SqliteOpenHelperProfileCallback sqliteOpenHelperCallback;
store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(
config, DATABASE_CONTACTS_OPEN_VERSION, sqliteOpenHelperCallback, errCode);
if (errCode != OHOS::NativeRdb::E_OK) {
HILOG_ERROR("ProfileDatabase errCode :%{public}d, ts = %{public}lld", errCode, (long long) time(NULL));
} else {
HILOG_INFO("ProfileDatabase errCode :%{public}d, ts = %{public}lld", errCode, (long long) time(NULL));
}
if (errCode != OHOS::NativeRdb::E_OK) {
HILOG_ERROR("ProfileDatabase rebase open error :%{public}d, ts = %{public}lld", errCode, (long long) time(NULL));
return;
}
std::shared_ptr<ContactsAccount> contactsAccount = ContactsAccount::GetInstance();
contactsAccount->PrepopulateCommonAccountTypes(store_);
ContactsType contactsType;
contactsType.PrepopulateCommonTypes(store_);
}
std::shared_ptr<ProfileDatabase> ProfileDatabase::GetInstance()
{
if (profileDatabase_ == nullptr || store_ == nullptr) {
g_mtx.lock();
profileDatabase_.reset(new ProfileDatabase());
g_mtx.unlock();
}
return profileDatabase_;
}
void ProfileDatabase::DestroyInstanceAndRestore(std::string restorePath)
{
g_mtx.lock();
if (access(restorePath.c_str(), F_OK) != 0) {
HILOG_ERROR("Restore file %{private}s does not exist, ts = %{public}lld", restorePath.c_str(), (long long) time(NULL));
g_mtx.unlock();
return;
}
OHOS::NativeRdb::RdbHelper::DeleteRdbStore(g_databaseName);
OHOS::NativeRdb::RdbHelper::ClearCache();
profileDatabase_ = nullptr;
Restore(restorePath);
g_mtx.unlock();
}
bool ProfileDatabase::Restore(std::string restorePath)
{
if (rename(restorePath.c_str(), g_databaseName.c_str())) {
HILOG_ERROR("Restore rename oldFileName = %{private}s to newFileName %{private}s", restorePath.c_str(),
g_databaseName.c_str());
return true;
}
return false;
}
int SqliteOpenHelperProfileCallback::OnCreate(OHOS::NativeRdb::RdbStore &store)
{
HILOG_WARN("ProfileDatabase OnCreate profile db.");
store.ExecuteSql(CREATE_CONTACT);
store.ExecuteSql(CREATE_CONTACT_INDEX);
store.ExecuteSql(CREATE_RAW_CONTACT);
store.ExecuteSql(CREATE_RAW_CONTACT_INDEX);
store.ExecuteSql(CREATE_RAW_CONTACT_INDEX_SORT);
store.ExecuteSql(CREATE_CONTACT_DATA);
store.ExecuteSql(CREATE_CONTACT_INDEX_DATA1);
store.ExecuteSql(CREATE_CONTACT_INDEX_DATA2);
store.ExecuteSql(CREATE_CONTACT_BLOCKLIST);
store.ExecuteSql(CREATE_LOCAL_LANG);
store.ExecuteSql(CREATE_ACCOUNT);
store.ExecuteSql(CREATE_PHOTO_FILES);
store.ExecuteSql(CREATE_CONTACT_TYPE);
store.ExecuteSql(CREATE_GROUPS);
store.ExecuteSql(CREATE_DELETED_RAW_CONTACT);
store.ExecuteSql(CREATE_SEARCH_CONTACT);
store.ExecuteSql(CREATE_SEARCH_CONTACT_INDEX1);
store.ExecuteSql(CREATE_SEARCH_CONTACT_INDEX2);
store.ExecuteSql(CREATE_SEARCH_CONTACT_VIEW);
store.ExecuteSql(MERGE_INFO);
store.ExecuteSql(CREATE_VIEW_CONTACT_DATA);
store.ExecuteSql(CREATE_VIEW_RAW_CONTACT);
store.ExecuteSql(CREATE_VIEW_CONTACT);
store.ExecuteSql(CREATE_VIEW_CONTACT_LOCATION);
store.ExecuteSql(CREATE_VIEW_GROUPS);
store.ExecuteSql(CREATE_VIEW_DELETED);
store.ExecuteSql(UPDATE_RAW_CONTACT_VERSION);
store.ExecuteSql(UPDATE_CONTACT_DATA_VERSION);
store.ExecuteSql(INSERT_CONTACT_QUICK_SEARCH);
store.ExecuteSql(CREATE_DATABASE_BACKUP_TASK);
store.ExecuteSql(CREATE_INSERT_BACKUP_TIME);
store.ExecuteSql(UPDATE_CONTACT_BY_INSERT_CONTACT_DATA);
store.ExecuteSql(UPDATE_CONTACT_BY_DELETE_CONTACT_DATA);
store.ExecuteSql(UPDATE_CONTACT_BY_UPDATE_CONTACT_DATA);
store.ExecuteSql(MERGE_INFO_INDEX);
return OHOS::NativeRdb::E_OK;
}
int SqliteOpenHelperProfileCallback::OnUpgrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
{
HILOG_INFO("ProfileDatabase OnUpgrade oldVersion is %{public}d , newVersion is %{public}d", oldVersion, newVersion);
if (oldVersion < newVersion && newVersion == DATABASE_NEW_VERSION) {
store.ExecuteSql("ALTER TABLE database_backup_task ADD COLUMN sync TEXT");
}
if (oldVersion < newVersion && newVersion == DATABASE_VERSION_2) {
UpgradeToV2(store, oldVersion, newVersion);
}
store.SetVersion(newVersion);
return OHOS::NativeRdb::E_OK;
}
void SqliteOpenHelperProfileCallback::UpgradeToV2(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
{
if (oldVersion >= newVersion || newVersion != DATABASE_VERSION_2) {
return;
}
store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN primary_contact INTEGER DEFAULT 0;");
store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN extra1 TEXT;");
store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN extra2 TEXT;");
store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN extra3 TEXT;");
store.ExecuteSql("ALTER TABLE raw_contact ADD COLUMN extra4 TEXT;");
store.ExecuteSql("ALTER TABLE contact_data ADD COLUMN extend8 TEXT;");
store.ExecuteSql("ALTER TABLE contact_data ADD COLUMN extend9 TEXT;");
store.ExecuteSql("ALTER TABLE contact_data ADD COLUMN extend10 TEXT;");
store.ExecuteSql("ALTER TABLE contact_data ADD COLUMN extend11 TEXT;");
store.ExecuteSql("DROP VIEW view_contact;");
store.ExecuteSql("DROP VIEW view_contact_data;");
store.ExecuteSql("DROP VIEW search_contact_view;");
store.ExecuteSql("DROP VIEW view_deleted;");
store.ExecuteSql(CREATE_VIEW_CONTACT);
store.ExecuteSql(CREATE_VIEW_CONTACT_DATA);
store.ExecuteSql(CREATE_SEARCH_CONTACT_VIEW);
store.ExecuteSql(CREATE_VIEW_DELETED);
}
int SqliteOpenHelperProfileCallback::OnDowngrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
{
HILOG_INFO("ProfileDatabase OnDowngrade oldVersion is %{public}d , newVersion is %{public}d",
oldVersion, newVersion);
if (oldVersion > newVersion && newVersion == DATABASE_CONTACTS_OPEN_VERSION) {
store.ExecuteSql(
"CREATE TABLE IF NOT EXISTS database_backup (id INTEGER PRIMARY KEY AUTOINCREMENT, backup_time "
"TEXT, backup_path TEXT, remarks TEXT)");
store.ExecuteSql(
"INSERT INTO database_backup(id, backup_time, backup_path, remarks) SELECT id, "
"backup_time, backup_path, remarks FROM database_backup_task");
store.ExecuteSql("DROP table database_backup_task");
store.ExecuteSql("ALTER table database_backup RENAME TO database_backup_task");
store.ExecuteSql(CREATE_INSERT_BACKUP_TIME);
}
int ret = store.SetVersion(newVersion);
return ret;
}
}
}