mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-05-23 22:37:41 +08:00
修复导入歌单时可能会导致歌单数据存储异常的问题(#500)
This commit is contained in:
parent
0d996e2bf3
commit
8210da380a
@ -5,6 +5,7 @@
|
|||||||
### 修复
|
### 修复
|
||||||
|
|
||||||
- 修复重复的数据初始化调用
|
- 修复重复的数据初始化调用
|
||||||
|
- 修复导入歌单时可能会导致歌单数据存储异常的问题(#500)
|
||||||
|
|
||||||
### 变更
|
### 变更
|
||||||
|
|
||||||
|
@ -2,7 +2,9 @@ import AsyncStorage from '@react-native-async-storage/async-storage'
|
|||||||
import { log } from '@/utils/log'
|
import { log } from '@/utils/log'
|
||||||
|
|
||||||
const partKeyPrefix = '@___PART___'
|
const partKeyPrefix = '@___PART___'
|
||||||
|
const partKeyArrPrefix = '@___PART_A___'
|
||||||
const partKeyPrefixRxp = /^@___PART___/
|
const partKeyPrefixRxp = /^@___PART___/
|
||||||
|
const partKeyArrPrefixRxp = /^@___PART_A___/
|
||||||
const keySplit = ','
|
const keySplit = ','
|
||||||
const limit = 500000
|
const limit = 500000
|
||||||
|
|
||||||
@ -15,16 +17,25 @@ const buildData = (key: string, value: any, datas: Array<[string, string]>) => {
|
|||||||
|
|
||||||
const partKeys = []
|
const partKeys = []
|
||||||
for (let i = 0, len = Math.floor(valueStr.length / limit); i <= len; i++) {
|
for (let i = 0, len = Math.floor(valueStr.length / limit); i <= len; i++) {
|
||||||
let partKey = `${partKeyPrefix}${key}${i}`
|
let partKey = `${partKeyArrPrefix}${key}${i}`
|
||||||
partKeys.push(partKey)
|
partKeys.push(partKey)
|
||||||
datas.push([partKey, valueStr.substring(i * limit, (i + 1) * limit)])
|
datas.push([partKey, valueStr.substring(i * limit, (i + 1) * limit)])
|
||||||
}
|
}
|
||||||
datas.push([key, `${partKeyPrefix}${partKeys.join(keySplit)}`])
|
datas.push([key, partKeyArrPrefix + JSON.stringify(partKeys)])
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleGetDataOld = async<T>(partKeys: string): Promise<T> => {
|
||||||
|
const keys = partKeys.replace(partKeyPrefixRxp, '').split(keySplit)
|
||||||
|
|
||||||
|
return AsyncStorage.multiGet(keys).then(datas => {
|
||||||
|
return JSON.parse(datas.map(data => data[1]).join(''))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleGetData = async<T>(partKeys: string): Promise<T> => {
|
const handleGetData = async<T>(partKeys: string): Promise<T> => {
|
||||||
const keys = partKeys.replace(partKeyPrefixRxp, '').split(keySplit)
|
if (partKeys.startsWith(partKeyPrefix)) return handleGetDataOld<T>(partKeys)
|
||||||
|
|
||||||
|
const keys = JSON.parse(partKeys.replace(partKeyArrPrefixRxp, '')) as string[]
|
||||||
return AsyncStorage.multiGet(keys).then(datas => {
|
return AsyncStorage.multiGet(keys).then(datas => {
|
||||||
return JSON.parse(datas.map(data => data[1]).join(''))
|
return JSON.parse(datas.map(data => data[1]).join(''))
|
||||||
})
|
})
|
||||||
@ -35,6 +46,7 @@ export const saveData = async(key: string, value: any) => {
|
|||||||
buildData(key, value, datas)
|
buildData(key, value, datas)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
await removeData(key)
|
||||||
await AsyncStorage.multiSet(datas)
|
await AsyncStorage.multiSet(datas)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
// saving error
|
// saving error
|
||||||
@ -52,7 +64,7 @@ export const getData = async<T = unknown>(key: string): Promise<T | null> => {
|
|||||||
log.error('storage error[getData]:', key, e.message)
|
log.error('storage error[getData]:', key, e.message)
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
if (value && partKeyPrefixRxp.test(value)) {
|
if (value && (partKeyPrefixRxp.test(value) || partKeyArrPrefixRxp.test(value))) {
|
||||||
return handleGetData<T>(value)
|
return handleGetData<T>(value)
|
||||||
} else if (value == null) return value
|
} else if (value == null) return value
|
||||||
return JSON.parse(value)
|
return JSON.parse(value)
|
||||||
@ -67,7 +79,8 @@ export const removeData = async(key: string) => {
|
|||||||
log.error('storage error[removeData]:', key, e.message)
|
log.error('storage error[removeData]:', key, e.message)
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
if (value && partKeyPrefixRxp.test(value)) {
|
if (value) {
|
||||||
|
if (partKeyPrefixRxp.test(value)) {
|
||||||
let partKeys = value.replace(partKeyPrefixRxp, '').split(keySplit)
|
let partKeys = value.replace(partKeyPrefixRxp, '').split(keySplit)
|
||||||
partKeys.push(key)
|
partKeys.push(key)
|
||||||
try {
|
try {
|
||||||
@ -77,7 +90,21 @@ export const removeData = async(key: string) => {
|
|||||||
log.error('storage error[removeData]:', key, e.message)
|
log.error('storage error[removeData]:', key, e.message)
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
} else {
|
return
|
||||||
|
} else if (partKeyArrPrefixRxp.test(value)) {
|
||||||
|
let partKeys = JSON.parse(value.replace(partKeyArrPrefixRxp, '')) as string[]
|
||||||
|
partKeys.push(key)
|
||||||
|
try {
|
||||||
|
await AsyncStorage.multiRemove(partKeys)
|
||||||
|
} catch (e: any) {
|
||||||
|
// remove error
|
||||||
|
log.error('storage error[removeData]:', key, e.message)
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await AsyncStorage.removeItem(key)
|
await AsyncStorage.removeItem(key)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
@ -85,7 +112,6 @@ export const removeData = async(key: string) => {
|
|||||||
log.error('storage error[removeData]:', key, e.message)
|
log.error('storage error[removeData]:', key, e.message)
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getAllKeys = async() => {
|
export const getAllKeys = async() => {
|
||||||
@ -114,7 +140,7 @@ export const getDataMultiple = async<T extends readonly string[]>(keys: T) => {
|
|||||||
}
|
}
|
||||||
const promises: Array<Promise<ReadonlyArray<[unknown | null]>>> = []
|
const promises: Array<Promise<ReadonlyArray<[unknown | null]>>> = []
|
||||||
for (const [, value] of datas) {
|
for (const [, value] of datas) {
|
||||||
if (value && partKeyPrefixRxp.test(value)) {
|
if (value && (partKeyPrefixRxp.test(value) || partKeyArrPrefixRxp.test(value))) {
|
||||||
promises.push(handleGetData(value))
|
promises.push(handleGetData(value))
|
||||||
} else {
|
} else {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||||
@ -132,6 +158,7 @@ export const saveDataMultiple = async(datas: Array<[string, any]>) => {
|
|||||||
buildData(key, value, allData)
|
buildData(key, value, allData)
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
await removeDataMultiple(datas.map(k => k[0]))
|
||||||
await AsyncStorage.multiSet(allData)
|
await AsyncStorage.multiSet(allData)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
// save error
|
// save error
|
||||||
@ -147,8 +174,12 @@ export const removeDataMultiple = async(keys: string[]) => {
|
|||||||
let allKeys = []
|
let allKeys = []
|
||||||
for (const [key, value] of datas) {
|
for (const [key, value] of datas) {
|
||||||
allKeys.push(key)
|
allKeys.push(key)
|
||||||
if (value && partKeyPrefixRxp.test(value)) {
|
if (value) {
|
||||||
|
if (partKeyPrefixRxp.test(value)) {
|
||||||
allKeys.push(...value.replace(partKeyPrefixRxp, '').split(keySplit))
|
allKeys.push(...value.replace(partKeyPrefixRxp, '').split(keySplit))
|
||||||
|
} else if (partKeyArrPrefixRxp.test(value)) {
|
||||||
|
allKeys.push(...JSON.parse(value.replace(partKeyPrefixRxp, '')) as string[])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -48,7 +48,8 @@ export const handleImport = (path: string, position: number) => {
|
|||||||
void readListData(path).then(async listData => {
|
void readListData(path).then(async listData => {
|
||||||
if (listData == null) return
|
if (listData == null) return
|
||||||
void handleImportListPart(listData, position)
|
void handleImportListPart(listData, position)
|
||||||
}).catch(() => {
|
}).catch((err) => {
|
||||||
|
log.error(err)
|
||||||
toast(global.i18n.t('setting_backup_part_import_list_tip_error'))
|
toast(global.i18n.t('setting_backup_part_import_list_tip_error'))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,8 @@ export const handleImportListPart = async(listData: LX.ConfigFile.MyListInfoPart
|
|||||||
position: Math.max(position, -1),
|
position: Math.max(position, -1),
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
toast(global.i18n.t('setting_backup_part_import_list_tip_success'))
|
toast(global.i18n.t('setting_backup_part_import_list_tip_success'))
|
||||||
}).catch(() => {
|
}).catch((err) => {
|
||||||
|
log.error(err)
|
||||||
toast(global.i18n.t('setting_backup_part_import_list_tip_error'))
|
toast(global.i18n.t('setting_backup_part_import_list_tip_error'))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -160,7 +161,8 @@ export const handleImportList = (path: string) => {
|
|||||||
void importPlayList(path).then((skipTip) => {
|
void importPlayList(path).then((skipTip) => {
|
||||||
if (skipTip) return
|
if (skipTip) return
|
||||||
toast(global.i18n.t('setting_backup_part_import_list_tip_success'))
|
toast(global.i18n.t('setting_backup_part_import_list_tip_success'))
|
||||||
}).catch(() => {
|
}).catch((err) => {
|
||||||
|
log.error(err)
|
||||||
toast(global.i18n.t('setting_backup_part_import_list_tip_error'))
|
toast(global.i18n.t('setting_backup_part_import_list_tip_error'))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ export const clearLogs = async() => {
|
|||||||
export const log = {
|
export const log = {
|
||||||
info(...msgs: any[]) {
|
info(...msgs: any[]) {
|
||||||
// console.info(...msgs)
|
// console.info(...msgs)
|
||||||
const msg = msgs.map(m => typeof m == 'string' ? m : JSON.stringify(m)).join(' ')
|
const msg = msgs.map(m => typeof m == 'string' ? m : m instanceof Error ? m.stack ?? m.message : JSON.stringify(m)).join(' ')
|
||||||
if (msg.startsWith('%c')) return
|
if (msg.startsWith('%c')) return
|
||||||
const time = new Date().toLocaleString()
|
const time = new Date().toLocaleString()
|
||||||
if (logTools.tempLog) {
|
if (logTools.tempLog) {
|
||||||
@ -46,15 +46,14 @@ export const log = {
|
|||||||
},
|
},
|
||||||
warn(...msgs: any[]) {
|
warn(...msgs: any[]) {
|
||||||
// console.warn(...msgs)
|
// console.warn(...msgs)
|
||||||
const msg = msgs.map(m => typeof m == 'string' ? m : JSON.stringify(m)).join(' ')
|
const msg = msgs.map(m => typeof m == 'string' ? m : m instanceof Error ? m.stack ?? m.message : JSON.stringify(m)).join(' ')
|
||||||
const time = new Date().toLocaleString()
|
const time = new Date().toLocaleString()
|
||||||
if (logTools.tempLog) {
|
if (logTools.tempLog) {
|
||||||
logTools.tempLog.push({ type: 'WARN', time, text: msg })
|
logTools.tempLog.push({ type: 'WARN', time, text: msg })
|
||||||
} else logTools.writeLog(`${time} WARN ${msg}`)
|
} else logTools.writeLog(`${time} WARN ${msg}`)
|
||||||
},
|
},
|
||||||
error(...msgs: any[]) {
|
error(...msgs: any[]) {
|
||||||
// console.error...(msgs)
|
const msg = msgs.map(m => typeof m == 'string' ? m : m instanceof Error ? m.stack ?? m.message : JSON.stringify(m)).join(' ')
|
||||||
const msg = msgs.map(m => typeof m == 'string' ? m : JSON.stringify(m)).join(' ')
|
|
||||||
const time = new Date().toLocaleString()
|
const time = new Date().toLocaleString()
|
||||||
if (logTools.tempLog) {
|
if (logTools.tempLog) {
|
||||||
logTools.tempLog.push({ type: 'ERROR', time, text: msg })
|
logTools.tempLog.push({ type: 'ERROR', time, text: msg })
|
||||||
|
Loading…
x
Reference in New Issue
Block a user