|
@@ -619,23 +619,31 @@ export default class MediaTable {
|
|
|
*/
|
|
*/
|
|
|
public async querySongsByArtist(artist: string, sortType?: number, isShowFileName?: boolean): Promise<VideoItem[]> {
|
|
public async querySongsByArtist(artist: string, sortType?: number, isShowFileName?: boolean): Promise<VideoItem[]> {
|
|
|
try {
|
|
try {
|
|
|
- const predicates = new relationalStore.RdbPredicates(RdbUtils.MEDIA_TABLE.tableName);
|
|
|
|
|
- predicates.equalTo(DB_COLUMNS.ARTIST, artist);
|
|
|
|
|
- predicates.equalTo(DB_COLUMNS.TYPE, CommonConstants.TYPE_LOCAL);
|
|
|
|
|
- this.applySortConditions(predicates, sortType, isShowFileName);
|
|
|
|
|
|
|
+ const trimmedArtist = artist?.trim() || '';
|
|
|
|
|
+ if (!trimmedArtist) {
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- return await new Promise((resolve, reject) => {
|
|
|
|
|
- this.accountTable.query(predicates, (resultSet: relationalStore.ResultSet) => {
|
|
|
|
|
- try {
|
|
|
|
|
- const result = this.parseResultSetToVideoItems(resultSet, sortType);
|
|
|
|
|
- resolve(result);
|
|
|
|
|
- } catch (err) {
|
|
|
|
|
- reject(err);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ // 使用SQL的TRIM函数匹配,解决数据库中artist字段可能有前后空格的问题
|
|
|
|
|
+ const tableName = RdbUtils.MEDIA_TABLE.tableName;
|
|
|
|
|
+ let orderBy = `${DB_COLUMNS.NAME} COLLATE NOCASE ASC`;
|
|
|
|
|
+ if (isShowFileName) {
|
|
|
|
|
+ orderBy = `${DB_COLUMNS.FILE_NAME} COLLATE NOCASE ASC`;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const sql = `SELECT * FROM ${tableName} WHERE TRIM(${DB_COLUMNS.ARTIST}) = ? AND ${DB_COLUMNS.TYPE} = ? ORDER BY ${orderBy}`;
|
|
|
|
|
+ const params: (string | number)[] = [trimmedArtist, CommonConstants.TYPE_LOCAL];
|
|
|
|
|
+
|
|
|
|
|
+ const resultSet = await this.accountTable.querySql(sql, params);
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result = this.parseResultSetToVideoItems(resultSet, sortType);
|
|
|
|
|
+ return result;
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ resultSet.close();
|
|
|
|
|
+ }
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
|
- Logger.error(`querySongsByArtist error: ${err.code} - ${err.message}`);
|
|
|
|
|
|
|
+ const error = err as Error;
|
|
|
|
|
+ Logger.error('heanup MediaTable', `querySongsByArtist error: ${error.message}`);
|
|
|
return [];
|
|
return [];
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -645,23 +653,31 @@ export default class MediaTable {
|
|
|
*/
|
|
*/
|
|
|
public async querySongsByAlbum(album: string, sortType?: number, isShowFileName?: boolean): Promise<VideoItem[]> {
|
|
public async querySongsByAlbum(album: string, sortType?: number, isShowFileName?: boolean): Promise<VideoItem[]> {
|
|
|
try {
|
|
try {
|
|
|
- const predicates = new relationalStore.RdbPredicates(RdbUtils.MEDIA_TABLE.tableName);
|
|
|
|
|
- predicates.equalTo(DB_COLUMNS.ALBUM, album);
|
|
|
|
|
- predicates.equalTo(DB_COLUMNS.TYPE, CommonConstants.TYPE_LOCAL);
|
|
|
|
|
- this.applySortConditions(predicates, sortType, isShowFileName);
|
|
|
|
|
|
|
+ const trimmedAlbum = album?.trim() || '';
|
|
|
|
|
+ if (!trimmedAlbum) {
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- return await new Promise((resolve, reject) => {
|
|
|
|
|
- this.accountTable.query(predicates, (resultSet: relationalStore.ResultSet) => {
|
|
|
|
|
- try {
|
|
|
|
|
- const result = this.parseResultSetToVideoItems(resultSet, sortType);
|
|
|
|
|
- resolve(result);
|
|
|
|
|
- } catch (err) {
|
|
|
|
|
- reject(err);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ // 使用SQL的TRIM函数匹配,解决数据库中album字段可能有前后空格的问题
|
|
|
|
|
+ const tableName = RdbUtils.MEDIA_TABLE.tableName;
|
|
|
|
|
+ let orderBy = `${DB_COLUMNS.NAME} COLLATE NOCASE ASC`;
|
|
|
|
|
+ if (isShowFileName) {
|
|
|
|
|
+ orderBy = `${DB_COLUMNS.FILE_NAME} COLLATE NOCASE ASC`;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const sql = `SELECT * FROM ${tableName} WHERE TRIM(${DB_COLUMNS.ALBUM}) = ? AND ${DB_COLUMNS.TYPE} = ? ORDER BY ${orderBy}`;
|
|
|
|
|
+ const params: (string | number)[] = [trimmedAlbum, CommonConstants.TYPE_LOCAL];
|
|
|
|
|
+
|
|
|
|
|
+ const resultSet = await this.accountTable.querySql(sql, params);
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result = this.parseResultSetToVideoItems(resultSet, sortType);
|
|
|
|
|
+ return result;
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ resultSet.close();
|
|
|
|
|
+ }
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
|
- Logger.error(`querySongsByAlbum error: ${err.code} - ${err.message}`);
|
|
|
|
|
|
|
+ const error = err as Error;
|
|
|
|
|
+ Logger.error('heanup MediaTable', `querySongsByAlbum error: ${error.message}`);
|
|
|
return [];
|
|
return [];
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -1506,7 +1522,8 @@ export default class MediaTable {
|
|
|
}
|
|
}
|
|
|
const whereSql = whereClauses.join(' AND ');
|
|
const whereSql = whereClauses.join(' AND ');
|
|
|
|
|
|
|
|
- const totalSql = `SELECT COUNT(DISTINCT ${columnName}) AS totalCount FROM ${tableName} WHERE ${whereSql}`;
|
|
|
|
|
|
|
+ // 使用TRIM函数去除空格,合并相同艺术家/专辑名的数据
|
|
|
|
|
+ const totalSql = `SELECT COUNT(DISTINCT TRIM(${columnName})) AS totalCount FROM ${tableName} WHERE ${whereSql}`;
|
|
|
const totalResultSet = await this.accountTable.querySql(totalSql, params);
|
|
const totalResultSet = await this.accountTable.querySql(totalSql, params);
|
|
|
let totalCount = 0;
|
|
let totalCount = 0;
|
|
|
if (totalResultSet.goToFirstRow()) {
|
|
if (totalResultSet.goToFirstRow()) {
|
|
@@ -1515,21 +1532,21 @@ export default class MediaTable {
|
|
|
totalResultSet.close();
|
|
totalResultSet.close();
|
|
|
|
|
|
|
|
const sortType = options.sortType ?? 9;
|
|
const sortType = options.sortType ?? 9;
|
|
|
- let orderBy = `${columnName} ASC`;
|
|
|
|
|
|
|
+ let orderBy = `name ASC`;
|
|
|
if (sortType === 5) {
|
|
if (sortType === 5) {
|
|
|
- orderBy = `${columnName} DESC`;
|
|
|
|
|
|
|
+ orderBy = `name DESC`;
|
|
|
} else if (sortType === 8) {
|
|
} else if (sortType === 8) {
|
|
|
- orderBy = `songCount ASC, ${columnName} ASC`;
|
|
|
|
|
|
|
+ orderBy = `songCount ASC, name ASC`;
|
|
|
} else if (sortType === 9) {
|
|
} else if (sortType === 9) {
|
|
|
- orderBy = `songCount DESC, ${columnName} ASC`;
|
|
|
|
|
|
|
+ orderBy = `songCount DESC, name ASC`;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const offset = options.pageIndex * options.pageSize;
|
|
const offset = options.pageIndex * options.pageSize;
|
|
|
const pageSql =
|
|
const pageSql =
|
|
|
- `SELECT ${columnName} AS name, COUNT(*) AS songCount, ` +
|
|
|
|
|
|
|
+ `SELECT TRIM(${columnName}) AS name, COUNT(*) AS songCount, ` +
|
|
|
`MAX(${DB_COLUMNS.PIXEL_MAP_PATH}) AS coverPath ` +
|
|
`MAX(${DB_COLUMNS.PIXEL_MAP_PATH}) AS coverPath ` +
|
|
|
`FROM ${tableName} WHERE ${whereSql} ` +
|
|
`FROM ${tableName} WHERE ${whereSql} ` +
|
|
|
- `GROUP BY ${columnName} ` +
|
|
|
|
|
|
|
+ `GROUP BY TRIM(${columnName}) ` +
|
|
|
`HAVING COUNT(*) > 0 ` +
|
|
`HAVING COUNT(*) > 0 ` +
|
|
|
`ORDER BY ${orderBy} ` +
|
|
`ORDER BY ${orderBy} ` +
|
|
|
`LIMIT ? OFFSET ?`;
|
|
`LIMIT ? OFFSET ?`;
|
|
@@ -1541,7 +1558,7 @@ export default class MediaTable {
|
|
|
if (resultSet.rowCount > 0) {
|
|
if (resultSet.rowCount > 0) {
|
|
|
resultSet.goToFirstRow();
|
|
resultSet.goToFirstRow();
|
|
|
for (let i = 0; i < resultSet.rowCount; i++) {
|
|
for (let i = 0; i < resultSet.rowCount; i++) {
|
|
|
- const name = resultSet.getString(resultSet.getColumnIndex('name'));
|
|
|
|
|
|
|
+ const name = resultSet.getString(resultSet.getColumnIndex('name')) || '';
|
|
|
const songCount = resultSet.getLong(resultSet.getColumnIndex('songCount'));
|
|
const songCount = resultSet.getLong(resultSet.getColumnIndex('songCount'));
|
|
|
const coverPath = resultSet.getString(resultSet.getColumnIndex('coverPath')) || '';
|
|
const coverPath = resultSet.getString(resultSet.getColumnIndex('coverPath')) || '';
|
|
|
countMap.set(name, songCount);
|
|
countMap.set(name, songCount);
|