|
|
@@ -5,6 +5,67 @@ import Logger from './Logger';
|
|
|
import RdbUtils from './RdbUtils';
|
|
|
import { Utility } from './Utility';
|
|
|
|
|
|
+/**
|
|
|
+ * 数据库字段常量接口定义
|
|
|
+ */
|
|
|
+interface DBColumnsInterface {
|
|
|
+ ID: string;
|
|
|
+ NAME: string;
|
|
|
+ FILE_PATH: string;
|
|
|
+ TYPE: string;
|
|
|
+ VIDEO_SIZE: string;
|
|
|
+ C_TIME: string;
|
|
|
+ PARENT_PATH: string;
|
|
|
+ IS_FAV: string;
|
|
|
+ PIXEL_MAP_PATH: string;
|
|
|
+ ARTIST: string;
|
|
|
+ ALBUM: string;
|
|
|
+ FILE_NAME: string;
|
|
|
+ SIZE: string;
|
|
|
+ DURATION: string;
|
|
|
+ MIME_TYPE: string;
|
|
|
+ TRACK_COUNT: string;
|
|
|
+ SAMPLE_RATE: string;
|
|
|
+ LAST_PLAYED_STR: string;
|
|
|
+ PLAY_COUNT: string;
|
|
|
+ LYRIC_CONTENT: string;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 媒体元数据接口定义
|
|
|
+ */
|
|
|
+export interface MediaMetadata {
|
|
|
+ duration?: string;
|
|
|
+ mimeType?: string;
|
|
|
+ sampleRate?: string;
|
|
|
+ trackCount?: string;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 数据库字段常量,避免硬编码
|
|
|
+ */
|
|
|
+const DB_COLUMNS: DBColumnsInterface = {
|
|
|
+ ID: 'id',
|
|
|
+ NAME: 'name',
|
|
|
+ FILE_PATH: 'filePath',
|
|
|
+ TYPE: 'mtype',
|
|
|
+ VIDEO_SIZE: 'videoSize',
|
|
|
+ C_TIME: 'cTime',
|
|
|
+ PARENT_PATH: 'parentPath',
|
|
|
+ IS_FAV: 'isFav',
|
|
|
+ PIXEL_MAP_PATH: 'pixelMapPath',
|
|
|
+ ARTIST: 'artist',
|
|
|
+ ALBUM: 'album',
|
|
|
+ FILE_NAME: 'fileName',
|
|
|
+ SIZE: 'size',
|
|
|
+ DURATION: 'duration',
|
|
|
+ MIME_TYPE: 'mimeType',
|
|
|
+ TRACK_COUNT: 'trackCount',
|
|
|
+ SAMPLE_RATE: 'sampleRate',
|
|
|
+ LAST_PLAYED_STR: 'lastPlayedStr',
|
|
|
+ PLAY_COUNT: 'playCount',
|
|
|
+ LYRIC_CONTENT: 'lyricContent'
|
|
|
+};
|
|
|
|
|
|
export default class MediaTable {
|
|
|
private accountTable = new RdbUtils(RdbUtils.MEDIA_TABLE.tableName, RdbUtils.MEDIA_TABLE.sqlCreate,
|
|
|
@@ -228,15 +289,12 @@ export default class MediaTable {
|
|
|
console.log(`${RdbUtils.RDB_TAG}` + 'Query no results!');
|
|
|
callback([]);
|
|
|
} else {
|
|
|
-
|
|
|
-
|
|
|
const result = this.parseResultSetToVideoItems(resultSet);
|
|
|
callback(result);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-
|
|
|
// 新增方法:根据parentPath查询数据
|
|
|
public queryByParentPath(path: string, callback: (result: VideoItem[]) => void) {
|
|
|
try {
|
|
|
@@ -249,14 +307,12 @@ export default class MediaTable {
|
|
|
const result = this.parseResultSetToVideoItems(resultSet);
|
|
|
callback(result);
|
|
|
});
|
|
|
- }catch (err) {
|
|
|
- Logger.error(` onecold testtag queryByParentPath: ${err.code} - ${err.message}`);
|
|
|
-
|
|
|
+ } catch (err) {
|
|
|
+ Logger.error(`查询parentPath失败: ${err.message}`);
|
|
|
+ callback([]);
|
|
|
}
|
|
|
- // 1. 构建查询条件
|
|
|
-
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 查询所有艺术家及其歌曲(返回Map结构:artist -> VideoItem[])
|
|
|
public queryArtistsWithSongs(callback: (result: Map<string, VideoItem[]>) => void) {
|
|
|
// 1. 查询去重的艺术家列表(非空)
|
|
|
@@ -290,9 +346,6 @@ export default class MediaTable {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
// 查询所有专辑及其歌曲(返回Map结构:album -> VideoItem[])
|
|
|
public queryAlbumsWithSongs(callback: (result: Map<string, VideoItem[]>) => void) {
|
|
|
// 1. 查询去重的专辑列表(非空)
|
|
|
@@ -326,8 +379,6 @@ export default class MediaTable {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
// 解析去重列数据(如artist/album)
|
|
|
private parseDistinctColumn(resultSet: relationalStore.ResultSet, columnName: string): string[] {
|
|
|
const uniqueValues = new Set<string>(); // 使用Set特性自动去重
|
|
|
@@ -347,69 +398,122 @@ export default class MediaTable {
|
|
|
return Array.from(uniqueValues); // Set转数组
|
|
|
}
|
|
|
|
|
|
- // 将ResultSet解析为VideoItem数组(复用原有逻辑)
|
|
|
+ // 将ResultSet解析为VideoItem数组
|
|
|
private parseResultSetToVideoItems(resultSet: relationalStore.ResultSet): VideoItem[] {
|
|
|
const items: VideoItem[] = [];
|
|
|
|
|
|
try {
|
|
|
- // 逆向遍历方案(规避鸿蒙API特性)
|
|
|
- while (resultSet.goToNextRow()) { // 自动边界检查
|
|
|
- const item = this.buildVideoItem(resultSet);
|
|
|
- // let id = resultSet.getString(resultSet.getColumnIndex('id'));
|
|
|
- // let name = resultSet.getString(resultSet.getColumnIndex('name'));
|
|
|
- // let filePath = resultSet.getString(resultSet.getColumnIndex('filePath'));
|
|
|
- // let type = resultSet.getDouble(resultSet.getColumnIndex('mtype'));
|
|
|
- // let videoSize = resultSet.getDouble(resultSet.getColumnIndex('videoSize'));
|
|
|
- // let cTime = resultSet.getString(resultSet.getColumnIndex('cTime'));
|
|
|
- // let size = resultSet.getString(resultSet.getColumnIndex('size'));
|
|
|
- // let parentPath = resultSet.getString(resultSet.getColumnIndex('parentPath'));
|
|
|
- //
|
|
|
- // let pixelMapToString = resultSet.getString(resultSet.getColumnIndex('pixelMapToString'));
|
|
|
- // let artist = resultSet.getString(resultSet.getColumnIndex('artist'));
|
|
|
- // let album = resultSet.getString(resultSet.getColumnIndex('album'));
|
|
|
- // let fileName = resultSet.getString(resultSet.getColumnIndex('fileName'));
|
|
|
- // let item = new VideoItem(name, id, filePath, type, videoSize, cTime,
|
|
|
- // undefined,size,pixelMapToString,artist,album,fileName);
|
|
|
- items.push(item);
|
|
|
+ // 检查结果集是否有效
|
|
|
+ if (resultSet && resultSet.rowCount > 0) {
|
|
|
+ while (resultSet.goToNextRow()) {
|
|
|
+ const item = this.buildVideoItem(resultSet);
|
|
|
+ items.push(item);
|
|
|
+ }
|
|
|
}
|
|
|
- // 释放数据集的内存
|
|
|
- resultSet.close();
|
|
|
} catch (err) {
|
|
|
- Logger.error(` onecold testtag parseResultSetToVideoItems: ${err.code} - ${err.message}`);
|
|
|
+ Logger.error(`解析结果集出错: ${err.message}`);
|
|
|
+ } finally {
|
|
|
+ // 确保结果集被关闭
|
|
|
+ if (resultSet) {
|
|
|
+ resultSet.close();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-
|
|
|
return items;
|
|
|
}
|
|
|
|
|
|
private buildVideoItem(rs: relationalStore.ResultSet): VideoItem {
|
|
|
// 添加空值保护
|
|
|
- const safeGet = (col: string) => rs.getColumnIndex(col) >= 0 ? rs.getString(rs.getColumnIndex(col)) : '';
|
|
|
-
|
|
|
- let item = new VideoItem(
|
|
|
- safeGet('name'),
|
|
|
- safeGet('id'),
|
|
|
- safeGet('filePath'),
|
|
|
- rs.getDouble(rs.getColumnIndex('mtype')) || 0,
|
|
|
- rs.getDouble(rs.getColumnIndex('videoSize')) || 0,safeGet('cTime'),undefined,safeGet('size'),
|
|
|
- safeGet('pixelMapPath'),safeGet('artist'),
|
|
|
- safeGet('album'),safeGet('fileName')
|
|
|
+ const safeGet = (col: string) => {
|
|
|
+ const index = rs.getColumnIndex(col);
|
|
|
+ return index >= 0 ? rs.getString(index) || '' : '';
|
|
|
+ };
|
|
|
+
|
|
|
+ const safeGetNumber = (col: string) => {
|
|
|
+ const index = rs.getColumnIndex(col);
|
|
|
+ return index >= 0 ? rs.getDouble(index) || 0 : 0;
|
|
|
+ };
|
|
|
+
|
|
|
+ let item = new VideoItem(
|
|
|
+ safeGet(DB_COLUMNS.NAME),
|
|
|
+ safeGet(DB_COLUMNS.ID),
|
|
|
+ safeGet(DB_COLUMNS.FILE_PATH),
|
|
|
+ safeGetNumber(DB_COLUMNS.TYPE),
|
|
|
+ safeGetNumber(DB_COLUMNS.VIDEO_SIZE),
|
|
|
+ safeGet(DB_COLUMNS.C_TIME),
|
|
|
+ undefined,
|
|
|
+ safeGet(DB_COLUMNS.SIZE),
|
|
|
+ safeGet(DB_COLUMNS.PIXEL_MAP_PATH),
|
|
|
+ safeGet(DB_COLUMNS.ARTIST),
|
|
|
+ safeGet(DB_COLUMNS.ALBUM),
|
|
|
+ safeGet(DB_COLUMNS.FILE_NAME)
|
|
|
);
|
|
|
- item.isFav = rs.getDouble(rs.getColumnIndex('isFav'));
|
|
|
-
|
|
|
- item.duration = safeGet('duration');
|
|
|
- item.mimeType = safeGet('mimeType');
|
|
|
- item.trackCount = safeGet('trackCount');
|
|
|
- item.sampleRate = safeGet('sampleRate');
|
|
|
- item.lastPlayedStr =safeGet('lastPlayedStr');
|
|
|
- // item.playCount = rs.getDouble(rs.getColumnIndex('playCount'));
|
|
|
- item.lyricContent = safeGet('lyricContent')
|
|
|
-
|
|
|
- return item
|
|
|
+
|
|
|
+ // 设置额外属性,添加安全检查
|
|
|
+ item.isFav = safeGetNumber(DB_COLUMNS.IS_FAV);
|
|
|
+ item.duration = safeGet(DB_COLUMNS.DURATION);
|
|
|
+ item.mimeType = safeGet(DB_COLUMNS.MIME_TYPE);
|
|
|
+ item.trackCount = safeGet(DB_COLUMNS.TRACK_COUNT);
|
|
|
+ item.sampleRate = safeGet(DB_COLUMNS.SAMPLE_RATE);
|
|
|
+ item.lastPlayedStr = safeGet(DB_COLUMNS.LAST_PLAYED_STR);
|
|
|
+ item.playCount = safeGetNumber(DB_COLUMNS.PLAY_COUNT);
|
|
|
+ item.lyricContent = safeGet(DB_COLUMNS.LYRIC_CONTENT);
|
|
|
+
|
|
|
+ return item;
|
|
|
}
|
|
|
|
|
|
+ // 根据文件路径查询数据
|
|
|
+ public queryByFilePath(filePath: string, callback: (result: VideoItem[]) => void) {
|
|
|
+ try {
|
|
|
+ const predicates = new relationalStore.RdbPredicates(RdbUtils.MEDIA_TABLE.tableName);
|
|
|
+ predicates.equalTo('filePath', filePath);
|
|
|
|
|
|
+ // 执行查询并处理结果
|
|
|
+ this.accountTable.query(predicates, (resultSet: relationalStore.ResultSet) => {
|
|
|
+ // 复用已有的解析逻辑
|
|
|
+ const result = this.parseResultSetToVideoItems(resultSet);
|
|
|
+ callback(result);
|
|
|
+ });
|
|
|
+ } catch (err) {
|
|
|
+ Logger.error(`查询文件路径失败 - filePath: ${filePath}, error: ${err.code} - ${err.message}`);
|
|
|
+ callback([]);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ // 更新媒体文件的元数据信息(采样率、MIME类型等)
|
|
|
+ public updateMediaMetadata(filePath: string, metadata: MediaMetadata, callback: (success: boolean) => void) {
|
|
|
+ try {
|
|
|
+ // 构建查询条件
|
|
|
+ const predicates = new relationalStore.RdbPredicates(RdbUtils.MEDIA_TABLE.tableName);
|
|
|
+ predicates.equalTo('filePath', filePath);
|
|
|
+
|
|
|
+ // 构建更新值
|
|
|
+ const valuesToUpdate: relationalStore.ValuesBucket = {};
|
|
|
+ if (metadata.duration) {
|
|
|
+ valuesToUpdate.duration = metadata.duration;
|
|
|
+ }
|
|
|
+ if (metadata.mimeType) {
|
|
|
+ valuesToUpdate.mimeType = metadata.mimeType;
|
|
|
+ }
|
|
|
+ if (metadata.sampleRate) {
|
|
|
+ valuesToUpdate.sampleRate = metadata.sampleRate;
|
|
|
+ }
|
|
|
+ if (metadata.trackCount) {
|
|
|
+ valuesToUpdate.trackCount = metadata.trackCount;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 执行更新
|
|
|
+ if (Object.keys(valuesToUpdate).length > 0) {
|
|
|
+ this.accountTable.updateData(predicates, valuesToUpdate, callback);
|
|
|
+ } else {
|
|
|
+ Logger.info('No metadata to update');
|
|
|
+ callback(false);
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ Logger.error(`更新媒体元数据失败: ${err.message}`);
|
|
|
+ callback(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
function generateBucket(item: VideoItem): relationalStore.ValuesBucket {
|
|
|
@@ -423,9 +527,6 @@ function generateBucket(item: VideoItem): relationalStore.ValuesBucket {
|
|
|
obj.parentPath = item.parentPath;
|
|
|
obj.isFav = item.isFav;
|
|
|
|
|
|
- // if(item.pixelMapToString){
|
|
|
- // obj.pixelMapToString = item.pixelMapToString;
|
|
|
- // }
|
|
|
if(item.artist){
|
|
|
obj.artist = item.artist;
|
|
|
}
|
|
|
@@ -442,7 +543,6 @@ function generateBucket(item: VideoItem): relationalStore.ValuesBucket {
|
|
|
obj.pixelMapPath = item.pixelMapPath;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
if(item.duration){
|
|
|
obj.duration = item.duration;
|
|
|
}
|