Commit 414cfd54 authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/sqlite/fulltext_search' into 'main'

Feat/sqlite/fulltext search

See merge request mycard/Neos!98
parents 57ab45b7 96826a5f
Pipeline #19964 passed with stages
in 10 minutes and 33 seconds
......@@ -3,7 +3,11 @@ import sqliteMiddleWare, { sqliteCmd } from "../middleware/sqlite";
export interface CardMeta {
id: number;
data: {
data: CardData;
text: CardText;
}
export interface CardData {
ot?: number;
setcode?: number;
type?: number;
......@@ -12,8 +16,10 @@ export interface CardMeta {
level?: number;
race?: number;
attribute?: number;
};
text: {
}
export interface CardText {
id?: number;
name?: string;
types?: string;
desc?: string;
......@@ -33,7 +39,6 @@ export interface CardMeta {
str14?: string;
str15?: string;
str16?: string;
};
}
/*
......@@ -48,8 +53,11 @@ export async function fetchCard(
local?: boolean
): Promise<CardMeta> {
if (local) {
return await sqliteMiddleWare({ cmd: sqliteCmd.SELECT, payload: id }).then(
(res) => (res ? res : { id, data: {}, text: {} })
return await sqliteMiddleWare({
cmd: sqliteCmd.SELECT,
payload: { id },
}).then((res) =>
res.selectResult ? res.selectResult : { id, data: {}, text: {} }
);
}
const res = await axios.get<CardMeta>("http://localhost:3030/cards/" + id);
......
......@@ -6,13 +6,15 @@
* */
import initSqlJs, { Database } from "sql.js";
import { CardMeta } from "../api/cards";
import { CardMeta, CardData, CardText } from "../api/cards";
export enum sqliteCmd {
// 初始化
INIT,
// 读取操作
SELECT,
// 全文搜索
FTS,
}
export interface sqliteAction {
......@@ -22,7 +24,15 @@ export interface sqliteAction {
dbUrl: string;
};
// 需要读取卡牌数据的ID
payload?: number;
payload?: {
id?: number;
query?: string;
};
}
export interface sqliteResult {
selectResult?: CardMeta;
ftsResult?: CardMeta[];
}
let YGODB: Database | null = null;
......@@ -31,7 +41,7 @@ const sqlPromise = initSqlJs({
});
// FIXME: 应该有个返回值,告诉业务方本次请求的结果,比如初始化DB失败
export default async function (action: sqliteAction) {
export default async function (action: sqliteAction): Promise<sqliteResult> {
switch (action.cmd) {
case sqliteCmd.INIT: {
const info = action.initInfo;
......@@ -46,27 +56,65 @@ export default async function (action: sqliteAction) {
console.warn("init YGODB action without initInfo");
}
break;
return {};
}
case sqliteCmd.SELECT: {
if (YGODB && action.payload) {
const code = action.payload;
const dataStmt = YGODB.prepare("SELECT * from datas WHERE ID = $id");
if (YGODB && action.payload && action.payload.id) {
const code = action.payload.id;
const dataStmt = YGODB.prepare("SELECT * FROM datas WHERE ID = $id");
const dataResult = dataStmt.getAsObject({ $id: code });
const textStmt = YGODB.prepare("SELECT * from texts WHERE ID = $id");
const textStmt = YGODB.prepare("SELECT * FROM texts WHERE ID = $id");
const textResult = textStmt.getAsObject({ $id: code });
return constructCardMeta(code, dataResult, textResult);
return {
selectResult: constructCardMeta(code, dataResult, textResult),
};
} else {
console.warn("ygo db not init or id not provied!");
}
return {};
}
case sqliteCmd.FTS: {
if (YGODB && action.payload && action.payload.query) {
const query = action.payload.query;
const ftsTexts: CardText[] = [];
const ftsMetas: CardMeta[] = [];
const textStmt = YGODB.prepare(
"SELECT * FROM texts WHERE name LIKE $query"
);
textStmt.bind({ $query: `%${query}%` });
while (textStmt.step()) {
const row = textStmt.getAsObject();
ftsTexts.push(row);
}
for (const text of ftsTexts) {
const id = text.id;
if (id) {
const dataStmt = YGODB.prepare(
"SELECT * FROM datas WHERE ID = $id"
);
const data: CardData = dataStmt.getAsObject({ $id: id });
ftsMetas.push({ id, data, text });
}
}
return { ftsResult: ftsMetas };
} else {
console.warn("ygo db not init!");
console.warn("ygo db not init or query not provied!");
}
break;
return {};
}
default: {
console.warn(`Unhandled sqlite command: ${action.cmd}`);
break;
return {};
}
}
}
......
......@@ -40,6 +40,7 @@ export default function WaitRoom() {
useEffect(() => {
if (ip && player && player.length != 0 && passWd && passWd.length != 0) {
const init = async () => {
// 页面第一次渲染时,通过socket中间件向ygopro服务端请求建立长连接
socketMiddleWare({
cmd: socketCmd.CONNECT,
......@@ -49,13 +50,16 @@ export default function WaitRoom() {
passWd,
},
});
}
// 初始化sqlite
sqliteMiddleWare({
await sqliteMiddleWare({
cmd: sqliteCmd.INIT,
initInfo: { dbUrl: "/ygopro-database/locales/zh-CN/cards.cdb" },
});
};
init();
}
}, []);
const dispatch = store.dispatch;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment