mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-12 09:18:14 +08:00
🤔 fix(db): 完成数据库数据初始化&更新,后者未经过测试
This commit is contained in:
@@ -5,18 +5,18 @@
|
|||||||
* @since Alpha v0.1.4
|
* @since Alpha v0.1.4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { initDatabase } from "./init";
|
import { initDatabase, resetDatabase, checkDatabase, sqlitePath } from "./init";
|
||||||
import { checkAchievement, checkAchievementSeries } from "./update";
|
import { checkAchievement, checkAchievementSeries } from "./update";
|
||||||
import { deleteDatabase, checkDatabase } from "./utils";
|
|
||||||
|
|
||||||
const TGSqlite = {
|
const TGSqlite = {
|
||||||
clearDB: deleteDatabase,
|
|
||||||
initDB: initDatabase,
|
initDB: initDatabase,
|
||||||
|
resetDB: resetDatabase,
|
||||||
checkDB: checkDatabase,
|
checkDB: checkDatabase,
|
||||||
update: {
|
update: {
|
||||||
achievement: checkAchievement,
|
achievement: checkAchievement,
|
||||||
achievementSeries: checkAchievementSeries,
|
achievementSeries: checkAchievementSeries,
|
||||||
},
|
},
|
||||||
|
dbPath: sqlitePath,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TGSqlite;
|
export default TGSqlite;
|
||||||
|
|||||||
@@ -9,6 +9,12 @@
|
|||||||
import Database from "tauri-plugin-sql-api";
|
import Database from "tauri-plugin-sql-api";
|
||||||
// sql
|
// sql
|
||||||
import initSql from "./init.sql?raw";
|
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 初始化数据库
|
* @description 初始化数据库
|
||||||
@@ -16,8 +22,78 @@ import initSql from "./init.sql?raw";
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
export async function initDatabase (): Promise<void> {
|
export async function initDatabase (): Promise<void> {
|
||||||
const db = await Database.load("sqlite:tauri-genshin.db");
|
const db = await Database.load(sqlitePath);
|
||||||
// 执行sql语句
|
// 初始化表格、触发器
|
||||||
await db.execute(initSql);
|
await db.execute(initSql);
|
||||||
|
// 初始化数据
|
||||||
|
await insertData(db);
|
||||||
await db.close();
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
import Database from "tauri-plugin-sql-api";
|
import Database from "tauri-plugin-sql-api";
|
||||||
// local
|
// local
|
||||||
import { TGAppData } from "../../data";
|
import { TGAppData } from "../../data";
|
||||||
|
import { sqlitePath } from "./init";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 数据比对-成就系列数据
|
* @description 数据比对-成就系列数据
|
||||||
@@ -16,10 +17,10 @@ import { TGAppData } from "../../data";
|
|||||||
* @returns {Promise<boolean>}
|
* @returns {Promise<boolean>}
|
||||||
*/
|
*/
|
||||||
export async function checkAchievement (): Promise<void> {
|
export async function checkAchievement (): Promise<void> {
|
||||||
const db = await Database.load("sqlite:tauri-genshin.db");
|
const db = await Database.load(sqlitePath);
|
||||||
Object.values(TGAppData.achievements).map(async (item) => {
|
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) {
|
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}')`;
|
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.execute(sql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
await db.close();
|
await db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,20 +45,20 @@ export async function checkAchievement (): Promise<void> {
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
export async function checkAchievementSeries (): Promise<void> {
|
export async function checkAchievementSeries (): Promise<void> {
|
||||||
const db = await Database.load("sqlite:tauri-genshin.db");
|
const db = await Database.load(sqlitePath);
|
||||||
Object.values(TGAppData.achievementSeries).map(async (item) => {
|
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) {
|
if (!selectRes || selectRes.length === 0) {
|
||||||
// 不存在则插入
|
// 不存在则插入
|
||||||
let sql;
|
let sql;
|
||||||
if (item.card) {
|
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}')`;
|
sql = `INSERT INTO AchievementSeries (id, \`order\`, name, version, icon, nameCard) VALUES (${item.id}, ${item.order}, '${item.name}', '${item.version}', '${item.icon}', '${item.card}')`;
|
||||||
} else {
|
} 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.execute(sql);
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
await db.close();
|
await db.close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="loading">
|
<div v-if="loading">
|
||||||
<TLoading />
|
<TLoading :title="loadingTitle" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<v-list class="config-list">
|
<v-list class="config-list">
|
||||||
@@ -116,6 +116,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item title="删除 IndexedDB" prepend-icon="mdi-delete" @click="tryConfirm('delDB')" />
|
<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 inset class="config-header">
|
||||||
路径
|
路径
|
||||||
</v-list-subheader>
|
</v-list-subheader>
|
||||||
@@ -146,7 +147,6 @@
|
|||||||
// vue
|
// vue
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import { getBuildTime } from "../utils/TGBuild";
|
import { getBuildTime } from "../utils/TGBuild";
|
||||||
|
|
||||||
import TLoading from "../components/t-loading.vue";
|
import TLoading from "../components/t-loading.vue";
|
||||||
import TConfirm from "../components/t-confirm.vue";
|
import TConfirm from "../components/t-confirm.vue";
|
||||||
// tauri
|
// tauri
|
||||||
@@ -159,8 +159,11 @@ import { useAchievementsStore } from "../store/modules/achievements";
|
|||||||
// utils
|
// utils
|
||||||
import { WriteTGData, DeleteTGData, ReadAllTGData } from "../utils/TGIndex";
|
import { WriteTGData, DeleteTGData, ReadAllTGData } from "../utils/TGIndex";
|
||||||
import { backupUiafData, restoreUiafData } from "../utils/UIAF";
|
import { backupUiafData, restoreUiafData } from "../utils/UIAF";
|
||||||
|
import TGSqlite from "../core/database/TGSqlite";
|
||||||
// data
|
// data
|
||||||
import { getDataList } from "../data/init";
|
import { getDataList } from "../data/init";
|
||||||
|
import Database from "tauri-plugin-sql-api";
|
||||||
|
import { onUnmounted } from "vue";
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
@@ -178,6 +181,7 @@ const osVersion = ref("" as string);
|
|||||||
|
|
||||||
// loading
|
// loading
|
||||||
const loading = ref(true as boolean);
|
const loading = ref(true as boolean);
|
||||||
|
const loadingTitle = ref("正在加载..." as string);
|
||||||
|
|
||||||
// data
|
// data
|
||||||
const showHome = ref(homeStore.getShowValue() as string[]);
|
const showHome = ref(homeStore.getShowValue() as string[]);
|
||||||
@@ -252,6 +256,11 @@ function tryConfirm (oper: string) {
|
|||||||
confirmOper.value = "delDB";
|
confirmOper.value = "delDB";
|
||||||
confirmShow.value = true;
|
confirmShow.value = true;
|
||||||
break;
|
break;
|
||||||
|
case "checkDB":
|
||||||
|
confirmText.value = "请确认已经备份关键数据。";
|
||||||
|
confirmOper.value = "checkDB";
|
||||||
|
confirmShow.value = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,6 +292,9 @@ async function doConfirm (oper: string) {
|
|||||||
case "delDB":
|
case "delDB":
|
||||||
delDB();
|
delDB();
|
||||||
break;
|
break;
|
||||||
|
case "checkDB":
|
||||||
|
await checkDB();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -400,6 +412,28 @@ function delDB () {
|
|||||||
snackbarColor.value = "success";
|
snackbarColor.value = "success";
|
||||||
snackbar.value = true;
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user