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"; ...@@ -3,7 +3,11 @@ import sqliteMiddleWare, { sqliteCmd } from "../middleware/sqlite";
export interface CardMeta { export interface CardMeta {
id: number; id: number;
data: { data: CardData;
text: CardText;
}
export interface CardData {
ot?: number; ot?: number;
setcode?: number; setcode?: number;
type?: number; type?: number;
...@@ -12,8 +16,10 @@ export interface CardMeta { ...@@ -12,8 +16,10 @@ export interface CardMeta {
level?: number; level?: number;
race?: number; race?: number;
attribute?: number; attribute?: number;
}; }
text: {
export interface CardText {
id?: number;
name?: string; name?: string;
types?: string; types?: string;
desc?: string; desc?: string;
...@@ -33,7 +39,6 @@ export interface CardMeta { ...@@ -33,7 +39,6 @@ export interface CardMeta {
str14?: string; str14?: string;
str15?: string; str15?: string;
str16?: string; str16?: string;
};
} }
/* /*
...@@ -48,8 +53,11 @@ export async function fetchCard( ...@@ -48,8 +53,11 @@ export async function fetchCard(
local?: boolean local?: boolean
): Promise<CardMeta> { ): Promise<CardMeta> {
if (local) { if (local) {
return await sqliteMiddleWare({ cmd: sqliteCmd.SELECT, payload: id }).then( return await sqliteMiddleWare({
(res) => (res ? res : { id, data: {}, text: {} }) 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); const res = await axios.get<CardMeta>("http://localhost:3030/cards/" + id);
......
...@@ -6,13 +6,15 @@ ...@@ -6,13 +6,15 @@
* */ * */
import initSqlJs, { Database } from "sql.js"; import initSqlJs, { Database } from "sql.js";
import { CardMeta } from "../api/cards"; import { CardMeta, CardData, CardText } from "../api/cards";
export enum sqliteCmd { export enum sqliteCmd {
// 初始化 // 初始化
INIT, INIT,
// 读取操作 // 读取操作
SELECT, SELECT,
// 全文搜索
FTS,
} }
export interface sqliteAction { export interface sqliteAction {
...@@ -22,7 +24,15 @@ export interface sqliteAction { ...@@ -22,7 +24,15 @@ export interface sqliteAction {
dbUrl: string; dbUrl: string;
}; };
// 需要读取卡牌数据的ID // 需要读取卡牌数据的ID
payload?: number; payload?: {
id?: number;
query?: string;
};
}
export interface sqliteResult {
selectResult?: CardMeta;
ftsResult?: CardMeta[];
} }
let YGODB: Database | null = null; let YGODB: Database | null = null;
...@@ -31,7 +41,7 @@ const sqlPromise = initSqlJs({ ...@@ -31,7 +41,7 @@ const sqlPromise = initSqlJs({
}); });
// FIXME: 应该有个返回值,告诉业务方本次请求的结果,比如初始化DB失败 // FIXME: 应该有个返回值,告诉业务方本次请求的结果,比如初始化DB失败
export default async function (action: sqliteAction) { export default async function (action: sqliteAction): Promise<sqliteResult> {
switch (action.cmd) { switch (action.cmd) {
case sqliteCmd.INIT: { case sqliteCmd.INIT: {
const info = action.initInfo; const info = action.initInfo;
...@@ -46,27 +56,65 @@ export default async function (action: sqliteAction) { ...@@ -46,27 +56,65 @@ export default async function (action: sqliteAction) {
console.warn("init YGODB action without initInfo"); console.warn("init YGODB action without initInfo");
} }
break; return {};
} }
case sqliteCmd.SELECT: { case sqliteCmd.SELECT: {
if (YGODB && action.payload) { if (YGODB && action.payload && action.payload.id) {
const code = action.payload; const code = action.payload.id;
const dataStmt = YGODB.prepare("SELECT * from datas WHERE ID = $id");
const dataStmt = YGODB.prepare("SELECT * FROM datas WHERE ID = $id");
const dataResult = dataStmt.getAsObject({ $id: code }); 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 }); 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 { } else {
console.warn("ygo db not init!"); console.warn("ygo db not init or query not provied!");
} }
break; return {};
} }
default: { default: {
console.warn(`Unhandled sqlite command: ${action.cmd}`); console.warn(`Unhandled sqlite command: ${action.cmd}`);
break; return {};
} }
} }
} }
......
...@@ -40,6 +40,7 @@ export default function WaitRoom() { ...@@ -40,6 +40,7 @@ export default function WaitRoom() {
useEffect(() => { useEffect(() => {
if (ip && player && player.length != 0 && passWd && passWd.length != 0) { if (ip && player && player.length != 0 && passWd && passWd.length != 0) {
const init = async () => {
// 页面第一次渲染时,通过socket中间件向ygopro服务端请求建立长连接 // 页面第一次渲染时,通过socket中间件向ygopro服务端请求建立长连接
socketMiddleWare({ socketMiddleWare({
cmd: socketCmd.CONNECT, cmd: socketCmd.CONNECT,
...@@ -49,13 +50,16 @@ export default function WaitRoom() { ...@@ -49,13 +50,16 @@ export default function WaitRoom() {
passWd, passWd,
}, },
}); });
}
// 初始化sqlite // 初始化sqlite
sqliteMiddleWare({ await sqliteMiddleWare({
cmd: sqliteCmd.INIT, cmd: sqliteCmd.INIT,
initInfo: { dbUrl: "/ygopro-database/locales/zh-CN/cards.cdb" }, initInfo: { dbUrl: "/ygopro-database/locales/zh-CN/cards.cdb" },
}); });
};
init();
}
}, []); }, []);
const dispatch = store.dispatch; 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