添加启动时的数据库表及表结构完整性校验
This commit is contained in:
@@ -1,108 +1,22 @@
|
||||
import Database from 'better-sqlite3'
|
||||
import path from 'path'
|
||||
import tables from './tables'
|
||||
import verifyDB from './verifyDB'
|
||||
// import migrateData from './migrate'
|
||||
|
||||
let db: Database.Database
|
||||
|
||||
|
||||
const initTables = (db: Database.Database) => {
|
||||
const sql = `
|
||||
CREATE TABLE "db_info" (
|
||||
"id" INTEGER NOT NULL UNIQUE,
|
||||
"field_name" TEXT,
|
||||
"field_value" TEXT,
|
||||
PRIMARY KEY("id" AUTOINCREMENT)
|
||||
);
|
||||
|
||||
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")
|
||||
);
|
||||
|
||||
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")
|
||||
);
|
||||
CREATE INDEX "index_my_list_music_info" ON "my_list_music_info" (
|
||||
"id",
|
||||
"listId"
|
||||
);
|
||||
|
||||
CREATE TABLE "my_list_music_info_order" (
|
||||
"listId" TEXT NOT NULL,
|
||||
"musicInfoId" TEXT NOT NULL,
|
||||
"order" INTEGER NOT NULL
|
||||
);
|
||||
CREATE INDEX "index_my_list_music_info_order" ON "my_list_music_info_order" (
|
||||
"listId",
|
||||
"musicInfoId"
|
||||
);
|
||||
|
||||
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")
|
||||
);
|
||||
CREATE INDEX "index_music_info_other_source" ON "music_info_other_source" (
|
||||
"source_id",
|
||||
"id"
|
||||
);
|
||||
|
||||
-- TODO "meta" TEXT NOT NULL,
|
||||
CREATE TABLE "lyric" (
|
||||
"id" TEXT NOT NULL,
|
||||
"source" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"text" TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "music_url" (
|
||||
"id" TEXT NOT NULL,
|
||||
"url" TEXT NOT NULL
|
||||
);
|
||||
|
||||
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.exec(`
|
||||
${Array.from(tables.values()).join('\n')}
|
||||
INSERT INTO "main"."db_info" ("field_name", "field_value") VALUES ('version', '1');
|
||||
`
|
||||
|
||||
db.exec(sql)
|
||||
`)
|
||||
}
|
||||
|
||||
|
||||
// 打开、初始化数据库
|
||||
export const init = (lxDataPath: string): boolean => {
|
||||
export const init = (lxDataPath: string): boolean | null => {
|
||||
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
|
||||
@@ -127,6 +41,10 @@ export const init = (lxDataPath: string): boolean => {
|
||||
|
||||
// https://www.sqlite.org/pragma.html#pragma_optimize
|
||||
if (dbFileExists) db.exec('PRAGMA optimize;')
|
||||
if (!verifyDB(db)) {
|
||||
db.close()
|
||||
return null
|
||||
}
|
||||
|
||||
// https://www.sqlite.org/lang_vacuum.html
|
||||
// db.exec('VACUUM "main"')
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
// export const sql = `
|
||||
// CREATE TABLE "db_info" (
|
||||
// "id" INTEGER NOT NULL UNIQUE,
|
||||
// "field_name" TEXT,
|
||||
// "field_value" TEXT,
|
||||
// PRIMARY KEY("id" AUTOINCREMENT)
|
||||
// );
|
||||
|
||||
// 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")
|
||||
// );
|
||||
|
||||
// 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")
|
||||
// );
|
||||
// CREATE INDEX "index_my_list_music_info" ON "my_list_music_info" (
|
||||
// "id",
|
||||
// "listId"
|
||||
// );
|
||||
|
||||
// CREATE TABLE "my_list_music_info_order" (
|
||||
// "listId" TEXT NOT NULL,
|
||||
// "musicInfoId" TEXT NOT NULL,
|
||||
// "order" INTEGER NOT NULL
|
||||
// );
|
||||
// CREATE INDEX "index_my_list_music_info_order" ON "my_list_music_info_order" (
|
||||
// "listId",
|
||||
// "musicInfoId"
|
||||
// );
|
||||
|
||||
// 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")
|
||||
// );
|
||||
// CREATE INDEX "index_music_info_other_source" ON "music_info_other_source" (
|
||||
// "source_id",
|
||||
// "id"
|
||||
// );
|
||||
|
||||
// -- TODO "meta" TEXT NOT NULL,
|
||||
// CREATE TABLE "lyric" (
|
||||
// "id" TEXT NOT NULL,
|
||||
// "source" TEXT NOT NULL,
|
||||
// "type" TEXT NOT NULL,
|
||||
// "text" TEXT NOT NULL
|
||||
// );
|
||||
|
||||
// CREATE TABLE "music_url" (
|
||||
// "id" TEXT NOT NULL,
|
||||
// "url" TEXT NOT NULL
|
||||
// );
|
||||
|
||||
// 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 tables = [
|
||||
// 'table_db_info',
|
||||
// 'table_my_list',
|
||||
// 'table_my_list_music_info',
|
||||
// 'index_index_my_list_music_info',
|
||||
// 'table_my_list_music_info_order',
|
||||
// 'index_index_my_list_music_info_order',
|
||||
// 'table_music_info_other_source',
|
||||
// 'index_index_music_info_other_source',
|
||||
// 'table_lyric',
|
||||
// 'table_music_url',
|
||||
// 'table_download_list',
|
||||
// ]
|
||||
|
||||
const tables = new Map<string, string>()
|
||||
|
||||
|
||||
tables.set('db_info', `
|
||||
CREATE TABLE "db_info" (
|
||||
"id" INTEGER NOT NULL UNIQUE,
|
||||
"field_name" TEXT,
|
||||
"field_value" TEXT,
|
||||
PRIMARY KEY("id" AUTOINCREMENT)
|
||||
);
|
||||
`)
|
||||
tables.set('my_list', `
|
||||
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")
|
||||
);
|
||||
`)
|
||||
tables.set('my_list_music_info', `
|
||||
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")
|
||||
);
|
||||
`)
|
||||
tables.set('index_my_list_music_info', `
|
||||
CREATE INDEX "index_my_list_music_info" ON "my_list_music_info" (
|
||||
"id",
|
||||
"listId"
|
||||
);
|
||||
`)
|
||||
tables.set('my_list_music_info_order', `
|
||||
CREATE TABLE "my_list_music_info_order" (
|
||||
"listId" TEXT NOT NULL,
|
||||
"musicInfoId" TEXT NOT NULL,
|
||||
"order" INTEGER NOT NULL
|
||||
);
|
||||
`)
|
||||
tables.set('index_my_list_music_info_order', `
|
||||
CREATE INDEX "index_my_list_music_info_order" ON "my_list_music_info_order" (
|
||||
"listId",
|
||||
"musicInfoId"
|
||||
);
|
||||
`)
|
||||
tables.set('music_info_other_source', `
|
||||
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")
|
||||
);
|
||||
`)
|
||||
tables.set('index_music_info_other_source', `
|
||||
CREATE INDEX "index_music_info_other_source" ON "music_info_other_source" (
|
||||
"source_id",
|
||||
"id"
|
||||
);
|
||||
`)
|
||||
tables.set('lyric', `
|
||||
-- TODO "meta" TEXT NOT NULL,
|
||||
CREATE TABLE "lyric" (
|
||||
"id" TEXT NOT NULL,
|
||||
"source" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"text" TEXT NOT NULL
|
||||
);
|
||||
`)
|
||||
tables.set('music_url', `
|
||||
CREATE TABLE "music_url" (
|
||||
"id" TEXT NOT NULL,
|
||||
"url" TEXT NOT NULL
|
||||
);
|
||||
`)
|
||||
tables.set('download_list', `
|
||||
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 default tables
|
||||
@@ -0,0 +1,25 @@
|
||||
import type Database from 'better-sqlite3'
|
||||
import tables from './tables'
|
||||
|
||||
const rxp = /\n|\s|;|--.+/g
|
||||
export default (db: Database.Database) => {
|
||||
const result = db.prepare('SELECT type,name,tbl_name,sql FROM "main".sqlite_master WHERE sql NOT NULL;').all()
|
||||
const dbTableMap = new Map<string, string>()
|
||||
for (const info of result) dbTableMap.set(info.name, info.sql.replace(rxp, ''))
|
||||
return Array.from(tables.entries()).every(([name, sql]) => {
|
||||
const dbSql = dbTableMap.get(name)
|
||||
return dbSql && dbSql == sql.replace(rxp, '')
|
||||
})
|
||||
// console.log(dbTableMap)
|
||||
// for (const [name, sql] of tables.entries()) {
|
||||
// const dbSql = dbTableMap.get(name)
|
||||
// if (dbSql) {
|
||||
// if (dbSql == sql.replace(rxp, '')) continue
|
||||
// console.log(dbSql)
|
||||
// console.log(sql.replace(rxp, ''))
|
||||
// } else {
|
||||
// console.log(name)
|
||||
// }
|
||||
// }
|
||||
// if (result.every((info) => { tables.includes() }))
|
||||
}
|
||||
Reference in New Issue
Block a user