From d770d499dab54fe4d43a97e606db8fe6b4380752 Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Tue, 25 Oct 2022 16:50:56 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B7=D0=B0=D0=B3=D0=BE=D1=82=D0=BE=D0=B2=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B4=D0=BB=D1=8F=20seriesSearch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/controllers/WebSocketController.js | 11 ++++ server/core/DbSearcher.js | 79 +++++++++++++++++++++++ server/core/WebWorker.js | 13 ++++ 3 files changed, 103 insertions(+) diff --git a/server/controllers/WebSocketController.js b/server/controllers/WebSocketController.js index e2b4dc4..64b402d 100644 --- a/server/controllers/WebSocketController.js +++ b/server/controllers/WebSocketController.js @@ -76,6 +76,8 @@ class WebSocketController { await this.getWorkerState(req, ws); break; case 'author-search': await this.authorSearch(req, ws); break; + case 'series-search': + await this.seriesSearch(req, ws); break; case 'get-author-book-list': await this.getAuthorBookList(req, ws); break; case 'get-series-book-list': @@ -142,6 +144,15 @@ class WebSocketController { this.send(result, req, ws); } + async seriesSearch(req, ws) { + if (!req.query) + throw new Error(`query is empty`); + + const result = await this.webWorker.seriesSearch(req.query); + + this.send(result, req, ws); + } + async getAuthorBookList(req, ws) { const result = await this.webWorker.getAuthorBookList(req.authorId); diff --git a/server/core/DbSearcher.js b/server/core/DbSearcher.js index 846930f..5efe3cd 100644 --- a/server/core/DbSearcher.js +++ b/server/core/DbSearcher.js @@ -269,6 +269,48 @@ class DbSearcher { return authorIds; } + async selectSeriesIds(query) { + const db = this.db; + + let seriesIds = []; + + //серии + if (query.series && query.series !== '*') { + const where = this.getWhere(query.series); + + const seriesRows = await db.select({ + table: 'series', + rawResult: true, + where: ` + const ids = ${where}; + + const result = new Set(); + for (const id of ids) { + const row = @unsafeRow(id); + for (const authorId of row.authorId) + result.add(authorId); + } + + return Array.from(result); + ` + }); + + seriesIds = seriesRows[0].rawResult; + } else { + const authorRows = await db.select({ + table: 'series', + rawResult: true, + where: `return Array.from(@all())`, + }); + + seriesIds = authorRows[0].rawResult; + } + + seriesIds.sort((a, b) => a - b); + + return seriesIds; + } + queryKey(q) { return JSON.stringify([q.author, q.series, q.title, q.genre, q.lang]); } @@ -382,6 +424,43 @@ class DbSearcher { } } + async seriesSearch(query) { + if (this.closed) + throw new Error('DbSearcher closed'); + + this.searchFlag++; + + try { + const db = this.db; + + const key = `series-ids-${this.queryKey(query)}`; + + //сначала попробуем найти в кеше + let seriesIds = await this.getCached(key); + if (seriesIds === null) {//не нашли в кеше, ищем в поисковых таблицах + seriesIds = await this.selectSeriesIds(query); + + await this.putCached(key, seriesIds); + } + + const totalFound = seriesIds.length; + let limit = (query.limit ? query.limit : 100); + limit = (limit > 1000 ? 1000 : limit); + const offset = (query.offset ? query.offset : 0); + + //выборка найденных авторов + const result = await db.select({ + table: 'series_book', + map: `(r) => ({id: r.id, series: r.series, bookCount: r.bookCount, bookDelCount: r.bookDelCount})`, + where: `@@id(${db.esc(seriesIds.slice(offset, offset + limit))})` + }); + + return {result, totalFound}; + } finally { + this.searchFlag--; + } + } + async getAuthorBookList(authorId) { if (this.closed) throw new Error('DbSearcher closed'); diff --git a/server/core/WebWorker.js b/server/core/WebWorker.js index cf6f5b3..20bf116 100644 --- a/server/core/WebWorker.js +++ b/server/core/WebWorker.js @@ -258,6 +258,19 @@ class WebWorker { }; } + async seriesSearch(query) { + this.checkMyState(); + + const config = await this.dbConfig(); + const result = await this.dbSearcher.seriesSearch(query); + + return { + series: result.result, + totalFound: result.totalFound, + inpxHash: (config.inpxHash ? config.inpxHash : ''), + }; + } + async getAuthorBookList(authorId) { this.checkMyState();