v2.0.0
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
import Database from 'better-sqlite3'
|
||||
import path from 'path'
|
||||
// import migrateData from './migrate'
|
||||
|
||||
let db: Database.Database
|
||||
|
||||
|
||||
const initTables = (db: Database.Database) => {
|
||||
db.exec(`
|
||||
CREATE TABLE "db_info" (
|
||||
"id" INTEGER NOT NULL UNIQUE,
|
||||
"field_name" TEXT,
|
||||
"field_value" TEXT,
|
||||
PRIMARY KEY("id" AUTOINCREMENT)
|
||||
)`)
|
||||
|
||||
db.prepare(`INSERT INTO "main"."db_info" ("field_name", "field_value") VALUES
|
||||
('version', '1')
|
||||
`).run()
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE "my_list" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"source" TEXT,
|
||||
"sourceListId" TEXT,
|
||||
"position" INTEGER NOT NULL,
|
||||
"locationUpdateTime" INTEGER,
|
||||
PRIMARY KEY("id")
|
||||
)`)
|
||||
// const insert = db.prepare(`INSERT INTO "main"."my_list" ("id", "name", "source", "sourceListId", "locationUpdateTime") VALUES
|
||||
// (@id, @name, @source, @sourceListId, @locationUpdateTime)`)
|
||||
// db.transaction((cats) => {
|
||||
// for (const cat of cats) insert.run(cat)
|
||||
// })([
|
||||
// { id: 'default', name: '默认列表', source: null, sourceListId: null, locationUpdateTime: null },
|
||||
// { id: 'love', name: '收藏列表', source: null, sourceListId: null, locationUpdateTime: null },
|
||||
// { id: 'temp', name: '临时列表', source: null, sourceListId: null, locationUpdateTime: null },
|
||||
// ])
|
||||
db.exec(`
|
||||
CREATE TABLE "my_list_music_info" (
|
||||
"id" TEXT NOT NULL,
|
||||
"listId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"singer" TEXT NOT NULL,
|
||||
"source" TEXT NOT NULL,
|
||||
"interval" TEXT,
|
||||
"meta" TEXT NOT NULL,
|
||||
UNIQUE("id","listId")
|
||||
)`)
|
||||
db.exec(`
|
||||
CREATE INDEX "index_my_list_music_info" ON "my_list_music_info" (
|
||||
"id",
|
||||
"listId"
|
||||
)`)
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE "my_list_music_info_order" (
|
||||
"listId" TEXT NOT NULL,
|
||||
"musicInfoId" TEXT NOT NULL,
|
||||
"order" INTEGER NOT NULL
|
||||
)`)
|
||||
db.exec(`
|
||||
CREATE INDEX "index_my_list_music_info_order" ON "my_list_music_info_order" (
|
||||
"listId",
|
||||
"musicInfoId"
|
||||
)`)
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE "music_info_other_source" (
|
||||
"source_id" TEXT NOT NULL,
|
||||
"id" TEXT NOT NULL,
|
||||
"source" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"singer" TEXT NOT NULL,
|
||||
"meta" TEXT NOT NULL,
|
||||
"order" INTEGER NOT NULL,
|
||||
UNIQUE("source_id","id")
|
||||
)`)
|
||||
db.exec(`
|
||||
CREATE INDEX "index_music_info_other_source" ON "music_info_other_source" (
|
||||
"source_id",
|
||||
"id"
|
||||
)`)
|
||||
|
||||
// TODO "meta" TEXT NOT NULL,
|
||||
db.exec(`
|
||||
CREATE TABLE "lyric" (
|
||||
"id" TEXT NOT NULL,
|
||||
"source" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"text" TEXT NOT NULL
|
||||
)`)
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE "music_url" (
|
||||
"id" TEXT NOT NULL,
|
||||
"url" TEXT NOT NULL
|
||||
)`)
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE "download_list" (
|
||||
"id" TEXT NOT NULL,
|
||||
"isComplate" INTEGER NOT NULL,
|
||||
"status" TEXT NOT NULL,
|
||||
"statusText" TEXT NOT NULL,
|
||||
"progress_downloaded" INTEGER NOT NULL,
|
||||
"progress_total" INTEGER NOT NULL,
|
||||
"url" TEXT,
|
||||
"quality" TEXT NOT NULL,
|
||||
"ext" TEXT NOT NULL,
|
||||
"fileName" TEXT NOT NULL,
|
||||
"filePath" TEXT NOT NULL,
|
||||
"musicInfo" TEXT NOT NULL,
|
||||
"position" INTEGER NOT NULL,
|
||||
PRIMARY KEY("id")
|
||||
)`)
|
||||
}
|
||||
|
||||
|
||||
// 打开、初始化数据库
|
||||
export const init = (lxDataPath: string): boolean => {
|
||||
const databasePath = path.join(lxDataPath, 'lx.data.db')
|
||||
const nativeBinding = path.join(__dirname, '../node_modules/better-sqlite3/build/Release/better_sqlite3.node')
|
||||
let dbFileExists = true
|
||||
|
||||
try {
|
||||
db = new Database(databasePath, {
|
||||
fileMustExist: true,
|
||||
nativeBinding,
|
||||
verbose: global.isDev ? console.log : undefined,
|
||||
})
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
db = new Database(databasePath, {
|
||||
nativeBinding,
|
||||
verbose: global.isDev ? console.log : undefined,
|
||||
})
|
||||
initTables(db)
|
||||
dbFileExists = false
|
||||
}
|
||||
|
||||
// if (dbFileExists) migrateData(db)
|
||||
|
||||
// https://www.sqlite.org/pragma.html#pragma_optimize
|
||||
db.exec('PRAGMA optimize;')
|
||||
|
||||
// https://www.sqlite.org/lang_vacuum.html
|
||||
// db.exec('VACUUM "main"')
|
||||
|
||||
process.on('exit', () => db.close())
|
||||
console.log('db inited')
|
||||
// require('./test')
|
||||
return dbFileExists
|
||||
}
|
||||
|
||||
// 获取数据库实例
|
||||
export const getDB = (): Database.Database => db
|
||||
@@ -0,0 +1,17 @@
|
||||
import { init } from './db'
|
||||
import { exposeWorker } from '../utils/worker'
|
||||
import { list, lyric, music_url, music_other_source, download } from './modules/index'
|
||||
|
||||
|
||||
const common = {
|
||||
init,
|
||||
}
|
||||
|
||||
exposeWorker(Object.assign(common, list, lyric, music_url, music_other_source, download))
|
||||
|
||||
export declare type workerDBSeriveTypes = typeof common
|
||||
& typeof list
|
||||
& typeof lyric
|
||||
& typeof music_url
|
||||
& typeof music_other_source
|
||||
& typeof download
|
||||
@@ -0,0 +1,32 @@
|
||||
import Database from 'better-sqlite3'
|
||||
|
||||
const migrateV1 = (db: Database.Database) => {
|
||||
db.exec('DROP TABLE "main"."download_list"')
|
||||
db.exec(`
|
||||
CREATE TABLE "download_list" (
|
||||
"id" TEXT NOT NULL,
|
||||
"isComplate" INTEGER NOT NULL,
|
||||
"status" TEXT NOT NULL,
|
||||
"statusText" TEXT NOT NULL,
|
||||
"progress_downloaded" INTEGER NOT NULL,
|
||||
"progress_total" INTEGER NOT NULL,
|
||||
"url" TEXT,
|
||||
"quality" TEXT NOT NULL,
|
||||
"ext" TEXT NOT NULL,
|
||||
"fileName" TEXT NOT NULL,
|
||||
"filePath" TEXT NOT NULL,
|
||||
"musicInfo" TEXT NOT NULL,
|
||||
"position" INTEGER NOT NULL,
|
||||
PRIMARY KEY("id")
|
||||
)`)
|
||||
db.prepare('UPDATE "main"."db_info" SET "field_value"=@value WHERE "field_name"=@name').run({ name: 'version', value: '2' })
|
||||
}
|
||||
|
||||
export default (db: Database.Database) => {
|
||||
const version = db.prepare('SELECT "field_value" FROM "main"."db_info" WHERE "field_name" = ?').get('version').field_value
|
||||
switch (version) {
|
||||
case '1':
|
||||
migrateV1(db)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import { getDB } from '../../db'
|
||||
import {
|
||||
createQueryStatement,
|
||||
createInsertStatement,
|
||||
createDeleteStatement,
|
||||
createUpdateStatement,
|
||||
createUpdatePositionStatement,
|
||||
createClearStatement,
|
||||
} from './statements'
|
||||
|
||||
/**
|
||||
* 查询下载歌曲列表
|
||||
*/
|
||||
export const queryDownloadList = (): LX.DBService.DownloadMusicInfo[] => {
|
||||
const queryStatement = createQueryStatement()
|
||||
return queryStatement.all()
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量插入下载歌曲并刷新顺序
|
||||
* @param mInfos 列表
|
||||
*/
|
||||
export const inertDownloadList = (mInfos: LX.DBService.DownloadMusicInfo[], listPositions: Array<{ id: string, position: number }>) => {
|
||||
const db = getDB()
|
||||
const insertStatement = createInsertStatement()
|
||||
const updatePositionStatement = createUpdatePositionStatement()
|
||||
db.transaction((mInfos: LX.DBService.DownloadMusicInfo[]) => {
|
||||
for (const info of mInfos) insertStatement.run(info)
|
||||
for (const info of listPositions) updatePositionStatement.run(info)
|
||||
})(mInfos)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除下载歌曲
|
||||
* @param ids 列表
|
||||
*/
|
||||
export const deleteDownloadList = (ids: string[]) => {
|
||||
const db = getDB()
|
||||
const deleteStatement = createDeleteStatement()
|
||||
db.transaction((ids: string[]) => {
|
||||
for (const id of ids) deleteStatement.run(id)
|
||||
})(ids)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新下载歌曲
|
||||
* @param urlInfo 列表
|
||||
*/
|
||||
export const updateDownloadList = (urlInfo: LX.DBService.DownloadMusicInfo[]) => {
|
||||
const db = getDB()
|
||||
const updateStatement = createUpdateStatement()
|
||||
db.transaction((urlInfo: LX.DBService.DownloadMusicInfo[]) => {
|
||||
for (const info of urlInfo) updateStatement.run(info)
|
||||
})(urlInfo)
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空下载歌曲列表
|
||||
*/
|
||||
export const clearDownloadList = () => {
|
||||
const clearStatement = createClearStatement()
|
||||
clearStatement.run()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
import {
|
||||
queryDownloadList,
|
||||
inertDownloadList,
|
||||
updateDownloadList,
|
||||
deleteDownloadList,
|
||||
clearDownloadList,
|
||||
} from './dbHelper'
|
||||
|
||||
let list: LX.Download.ListItem[]
|
||||
|
||||
const toDBDownloadInfo = (musicInfos: LX.Download.ListItem[], offset: number = 0): LX.DBService.DownloadMusicInfo[] => {
|
||||
return musicInfos.map((info, index) => {
|
||||
return {
|
||||
id: info.id,
|
||||
isComplate: info.isComplate ? 1 : 0,
|
||||
status: info.status,
|
||||
statusText: info.statusText,
|
||||
progress_downloaded: info.downloaded,
|
||||
progress_total: info.total,
|
||||
url: info.metadata.url,
|
||||
quality: info.metadata.quality,
|
||||
ext: info.metadata.ext,
|
||||
fileName: info.metadata.fileName,
|
||||
filePath: info.metadata.filePath,
|
||||
musicInfo: JSON.stringify(info.metadata.musicInfo),
|
||||
position: offset + index,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const initDownloadList = () => {
|
||||
list = queryDownloadList().map(item => {
|
||||
const musicInfo = JSON.parse(item.musicInfo) as LX.Music.MusicInfoOnline
|
||||
return {
|
||||
id: item.id,
|
||||
isComplate: item.isComplate == 1,
|
||||
status: item.status,
|
||||
statusText: item.statusText,
|
||||
downloaded: item.progress_downloaded,
|
||||
total: item.progress_total,
|
||||
progress: item.progress_total ? parseInt((item.progress_downloaded / item.progress_total).toFixed(2)) * 100 : 0,
|
||||
speed: '',
|
||||
metadata: {
|
||||
musicInfo,
|
||||
url: item.url,
|
||||
quality: item.quality,
|
||||
ext: item.ext,
|
||||
fileName: item.fileName,
|
||||
filePath: item.filePath,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下载列表
|
||||
* @returns 下载列表
|
||||
*/
|
||||
export const getDownloadList = (): LX.Download.ListItem[] => {
|
||||
if (!list) initDownloadList()
|
||||
return list
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加下载歌曲信息
|
||||
* @param downloadInfos url信息
|
||||
*/
|
||||
export const downloadInfoSave = (downloadInfos: LX.Download.ListItem[], addMusicLocationType: LX.AddMusicLocationType) => {
|
||||
if (!list) initDownloadList()
|
||||
if (addMusicLocationType == 'top') {
|
||||
let newList = [...list]
|
||||
newList.unshift(...downloadInfos)
|
||||
inertDownloadList(toDBDownloadInfo(downloadInfos), newList.slice(downloadInfos.length - 1).map((info, index) => {
|
||||
return { id: info.id, position: index }
|
||||
}))
|
||||
list = newList
|
||||
} else {
|
||||
inertDownloadList(toDBDownloadInfo(downloadInfos, list.length), [])
|
||||
list.push(...downloadInfos)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新列表信息
|
||||
* @param lists 列表信息
|
||||
*/
|
||||
export const downloadInfoUpdate = (lists: LX.Download.ListItem[]) => {
|
||||
updateDownloadList(toDBDownloadInfo(lists))
|
||||
if (list) {
|
||||
for (const item of lists) {
|
||||
const index = list.findIndex(info => info.id === item.id)
|
||||
if (index < 0) continue
|
||||
list.splice(index, 1, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除下载列表
|
||||
* @param ids 歌曲id
|
||||
*/
|
||||
export const downloadInfoRemove = (ids: string[]) => {
|
||||
deleteDownloadList(ids)
|
||||
if (list) {
|
||||
for (let i = list.length; i--;) {
|
||||
let idx = ids.indexOf(list[i].id)
|
||||
if (idx < 0) continue
|
||||
list.splice(i, 1)
|
||||
ids.splice(idx, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空下载列表
|
||||
*/
|
||||
export const downloadInfoClear = () => {
|
||||
clearDownloadList()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import { getDB } from '../../db'
|
||||
|
||||
/**
|
||||
* 创建下载列表查询语句
|
||||
* @returns 查询语句
|
||||
*/
|
||||
export const createQueryStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare(`
|
||||
SELECT "id", "isComplate", "status", "statusText", "progress_downloaded", "progress_total", "url", "quality", "ext", "fileName", "filePath", "musicInfo", "position"
|
||||
FROM download_list
|
||||
ORDER BY "position" ASC
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建下载记录插入语句
|
||||
* @returns 插入语句
|
||||
*/
|
||||
export const createInsertStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.DownloadMusicInfo]>(`
|
||||
INSERT INTO "main"."download_list" ("id", "isComplate", "status", "statusText", "progress_downloaded", "progress_total", "url", "quality", "ext", "fileName", "filePath", "musicInfo", "position")
|
||||
VALUES (@id, @isComplate, @status, @statusText, @progress_downloaded, @progress_total, @url, @quality, @ext, @fileName, @filePath, @musicInfo, @position)`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建下载记录清空语句
|
||||
* @returns 清空语句
|
||||
*/
|
||||
export const createClearStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare(`
|
||||
DELETE FROM "main"."download_list"
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建下载记录删除语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createDeleteStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>(`
|
||||
DELETE FROM "main"."download_list"
|
||||
WHERE "id"=?
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建下载记录更新语句
|
||||
* @returns 更新语句
|
||||
*/
|
||||
export const createUpdateStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.DownloadMusicInfo]>(`
|
||||
UPDATE "main"."download_list"
|
||||
SET "isComplate"=@isComplate, "status"=@status, "statusText"=@statusText, "progress_downloaded"=@progress_downloaded, "progress_total"=@progress_total, "url"=@url, "filePath"=@filePath
|
||||
WHERE "id"=@id`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建下载记录顺序更新语句
|
||||
* @returns 更新语句
|
||||
*/
|
||||
export const createUpdatePositionStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[{ id: string, position: number }]>(`
|
||||
UPDATE "main"."download_list"
|
||||
SET "position"=@position
|
||||
WHERE "id"=@id`)
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
export * as list from './list'
|
||||
export * as lyric from './lyric'
|
||||
export * as music_url from './music_url'
|
||||
export * as music_other_source from './music_other_source'
|
||||
export * as download from './download'
|
||||
@@ -0,0 +1,361 @@
|
||||
import { getDB } from '../../db'
|
||||
import {
|
||||
createListQueryStatement,
|
||||
createListInsertStatement,
|
||||
createListDeleteStatement,
|
||||
createListClearStatement,
|
||||
createListUpdateStatement,
|
||||
createMusicInfoQueryStatement,
|
||||
createMusicInfoInsertStatement,
|
||||
createMusicInfoUpdateStatement,
|
||||
createMusicInfoDeleteStatement,
|
||||
createMusicInfoDeleteByListIdStatement,
|
||||
createMusicInfoOrderInsertStatement,
|
||||
createMusicInfoOrderDeleteStatement,
|
||||
createMusicInfoOrderDeleteByListIdStatement,
|
||||
createMusicInfoClearStatement,
|
||||
createMusicInfoOrderClearStatement,
|
||||
createMusicInfoByListAndMusicInfoIdQueryStatement,
|
||||
createMusicInfoByMusicInfoIdQueryStatement,
|
||||
} from './statements'
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
* @returns
|
||||
*/
|
||||
export const queryAllUserList = (): LX.DBService.UserListInfo[] => {
|
||||
return createListQueryStatement().all()
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量插入用户列表
|
||||
* @param lists 列表
|
||||
* @param isClear 是否清空列表
|
||||
*/
|
||||
export const inertUserLists = (lists: LX.DBService.UserListInfo[], isClear: boolean = false) => {
|
||||
const db = getDB()
|
||||
const listClearStatement = createListClearStatement()
|
||||
const listInsertStatement = createListInsertStatement()
|
||||
db.transaction((lists: LX.DBService.UserListInfo[]) => {
|
||||
if (isClear) listClearStatement.run()
|
||||
for (const list of lists) {
|
||||
listInsertStatement.run({
|
||||
id: list.id,
|
||||
name: list.name,
|
||||
source: list.source,
|
||||
sourceListId: list.sourceListId,
|
||||
locationUpdateTime: list.locationUpdateTime,
|
||||
position: list.position,
|
||||
})
|
||||
}
|
||||
})(lists)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除用户列表及列表内歌曲
|
||||
* @param listIds 列表id
|
||||
*/
|
||||
export const deleteUserLists = (listIds: string[]) => {
|
||||
const db = getDB()
|
||||
const listDeleteStatement = createListDeleteStatement()
|
||||
const musicInfoDeleteByListIdStatement = createMusicInfoDeleteByListIdStatement()
|
||||
const musicInfoOrderDeleteByListIdStatement = createMusicInfoOrderDeleteByListIdStatement()
|
||||
db.transaction((listIds: string[]) => {
|
||||
for (const id of listIds) {
|
||||
listDeleteStatement.run(id)
|
||||
musicInfoDeleteByListIdStatement.run(id)
|
||||
musicInfoOrderDeleteByListIdStatement.run(id)
|
||||
}
|
||||
})(listIds)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新用户列表
|
||||
* @param lists 列表
|
||||
*/
|
||||
export const updateUserLists = (lists: LX.DBService.UserListInfo[]) => {
|
||||
const db = getDB()
|
||||
const listUpdateStatement = createListUpdateStatement()
|
||||
db.transaction((lists: LX.DBService.UserListInfo[]) => {
|
||||
for (const list of lists) listUpdateStatement.run(list)
|
||||
})(lists)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量添加歌曲
|
||||
* @param list
|
||||
*/
|
||||
export const insertMusicInfoList = (list: LX.DBService.MusicInfo[]) => {
|
||||
const musicInfoInsertStatement = createMusicInfoInsertStatement()
|
||||
const musicInfoOrderInsertStatement = createMusicInfoOrderInsertStatement()
|
||||
const db = getDB()
|
||||
return db.transaction((musics: LX.DBService.MusicInfo[]) => {
|
||||
for (const music of musics) {
|
||||
musicInfoInsertStatement.run(music)
|
||||
musicInfoOrderInsertStatement.run({
|
||||
listId: music.listId,
|
||||
musicInfoId: music.id,
|
||||
order: music.order,
|
||||
})
|
||||
}
|
||||
})(list)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加歌曲并刷新排序
|
||||
* @param list 新增歌曲
|
||||
* @param listId 列表Id
|
||||
* @param listAll 原始列表歌曲,列表去重后
|
||||
*/
|
||||
export const insertMusicInfoListAndRefreshOrder = (list: LX.DBService.MusicInfo[], listId: string, listAll: LX.DBService.MusicInfo[]) => {
|
||||
const musicInfoInsertStatement = createMusicInfoInsertStatement()
|
||||
const musicInfoOrderInsertStatement = createMusicInfoOrderInsertStatement()
|
||||
const musicInfoOrderDeleteByListIdStatement = createMusicInfoOrderDeleteByListIdStatement()
|
||||
|
||||
const db = getDB()
|
||||
db.transaction((list: LX.DBService.MusicInfo[], listId: string, listAll: LX.DBService.MusicInfo[]) => {
|
||||
musicInfoOrderDeleteByListIdStatement.run(listId)
|
||||
for (const music of list) {
|
||||
musicInfoInsertStatement.run(music)
|
||||
musicInfoOrderInsertStatement.run({
|
||||
listId: music.listId,
|
||||
musicInfoId: music.id,
|
||||
order: music.order,
|
||||
})
|
||||
}
|
||||
for (const music of listAll) {
|
||||
musicInfoOrderInsertStatement.run({
|
||||
listId: music.listId,
|
||||
musicInfoId: music.id,
|
||||
order: music.order,
|
||||
})
|
||||
}
|
||||
})(list, listId, listAll)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新歌曲
|
||||
* @param list
|
||||
*/
|
||||
export const updateMusicInfos = (list: LX.DBService.MusicInfo[]) => {
|
||||
const musicInfoUpdateStatement = createMusicInfoUpdateStatement()
|
||||
const db = getDB()
|
||||
db.transaction((musics: LX.DBService.MusicInfo[]) => {
|
||||
for (const music of musics) {
|
||||
musicInfoUpdateStatement.run(music)
|
||||
}
|
||||
})(list)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表内的歌曲
|
||||
* @param listId 列表Id
|
||||
* @returns 列表歌曲
|
||||
*/
|
||||
export const queryMusicInfoByListId = (listId: string): LX.DBService.MusicInfo[] => {
|
||||
const musicInfoQueryStatement = createMusicInfoQueryStatement()
|
||||
return musicInfoQueryStatement.all({ listId })
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量移动歌曲
|
||||
* @param fromId 源列表Id
|
||||
* @param ids 要移动的歌曲
|
||||
* @param musicInfos 音乐信息
|
||||
*/
|
||||
export const moveMusicInfo = (fromId: string, ids: string[], musicInfos: LX.DBService.MusicInfo[]) => {
|
||||
const musicInfoInsertStatement = createMusicInfoInsertStatement()
|
||||
const musicInfoOrderInsertStatement = createMusicInfoOrderInsertStatement()
|
||||
const musicInfoDeleteStatement = createMusicInfoDeleteStatement()
|
||||
const musicInfoOrderDeleteStatement = createMusicInfoOrderDeleteStatement()
|
||||
// const musicInfoOrderDeleteByListIdStatement = createMusicInfoOrderDeleteByListIdStatement()
|
||||
|
||||
const db = getDB()
|
||||
db.transaction((fromId: string, ids: string[], musicInfos: LX.DBService.MusicInfo[]) => {
|
||||
// musicInfoOrderDeleteByListIdStatement.run(fromId)
|
||||
for (const id of ids) {
|
||||
musicInfoDeleteStatement.run({ listId: fromId, id })
|
||||
musicInfoOrderDeleteStatement.run({ listId: fromId, id })
|
||||
}
|
||||
for (const music of musicInfos) {
|
||||
musicInfoInsertStatement.run(music)
|
||||
musicInfoOrderInsertStatement.run({
|
||||
listId: music.listId,
|
||||
musicInfoId: music.id,
|
||||
order: music.order,
|
||||
})
|
||||
}
|
||||
})(fromId, ids, musicInfos)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量移动歌曲并刷新排序
|
||||
* @param fromId 源列表Id
|
||||
* @param ids 要移动的歌曲id,原始选择的歌曲
|
||||
* @param musicInfos 要移动的歌曲,目标列表去重后
|
||||
* @param toListAll 目标列表歌曲
|
||||
*/
|
||||
export const moveMusicInfoAndRefreshOrder = (fromId: string, ids: string[], toId: string, musicInfos: LX.DBService.MusicInfo[], toListAll: LX.DBService.MusicInfo[]) => {
|
||||
const musicInfoInsertStatement = createMusicInfoInsertStatement()
|
||||
const musicInfoDeleteStatement = createMusicInfoDeleteStatement()
|
||||
const musicInfoOrderDeleteStatement = createMusicInfoOrderDeleteStatement()
|
||||
const musicInfoOrderInsertStatement = createMusicInfoOrderInsertStatement()
|
||||
const musicInfoOrderDeleteByListIdStatement = createMusicInfoOrderDeleteByListIdStatement()
|
||||
|
||||
const db = getDB()
|
||||
db.transaction((fromId: string, ids: string[], musicInfos: LX.DBService.MusicInfo[], toListAll: LX.DBService.MusicInfo[]) => {
|
||||
for (const id of ids) {
|
||||
musicInfoDeleteStatement.run({ listId: fromId, id })
|
||||
musicInfoOrderDeleteStatement.run({ listId: fromId, id })
|
||||
}
|
||||
musicInfoOrderDeleteByListIdStatement.run(toId)
|
||||
for (const music of musicInfos) {
|
||||
musicInfoInsertStatement.run(music)
|
||||
musicInfoOrderInsertStatement.run({
|
||||
listId: music.listId,
|
||||
musicInfoId: music.id,
|
||||
order: music.order,
|
||||
})
|
||||
}
|
||||
for (const music of toListAll) {
|
||||
musicInfoOrderInsertStatement.run({
|
||||
listId: music.listId,
|
||||
musicInfoId: music.id,
|
||||
order: music.order,
|
||||
})
|
||||
}
|
||||
})(fromId, ids, musicInfos, toListAll)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量移除列表内音乐
|
||||
* @param listId 列表id
|
||||
* @param ids 音乐id
|
||||
*/
|
||||
export const removeMusicInfos = (listId: string, ids: string[]) => {
|
||||
const musicInfoDeleteStatement = createMusicInfoDeleteStatement()
|
||||
const musicInfoOrderDeleteStatement = createMusicInfoOrderDeleteStatement()
|
||||
const db = getDB()
|
||||
return db.transaction((listId: string, ids: string[]) => {
|
||||
for (const id of ids) {
|
||||
musicInfoDeleteStatement.run({ listId, id })
|
||||
musicInfoOrderDeleteStatement.run({ listId, id })
|
||||
}
|
||||
})(listId, ids)
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空列表内歌曲
|
||||
* @param listId 列表id
|
||||
*/
|
||||
export const removeMusicInfoByListId = (listId: string) => {
|
||||
const db = getDB()
|
||||
const musicInfoDeleteByListIdStatement = createMusicInfoDeleteByListIdStatement()
|
||||
const musicInfoOrderDeleteByListIdStatement = createMusicInfoOrderDeleteByListIdStatement()
|
||||
db.transaction((listId: string) => {
|
||||
musicInfoDeleteByListIdStatement.run(listId)
|
||||
musicInfoOrderDeleteByListIdStatement.run(listId)
|
||||
})(listId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建根据列表Id与音乐id查询音乐信息
|
||||
* @param listId 列表id
|
||||
* @param musicInfoId 音乐id
|
||||
* @returns
|
||||
*/
|
||||
export const queryMusicInfoByListIdAndMusicInfoId = (listId: string, musicInfoId: string): LX.DBService.MusicInfo | null => {
|
||||
const musicInfoByListAndMusicInfoIdQueryStatement = createMusicInfoByListAndMusicInfoIdQueryStatement()
|
||||
return musicInfoByListAndMusicInfoIdQueryStatement.get({ listId, musicInfoId })
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建根据音乐id查询所有列表的音乐信息
|
||||
* @param id 音乐id
|
||||
* @returns
|
||||
*/
|
||||
export const queryMusicInfoByMusicInfoId = (id: string): LX.DBService.MusicInfo[] => {
|
||||
const musicInfoByMusicInfoIdQueryStatement = createMusicInfoByMusicInfoIdQueryStatement()
|
||||
return musicInfoByMusicInfoIdQueryStatement.all(id)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新歌曲位置
|
||||
* @param listId 列表id
|
||||
* @param musicInfoOrders 音乐顺序
|
||||
*/
|
||||
export const updateMusicInfoOrder = (listId: string, musicInfoOrders: LX.DBService.MusicInfoOrder[]) => {
|
||||
const db = getDB()
|
||||
const musicInfoOrderInsertStatement = createMusicInfoOrderInsertStatement()
|
||||
const musicInfoOrderDeleteByListIdStatement = createMusicInfoOrderDeleteByListIdStatement()
|
||||
db.transaction((listId: string, musicInfoOrders: LX.DBService.MusicInfoOrder[]) => {
|
||||
musicInfoOrderDeleteByListIdStatement.run(listId)
|
||||
for (const orderInfo of musicInfoOrders) musicInfoOrderInsertStatement.run(orderInfo)
|
||||
})(listId, musicInfoOrders)
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆盖列表内的歌曲
|
||||
* @param listId 列表id
|
||||
* @param musicInfos 歌曲列表
|
||||
*/
|
||||
export const overwriteMusicInfo = (listId: string, musicInfos: LX.DBService.MusicInfo[]) => {
|
||||
const db = getDB()
|
||||
const musicInfoDeleteByListIdStatement = createMusicInfoDeleteByListIdStatement()
|
||||
const musicInfoOrderDeleteByListIdStatement = createMusicInfoOrderDeleteByListIdStatement()
|
||||
const musicInfoInsertStatement = createMusicInfoInsertStatement()
|
||||
const musicInfoOrderInsertStatement = createMusicInfoOrderInsertStatement()
|
||||
db.transaction((listId: string, musicInfos: LX.DBService.MusicInfo[]) => {
|
||||
musicInfoDeleteByListIdStatement.run(listId)
|
||||
musicInfoOrderDeleteByListIdStatement.run(listId)
|
||||
for (const musicInfo of musicInfos) {
|
||||
musicInfoInsertStatement.run(musicInfo)
|
||||
musicInfoOrderInsertStatement.run({
|
||||
listId: musicInfo.listId,
|
||||
musicInfoId: musicInfo.id,
|
||||
order: musicInfo.order,
|
||||
})
|
||||
}
|
||||
})(listId, musicInfos)
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆盖整个列表
|
||||
* @param lists 列表
|
||||
* @param musicInfos 歌曲列表
|
||||
*/
|
||||
export const overwriteListData = (lists: LX.DBService.UserListInfo[], musicInfos: LX.DBService.MusicInfo[]) => {
|
||||
const db = getDB()
|
||||
const listClearStatement = createListClearStatement()
|
||||
const listInsertStatement = createListInsertStatement()
|
||||
const musicInfoClearStatement = createMusicInfoClearStatement()
|
||||
const musicInfoInsertStatement = createMusicInfoInsertStatement()
|
||||
const musicInfoOrderClearStatement = createMusicInfoOrderClearStatement()
|
||||
const musicInfoOrderInsertStatement = createMusicInfoOrderInsertStatement()
|
||||
db.transaction((lists: LX.DBService.UserListInfo[], musicInfos: LX.DBService.MusicInfo[]) => {
|
||||
listClearStatement.run()
|
||||
for (const list of lists) {
|
||||
listInsertStatement.run({
|
||||
id: list.id,
|
||||
name: list.name,
|
||||
source: list.source,
|
||||
sourceListId: list.sourceListId,
|
||||
locationUpdateTime: list.locationUpdateTime,
|
||||
position: list.position,
|
||||
})
|
||||
}
|
||||
musicInfoClearStatement.run()
|
||||
musicInfoOrderClearStatement.run()
|
||||
for (const musicInfo of musicInfos) {
|
||||
musicInfoInsertStatement.run(musicInfo)
|
||||
musicInfoOrderInsertStatement.run({
|
||||
listId: musicInfo.listId,
|
||||
musicInfoId: musicInfo.id,
|
||||
order: musicInfo.order,
|
||||
})
|
||||
}
|
||||
})(lists, musicInfos)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,407 @@
|
||||
import { LIST_IDS } from '@common/constants'
|
||||
import {
|
||||
deleteUserLists,
|
||||
inertUserLists,
|
||||
insertMusicInfoList,
|
||||
insertMusicInfoListAndRefreshOrder,
|
||||
moveMusicInfo,
|
||||
moveMusicInfoAndRefreshOrder,
|
||||
overwriteListData,
|
||||
overwriteMusicInfo,
|
||||
queryAllUserList,
|
||||
queryMusicInfoByListId,
|
||||
queryMusicInfoByListIdAndMusicInfoId,
|
||||
queryMusicInfoByMusicInfoId,
|
||||
removeMusicInfoByListId,
|
||||
removeMusicInfos,
|
||||
updateMusicInfoOrder,
|
||||
updateMusicInfos,
|
||||
updateUserLists as updateUserListsFromDB,
|
||||
} from './dbHelper'
|
||||
|
||||
let userLists: LX.DBService.UserListInfo[]
|
||||
let musicLists = new Map<string, LX.Music.MusicInfo[]>()
|
||||
|
||||
const toDBMusicInfo = (musicInfos: LX.Music.MusicInfo[], listId: string, offset: number = 0): LX.DBService.MusicInfo[] => {
|
||||
return musicInfos.map((info, index) => {
|
||||
return {
|
||||
...info,
|
||||
listId,
|
||||
meta: JSON.stringify(info.meta),
|
||||
order: offset + index,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有用户列表
|
||||
* @returns
|
||||
*/
|
||||
export const getAllUserList = (): LX.List.UserListInfo[] => {
|
||||
if (userLists == null) userLists = queryAllUserList()
|
||||
|
||||
return userLists.map(list => {
|
||||
const { position, ...newList } = list
|
||||
return newList
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量创建列表
|
||||
* @param position 列表位置
|
||||
* @param lists 列表信息
|
||||
*/
|
||||
export const createUserLists = (position: number, lists: LX.List.UserListInfo[]) => {
|
||||
if (userLists == null) userLists = queryAllUserList()
|
||||
if (position < 0 || position >= userLists.length) {
|
||||
const newLists: LX.DBService.UserListInfo[] = lists.map((list, index) => {
|
||||
return {
|
||||
...list,
|
||||
position: position + index,
|
||||
}
|
||||
})
|
||||
inertUserLists(newLists)
|
||||
userLists = [...userLists, ...newLists]
|
||||
} else {
|
||||
const newUserLists = [...userLists]
|
||||
// @ts-expect-error
|
||||
newUserLists.splice(position, 0, ...lists)
|
||||
newUserLists.forEach((list, index) => {
|
||||
list.position = index
|
||||
})
|
||||
inertUserLists(newUserLists, true)
|
||||
userLists = newUserLists
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆盖列表
|
||||
* @param lists 列表信息
|
||||
*/
|
||||
export const setUserLists = (lists: LX.List.UserListInfo[]) => {
|
||||
const newUserLists: LX.DBService.UserListInfo[] = lists.map((list, index) => {
|
||||
return {
|
||||
...list,
|
||||
position: index,
|
||||
}
|
||||
})
|
||||
inertUserLists(newUserLists, true)
|
||||
userLists = newUserLists
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除列表
|
||||
* @param ids 列表ids
|
||||
*/
|
||||
export const removeUserLists = (ids: string[]) => {
|
||||
deleteUserLists(ids)
|
||||
if (userLists) userLists = queryAllUserList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新列表信息
|
||||
* @param lists 列表信息
|
||||
*/
|
||||
export const updateUserLists = (lists: LX.List.UserListInfo[]) => {
|
||||
const positionMap = new Map<string, number>()
|
||||
for (const list of userLists) {
|
||||
positionMap.set(list.id, list.position)
|
||||
}
|
||||
const dbList: LX.DBService.UserListInfo[] = lists.map(list => {
|
||||
const position = positionMap.get(list.id)
|
||||
if (position == null) return null
|
||||
return {
|
||||
...list,
|
||||
position,
|
||||
}
|
||||
}).filter(Boolean) as LX.DBService.UserListInfo[]
|
||||
updateUserListsFromDB(dbList)
|
||||
if (userLists) userLists = queryAllUserList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新列表位置
|
||||
* @param position 列表位置
|
||||
* @param ids 列表ids
|
||||
*/
|
||||
export const updateUserListsPosition = (position: number, ids: string[]) => {
|
||||
if (userLists == null) userLists = queryAllUserList()
|
||||
|
||||
const newUserLists = [...userLists]
|
||||
|
||||
const updateLists: LX.DBService.UserListInfo[] = []
|
||||
|
||||
for (let i = newUserLists.length - 1; i >= 0; i--) {
|
||||
if (ids.includes(newUserLists[i].id)) {
|
||||
const list = newUserLists.splice(i, 1)[0]
|
||||
list.locationUpdateTime = Date.now()
|
||||
updateLists.push(list)
|
||||
}
|
||||
}
|
||||
position = Math.min(newUserLists.length, position)
|
||||
|
||||
newUserLists.splice(position, 0, ...updateLists)
|
||||
newUserLists.forEach((list, index) => {
|
||||
list.position = index
|
||||
})
|
||||
inertUserLists(newUserLists, true)
|
||||
userLists = newUserLists
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据列表ID获取列表内歌曲
|
||||
* @param listId 列表ID
|
||||
* @returns 列表内歌曲
|
||||
*/
|
||||
export const getListMusics = (listId: string): LX.Music.MusicInfo[] => {
|
||||
let targetList: LX.Music.MusicInfo[] | undefined = musicLists.get(listId)
|
||||
if (targetList == null) {
|
||||
targetList = queryMusicInfoByListId(listId).map(info => {
|
||||
return {
|
||||
id: info.id,
|
||||
name: info.name,
|
||||
singer: info.singer,
|
||||
source: info.source,
|
||||
interval: info.interval,
|
||||
meta: JSON.parse(info.meta),
|
||||
}
|
||||
})
|
||||
musicLists.set(listId, targetList)
|
||||
}
|
||||
|
||||
return targetList
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆盖列表内的歌曲
|
||||
* @param listId 列表id
|
||||
* @param musicInfos 歌曲列表
|
||||
*/
|
||||
export const musicOverwrite = (listId: string, musicInfos: LX.Music.MusicInfo[]) => {
|
||||
let targetList = getListMusics(listId)
|
||||
overwriteMusicInfo(listId, toDBMusicInfo(musicInfos, listId))
|
||||
if (targetList) targetList.splice(0, targetList.length, ...musicInfos)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加歌曲
|
||||
* @param listId 列表id
|
||||
* @param musicInfos 添加的歌曲信息
|
||||
* @param addMusicLocationType 添加在到列表的位置
|
||||
*/
|
||||
export const musicsAdd = (listId: string, musicInfos: LX.Music.MusicInfo[], addMusicLocationType: LX.AddMusicLocationType) => {
|
||||
let targetList = getListMusics(listId)
|
||||
|
||||
const set = new Set<string>()
|
||||
for (const item of targetList) set.add(item.id)
|
||||
musicInfos = musicInfos.filter(item => {
|
||||
if (set.has(item.id)) return false
|
||||
set.add(item.id)
|
||||
return true
|
||||
})
|
||||
|
||||
switch (addMusicLocationType) {
|
||||
case 'top':
|
||||
insertMusicInfoListAndRefreshOrder(toDBMusicInfo(musicInfos, listId), listId, toDBMusicInfo(targetList, listId, musicInfos.length))
|
||||
targetList.unshift(...musicInfos)
|
||||
break
|
||||
case 'bottom':
|
||||
default:
|
||||
insertMusicInfoList(toDBMusicInfo(musicInfos, listId, targetList.length))
|
||||
targetList.push(...musicInfos)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除歌曲
|
||||
* @param listId 列表Id
|
||||
* @param ids 要删除歌曲的id
|
||||
*/
|
||||
export const musicsRemove = (listId: string, ids: string[]) => {
|
||||
let targetList = getListMusics(listId)
|
||||
if (!targetList.length) return
|
||||
ids = [...ids]
|
||||
removeMusicInfos(listId, ids)
|
||||
for (let i = targetList.length - 1; i > -1; i--) {
|
||||
const item = targetList[i]
|
||||
const index = ids.indexOf(item.id)
|
||||
if (index < 0) continue
|
||||
ids.splice(index, 1)
|
||||
targetList.splice(i, 1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量移动歌曲
|
||||
* @param fromId 源列表id
|
||||
* @param toId 目标列表id
|
||||
* @param musicInfos 添加的歌曲信息
|
||||
* @param addMusicLocationType 添加在到列表的位置
|
||||
*/
|
||||
export const musicsMove = (fromId: string, toId: string, musicInfos: LX.Music.MusicInfo[], addMusicLocationType: LX.AddMusicLocationType) => {
|
||||
const ids = musicInfos.map(musicInfo => musicInfo.id)
|
||||
let toList = getListMusics(toId)
|
||||
switch (addMusicLocationType) {
|
||||
case 'top':
|
||||
moveMusicInfoAndRefreshOrder(fromId, ids, toId, toDBMusicInfo(musicInfos, toId), toDBMusicInfo(toList, toId, musicInfos.length))
|
||||
break
|
||||
case 'bottom':
|
||||
default:
|
||||
moveMusicInfo(fromId, ids, toDBMusicInfo(musicInfos, toId, toList.length))
|
||||
break
|
||||
}
|
||||
musicsRemove(fromId, ids)
|
||||
musicsAdd(toId, musicInfos, addMusicLocationType)
|
||||
// let fromList = getListMusics(fromId)
|
||||
// let toList = getListMusics(toId)
|
||||
|
||||
// const ids = musicInfos.map(musicInfo => musicInfo.id)
|
||||
|
||||
// const map = new Map<string, LX.Music.MusicInfo>()
|
||||
// for (const item of toList) map.set(item.id, item)
|
||||
// musicInfos = musicInfos.filter(item => {
|
||||
// if (map.has(item.id)) return false
|
||||
// map.set(item.id, item)
|
||||
// return true
|
||||
// })
|
||||
|
||||
// switch (addMusicLocationType) {
|
||||
// case 'top':
|
||||
// moveMusicInfoAndRefreshOrder(fromId, ids, toId, toDBMusicInfo(musicInfos, toId), toDBMusicInfo(toList, toId, musicInfos.length))
|
||||
// toList.unshift(...musicInfos)
|
||||
// break
|
||||
// case 'bottom':
|
||||
// default:
|
||||
// moveMusicInfo(fromId, ids, toDBMusicInfo(musicInfos, toId, toList.length))
|
||||
// toList.push(...musicInfos)
|
||||
// break
|
||||
// }
|
||||
// for (let i = fromList.length - 1; i > -1; i--) {
|
||||
// const item = fromList[i]
|
||||
// const index = ids.indexOf(item.id)
|
||||
// if (index < 0) continue
|
||||
// ids.splice(index, 1)
|
||||
// fromList.splice(i, 1)
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新歌曲信息
|
||||
* @param musicInfos 歌曲&列表信息
|
||||
*/
|
||||
export const musicsUpdate = (musicInfos: LX.List.ListActionMusicUpdate) => {
|
||||
updateMusicInfos(musicInfos.map(({ id, musicInfo }) => {
|
||||
return {
|
||||
...musicInfo,
|
||||
listId: id,
|
||||
meta: JSON.stringify(musicInfo.meta),
|
||||
order: 0,
|
||||
}
|
||||
}))
|
||||
for (const { id, musicInfo } of musicInfos) {
|
||||
const targetList = musicLists.get(id)
|
||||
if (targetList == null) continue
|
||||
const targetMusic = targetList.find(item => item.id == musicInfo.id)
|
||||
if (!targetMusic) continue
|
||||
targetMusic.name = musicInfo.name
|
||||
targetMusic.singer = musicInfo.singer
|
||||
targetMusic.source = musicInfo.source
|
||||
targetMusic.interval = musicInfo.interval
|
||||
targetMusic.meta = musicInfo.meta
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空列表内的歌曲
|
||||
* @param listId 列表Id
|
||||
*/
|
||||
export const musicsClear = (listId: string) => {
|
||||
removeMusicInfoByListId(listId)
|
||||
const targetList = getListMusics(listId)
|
||||
if (targetList == null) return
|
||||
targetList.slice(0, targetList.length)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新歌曲位置
|
||||
* @param listId 列表id
|
||||
* @param position 新位置
|
||||
* @param ids 要更新位置的歌曲id
|
||||
*/
|
||||
export const musicsPositionUpdate = (listId: string, position: number, ids: string[]) => {
|
||||
let targetList = getListMusics(listId)
|
||||
if (!targetList.length) return
|
||||
|
||||
const newTargetList = [...targetList]
|
||||
const infos = Array(ids.length)
|
||||
for (let i = newTargetList.length; i--;) {
|
||||
const item = newTargetList[i]
|
||||
const index = ids.indexOf(item.id)
|
||||
if (index < 0) continue
|
||||
infos.splice(index, 1, newTargetList.splice(i, 1)[0])
|
||||
}
|
||||
newTargetList.splice(Math.min(position, newTargetList.length), 0, ...infos)
|
||||
|
||||
updateMusicInfoOrder(listId, newTargetList.map((info, index) => {
|
||||
return {
|
||||
listId,
|
||||
musicInfoId: info.id,
|
||||
order: index,
|
||||
}
|
||||
}))
|
||||
musicLists.set(listId, newTargetList)
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆盖所有列表数据
|
||||
* @param myListData 完整列表数据
|
||||
*/
|
||||
export const listDataOverwrite = (myListData: MakeOptional<LX.List.ListDataFull, 'tempList'>) => {
|
||||
const dbLists: LX.DBService.UserListInfo[] = []
|
||||
const listData: LX.List.ListDataFull = {
|
||||
...myListData,
|
||||
tempList: myListData.tempList ?? getListMusics(LIST_IDS.TEMP),
|
||||
}
|
||||
|
||||
const dbMusicInfos: LX.DBService.MusicInfo[] = [
|
||||
...toDBMusicInfo(listData.defaultList, LIST_IDS.DEFAULT),
|
||||
...toDBMusicInfo(listData.loveList, LIST_IDS.LOVE),
|
||||
...toDBMusicInfo(listData.tempList, LIST_IDS.TEMP),
|
||||
]
|
||||
listData.userList.forEach(({ list, ...listInfo }, index) => {
|
||||
dbLists.push({ ...listInfo, position: index })
|
||||
dbMusicInfos.push(...toDBMusicInfo(list, listInfo.id))
|
||||
})
|
||||
overwriteListData(dbLists, dbMusicInfos)
|
||||
|
||||
if (userLists) userLists.splice(0, userLists.length, ...dbLists)
|
||||
else userLists = dbLists
|
||||
|
||||
musicLists.clear()
|
||||
musicLists.set(LIST_IDS.DEFAULT, listData.defaultList)
|
||||
musicLists.set(LIST_IDS.LOVE, listData.loveList)
|
||||
musicLists.set(LIST_IDS.TEMP, listData.tempList)
|
||||
for (const list of listData.userList) musicLists.set(list.id, list.list)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查音乐是否存在列表中
|
||||
* @param listId 列表id
|
||||
* @param musicInfoId 音乐id
|
||||
* @returns
|
||||
*/
|
||||
export const checkListExistMusic = (listId: string, musicInfoId: string): boolean => {
|
||||
const musicInfo = queryMusicInfoByListIdAndMusicInfoId(listId, musicInfoId)
|
||||
return musicInfo != null
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有存在该音乐的列表id
|
||||
* @param musicInfoId 音乐id
|
||||
* @returns
|
||||
*/
|
||||
export const getMusicExistListIds = (musicInfoId: string): string[] => {
|
||||
const musicInfos = queryMusicInfoByMusicInfoId(musicInfoId)
|
||||
return musicInfos.map(m => m.listId)
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
import { getDB } from '../../db'
|
||||
|
||||
|
||||
/**
|
||||
* 创建列表查询语句
|
||||
* @returns 查询语句
|
||||
*/
|
||||
export const createListQueryStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare(`
|
||||
SELECT "id", "name", "source", "sourceListId", "position", "locationUpdateTime"
|
||||
FROM "main"."my_list"
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建列表插入语句
|
||||
* @returns 插入语句
|
||||
*/
|
||||
export const createListInsertStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.UserListInfo]>(`
|
||||
INSERT INTO "main"."my_list" ("id", "name", "source", "sourceListId", "position", "locationUpdateTime")
|
||||
VALUES (@id, @name, @source, @sourceListId, @position, @locationUpdateTime)`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建列表清空语句
|
||||
* @returns 清空语句
|
||||
*/
|
||||
export const createListClearStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare('DELETE FROM "main"."my_list"')
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建列表删除语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createListDeleteStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>('DELETE FROM "main"."my_list" WHERE "id"=?')
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建列表更新语句
|
||||
* @returns 更新语句
|
||||
*/
|
||||
export const createListUpdateStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.UserListInfo]>(`
|
||||
UPDATE "main"."my_list"
|
||||
SET "name"=@name, "source"=@source, "sourceListId"=@sourceListId, "locationUpdateTime"=@locationUpdateTime
|
||||
WHERE "id"=@id`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建音乐信息查询语句
|
||||
* @returns 查询语句
|
||||
*/
|
||||
export const createMusicInfoQueryStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.MusicInfoQuery]>(`
|
||||
SELECT mInfo."id", mInfo."name", mInfo."singer", mInfo."source", mInfo."interval", mInfo."meta"
|
||||
FROM my_list_music_info mInfo
|
||||
LEFT JOIN my_list_music_info_order O
|
||||
ON mInfo.id=O.musicInfoId AND O.listId=@listId
|
||||
WHERE mInfo.listId=@listId
|
||||
ORDER BY O."order" ASC
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建音乐信息插入语句
|
||||
* @returns 插入语句
|
||||
*/
|
||||
export const createMusicInfoInsertStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.MusicInfo]>(`
|
||||
INSERT INTO "main"."my_list_music_info" ("id", "listId", "name", "singer", "source", "interval", "meta")
|
||||
VALUES (@id, @listId, @name, @singer, @source, @interval, @meta)`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建音乐信息更新语句
|
||||
* @returns 更新语句
|
||||
*/
|
||||
export const createMusicInfoUpdateStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.MusicInfo]>(`
|
||||
UPDATE "main"."my_list_music_info"
|
||||
SET "name"=@name, "singer"=@singer, "source"=@source, "interval"=@interval, "meta"=@meta
|
||||
WHERE "id"=@id AND "listId"=@listId`)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建清空音乐信息语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createMusicInfoClearStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare('DELETE FROM "main"."my_list_music_info"')
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建根据列表id批量删除音乐信息语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createMusicInfoDeleteByListIdStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>('DELETE FROM "main"."my_list_music_info" WHERE "listId"=?')
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建根据列表Id与音乐id批量删除音乐信息语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createMusicInfoDeleteStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.MusicInfoRemove]>('DELETE FROM "main"."my_list_music_info" WHERE "id"=@id AND "listId"=@listId')
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建根据列表Id与音乐id查询音乐信息语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createMusicInfoByListAndMusicInfoIdQueryStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.ListMusicInfoQuery]>(`SELECT "id", "name", "singer", "source", "interval", "meta"
|
||||
FROM "main"."my_list_music_info"
|
||||
WHERE "id"=@musicInfoId
|
||||
AND "listId"=@listId`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建根据音乐id查询音乐信息语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createMusicInfoByMusicInfoIdQueryStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>(`SELECT "id", "name", "singer", "source", "interval", "meta", "listId"
|
||||
FROM "main"."my_list_music_info"
|
||||
WHERE "id"=?`)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建音乐信息排序插入语句
|
||||
* @returns 插入语句
|
||||
*/
|
||||
export const createMusicInfoOrderInsertStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.MusicInfoOrder]>(`
|
||||
INSERT INTO "main"."my_list_music_info_order" ("listId", "musicInfoId", "order")
|
||||
VALUES (@listId, @musicInfoId, @order)`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建清空音乐排序语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createMusicInfoOrderClearStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare('DELETE FROM "main"."my_list_music_info_order"')
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建根据列表id删除音乐排序语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createMusicInfoOrderDeleteByListIdStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>('DELETE FROM "main"."my_list_music_info_order" WHERE "listId"=?')
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建根据列表Id与音乐id删除音乐排序语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createMusicInfoOrderDeleteStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.MusicInfoRemove]>('DELETE FROM "main"."my_list_music_info_order" WHERE "musicInfoId"=@id AND "listId"=@listId')
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
import { getDB } from '../../db'
|
||||
import {
|
||||
createLyricQueryStatement,
|
||||
createRawLyricQueryStatement,
|
||||
createRawLyricInsertStatement,
|
||||
createRawLyricDeleteStatement,
|
||||
createRawLyricUpdateStatement,
|
||||
createRawLyricClearStatement,
|
||||
createEditedLyricQueryStatement,
|
||||
createEditedLyricInsertStatement,
|
||||
createEditedLyricDeleteStatement,
|
||||
createEditedLyricUpdateStatement,
|
||||
createEditedLyricClearStatement,
|
||||
createEditedLyricCountStatement,
|
||||
createRawLyricCountStatement,
|
||||
} from './statements'
|
||||
|
||||
/**
|
||||
* 查询原始歌词
|
||||
* @param id 歌曲id
|
||||
* @returns 歌词信息
|
||||
*/
|
||||
export const queryLyric = (id: string): LX.DBService.Lyricnfo[] => {
|
||||
const lyricQueryStatement = createLyricQueryStatement()
|
||||
return lyricQueryStatement.all(id)
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询原始歌词
|
||||
* @param id 歌曲id
|
||||
* @returns 歌词信息
|
||||
*/
|
||||
export const queryRawLyric = (id: string): LX.DBService.Lyricnfo[] => {
|
||||
const rawLyricQueryStatement = createRawLyricQueryStatement()
|
||||
return rawLyricQueryStatement.all(id)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量插入原始歌词
|
||||
* @param lyrics 列表
|
||||
*/
|
||||
export const inertRawLyric = (lyrics: LX.DBService.Lyricnfo[]) => {
|
||||
const db = getDB()
|
||||
const rawLyricInsertStatement = createRawLyricInsertStatement()
|
||||
db.transaction((lyrics: LX.DBService.Lyricnfo[]) => {
|
||||
for (const lyric of lyrics) rawLyricInsertStatement.run(lyric)
|
||||
})(lyrics)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除原始歌词
|
||||
* @param ids 列表
|
||||
*/
|
||||
export const deleteRawLyric = (ids: string[]) => {
|
||||
const db = getDB()
|
||||
const rawLyricDeleteStatement = createRawLyricDeleteStatement()
|
||||
db.transaction((ids: string[]) => {
|
||||
for (const id of ids) rawLyricDeleteStatement.run(id)
|
||||
})(ids)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新原始歌词
|
||||
* @param lyrics 列表
|
||||
*/
|
||||
export const updateRawLyric = (lyrics: LX.DBService.Lyricnfo[]) => {
|
||||
const db = getDB()
|
||||
const rawLyricUpdateStatement = createRawLyricUpdateStatement()
|
||||
db.transaction((lyrics: LX.DBService.Lyricnfo[]) => {
|
||||
for (const lyric of lyrics) rawLyricUpdateStatement.run(lyric)
|
||||
})(lyrics)
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空原始歌词
|
||||
*/
|
||||
export const clearRawLyric = () => {
|
||||
const rawLyricClearStatement = createRawLyricClearStatement()
|
||||
rawLyricClearStatement.run()
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计已编辑歌词数量
|
||||
*/
|
||||
export const countRawLyric = () => {
|
||||
const countStatement = createRawLyricCountStatement()
|
||||
return countStatement.get().count
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询已编辑歌词
|
||||
* @param id 歌曲id
|
||||
* @returns 歌词信息
|
||||
*/
|
||||
export const queryEditedLyric = (id: string): LX.DBService.Lyricnfo[] => {
|
||||
const rawLyricQueryStatement = createEditedLyricQueryStatement()
|
||||
return rawLyricQueryStatement.all(id)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量插入已编辑歌词
|
||||
* @param lyrics 列表
|
||||
*/
|
||||
export const inertEditedLyric = (lyrics: LX.DBService.Lyricnfo[]) => {
|
||||
const db = getDB()
|
||||
const rawLyricInsertStatement = createEditedLyricInsertStatement()
|
||||
db.transaction((lyrics: LX.DBService.Lyricnfo[]) => {
|
||||
for (const lyric of lyrics) rawLyricInsertStatement.run(lyric)
|
||||
})(lyrics)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除已编辑歌词
|
||||
* @param ids 列表
|
||||
*/
|
||||
export const deleteEditedLyric = (ids: string[]) => {
|
||||
const db = getDB()
|
||||
const rawLyricDeleteStatement = createEditedLyricDeleteStatement()
|
||||
db.transaction((ids: string[]) => {
|
||||
for (const id of ids) rawLyricDeleteStatement.run(id)
|
||||
})(ids)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新已编辑歌词
|
||||
* @param lyrics 列表
|
||||
*/
|
||||
export const updateEditedLyric = (lyrics: LX.DBService.Lyricnfo[]) => {
|
||||
const db = getDB()
|
||||
const rawLyricUpdateStatement = createEditedLyricUpdateStatement()
|
||||
db.transaction((lyrics: LX.DBService.Lyricnfo[]) => {
|
||||
for (const lyric of lyrics) rawLyricUpdateStatement.run(lyric)
|
||||
})(lyrics)
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空已编辑歌词
|
||||
*/
|
||||
export const clearEditedLyric = () => {
|
||||
const rawLyricClearStatement = createEditedLyricClearStatement()
|
||||
rawLyricClearStatement.run()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 统计已编辑歌词数量
|
||||
*/
|
||||
export const countEditedLyric = () => {
|
||||
const countStatement = createEditedLyricCountStatement()
|
||||
return countStatement.get().count
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
import {
|
||||
queryLyric,
|
||||
queryRawLyric,
|
||||
inertRawLyric,
|
||||
deleteRawLyric,
|
||||
updateRawLyric,
|
||||
clearRawLyric,
|
||||
queryEditedLyric,
|
||||
inertEditedLyric,
|
||||
deleteEditedLyric,
|
||||
updateEditedLyric,
|
||||
clearEditedLyric,
|
||||
countEditedLyric,
|
||||
countRawLyric,
|
||||
} from './dbHelper'
|
||||
|
||||
const keys = ['lyric', 'tlyric', 'rlyric', 'lxlyric'] as const
|
||||
|
||||
const toDBLyric = (id: string, source: LX.DBService.Lyricnfo['source'], lyricInfo: LX.Music.LyricInfo): LX.DBService.Lyricnfo[] => {
|
||||
return (keys.map(k => [k, lyricInfo[k]])
|
||||
.filter(([k, t]) => t != null) as Array<[LX.DBService.Lyricnfo['type'], string]>)
|
||||
.map(([k, t]) => {
|
||||
return {
|
||||
id,
|
||||
type: k,
|
||||
text: Buffer.from(t).toString('base64'),
|
||||
source,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取歌词
|
||||
* @param id 歌曲id
|
||||
* @returns 歌词信息
|
||||
*/
|
||||
export const getPlayerLyric = (id: string): LX.Player.LyricInfo => {
|
||||
const lyrics = queryLyric(id)
|
||||
|
||||
let lyricInfo: LX.Music.LyricInfo = {
|
||||
lyric: '',
|
||||
}
|
||||
let rawLyricInfo: LX.Music.LyricInfo = {
|
||||
lyric: '',
|
||||
}
|
||||
for (const lyric of lyrics) {
|
||||
switch (lyric.source) {
|
||||
case 'edited':
|
||||
if (lyric.type == 'lyric') lyricInfo.lyric = Buffer.from(lyric.text, 'base64').toString()
|
||||
else if (lyric.text != null) lyricInfo[lyric.type] = Buffer.from(lyric.text, 'base64').toString()
|
||||
break
|
||||
default:
|
||||
if (lyric.type == 'lyric') rawLyricInfo.lyric = Buffer.from(lyric.text, 'base64').toString()
|
||||
else if (lyric.text != null) rawLyricInfo[lyric.type] = Buffer.from(lyric.text, 'base64').toString()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return lyricInfo.lyric ? {
|
||||
...lyricInfo,
|
||||
rawlrcInfo: rawLyricInfo,
|
||||
} : {
|
||||
...rawLyricInfo,
|
||||
rawlrcInfo: rawLyricInfo,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取原始歌词
|
||||
* @param id 歌曲id
|
||||
* @returns 歌词信息
|
||||
*/
|
||||
export const getRawLyric = (id: string): LX.Music.LyricInfo => {
|
||||
const lyrics = queryRawLyric(id)
|
||||
|
||||
let lyricInfo: LX.Music.LyricInfo = {
|
||||
lyric: '',
|
||||
}
|
||||
for (const lyric of lyrics) {
|
||||
if (lyric.type == 'lyric') lyricInfo.lyric = Buffer.from(lyric.text, 'base64').toString()
|
||||
else if (lyric.text != null) lyricInfo[lyric.type] = Buffer.from(lyric.text, 'base64').toString()
|
||||
}
|
||||
|
||||
return lyricInfo
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存原始歌词信息
|
||||
* @param id 歌曲id
|
||||
* @param lyricInfo 歌词信息
|
||||
*/
|
||||
export const rawLyricAdd = (id: string, lyricInfo: LX.Music.LyricInfo) => {
|
||||
inertRawLyric(toDBLyric(id, 'raw', lyricInfo))
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除原始歌词信息
|
||||
* @param ids 歌曲id
|
||||
*/
|
||||
export const rawLyricRemove = (ids: string[]) => {
|
||||
deleteRawLyric(ids)
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新原始歌词信息
|
||||
* @param id 歌曲id
|
||||
* @param lyricInfo 歌词信息
|
||||
*/
|
||||
export const rawLyricUpdate = (id: string, lyricInfo: LX.Music.LyricInfo) => {
|
||||
updateRawLyric(toDBLyric(id, 'raw', lyricInfo))
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空原始歌词信息
|
||||
*/
|
||||
export const rawLyricClear = () => {
|
||||
clearRawLyric()
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计原始歌词数量
|
||||
*/
|
||||
export const rawLyricCount = () => {
|
||||
return countRawLyric()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取已编辑歌词
|
||||
* @param id 歌曲id
|
||||
* @returns 歌词信息
|
||||
*/
|
||||
export const getEditedLyric = (id: string): LX.Music.LyricInfo => {
|
||||
const lyrics = queryEditedLyric(id)
|
||||
|
||||
let lyricInfo: LX.Music.LyricInfo = {
|
||||
lyric: '',
|
||||
}
|
||||
for (const lyric of lyrics) {
|
||||
if (lyric.type == 'lyric') lyricInfo.lyric = Buffer.from(lyric.text, 'base64').toString()
|
||||
else if (lyric.text != null) lyricInfo[lyric.type] = Buffer.from(lyric.text, 'base64').toString()
|
||||
}
|
||||
|
||||
return lyricInfo
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存已编辑歌词信息
|
||||
* @param id 歌曲id
|
||||
* @param lyricInfo 歌词信息
|
||||
*/
|
||||
export const editedLyricAdd = (id: string, lyricInfo: LX.Music.LyricInfo) => {
|
||||
inertEditedLyric(toDBLyric(id, 'edited', lyricInfo))
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除已编辑歌词信息
|
||||
* @param ids 歌曲id
|
||||
*/
|
||||
export const editedLyricRemove = (ids: string[]) => {
|
||||
deleteEditedLyric(ids)
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新已编辑歌词信息
|
||||
* @param id 歌曲id
|
||||
* @param lyricInfo 歌词信息
|
||||
*/
|
||||
export const editedLyricUpdate = (id: string, lyricInfo: LX.Music.LyricInfo) => {
|
||||
updateEditedLyric(toDBLyric(id, 'edited', lyricInfo))
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空已编辑歌词信息
|
||||
*/
|
||||
export const editedLyricClear = () => {
|
||||
clearEditedLyric()
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增或更新已编辑歌词信息
|
||||
* @param id 歌曲id
|
||||
* @param lyricInfo 歌词信息
|
||||
*/
|
||||
export const editedLyricUpdateAddAndUpdate = (id: string, lyricInfo: LX.Music.LyricInfo) => {
|
||||
const lyrics = queryEditedLyric(id)
|
||||
if (lyrics.length) updateEditedLyric(toDBLyric(id, 'edited', lyricInfo))
|
||||
else inertEditedLyric(toDBLyric(id, 'edited', lyricInfo))
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计已编辑歌词数量
|
||||
*/
|
||||
export const editedLyricCount = () => {
|
||||
return countEditedLyric()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
import { getDB } from '../../db'
|
||||
|
||||
const RAW_LYRIC = 'raw'
|
||||
const EDITED_LYRIC = 'edited'
|
||||
|
||||
/**
|
||||
* 创建歌词查询语句
|
||||
* @returns 查询语句
|
||||
*/
|
||||
export const createLyricQueryStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>(`
|
||||
SELECT "type", "text", "source"
|
||||
FROM "main"."lyric"
|
||||
WHERE "id"=?
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建原始歌词查询语句
|
||||
* @returns 查询语句
|
||||
*/
|
||||
export const createRawLyricQueryStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>(`
|
||||
SELECT "type", "text"
|
||||
FROM "main"."lyric"
|
||||
WHERE "id"=? AND "source"='${RAW_LYRIC}'
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建原始歌词插入语句
|
||||
* @returns 插入语句
|
||||
*/
|
||||
export const createRawLyricInsertStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.Lyricnfo]>(`
|
||||
INSERT INTO "main"."lyric" ("id", "type", "text", "source")
|
||||
VALUES (@id, @type, @text, '${RAW_LYRIC}')`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建原始歌词清空语句
|
||||
* @returns 清空语句
|
||||
*/
|
||||
export const createRawLyricClearStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare(`
|
||||
DELETE FROM "main"."lyric"
|
||||
WHERE "source"='${RAW_LYRIC}'
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建原始歌词删除语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createRawLyricDeleteStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>(`
|
||||
DELETE FROM "main"."lyric"
|
||||
WHERE "id"=? AND "source"='${RAW_LYRIC}'
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建原始歌词更新语句
|
||||
* @returns 更新语句
|
||||
*/
|
||||
export const createRawLyricUpdateStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.Lyricnfo]>(`
|
||||
UPDATE "main"."lyric"
|
||||
SET "text"=@text
|
||||
WHERE "id"=@id AND "source"='${RAW_LYRIC}' AND "type"=@type`)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建原始歌词数量统计语句
|
||||
* @returns 统计语句
|
||||
*/
|
||||
export const createRawLyricCountStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare(`SELECT COUNT(*) as count FROM "main"."lyric" WHERE "source"='${RAW_LYRIC}'`)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建已编辑歌词查询语句
|
||||
* @returns 查询语句
|
||||
*/
|
||||
export const createEditedLyricQueryStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>(`
|
||||
SELECT "type", "text"
|
||||
FROM "main"."lyric"
|
||||
WHERE "id"=? AND "source"='${EDITED_LYRIC}'
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建已编辑歌词插入语句
|
||||
* @returns 插入语句
|
||||
*/
|
||||
export const createEditedLyricInsertStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.Lyricnfo]>(`
|
||||
INSERT INTO "main"."lyric" ("id", "type", "text", "source")
|
||||
VALUES (@id, @type, @text, '${EDITED_LYRIC}')`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建已编辑歌词清空语句
|
||||
* @returns 清空语句
|
||||
*/
|
||||
export const createEditedLyricClearStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare(`
|
||||
DELETE FROM "main"."lyric"
|
||||
WHERE "source"='${EDITED_LYRIC}'
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建已编辑歌词删除语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createEditedLyricDeleteStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>(`
|
||||
DELETE FROM "main"."lyric"
|
||||
WHERE "id"=? AND "source"='${EDITED_LYRIC}'
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建已编辑歌词更新语句
|
||||
* @returns 更新语句
|
||||
*/
|
||||
export const createEditedLyricUpdateStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.Lyricnfo]>(`
|
||||
UPDATE "main"."lyric"
|
||||
SET "text"=@text
|
||||
WHERE "id"=@id AND "source"='${EDITED_LYRIC}' AND "type"=@type`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建已编辑歌词数量统计语句
|
||||
* @returns 统计语句
|
||||
*/
|
||||
export const createEditedLyricCountStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare(`SELECT COUNT(*) as count FROM "main"."lyric" WHERE "source"='${EDITED_LYRIC}'`)
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { getDB } from '../../db'
|
||||
import {
|
||||
createMusicInfoQueryStatement,
|
||||
createMusicInfoInsertStatement,
|
||||
createMusicInfoDeleteStatement,
|
||||
createMusicInfoClearStatement,
|
||||
createCountStatement,
|
||||
} from './statements'
|
||||
|
||||
|
||||
/**
|
||||
* 查询歌曲信息
|
||||
* @param id 歌曲id
|
||||
* @returns 歌曲信息
|
||||
*/
|
||||
export const queryMusicInfo = (id: string): LX.DBService.MusicInfoOtherSource[] => {
|
||||
const musicInfoQueryStatement = createMusicInfoQueryStatement()
|
||||
return musicInfoQueryStatement.all(id)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量插入歌曲信息
|
||||
* @param musicInfos 列表
|
||||
*/
|
||||
export const inertMusicInfo = (musicInfos: LX.DBService.MusicInfoOtherSource[]) => {
|
||||
const db = getDB()
|
||||
const musicInfoInsertStatement = createMusicInfoInsertStatement()
|
||||
db.transaction((musicInfos: LX.DBService.MusicInfoOtherSource[]) => {
|
||||
for (const info of musicInfos) musicInfoInsertStatement.run(info)
|
||||
})(musicInfos)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除歌曲信息
|
||||
* @param ids 列表
|
||||
*/
|
||||
export const deleteMusicInfo = (ids: string[]) => {
|
||||
const db = getDB()
|
||||
const musicInfoDeleteStatement = createMusicInfoDeleteStatement()
|
||||
db.transaction((ids: string[]) => {
|
||||
for (const id of ids) musicInfoDeleteStatement.run(id)
|
||||
})(ids)
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空歌曲信息
|
||||
*/
|
||||
export const clearMusicInfo = () => {
|
||||
const musicInfoClearStatement = createMusicInfoClearStatement()
|
||||
musicInfoClearStatement.run()
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计歌曲信息数量
|
||||
*/
|
||||
export const countMusicInfo = () => {
|
||||
const countStatement = createCountStatement()
|
||||
return countStatement.get().count
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import {
|
||||
queryMusicInfo,
|
||||
inertMusicInfo,
|
||||
deleteMusicInfo,
|
||||
clearMusicInfo,
|
||||
countMusicInfo,
|
||||
} from './dbHelper'
|
||||
|
||||
|
||||
const toDBMusicInfo = (id: string, musicInfos: LX.Music.MusicInfo[]): LX.DBService.MusicInfoOtherSource[] => {
|
||||
return musicInfos.map((info, index) => {
|
||||
return {
|
||||
...info,
|
||||
meta: JSON.stringify(info.meta),
|
||||
source_id: id,
|
||||
order: index,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取歌曲信息
|
||||
* @param id 歌曲id
|
||||
* @returns 歌词信息
|
||||
*/
|
||||
export const getMusicInfoOtherSource = (id: string): LX.Music.MusicInfoOnline[] => {
|
||||
const list = queryMusicInfo(id).map(info => {
|
||||
return {
|
||||
id: info.id,
|
||||
name: info.name,
|
||||
singer: info.singer,
|
||||
source: info.source,
|
||||
interval: info.interval,
|
||||
meta: JSON.parse(info.meta),
|
||||
}
|
||||
})
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存歌曲信息信息
|
||||
* @param id 歌曲id
|
||||
* @param musicInfos 歌词信息
|
||||
*/
|
||||
export const musicInfoOtherSourceAdd = (id: string, musicInfos: LX.Music.MusicInfoOnline[]) => {
|
||||
inertMusicInfo(toDBMusicInfo(id, musicInfos))
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除歌曲信息信息
|
||||
* @param ids 歌曲id
|
||||
*/
|
||||
export const musicInfoOtherSourceRemove = (ids: string[]) => {
|
||||
deleteMusicInfo(ids)
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空歌曲信息信息
|
||||
*/
|
||||
export const musicInfoOtherSourceClear = () => {
|
||||
clearMusicInfo()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 统计歌曲信息信息数量
|
||||
*/
|
||||
export const musicInfoOtherSourceCount = () => {
|
||||
return countMusicInfo()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { getDB } from '../../db'
|
||||
|
||||
|
||||
/**
|
||||
* 创建歌曲信息查询语句
|
||||
* @returns 查询语句
|
||||
*/
|
||||
export const createMusicInfoQueryStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>(`
|
||||
SELECT "id", "name", "singer", "source", "meta"
|
||||
FROM "main"."music_info_other_source"
|
||||
WHERE source_id=?
|
||||
ORDER BY "order" ASC
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建歌曲信息插入语句
|
||||
* @returns 插入语句
|
||||
*/
|
||||
export const createMusicInfoInsertStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.MusicInfoOtherSource]>(`
|
||||
INSERT INTO "main"."music_info_other_source" ("id", "name", "singer", "source", "meta", "source_id", "order")
|
||||
VALUES (@id, @name, @singer, @source, @meta, @source_id, @order)
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建歌曲信息清空语句
|
||||
* @returns 清空语句
|
||||
*/
|
||||
export const createMusicInfoClearStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare(`
|
||||
DELETE FROM "main"."music_info_other_source"
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建歌曲信息删除语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createMusicInfoDeleteStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>(`
|
||||
DELETE FROM "main"."music_info_other_source"
|
||||
WHERE "source_id"=?
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数量统计语句
|
||||
* @returns 统计语句
|
||||
*/
|
||||
export const createCountStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare('SELECT COUNT(*) as count FROM "main"."music_info_other_source"')
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import { getDB } from '../../db'
|
||||
import {
|
||||
createQueryStatement,
|
||||
createInsertStatement,
|
||||
createDeleteStatement,
|
||||
// createUpdateStatement,
|
||||
createClearStatement,
|
||||
createCountStatement,
|
||||
} from './statements'
|
||||
|
||||
/**
|
||||
* 查询歌曲url
|
||||
* @param id 歌曲id
|
||||
* @returns url
|
||||
*/
|
||||
export const queryMusicUrl = (id: string): string | null => {
|
||||
const queryStatement = createQueryStatement()
|
||||
return queryStatement.get(id)?.url
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量插入歌曲url
|
||||
* @param urlInfo 列表
|
||||
*/
|
||||
export const inertMusicUrl = (urlInfo: LX.DBService.MusicUrlInfo[]) => {
|
||||
const db = getDB()
|
||||
const insertStatement = createInsertStatement()
|
||||
const deleteStatement = createDeleteStatement()
|
||||
db.transaction((urlInfo: LX.DBService.MusicUrlInfo[]) => {
|
||||
for (const info of urlInfo) {
|
||||
deleteStatement.run(info.id)
|
||||
insertStatement.run(info)
|
||||
}
|
||||
})(urlInfo)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除歌曲url
|
||||
* @param ids 列表
|
||||
*/
|
||||
export const deleteMusicUrl = (ids: string[]) => {
|
||||
const db = getDB()
|
||||
const deleteStatement = createDeleteStatement()
|
||||
db.transaction((ids: string[]) => {
|
||||
for (const id of ids) deleteStatement.run(id)
|
||||
})(ids)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新歌曲url
|
||||
* @param urlInfo 列表
|
||||
*/
|
||||
// export const updateMusicUrl = (urlInfo: LX.DBService.MusicUrlInfo[]) => {
|
||||
// const db = getDB()
|
||||
// const updateStatement = createUpdateStatement()
|
||||
// db.transaction((urlInfo: LX.DBService.MusicUrlInfo[]) => {
|
||||
// for (const info of urlInfo) updateStatement.run(info)
|
||||
// })(urlInfo)
|
||||
// }
|
||||
|
||||
/**
|
||||
* 清空歌曲url
|
||||
*/
|
||||
export const clearMusicUrl = () => {
|
||||
const clearStatement = createClearStatement()
|
||||
clearStatement.run()
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计歌曲信息数量
|
||||
*/
|
||||
export const countMusicUrl = () => {
|
||||
const countStatement = createCountStatement()
|
||||
return countStatement.get().count
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import {
|
||||
queryMusicUrl,
|
||||
inertMusicUrl,
|
||||
deleteMusicUrl,
|
||||
clearMusicUrl,
|
||||
countMusicUrl,
|
||||
} from './dbHelper'
|
||||
|
||||
|
||||
/**
|
||||
* 获取歌曲url
|
||||
* @param id 歌曲id
|
||||
* @returns 歌曲url
|
||||
*/
|
||||
export const getMusicUrl = (id: string): string | null => {
|
||||
const url = queryMusicUrl(id)
|
||||
return url
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存歌曲url
|
||||
* @param urlInfos url信息
|
||||
*/
|
||||
export const musicUrlSave = (urlInfos: LX.Music.MusicUrlInfo[]) => {
|
||||
inertMusicUrl(urlInfos)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除歌曲url
|
||||
* @param ids 歌曲id
|
||||
*/
|
||||
export const musicUrlRemove = (ids: string[]) => {
|
||||
deleteMusicUrl(ids)
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空歌曲url
|
||||
*/
|
||||
export const musicUrlClear = () => {
|
||||
clearMusicUrl()
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计歌曲url数量
|
||||
*/
|
||||
export const musicUrlCount = () => {
|
||||
return countMusicUrl()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import { getDB } from '../../db'
|
||||
|
||||
/**
|
||||
* 创建歌曲url查询语句
|
||||
* @returns 查询语句
|
||||
*/
|
||||
export const createQueryStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>(`
|
||||
SELECT "url"
|
||||
FROM "main"."music_url"
|
||||
WHERE "id"=?
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建歌曲url插入语句
|
||||
* @returns 插入语句
|
||||
*/
|
||||
export const createInsertStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.MusicUrlInfo]>(`
|
||||
INSERT INTO "main"."music_url" ("id", "url")
|
||||
VALUES (@id, @url)`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建歌曲url清空语句
|
||||
* @returns 清空语句
|
||||
*/
|
||||
export const createClearStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare(`
|
||||
DELETE FROM "main"."music_url"
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建歌曲url删除语句
|
||||
* @returns 删除语句
|
||||
*/
|
||||
export const createDeleteStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[string]>(`
|
||||
DELETE FROM "main"."music_url"
|
||||
WHERE "id"=?
|
||||
`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建歌曲url更新语句
|
||||
* @returns 更新语句
|
||||
*/
|
||||
export const createUpdateStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare<[LX.DBService.MusicUrlInfo]>(`
|
||||
UPDATE "main"."music_url"
|
||||
SET "url"=@url
|
||||
WHERE "id"=@id`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数量统计语句
|
||||
* @returns 统计语句
|
||||
*/
|
||||
export const createCountStatement = () => {
|
||||
const db = getDB()
|
||||
return db.prepare('SELECT COUNT(*) as count FROM "main"."music_url"')
|
||||
}
|
||||
Reference in New Issue
Block a user