🤔 feat(sql): 基础准备差不多了,可以开测了

This commit is contained in:
BTMuli
2023-04-24 19:16:45 +08:00
parent eeba1f9978
commit 42f6d7bdaa
6 changed files with 338 additions and 0 deletions

View 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
View 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
View 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();
}

View 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();
}

View 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 });
}
}

View File

@@ -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
}
}