🤔 fix(db): 完成数据库数据初始化&更新,后者未经过测试

This commit is contained in:
BTMuli
2023-04-24 20:19:52 +08:00
parent 0c178f8958
commit ff36275184
5 changed files with 127 additions and 44 deletions

View File

@@ -5,18 +5,18 @@
* @since Alpha v0.1.4
*/
import { initDatabase } from "./init";
import { initDatabase, resetDatabase, checkDatabase, sqlitePath } from "./init";
import { checkAchievement, checkAchievementSeries } from "./update";
import { deleteDatabase, checkDatabase } from "./utils";
const TGSqlite = {
clearDB: deleteDatabase,
initDB: initDatabase,
resetDB: resetDatabase,
checkDB: checkDatabase,
update: {
achievement: checkAchievement,
achievementSeries: checkAchievementSeries,
},
dbPath: sqlitePath,
};
export default TGSqlite;

View File

@@ -9,6 +9,12 @@
import Database from "tauri-plugin-sql-api";
// sql
import initSql from "./init.sql?raw";
// local
import { TGAppData } from "../../data";
export const sqlitePath = "sqlite:tauri-genshin.db";
export const sqliteTBList = ["Achievements", "AchievementSeries"];
export const sqliteTGList = ["SeriesInsert", "SeriesUpdate", "AchievementInsert", "AchievementUpdate"];
/**
* @description 初始化数据库
@@ -16,8 +22,78 @@ import initSql from "./init.sql?raw";
* @returns {Promise<void>}
*/
export async function initDatabase (): Promise<void> {
const db = await Database.load("sqlite:tauri-genshin.db");
// 执行sql语句
const db = await Database.load(sqlitePath);
// 初始化表格、触发器
await db.execute(initSql);
// 初始化数据
await insertData(db);
await db.close();
}
/**
* @description 初始化数据
* @since Alpha v0.1.4
* @param {Database} db
* @returns {Promise<void>}
*/
async function insertData (db: Database): Promise<void> {
// 插入成就系列数据
await Promise.all(Object.values(TGAppData.achievementSeries).map(async (item) => {
let sql;
if (item.card) {
sql = `INSERT INTO AchievementSeries (id, \`order\`, name, version, icon, nameCard) VALUES (${item.id}, ${item.order}, '${item.name}', '${item.version}', '${item.icon}', '${item.card}')`;
} else {
sql = `INSERT INTO AchievementSeries (id, \`order\`, name, version, icon, nameCard) VALUES (${item.id}, ${item.order}, '${item.name}', '${item.version}', '${item.icon}', NULL)`;
}
await db.execute(sql);
},
));
// 插入成就数据
await Promise.all(Object.values(TGAppData.achievements).map(async (item) => {
const sql = `INSERT INTO Achievements (id, series, \`order\`, name, description, reward, version) VALUES (${item.id}, ${item.series}, ${item.order}, '${item.name}', '${item.description}', ${item.reward}, '${item.version}')`;
await db.execute(sql);
},
));
};
/**
* @description 删除所有数据,重新创建数据
* @since Alpha v0.1.4
* @returns {Promise<void>}
*/
export async function resetDatabase (): Promise<void> {
const db = await Database.load(sqlitePath);
// 删除所有触发器
await Promise.all(sqliteTGList.map(async (trigger) => {
await db.execute(`DROP TRIGGER IF EXISTS ${trigger}`);
}));
// 删除所有表格
await Promise.all(sqliteTBList.map(async (table) => {
await db.execute(`DROP TABLE IF EXISTS ${table}`);
}));
await db.close();
await initDatabase();
}
/**
* @description 检测表单是否完整
* @since Alpha v0.1.4
* @returns {Promise<boolean>}
*/
export async function checkDatabase (): Promise<boolean> {
const db = await Database.load(sqlitePath);
// 获取所有表格
const tables: Array<{ name: string }> = await db.select("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name");
// 获取所有触发器
const triggers: Array<{ name: string }> = await db.select("SELECT name FROM sqlite_master WHERE type='trigger' ORDER BY name");
await db.close();
let res;
if (tables.length !== sqliteTBList.length || triggers.length !== sqliteTGList.length) {
res = false;
} else if (tables.every((item) => sqliteTBList.includes(item.name)) && triggers.every((item) => sqliteTGList.includes(item.name))) {
res = true;
} else {
res = false;
}
return res;
}

View File

@@ -8,6 +8,7 @@
import Database from "tauri-plugin-sql-api";
// local
import { TGAppData } from "../../data";
import { sqlitePath } from "./init";
/**
* @description 数据比对-成就系列数据
@@ -16,10 +17,10 @@ import { TGAppData } from "../../data";
* @returns {Promise<boolean>}
*/
export async function checkAchievement (): Promise<void> {
const db = await Database.load("sqlite:tauri-genshin.db");
Object.values(TGAppData.achievements).map(async (item) => {
const db = await Database.load(sqlitePath);
await Promise.all(Object.values(TGAppData.achievements).map(async (item) => {
// 检测是否存在
const selectRes: BTMuli.SQLite.Achievements[] = await db.select(`SELECT * FROM achievement WHERE id = ${item.id}`);
const selectRes: BTMuli.SQLite.Achievements[] = await db.select(`SELECT * FROM Achievements WHERE id = ${item.id}`);
if (!selectRes || selectRes.length === 0) {
// 不存在则插入
const sql = `INSERT INTO Achievements (id, series, \`order\`, name, description, reward, version) VALUES (${item.id}, ${item.series}, ${item.order}, '${item.name}', '${item.description}', ${item.reward}, '${item.version}')`;
@@ -33,7 +34,7 @@ export async function checkAchievement (): Promise<void> {
await db.execute(sql);
}
}
});
}));
await db.close();
}
@@ -44,20 +45,20 @@ export async function checkAchievement (): Promise<void> {
* @returns {Promise<void>}
*/
export async function checkAchievementSeries (): Promise<void> {
const db = await Database.load("sqlite:tauri-genshin.db");
Object.values(TGAppData.achievementSeries).map(async (item) => {
const db = await Database.load(sqlitePath);
await Promise.all(Object.values(TGAppData.achievementSeries).map(async (item) => {
// 检测是否存在
const selectRes: BTMuli.SQLite.AchievementSeries[] = await db.select(`SELECT * FROM achievement_series WHERE id = ${item.id}`);
const selectRes: BTMuli.SQLite.AchievementSeries[] = await db.select(`SELECT * FROM AchievementSeries WHERE id = ${item.id}`);
if (!selectRes || selectRes.length === 0) {
// 不存在则插入
let sql;
if (item.card) {
sql = `INSERT INTO AchievementSeries (id, \`order\`, name, version, icon, nameCard) VALUES (${item.id}, ${item.order}, '${item.name}', '${item.version}', '${item.icon}', '${item.card}')`;
} else {
sql = `INSERT INTO AchievementSeries (id, \`order\`, name, version, icon) VALUES (${item.id}, ${item.order}, '${item.name}', '${item.version}', '${item.icon}')`;
sql = `INSERT INTO AchievementSeries (id, \`order\`, name, version, icon, nameCard) VALUES (${item.id}, ${item.order}, '${item.name}', '${item.version}', '${item.icon}', NULL)`;
}
await db.execute(sql);
}
});
}));
await db.close();
}

View File

@@ -1,28 +0,0 @@
/**
* @file core database utils.ts
* @description SQLite 数据库相关工具函数
* @since Alpha v0.1.4
*/
// tauri
import { fs } from "@tauri-apps/api";
/**
* @description 检测数据库是否存在
* @since Alpha v0.1.4
* @returns {Promise<boolean>}
*/
export async function checkDatabase (): Promise<boolean> {
return await fs.exists("tauri-genshin.db", { dir: fs.BaseDirectory.AppConfig });
}
/**
* @description 删除数据库
* @since Alpha v0.1.4
* @returns {Promise<void>}
*/
export async function deleteDatabase (): Promise<void> {
if (await checkDatabase()) {
await fs.removeFile("tauri-genshin.db", { dir: fs.BaseDirectory.AppConfig });
}
}

View File

@@ -1,6 +1,6 @@
<template>
<div v-if="loading">
<TLoading />
<TLoading :title="loadingTitle" />
</div>
<div v-else>
<v-list class="config-list">
@@ -116,6 +116,7 @@
</template>
</v-list-item>
<v-list-item title="删除 IndexedDB" prepend-icon="mdi-delete" @click="tryConfirm('delDB')" />
<v-list-item title="检测 SQLite 数据库完整性" prepend-icon="mdi-database-check" @click="tryConfirm('checkDB')" />
<v-list-subheader inset class="config-header">
路径
</v-list-subheader>
@@ -146,7 +147,6 @@
// vue
import { onMounted, ref } from "vue";
import { getBuildTime } from "../utils/TGBuild";
import TLoading from "../components/t-loading.vue";
import TConfirm from "../components/t-confirm.vue";
// tauri
@@ -159,8 +159,11 @@ import { useAchievementsStore } from "../store/modules/achievements";
// utils
import { WriteTGData, DeleteTGData, ReadAllTGData } from "../utils/TGIndex";
import { backupUiafData, restoreUiafData } from "../utils/UIAF";
import TGSqlite from "../core/database/TGSqlite";
// data
import { getDataList } from "../data/init";
import Database from "tauri-plugin-sql-api";
import { onUnmounted } from "vue";
// Store
const appStore = useAppStore();
@@ -178,6 +181,7 @@ const osVersion = ref("" as string);
// loading
const loading = ref(true as boolean);
const loadingTitle = ref("正在加载..." as string);
// data
const showHome = ref(homeStore.getShowValue() as string[]);
@@ -252,6 +256,11 @@ function tryConfirm (oper: string) {
confirmOper.value = "delDB";
confirmShow.value = true;
break;
case "checkDB":
confirmText.value = "请确认已经备份关键数据。";
confirmOper.value = "checkDB";
confirmShow.value = true;
break;
}
}
@@ -283,6 +292,9 @@ async function doConfirm (oper: string) {
case "delDB":
delDB();
break;
case "checkDB":
await checkDB();
break;
default:
break;
}
@@ -400,6 +412,28 @@ function delDB () {
snackbarColor.value = "success";
snackbar.value = true;
}
// 检查 SQLite 数据库
async function checkDB () {
loadingTitle.value = "正在检查数据库表单完整性...";
const res = await TGSqlite.checkDB();
if (!res) {
loadingTitle.value = "检测到表单不完整,正在重置数据库...";
await TGSqlite.resetDB();
loading.value = false;
snackbarText.value = "数据库已重置!请载入备份数据。";
snackbarColor.value = "success";
snackbar.value = true;
} else {
loadingTitle.value = "正在检查数据库数据完整性...";
await TGSqlite.update.achievement();
await TGSqlite.update.achievementSeries();
loading.value = false;
snackbarText.value = "数据库检查完毕!";
snackbarColor.value = "success";
snackbar.value = true;
}
}
</script>
<style lang="css" scoped>