Эх сурвалжийг харах

Добавлен titleSearch

Book Pauk 2 жил өмнө
parent
commit
491c2f3406

+ 4 - 0
client/components/Api/Api.vue

@@ -214,6 +214,10 @@ class Api {
         return await this.request({action: 'series-search', query});
     }
 
+    async titleSearch(query) {
+        return await this.request({action: 'title-search', query});
+    }
+
     async getAuthorBookList(authorId) {
         return await this.request({action: 'get-author-book-list', authorId});
     }

+ 14 - 0
server/controllers/WebSocketController.js

@@ -78,6 +78,8 @@ class WebSocketController {
                     await this.authorSearch(req, ws); break;
                 case 'series-search':
                     await this.seriesSearch(req, ws); break;
+                case 'title-search':
+                    await this.titleSearch(req, ws); break;
                 case 'get-author-book-list':
                     await this.getAuthorBookList(req, ws); break;
                 case 'get-series-book-list':
@@ -156,6 +158,18 @@ class WebSocketController {
         this.send(result, req, ws);
     }
 
+    async titleSearch(req, ws) {
+        if (!this.config.extendedSearch)
+            throw new Error(`Extended search disabled`);
+
+        if (!req.query)
+            throw new Error(`query is empty`);
+
+        const result = await this.webWorker.titleSearch(req.query);
+
+        this.send(result, req, ws);
+    }
+
     async getAuthorBookList(req, ws) {
         const result = await this.webWorker.getAuthorBookList(req.authorId);
 

+ 89 - 0
server/core/DbSearcher.js

@@ -513,6 +513,58 @@ class DbSearcher {
         return seriesIds;
     }
 
+    async selectTitleIds(query) {
+        const db = this.db;
+
+        let titleIds = false;
+        let isAll = !(query.title && query.title !== '*');
+
+        //серии
+        const titleKеy = `title-ids-title-${query.title}`;
+        titleIds = await this.getCached(titleKеy);
+
+        if (titleIds === null) {
+            if (query.title && query.title !== '*') {
+                const where = this.getWhere(query.title);
+
+                const seriesRows = await db.select({
+                    table: 'title',
+                    rawResult: true,
+                    where: `return Array.from(${where})`,
+                });
+
+                titleIds = seriesRows[0].rawResult;
+            } else {
+                const seriesRows = await db.select({
+                    table: 'title',
+                    rawResult: true,
+                    where: `return Array.from(@all())`,
+                });
+
+                titleIds = seriesRows[0].rawResult;
+            }
+
+            titleIds.sort((a, b) => a - b);
+
+            await this.putCached(titleKеy, titleIds);
+        }
+
+        const where = this.getWhere2(query, (isAll ? false : titleIds), 'title');
+
+        if (where) {
+            //тяжелый запрос перебором в series_book
+            const rows = await db.select({
+                table: 'title_book',
+                rawResult: true,
+                where,
+            });
+
+            titleIds = rows[0].rawResult;
+        }
+
+        return titleIds;
+    }
+
     queryKey(q) {
         return JSON.stringify([q.author, q.series, q.title, q.genre, q.lang]);
     }
@@ -663,6 +715,43 @@ class DbSearcher {
         }
     }
 
+    async titleSearch(query) {
+        if (this.closed)
+            throw new Error('DbSearcher closed');
+
+        this.searchFlag++;
+
+        try {
+            const db = this.db;
+
+            const key = `title-ids-${this.queryKey(query)}`;
+
+            //сначала попробуем найти в кеше
+            let seriesIds = await this.getCached(key);
+            if (seriesIds === null) {//не нашли в кеше, ищем в поисковых таблицах
+                seriesIds = await this.selectTitleIds(query);
+
+                await this.putCached(key, seriesIds);
+            }
+
+            const totalFound = seriesIds.length;
+            let limit = (query.limit ? query.limit : 100);
+            limit = (limit > maxLimit ? maxLimit : limit);
+            const offset = (query.offset ? query.offset : 0);
+
+            //выборка найденных авторов
+            const result = await db.select({
+                table: 'title_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');

+ 13 - 0
server/core/WebWorker.js

@@ -274,6 +274,19 @@ class WebWorker {
         };
     }
 
+    async titleSearch(query) {
+        this.checkMyState();
+
+        const config = await this.dbConfig();
+        const result = await this.dbSearcher.titleSearch(query);
+
+        return {
+            title: result.result,
+            totalFound: result.totalFound,
+            inpxHash: (config.inpxHash ? config.inpxHash : ''),
+        };
+    }
+
     async getAuthorBookList(authorId) {
         this.checkMyState();