mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-12 09:18:14 +08:00
🤔 feat(sql): 基础准备差不多了,可以开测了
This commit is contained in:
22
src/core/database/TGSqlite.ts
Normal file
22
src/core/database/TGSqlite.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* @file core database TGSqlite.ts
|
||||||
|
* @description SQLite 数据库相关
|
||||||
|
* @author BTMuli<bt-muli@outlook.com>
|
||||||
|
* @since Alpha v0.1.4
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { initDatabase } from "./init";
|
||||||
|
import { checkAchievement, checkAchievementSeries } from "./update";
|
||||||
|
import { deleteDatabase, checkDatabase } from "./utils";
|
||||||
|
|
||||||
|
const TGSqlite = {
|
||||||
|
clearDB: deleteDatabase,
|
||||||
|
initDB: initDatabase,
|
||||||
|
checkDB: checkDatabase,
|
||||||
|
update: {
|
||||||
|
achievement: checkAchievement,
|
||||||
|
achievementSeries: checkAchievementSeries,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TGSqlite;
|
||||||
142
src/core/database/init.sql
Normal file
142
src/core/database/init.sql
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* @file core database init.sql
|
||||||
|
* @description SQLite 初始化
|
||||||
|
* @author BTMuli<bt-muli@outlook>
|
||||||
|
* @since Alpha v0.1.4
|
||||||
|
*/
|
||||||
|
|
||||||
|
-- /////////////////////////////
|
||||||
|
-- 创建各种表
|
||||||
|
-- /////////////////////////////
|
||||||
|
-- ----------------------------
|
||||||
|
-- 成就系列表
|
||||||
|
-- @table AchievementSeries
|
||||||
|
-- @field {number} id 成就系列ID,主键
|
||||||
|
-- @field {number} order 成就系列排列顺序
|
||||||
|
-- @field {string} name 成就系列名称
|
||||||
|
-- @field {string} version 成就系列版本
|
||||||
|
-- @field {number} totalCount 成就系列总成就数
|
||||||
|
-- @field {number} finCount 成就系列已完成成就数
|
||||||
|
-- @field {string} icon 成就系列图标
|
||||||
|
-- @field {string} nameCard 成就系列名片名称
|
||||||
|
-- @field {string} updated 数据更新时间
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS AchievementSeries
|
||||||
|
(
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
"order" INTEGER,
|
||||||
|
name TEXT DEFAULT NULL,
|
||||||
|
version TEXT DEFAULT NULL,
|
||||||
|
totalCount INTEGER DEFAULT 0,
|
||||||
|
finCount INTEGER DEFAULT 0,
|
||||||
|
icon TEXT DEFAULT NULL,
|
||||||
|
nameCard TEXT DEFAULT NULL,
|
||||||
|
updated TEXT DEFAULT NULL
|
||||||
|
);
|
||||||
|
-- ----------------------------
|
||||||
|
-- 成就数据表
|
||||||
|
-- @table Achievements
|
||||||
|
-- @field {number} id 成就ID,主键
|
||||||
|
-- @field {number} series 成就系列ID,为成就系列表的主键
|
||||||
|
-- @field {number} order 成就排序
|
||||||
|
-- @field {string} name 成就名称
|
||||||
|
-- @field {string} description 成就描述
|
||||||
|
-- @field {number} reward 成就奖励
|
||||||
|
-- @field {boolean} isCompleted 成就是否已完成,默认为false
|
||||||
|
-- @field {string} completedTime 成就完成时间,默认为null
|
||||||
|
-- @field {number} progress 成就进度,默认为0
|
||||||
|
-- @field {string} version 成就版本
|
||||||
|
-- @field {string} updated 数据更新时间
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS Achievements
|
||||||
|
(
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
series INTEGER,
|
||||||
|
"order" INTEGER,
|
||||||
|
name TEXT DEFAULT NULL,
|
||||||
|
description TEXT DEFAULT NULL,
|
||||||
|
reward INTEGER DEFAULT 0,
|
||||||
|
isCompleted BOOLEAN DEFAULT 0,
|
||||||
|
completedTime TEXT DEFAULT NULL,
|
||||||
|
progress INTEGER DEFAULT 0,
|
||||||
|
version TEXT DEFAULT NULL,
|
||||||
|
updated TEXT DEFAULT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
-- /////////////////////////////
|
||||||
|
-- 创建各种触发器
|
||||||
|
-- /////////////////////////////
|
||||||
|
-- ----------------------------
|
||||||
|
-- 成就系列数据插入触发器
|
||||||
|
-- @trigger SeriesInsert
|
||||||
|
-- @description 当成就系列数据插入时,更新更新时间
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE TRIGGER IF NOT EXISTS SeriesInsert
|
||||||
|
AFTER INSERT
|
||||||
|
ON AchievementSeries
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE AchievementSeries SET updated = datetime('now') WHERE id = NEW.id;
|
||||||
|
END;
|
||||||
|
-- ----------------------------
|
||||||
|
-- 成就系列数据更新触发器
|
||||||
|
-- @trigger SeriesUpdate
|
||||||
|
-- @description 当成就系列数据更新时,更新更新时间
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE TRIGGER IF NOT EXISTS SeriesUpdate
|
||||||
|
AFTER UPDATE
|
||||||
|
OF totalCount, finCount, version
|
||||||
|
ON AchievementSeries
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE AchievementSeries SET updated = datetime('now') WHERE id = NEW.id;
|
||||||
|
END;
|
||||||
|
-- ----------------------------
|
||||||
|
-- 成就数据插入触发器
|
||||||
|
-- @trigger AchievementInsert
|
||||||
|
-- @description 当成就数据插入时,更新成就系列表中的数据
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE TRIGGER IF NOT EXISTS AchievementInsert
|
||||||
|
AFTER INSERT
|
||||||
|
ON Achievements
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
-- 更新更新时间
|
||||||
|
UPDATE Achievements SET updated = datetime('now') WHERE id = NEW.id;
|
||||||
|
-- 更新成就系列总数
|
||||||
|
UPDATE AchievementSeries SET totalCount = AchievementSeries.totalCount + 1 WHERE id = NEW.series;
|
||||||
|
-- 如果是已完成成就,则更新成就系列完成数
|
||||||
|
UPDATE AchievementSeries
|
||||||
|
SET finCount = AchievementSeries.finCount + 1
|
||||||
|
WHERE NEW.isCompleted = 1 AND id = NEW.series;
|
||||||
|
-- 如果成就系列版本低于成就版本,则更新成就系列版本
|
||||||
|
UPDATE AchievementSeries SET version = NEW.version WHERE version < NEW.version AND id = NEW.series;
|
||||||
|
END;
|
||||||
|
-- ----------------------------
|
||||||
|
-- 成就数据更新触发器
|
||||||
|
-- @trigger AchievementUpdate
|
||||||
|
-- @description 当成就数据更新时,更新成就系列表中的数据
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE TRIGGER IF NOT EXISTS AchievementUpdate
|
||||||
|
AFTER UPDATE
|
||||||
|
OF isCompleted, completedTime, progress
|
||||||
|
ON Achievements
|
||||||
|
FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
-- 更新更新时间
|
||||||
|
UPDATE Achievements
|
||||||
|
SET updated = datetime('now')
|
||||||
|
WHERE id = NEW.id;
|
||||||
|
-- 如果是已完成成就,则更新成就系列完成数
|
||||||
|
UPDATE AchievementSeries
|
||||||
|
SET finCount = AchievementSeries.finCount + 1
|
||||||
|
WHERE id = NEW.series
|
||||||
|
AND OLD.isCompleted = 0
|
||||||
|
AND NEW.isCompleted = 1;
|
||||||
|
-- 如果是未完成成就,则更新成就系列完成数
|
||||||
|
UPDATE AchievementSeries
|
||||||
|
SET finCount = AchievementSeries.finCount - 1
|
||||||
|
WHERE id = NEW.series
|
||||||
|
AND OLD.isCompleted = 1
|
||||||
|
AND NEW.isCompleted = 0;
|
||||||
|
END;
|
||||||
23
src/core/database/init.ts
Normal file
23
src/core/database/init.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* @file core database init.ts
|
||||||
|
* @description SQLite 数据库初始化
|
||||||
|
* @author BTMuli<bt-muli@outlook.com>
|
||||||
|
* @since Alpha v0.1.4
|
||||||
|
*/
|
||||||
|
|
||||||
|
// tauri
|
||||||
|
import Database from "tauri-plugin-sql-api";
|
||||||
|
// sql
|
||||||
|
import initSql from "./init.sql?raw";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 初始化数据库
|
||||||
|
* @since Alpha v0.1.4
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
export async function initDatabase (): Promise<void> {
|
||||||
|
const db = await Database.load("sqlite:tauri-genshin.db");
|
||||||
|
// 执行sql语句
|
||||||
|
await db.execute(initSql);
|
||||||
|
await db.close();
|
||||||
|
}
|
||||||
63
src/core/database/update.ts
Normal file
63
src/core/database/update.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* @file core database update.ts
|
||||||
|
* @description SQLite 数据库更新相关
|
||||||
|
* @since Alpha v0.1.4
|
||||||
|
*/
|
||||||
|
|
||||||
|
// tauri
|
||||||
|
import Database from "tauri-plugin-sql-api";
|
||||||
|
// local
|
||||||
|
import { TGAppData } from "../../data";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 数据比对-成就系列数据
|
||||||
|
* @description 数据只有两种情况:新增、更新
|
||||||
|
* @since Alpha v0.1.4
|
||||||
|
* @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 selectRes: BTMuli.SQLite.Achievements[] = await db.select(`SELECT * FROM achievement 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}')`;
|
||||||
|
await db.execute(sql);
|
||||||
|
} else {
|
||||||
|
// 比对两者数据
|
||||||
|
const selectItem = selectRes[0];
|
||||||
|
if (selectItem.name !== item.name || selectItem.description !== item.description || selectItem.reward !== item.reward) {
|
||||||
|
// 更新
|
||||||
|
const sql = `UPDATE Achievements SET name = '${item.name}', description = '${item.description}', reward = ${item.reward}, version = '${item.version}' WHERE id = ${item.id}`;
|
||||||
|
await db.execute(sql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await db.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 数据比对-成就系列数据
|
||||||
|
* @description 只有新增,更新靠触发器解决
|
||||||
|
* @since Alpha v0.1.4
|
||||||
|
* @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 selectRes: BTMuli.SQLite.AchievementSeries[] = await db.select(`SELECT * FROM achievement_series 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}')`;
|
||||||
|
}
|
||||||
|
await db.execute(sql);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await db.close();
|
||||||
|
}
|
||||||
28
src/core/database/utils.ts
Normal file
28
src/core/database/utils.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* @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 });
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/types/Achievement.d.ts
vendored
60
src/types/Achievement.d.ts
vendored
@@ -109,3 +109,63 @@ declare namespace TGPlugin.UIAF {
|
|||||||
status: number
|
status: number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare namespace BTMuli.SQLite {
|
||||||
|
/**
|
||||||
|
* @description 数据库-成就表
|
||||||
|
* @since Alpha v0.1.4
|
||||||
|
* @interface Achievements
|
||||||
|
* @property {number} id - 成就 ID
|
||||||
|
* @property {number} series - 成就系列 ID
|
||||||
|
* @property {number} order - 成就排列顺序,用于展示全部成就
|
||||||
|
* @property {string} name - 成就名称
|
||||||
|
* @property {string} description - 成就描述
|
||||||
|
* @property {number} reward - 成就奖励
|
||||||
|
* @property {number} isCompleted - 成就是否完成
|
||||||
|
* @property {string} completedTime - 成就完成时间
|
||||||
|
* @property {number} progress - 成就进度
|
||||||
|
* @property {string} version - 成就版本
|
||||||
|
* @property {string} updated - 数据库更新时间
|
||||||
|
* @return Achievements
|
||||||
|
*/
|
||||||
|
export interface Achievements {
|
||||||
|
id: number
|
||||||
|
series: number
|
||||||
|
order: number
|
||||||
|
name: string | null
|
||||||
|
description: string | null
|
||||||
|
reward: number
|
||||||
|
isCompleted: 0 | 1
|
||||||
|
completedTime: string | null
|
||||||
|
progress: number
|
||||||
|
version: string | null
|
||||||
|
updated: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 数据库-成就系列表
|
||||||
|
* @since Alpha v0.1.4
|
||||||
|
* @interface AchievementSeries
|
||||||
|
* @property {number} id - 成就系列 ID
|
||||||
|
* @property {number} order - 成就系列排列顺序,用于展示全部成就系列
|
||||||
|
* @property {string} name - 成就系列名称
|
||||||
|
* @property {string} version - 成就系列版本
|
||||||
|
* @property {number} totalConut - 成就系列包含的成就数
|
||||||
|
* @property {number} finCount - 成就系列已完成的成就数
|
||||||
|
* @property {string} icon - 成就系列图标
|
||||||
|
* @property {string} nameCard - 成就系列对应名片
|
||||||
|
* @property {string} updated - 数据库更新时间
|
||||||
|
* @returns AchievementSeries
|
||||||
|
*/
|
||||||
|
export interface AchievementSeries {
|
||||||
|
id: number
|
||||||
|
order: number
|
||||||
|
name: string | null
|
||||||
|
version: string | null
|
||||||
|
totalCount: number
|
||||||
|
finCount: number
|
||||||
|
icon: string | null
|
||||||
|
nameCard: string | null
|
||||||
|
updated: string | null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user