Работа над списком книг в серии

This commit is contained in:
Book Pauk
2022-10-10 17:02:58 +07:00
parent ec96d4af39
commit 0e2ef4133e
6 changed files with 139 additions and 10 deletions

View File

@@ -220,6 +220,16 @@ class Api {
return response;
}
async getSeriesBookList(seriesId) {
const response = await this.request({action: 'get-series-book-list', seriesId});
if (response.error) {
throw new Error(response.error);
}
return response;
}
async getGenreTree() {
const response = await this.request({action: 'get-genre-tree'});

View File

@@ -878,6 +878,29 @@ class Search {
}
}
async loadSeriesBooks(seriesId) {
try {
let result;
if (this.abCacheEnabled) {
const key = `series-${seriesId}-${this.inpxHash}`;
const data = await authorBooksStorage.getData(key);
if (data) {
result = JSON.parse(data);
} else {
result = await this.api.getBookList(seriesId);
await authorBooksStorage.setData(key, JSON.stringify(result));
}
} else {
result = await this.api.getBookList(seriesId);
}
return JSON.parse(result.books);
} catch (e) {
this.$root.stdDialog.alert(e.message, 'Ошибка');
}
}
filterBooks(loadedBooks) {
const s = this.search;

View File

@@ -79,6 +79,8 @@ class WebSocketController {
await this.search(req, ws); break;
case 'get-book-list':
await this.getBookList(req, ws); break;
case 'get-series-book-list':
await this.getSeriesBookList(req, ws); break;
case 'get-genre-tree':
await this.getGenreTree(req, ws); break;
case 'get-book-link':
@@ -150,6 +152,15 @@ class WebSocketController {
this.send(result, req, ws);
}
async getSeriesBookList(req, ws) {
if (!utils.hasProp(req, 'seriesId'))
throw new Error(`seriesId is empty`);
const result = await this.webWorker.getSeriesBookList(req.seriesId);
this.send(result, req, ws);
}
async getGenreTree(req, ws) {
const result = await this.webWorker.getGenreTree();

View File

@@ -307,12 +307,12 @@ class DbCreator {
callback({progress: 1});
//чистка памяти, ибо жрет как не в себя
await db.drop({table: 'book'});
await db.close({table: 'book'});
await db.freeMemory();
utils.freeMemory();
//парсинг 2, подготовка
const parseField = (fieldValue, fieldMap, fieldArr, authorIds) => {
const parseField = (fieldValue, fieldMap, fieldArr, authorIds, bookId) => {
if (!fieldValue)
fieldValue = emptyFieldValue;
@@ -324,6 +324,8 @@ class DbCreator {
fieldRec = fieldArr[fieldId];
} else {
fieldRec = {id: fieldArr.length, value, authorId: new Set()};
if (bookId)
fieldRec.bookId = new Set();
fieldArr.push(fieldRec);
fieldMap.set(value, fieldRec.id);
}
@@ -331,6 +333,9 @@ class DbCreator {
for (const id of authorIds) {
fieldRec.authorId.add(id);
}
if (bookId)
fieldRec.bookId.add(bookId);
};
const parseBookRec = (rec) => {
@@ -346,7 +351,7 @@ class DbCreator {
}
//серии
parseField(rec.series, seriesMap, seriesArr, authorIds);
parseField(rec.series, seriesMap, seriesArr, authorIds, rec.id);
//названия
parseField(rec.title, titleMap, titleArr, authorIds);
@@ -464,7 +469,7 @@ class DbCreator {
//сохраним поисковые таблицы
const chunkSize = 10000;
const saveTable = async(table, arr, nullArr, authorIdToArray = true) => {
const saveTable = async(table, arr, nullArr, authorIdToArray = false, bookIdToArray = false) => {
arr.sort((a, b) => a.value.localeCompare(b.value));
@@ -482,6 +487,11 @@ class DbCreator {
rec.authorId = Array.from(rec.authorId);
}
if (bookIdToArray) {
for (const rec of chunk)
rec.bookId = Array.from(rec.bookId);
}
await db.insert({table, rows: chunk});
if (i % 5 == 0) {
@@ -500,23 +510,23 @@ class DbCreator {
//author
callback({job: 'author save', jobMessage: 'Сохранение индекса авторов', jobStep: 6, progress: 0});
await saveTable('author', authorArr, () => {authorArr = null}, false);
await saveTable('author', authorArr, () => {authorArr = null});
//series
callback({job: 'series save', jobMessage: 'Сохранение индекса серий', jobStep: 7, progress: 0});
await saveTable('series', seriesArr, () => {seriesArr = null});
await saveTable('series', seriesArr, () => {seriesArr = null}, true, true);
//title
callback({job: 'title save', jobMessage: 'Сохранение индекса названий', jobStep: 8, progress: 0});
await saveTable('title', titleArr, () => {titleArr = null});
await saveTable('title', titleArr, () => {titleArr = null}, true);
//genre
callback({job: 'genre save', jobMessage: 'Сохранение индекса жанров', jobStep: 9, progress: 0});
await saveTable('genre', genreArr, () => {genreArr = null});
await saveTable('genre', genreArr, () => {genreArr = null}, true);
//lang
callback({job: 'lang save', jobMessage: 'Сохранение индекса языков', jobStep: 10, progress: 0});
await saveTable('lang', langArr, () => {langArr = null});
await saveTable('lang', langArr, () => {langArr = null}, true);
//кэш-таблицы запросов
await db.create({table: 'query_cache'});

View File

@@ -273,7 +273,7 @@ class DbSearcher {
});
let author = '';
let books = [];
let books = '';
if (rows.length) {
author = rows[0].author;
@@ -331,6 +331,75 @@ class DbSearcher {
}
}
async selectSeriesBookList(seriesId) {
const db = this.db;
//выборка серии по seriesId
const rows = await db.select({
table: 'series',
where: `@@id(${db.esc(seriesId)})`
});
let books = [];
if (rows.length) {
books = await db.select({
table: 'book',
where: `@@id(${db.esc(rows[0].bookId)})`
});
}
return {books: JSON.stringify(books)};
}
async getSeriesBookList(seriesId) {
if (this.closed)
throw new Error('DbSearcher closed');
this.searchFlag++;
try {
const db = this.db;
let result;
if (this.config.queryCacheEnabled) {
const key = `series_books-${seriesId}`;
const rows = await db.select({table: 'query_cache', where: `@@id(${db.esc(key)})`});
if (rows.length) {//нашли в кеше
await db.insert({
table: 'query_time',
replace: true,
rows: [{id: key, time: Date.now()}],
});
result = rows[0].value;
} else {//не нашли в кеше
result = await this.selectSeriesBookList(seriesId);
//кладем в кеш
await db.insert({
table: 'query_cache',
replace: true,
rows: [{id: key, value: result}],
});
await db.insert({
table: 'query_time',
replace: true,
rows: [{id: key, time: Date.now()}],
});
}
} else {
result = await this.selectSeriesBookList(seriesId);
}
return result;
} finally {
this.searchFlag--;
}
}
async periodicCleanCache() {
this.timer = null;
const cleanInterval = this.config.cacheCleanInterval*60*1000;

View File

@@ -227,6 +227,12 @@ class WebWorker {
return await this.dbSearcher.getBookList(authorId);
}
async getSeriesBookList(seriesId) {
this.checkMyState();
return await this.dbSearcher.getSeriesBookList(seriesId);
}
async getGenreTree() {
this.checkMyState();