db_music.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. import Logger from "@/util/logger.ts";
  2. import { loadDb} from "@/common/db/db.ts";
  3. import {handle, PromiseResult} from "@/util/promiseHandle.ts";
  4. import {AppDbName} from "@/types/appConfig.ts";
  5. import {Knex} from "knex";
  6. import {MusicScanSetting, MusicTableName, PlayList} from "@/types/musicType.ts";
  7. let logger = Logger.logger('music_db', 'info');
  8. async function _initScanConfigTable(db : Knex): PromiseResult<boolean> {
  9. let [err, hasTable] = await handle(
  10. db.schema.hasTable(MusicTableName.music_scan_setting)
  11. )
  12. if (err) {
  13. err = err as Error;
  14. logger.error(`[音频扫描库] ${err.message}`)
  15. return [new Error('音频扫描库初始化失败'), false]
  16. }
  17. console.log(hasTable)
  18. if (hasTable) {
  19. return [null, true];
  20. }
  21. let [createErr, _res] = await handle(db?.schema.createTable(MusicTableName.music_scan_setting, (table) => {
  22. // 初始化扫描配置
  23. logger.info(`[初始化音频扫描库]`)
  24. table.increments('id').primary()
  25. table.string('name')
  26. table.string('path')
  27. table.boolean('scanSubDir')
  28. table.boolean('isFileRepeat')
  29. }))
  30. if (createErr) {
  31. createErr = createErr as Error;
  32. logger.error(`[初始化磁贴表失败] ${createErr.message}`)
  33. return [createErr, false];
  34. }
  35. logger.info('[初始化音频扫描配置成功]')
  36. return [null, true];
  37. }
  38. async function _initPlayListTable(db : Knex): PromiseResult<boolean> {
  39. let [err, hasTable] = await handle(
  40. db.schema.hasTable(MusicTableName.music_play_list)
  41. )
  42. if (err) {
  43. err = err as Error;
  44. logger.error(`[歌单初始化] ${err.message}`)
  45. return [new Error('歌单初始化'), false]
  46. }
  47. if (hasTable) {
  48. return [null, true];
  49. }
  50. let [createErr, _res] = await handle(
  51. db.schema.createTable(MusicTableName.music_play_list, (table) => {
  52. logger.info(`[初始化音频播放列表库]`)
  53. table.increments('id').primary()
  54. table.string('name')
  55. table.string('icon')
  56. table.string('cover')
  57. table.string('description')
  58. table.integer('playCount')
  59. table.integer('trackCount')
  60. table.integer('createTime')
  61. table.boolean('isTagSearch')
  62. table.integer('lastPlayTime')
  63. table.boolean('isSync')
  64. table.boolean('isPublic')
  65. table.boolean('isLike')
  66. }))
  67. if (createErr) {
  68. createErr = createErr as Error;
  69. logger.error(`[初始化歌单失败] ${createErr.message}`)
  70. return [createErr, false];
  71. }
  72. // 添加默认歌单
  73. await db.insert({
  74. name: '我的喜爱',
  75. icon: 'favorite',
  76. cover: 'favorite',
  77. description: '我的喜爱',
  78. playCount: 0,
  79. trackCount: 0,
  80. createTime: Date.now(),
  81. isTagSearch: false,
  82. lastPlayTime: Date.now(),
  83. isSync: false,
  84. isPublic: false,
  85. isLike: true,
  86. }).into(MusicTableName.music_play_list)
  87. logger.info('[初始化我的喜爱歌单成功]')
  88. return [null, true];
  89. }
  90. async function _initSongsTable(db : Knex): PromiseResult<boolean>
  91. {
  92. let [err, hasTable] = await handle(
  93. db.schema.hasTable(MusicTableName.music_songs)
  94. )
  95. if (err) {
  96. err = err as Error;
  97. logger.error(`[音频表初始化] ${err.message}`)
  98. return [new Error('音频表初始化'), false]
  99. }
  100. if (hasTable) {
  101. return [null, true];
  102. }
  103. let [createErr, _res] = await handle(
  104. db.schema.createTable(MusicTableName.music_songs, (table) => {
  105. logger.info(`[初始化音频库]`)
  106. table.increments('id').primary()
  107. table.string('name')
  108. table.string('artists')
  109. table.string('album')
  110. table.string('cover')
  111. table.integer('duration')
  112. table.boolean('isLike')
  113. table.string('origin')
  114. table.integer('type')
  115. table.boolean('isLocal')
  116. table.string('filePath')
  117. table.string('lyricPath')
  118. table.string('tags')
  119. table.integer('playCount')
  120. }))
  121. if (createErr) {
  122. createErr = createErr as Error;
  123. logger.error(`[初始化音频库失败] ${createErr.message}`)
  124. return [createErr, false];
  125. }
  126. logger.info('[初始化音频库成功]')
  127. return [null, true];
  128. }
  129. async function _initPlaylistSongs(db : Knex): PromiseResult<boolean>
  130. {
  131. let [err, hasTable] = await handle(
  132. db.schema.hasTable(MusicTableName.music_play_list_songs)
  133. )
  134. if (err) {
  135. err = err as Error;
  136. logger.error(`[歌单歌曲表初始化] ${err.message}`)
  137. return [new Error('歌单歌曲表初始化'), false]
  138. }
  139. if (hasTable) {
  140. return [null, true];
  141. }
  142. let [createErr, _res] = await handle(
  143. db.schema.createTable(MusicTableName.music_play_list_songs, (table) => {
  144. logger.info(`[初始化歌单歌曲库]`)
  145. table.increments('id').primary()
  146. table.integer('musicId')
  147. table.integer('playListId')
  148. table.integer('order')
  149. }))
  150. if (createErr) {
  151. createErr = createErr as Error;
  152. logger.error(`[初始化歌单歌曲库失败] ${createErr.message}`)
  153. return [createErr, false];
  154. }
  155. logger.info('[初始化歌单歌曲库成功]')
  156. return [null, true];
  157. }
  158. export async function initMusicData() : PromiseResult<boolean>
  159. {
  160. let db = loadDb(AppDbName.music_db)
  161. if(!db){
  162. logger.error('数据库初始化失败')
  163. return [new Error('音乐数据库初始化失败'), false]
  164. }
  165. let [err, res] = await _initScanConfigTable(db);
  166. if (err) {
  167. err = err as Error;
  168. logger.error(`[初始化扫描库失败] ${err.message}`)
  169. return [err, false];
  170. }
  171. [err, res] = await _initPlayListTable(db);
  172. if (err) {
  173. err = err as Error;
  174. logger.error(`[初始化播放列表库失败] ${err.message}`)
  175. return [err, false];
  176. }
  177. [err, res] = await _initSongsTable(db);
  178. if (err) {
  179. err = err as Error;
  180. logger.error(`[初始化音频库失败] ${err.message}`)
  181. return [err, false];
  182. }
  183. [err, res] = await _initPlaylistSongs(db);
  184. if (err) {
  185. err = err as Error;
  186. logger.error(`[初始化歌单歌曲库失败] ${err.message}`)
  187. return [err, false];
  188. }
  189. logger.info('[初始化音频库成功]')
  190. return [null, res]
  191. }
  192. // 根据扫描地址获取扫描配置
  193. export async function getScanConfigByPath(path: string, id: number[] = []) : PromiseResult<MusicScanSetting[]>
  194. {
  195. let db = loadDb(AppDbName.music_db)
  196. if(!db){
  197. logger.error('数据库初始化失败')
  198. return [new Error('音乐数据库初始化失败'), null]
  199. }
  200. let [err, res] = await handle(
  201. db.select('name', 'path', 'scanSubDir', 'isFileRepeat')
  202. .from(MusicTableName.music_scan_setting)
  203. .where('path', path)
  204. // 排除id
  205. .whereNotIn('id', id)
  206. )
  207. if (err) {
  208. err = err as Error;
  209. logger.error(`[获取扫描配置失败] ${err.message}`)
  210. return [err, null];
  211. }
  212. return [null, res as MusicScanSetting[]];
  213. }
  214. export async function getScanConfig() : PromiseResult<MusicScanSetting[]>
  215. {
  216. let db = loadDb(AppDbName.music_db)
  217. if(!db){
  218. logger.error('数据库初始化失败')
  219. return [new Error('音乐数据库初始化失败'), null]
  220. }
  221. // 将下面的 scanSubDir 转为 boolean 类型
  222. let [err, res] = await handle(
  223. db.select('id', 'name', 'path', 'scanSubDir', 'isFileRepeat')
  224. .from<MusicScanSetting>(MusicTableName.music_scan_setting).withSchema(MusicTableName.music_scan_setting)
  225. )
  226. if (err) {
  227. err = err as Error;
  228. logger.error(`[获取扫描配置失败] ${err.message}`)
  229. return [err, null];
  230. }
  231. return [null, res as MusicScanSetting[]];
  232. }
  233. export async function addScanConfig(scanConfig: MusicScanSetting) : PromiseResult<boolean>
  234. {
  235. let db = loadDb(AppDbName.music_db)
  236. if(!db){
  237. logger.error('数据库初始化失败')
  238. return [new Error('音乐数据库初始化失败'), false]
  239. }
  240. // 移除其中的 id
  241. let addScanConfig = {
  242. name: scanConfig.name,
  243. path: scanConfig.path,
  244. scanSubDir: scanConfig.scanSubDir,
  245. isFileRepeat: scanConfig.isFileRepeat
  246. }
  247. let [err, _res] = await handle(
  248. db.insert(addScanConfig).into(MusicTableName.music_scan_setting)
  249. )
  250. if (err) {
  251. err = err as Error;
  252. logger.error(`[添加扫描配置失败] ${err.message}`)
  253. return [err, false];
  254. }
  255. return [null, true];
  256. }
  257. export async function updateScanConfig(scanConfig: MusicScanSetting) : PromiseResult<boolean>
  258. {
  259. let db = loadDb(AppDbName.music_db)
  260. if(!db){
  261. logger.error('数据库初始化失败')
  262. return [new Error('音乐数据库初始化失败'), false]
  263. }
  264. let [err, _res] = await handle(
  265. db.update(scanConfig).into(MusicTableName.music_scan_setting).where('id', scanConfig.id)
  266. )
  267. if (err) {
  268. err = err as Error;
  269. }
  270. return [err, true];
  271. }
  272. export async function deleteScanConfig(id: number) : PromiseResult<boolean>
  273. {
  274. let db = loadDb(AppDbName.music_db)
  275. if(!db){
  276. logger.error('数据库初始化失败')
  277. return [new Error('音乐数据库初始化失败'), false]
  278. }
  279. let [err, _res] = await handle(
  280. db.delete().from(MusicTableName.music_scan_setting).where('id', id)
  281. )
  282. if (err) {
  283. err= err as Error;
  284. }
  285. return [err, true];
  286. }
  287. export async function getPlayList() : PromiseResult<PlayList[]>
  288. {
  289. let db = loadDb(AppDbName.music_db)
  290. if(!db){
  291. logger.error('数据库初始化失败')
  292. return [new Error('音乐数据库初始化失败'), null]
  293. }
  294. let [err, res] = await handle(
  295. db.select('id', 'name', 'icon', 'cover', 'description', 'playCount', 'trackCount', 'createTime', 'isTagSearch', 'lastPlayTime', 'isSync', 'isPublic', 'isLike')
  296. .from(MusicTableName.music_play_list)
  297. )
  298. if (err) {
  299. err = err as Error;
  300. logger.error(`[获取播放列表失败] ${err.message}`)
  301. return [err, null];
  302. }
  303. return [null, res as PlayList[]];
  304. }
  305. export async function addPlayList(playList: PlayList) : PromiseResult<boolean>
  306. {
  307. let db = loadDb(AppDbName.music_db)
  308. if(!db){
  309. logger.error('数据库初始化失败')
  310. return [new Error('音乐数据库初始化失败'), false]
  311. }
  312. let [err, _res] = await handle(
  313. db.insert(playList).into(MusicTableName.music_play_list)
  314. )
  315. if (err) {
  316. err = err as Error;
  317. logger.error(`[添加播放列表失败] ${err.message}`)
  318. return [err, false];
  319. }
  320. return [null, true];
  321. }