/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved.
* 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.
*/
import i18n from '@ohos.i18n';
import type common from '@ohos.app.ability.common';
import relationalStore from '@ohos.data.relationalStore';
import { LogUtil } from '../utils/LogUtil';
import DatabaseManager from './DatabaseManager';
import {
SQL_CREATE_OPERATION_TABLE,
ENABLED_TRUE,
ENABLED_FALSE,
SearchItemOperation,
OPERATION_TABLE,
} from './types';
import { CheckEmptyUtils } from '../utils/CheckEmptyUtils';
import { RdbTaskPool } from '../rdb/RdbTaskPool';
/* instrument ignore file */
const TAG: string = 'SearchItemOperationManager';
const RDB_CORRUPTION_ERROR_CODE: number = 14800011;
export class SearchItemOperationManager extends DatabaseManager {
/**
* 获取关系数据库存储对象
* 如果已初始化过,则直接返回之前获取的对象
* 如果没有初始化过,则使用接口获取对象,并执行数据库建表命令,如果表未创建,则会创建一张新的表
*
* @return 关系数据库存储对象
*/
async getRdbStore(): Promise<relationalStore.RdbStore> {
const rdbStore = await super.getRdbStore(SQL_CREATE_OPERATION_TABLE);
return rdbStore;
}
/**
* 插入搜索项的操作记录
*
* @param searchOperationData 操作项封装对象
* @returns
*/
async insertSearchOperationData(searchOperationData: SearchItemOperation): Promise<void> {
const rdbStore = await this.getRdbStore();
if (searchOperationData) {
try {
const predicates = new relationalStore.RdbPredicates(OPERATION_TABLE);
predicates.equalTo('itemName', searchOperationData.itemName).and()
.equalTo('locale', searchOperationData.locale)
.and().equalTo('bundleName', searchOperationData.bundleName);
const resultSet = await rdbStore.query(predicates);
if (resultSet.rowCount) {
LogUtil.info(`${TAG} start updateSearchHistoryData... `);
await rdbStore.update(this.getDbBucketList(searchOperationData), predicates);
resultSet.close();
LogUtil.info(`${TAG} updateSearchHistoryData success`);
return;
}
resultSet.close();
LogUtil.info(`${TAG} start insertSearchHistoryData...`);
await rdbStore.insert(OPERATION_TABLE, this.getDbBucketList(searchOperationData));
LogUtil.info(`${TAG} insertSearchHistoryData result`);
} catch (error) {
LogUtil.error(`${TAG} insertSearchHistoryData message: ${error?.message}, code: ${error?.code}`);
if (error.code === RDB_CORRUPTION_ERROR_CODE) {
await super.restoreRdb();
}
}
}
}
/**
* 批量插入数据
* @param itemInfoList 操作历史表
* @param context 上下文
* @returns void
*/
async batchInsertSearchItemOperationData(itemInfoList: Array<SearchItemOperation>,
context?: common.Context): Promise<void> {
if (itemInfoList === undefined || itemInfoList.length === 0) {
LogUtil.error(`${TAG} batchInsertSearchItemOperationData error: array is empty!`);
return;
}
try {
LogUtil.info(`${TAG} start batchInsertSearchItemOperationData`);
let searchItemOperationInfos: relationalStore.ValuesBucket[] = [];
itemInfoList.forEach((itemInfo) => {
searchItemOperationInfos.push(this.getDbBucketList(itemInfo));
})
LogUtil.info(`${TAG} batchInsertSearchItemOperationData size:${searchItemOperationInfos.length}`);
let result = await RdbTaskPool.getInstance().batchInsert(OPERATION_TABLE, searchItemOperationInfos, context);
LogUtil.info(`${TAG} batchInsertSearchItemOperationData result: ${result}`);
} catch (error) {
LogUtil.error(`${TAG} batchInsertSearchItemOperationData error: ${error?.message}`);
}
}
/**
* 查询历史操作记录
*
* @param bundleName 可选参数包名
* @returns list
*/
async querySearchItemOperationData(bundleName?: string, itemList?: string[],
businessId?: string): Promise<SearchItemOperation[]> {
const rdbStore = await this.getRdbStore();
let searchItemOperationList: SearchItemOperation[] = [];
if (!rdbStore) {
return searchItemOperationList;
}
try {
const predicates = new relationalStore.RdbPredicates(OPERATION_TABLE);
let curLocale: string = i18n.System.getSystemLocale();
predicates.equalTo('locale', curLocale);
if (bundleName !== undefined) {
predicates.and().equalTo('bundleName', bundleName);
}
if (businessId) {
predicates.and().equalTo('businessId', businessId);
}
if (itemList !== undefined && itemList.length > 0) {
predicates.and().in('itemName', itemList);
}
const resultSet = await rdbStore.query(predicates);
while (resultSet.goToNextRow()) {
const locale: string = resultSet.getString(resultSet.getColumnIndex('locale'));
const itemName: string = resultSet.getString(resultSet.getColumnIndex('itemName'));
const itemTitle: string = resultSet.getString(resultSet.getColumnIndex('itemTitle'));
const itemDescription: string = resultSet.getString(resultSet.getColumnIndex('itemDescription'));
const entryKey: string = resultSet.getString(resultSet.getColumnIndex('entryKey'));
const pageTitle: string = resultSet.getString(resultSet.getColumnIndex('pageTitle'));
const params: string = resultSet.getString(resultSet.getColumnIndex('params'));
const enable: boolean = resultSet.getLong(resultSet.getColumnIndex('enable')) === ENABLED_TRUE;
const icon: string = resultSet.getString(resultSet.getColumnIndex('icon'));
const alias: string = resultSet.getString(resultSet.getColumnIndex('alias'));
const childItems: string = resultSet.getString(resultSet.getColumnIndex('childItems'));
const path: string = resultSet.getString(resultSet.getColumnIndex('path'));
const bundleName: string = resultSet.getString(resultSet.getColumnIndex('bundleName'));
const checkType: string = resultSet.getString(resultSet.getColumnIndex('checkType'));
const checkKey: string = resultSet.getString(resultSet.getColumnIndex('checkKey'));
const checkValue: string = resultSet.getString(resultSet.getColumnIndex('checkValue'));
const content: string = resultSet.getString(resultSet.getColumnIndex('content'));
const status: string = resultSet.getString(resultSet.getColumnIndex('status'));
const timestamp: number = resultSet.getLong(resultSet.getColumnIndex('timestamp'));
const businessId: string = resultSet.getString(resultSet.getColumnIndex('businessId'));
const optBundleName: string = resultSet.getString(resultSet.getColumnIndex('optBundleName'));
searchItemOperationList.push({
locale,
itemName,
itemTitle,
itemDescription,
entryKey,
pageTitle,
params,
enable,
icon,
alias,
childItems,
path,
bundleName,
checkType,
checkKey,
checkValue,
content,
status,
timestamp,
businessId,
optBundleName
});
}
resultSet.close();
return searchItemOperationList;
} catch (error) {
LogUtil.error(`${TAG} query searchItemOperationList message: ${error?.message}, code: ${error?.code}`);
if (error.code === RDB_CORRUPTION_ERROR_CODE) {
await super.restoreRdb();
}
return searchItemOperationList;
}
}
async querySearchOpMap(bundleName?: string): Promise<Map<string, SearchItemOperation>> {
let itemMap: Map<string, SearchItemOperation> = new Map();
let list: SearchItemOperation[] = await this.querySearchItemOperationData(bundleName);
if (list.length === 0) {
return itemMap;
}
list.forEach(item => {
itemMap.set(item.itemName, item);
});
return itemMap;
}
/**
* 删除itemName的操作历史记录
*
* @param itemName
* @returns
*/
async deleteSearchItem(itemName: string, bundleName: string): Promise<void> {
if (CheckEmptyUtils.checkStrIsEmpty(itemName)) {
LogUtil.showError(TAG, 'deleteSearchItem error, itemName is empty');
return;
}
const rdbStore = await this.getRdbStore();
try {
rdbStore.beginTransaction();
const predicates = new relationalStore.RdbPredicates(OPERATION_TABLE);
let curLocale: string = i18n.System.getSystemLocale();
predicates.equalTo('locale', curLocale).and().equalTo('itemName', itemName)
.and().equalTo('bundleName', bundleName);
let result = await rdbStore.delete(predicates);
rdbStore.commit();
LogUtil.showInfo(TAG, `delete search item operation: ${curLocale}, ${itemName} changeRows: ${result}`);
} catch (error) {
LogUtil.showError(TAG, `deleteSearchItem operation error, message: ${error?.message},
code: ${error?.code}, ${RDB_CORRUPTION_ERROR_CODE}, ${error?.code === RDB_CORRUPTION_ERROR_CODE}}`);
if (error?.code === RDB_CORRUPTION_ERROR_CODE) {
await super.restoreRdb();
}
rdbStore.rollBack();
}
}
private getDbBucketList(itemInfo: SearchItemOperation): relationalStore.ValuesBucket {
return {
'locale': itemInfo.locale,
'itemName': itemInfo.itemName,
'itemTitle': itemInfo.itemTitle,
'itemDescription': itemInfo.itemDescription,
'entryKey': itemInfo.entryKey,
'pageTitle': itemInfo.pageTitle,
'params': itemInfo.params,
'enable': itemInfo.enable ? ENABLED_TRUE : ENABLED_FALSE,
'icon': itemInfo.icon,
'alias': itemInfo.alias,
'childItems': itemInfo.childItems,
'path': itemInfo.path,
'bundleName': itemInfo.bundleName,
'checkType': itemInfo.checkType,
'checkKey': itemInfo.checkKey,
'checkValue': itemInfo.checkValue,
'content': itemInfo.content,
'status': itemInfo.status,
'timestamp': itemInfo.timestamp,
'businessId': itemInfo.businessId,
'optBundleName': itemInfo.optBundleName,
}
}
}
export default new SearchItemOperationManager();