* Copyright (c) Huawei Device 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 { RdbStoreHelper } from '@ohos/frameworkwrapper/src/main/ets/service/db/RdbStoreHelper';
import { ArrayUtils, DomainName, LogDomain, LogHelper, TraceUtil } from '@ohos/basicutils';
import { DeviceHelper, HiDfxEventUtil } from '@ohos/frameworkwrapper';
import rdb from '@ohos.data.relationalStore';
import { IDataHandler } from './InfoDataHandleController';
import GridLayoutInfoColumns, { GridLayoutInfoEnums } from './column/GridLayoutInfoColumns';
import { CommonConstants } from '../constants/CommonConstants';
import GridLayoutItemInfoDB from '../entity/GridLayoutItemInfoDataBase';
import type GridLayoutItemInfo from '../bean/GridLayoutItemInfo';
import { SceneMsgEnum } from '../TsIndex';
const TAG: string = 'MinorUpdateHandler';
const log: LogHelper = LogHelper.getLogHelper(LogDomain.HOME, TAG);
const MAX_DOCK_NUM = 4;
* 修改少量数据时的处理方案:遍历数据在数据库中是否存在,存在则更新,不存在则添加入数据库,总计操作2*size次sql
* 单次sql执行效率更高,但是累积操作次数较多,适合精准更新少量数据
*/
export default class MinorUpdateHandler implements IDataHandler {
async handleDataToRdb(target: string, gridItemList: GridLayoutItemInfo[],
rdbStoreHelper: RdbStoreHelper, container?: number, screenId?: number, reason?: string):
Promise<void> {
if (ArrayUtils.isEmpty(gridItemList)) {
log.showError('gridItemList is null on handleDataToRdb');
return;
}
log.showInfo('handleDataToRdb target: %{public}s, dataSize: %{public}d', target, gridItemList.length);
for (let i = 0; i < gridItemList.length; i++) {
let element: GridLayoutItemInfo = gridItemList[i];
const predicates = new rdb.RdbPredicates(target);
predicates.equalTo(GridLayoutInfoColumns.TYPE_ID, element.typeId);
if (!DeviceHelper.isPhoneOrPad()) {
predicates.and().notEqualTo(GridLayoutInfoColumns.CONTAINER, CommonConstants.CONTAINER_SMARTDOCK);
const conditionContainer = container ?? element.container;
if (conditionContainer) {
predicates.and().equalTo(GridLayoutInfoColumns.CONTAINER, conditionContainer);
}
}
if (element.typeId === CommonConstants.TYPE_FOLDER || element.typeId === CommonConstants.TYPE_REGION_FOLDER) {
predicates.and().equalTo(GridLayoutInfoColumns.INFO_ID, element.folderId);
} else if (element.typeId === CommonConstants.TYPE_CARD) {
predicates.and().equalTo(GridLayoutInfoColumns.INFO_ID, element.cardId);
} else if (element.typeId === CommonConstants.TYPE_FILE_FOLDER) {
predicates.and().equalTo(GridLayoutInfoColumns.FILE_INO, element.ino);
} else if (element.typeId === CommonConstants.TYPE_FORM_STACK) {
predicates.and().equalTo(GridLayoutInfoColumns.INFO_ID, element.formStackId);
} else {
predicates.and().equalTo(GridLayoutInfoColumns.BUNDLE_NAME, element.bundleName);
if (element.typeId === CommonConstants.TYPE_APP) {
predicates.and().equalTo(GridLayoutInfoColumns.APP_INDEX, element.appIndex ?? 0);
}
if (element.typeId === CommonConstants.TYPE_SHORTCUT_ICON) {
predicates.and().equalTo(GridLayoutInfoColumns.APP_INDEX, element.appIndex ?? 0)
.and().equalTo(GridLayoutInfoColumns.SHORTCUT_ID, element.shortcutId ?? '');
}
}
let isExist: boolean = await rdbStoreHelper.isExistData(predicates);
if (isExist) {
let valuesBucket: rdb.ValuesBucket = {
[GridLayoutInfoEnums.ROW]: element.row,
[GridLayoutInfoEnums.COLUMN]: element.column,
[GridLayoutInfoEnums.PAGE_INDEX]: element.page,
[GridLayoutInfoEnums.PORTRAIT_ROW]: element.portraitRow,
[GridLayoutInfoEnums.PORTRAIT_COLUMN]: element.portraitColumn,
[GridLayoutInfoEnums.PORTRAIT_PAGE_INDEX]: element.portraitPage,
[GridLayoutInfoEnums.PORTRAIT_WIDTH]: element.portraitArea?.[0] ?? -1,
[GridLayoutInfoEnums.PORTRAIT_HEIGHT]: element.portraitArea?.[1] ?? -1,
[GridLayoutInfoEnums.LANDSCAPE_ROW]: element.landscapeRow,
[GridLayoutInfoEnums.LANDSCAPE_COLUMN]: element.landscapeColumn,
[GridLayoutInfoEnums.LANDSCAPE_PAGE_INDEX]: element.landscapePage,
[GridLayoutInfoEnums.LANDSCAPE_WIDTH]: element.landscapeArea?.[0] ?? -1,
[GridLayoutInfoEnums.LANDSCAPE_HEIGHT]: element.landscapeArea?.[1] ?? -1,
[GridLayoutInfoEnums.CONTAINER]: container ? container : element.container,
[GridLayoutInfoEnums.WIDTH]: element.area?.[0],
[GridLayoutInfoEnums.HEIGHT]: element.area?.[1],
[GridLayoutInfoEnums.SCREEN_ID]: screenId ?? 0,
};
if (element.typeId === CommonConstants.TYPE_FILE_FOLDER ||
element.typeId === CommonConstants.TYPE_REGION_FOLDER) {
valuesBucket[GridLayoutInfoColumns.URI] = element.uri;
valuesBucket[GridLayoutInfoColumns.INFO_NAME] = element.fileFolderName;
}
let num: number = await rdbStoreHelper.update(predicates, valuesBucket, undefined, SceneMsgEnum.MINOR_UPDATE, false, 0, target);
this.toLog('update', target, element, num, container);
continue;
}
log.showInfo('insert item to rdb, target: %{public}s, bundleName: %{public}s', target, element.bundleName);
let valuesBucket: rdb.ValuesBucket = GridLayoutItemInfoDB.toGridLayoutItemInfoDB(element).toValuesBucket();
valuesBucket[GridLayoutInfoColumns.CONTAINER] = container ? container : element.container;
let num: number = await rdbStoreHelper.insert(target, valuesBucket);
this.toLog('insert', target, element, num, container);
}
for (let i = 0; i < gridItemList.length; i++) {
const conditionContainer = container ?? gridItemList[i].container;
if (DeviceHelper.isPhone() && conditionContainer === CommonConstants.CONTAINER_SMARTDOCK) {
let predicates = new rdb.RdbPredicates(target);
predicates.equalTo(GridLayoutInfoColumns.CONTAINER, CommonConstants.CONTAINER_SMARTDOCK);
predicates.orderByAsc(GridLayoutInfoColumns.COLUMN);
let resultSet = await rdbStoreHelper.query(predicates, []);
const count: number = resultSet.columnCount;
if (count > MAX_DOCK_NUM) {
HiDfxEventUtil.reportDockRegionItemsCount(CommonConstants.DOCK_RESIDENT, count, reason);
}
break;
}
}
}
private toLog(label: string, target: string, element: GridLayoutItemInfo, num: number,
container?: number): void {
let res: string = num > 0 ? 'success' : 'failed';
log.showWarn('%{public}s item to rdb %{public}s, target: %{public}s, bundleName: %{public}s, num: %{public}d, container: %{public}d, page: %{public}d, row: %{public}d, column: %{public}d',
label, res, target, element.bundleName, num, container ? container : element.container, element.page, element.row,
element.column);
}
}