Добавлен метод api /reader/storage и класс ReaderStorage
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
const BaseController = require('./BaseController');
|
const BaseController = require('./BaseController');
|
||||||
const ReaderWorker = require('../core/ReaderWorker');
|
const ReaderWorker = require('../core/ReaderWorker');
|
||||||
const workerState = require('../core/workerState');
|
const readerStorage = require('../core/readerStorage');
|
||||||
//const log = require('../core/getLogger').getLog();
|
const workerState = require('../core/workerState');
|
||||||
//const _ = require('lodash');
|
|
||||||
|
|
||||||
class ReaderController extends BaseController {
|
class ReaderController extends BaseController {
|
||||||
constructor(config) {
|
constructor(config) {
|
||||||
@@ -27,6 +26,24 @@ class ReaderController extends BaseController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async storage(req, res) {
|
||||||
|
const request = req.body;
|
||||||
|
let error = '';
|
||||||
|
try {
|
||||||
|
if (!request.action)
|
||||||
|
throw new Error(`key 'action' is empty`);
|
||||||
|
if (!request.items || Array.isArray(request.data))
|
||||||
|
throw new Error(`key 'items' is empty`);
|
||||||
|
|
||||||
|
return await readerStorage.doAction(request);
|
||||||
|
} catch (e) {
|
||||||
|
error = e.message;
|
||||||
|
}
|
||||||
|
//bad request
|
||||||
|
res.status(400).send({error});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
async uploadFile(req, res) {
|
async uploadFile(req, res) {
|
||||||
const file = req.file;
|
const file = req.file;
|
||||||
let error = '';
|
let error = '';
|
||||||
|
|||||||
92
server/core/readerStorage.js
Normal file
92
server/core/readerStorage.js
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
const SQL = require('sql-template-strings');
|
||||||
|
const _ = require('lodash');
|
||||||
|
|
||||||
|
const connManager = require('../db/connManager');
|
||||||
|
|
||||||
|
class ReaderStorage {
|
||||||
|
constructor() {
|
||||||
|
this.storagePool = connManager.pool.readerStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
async doAction(act) {
|
||||||
|
let result = {};
|
||||||
|
switch (act.action) {
|
||||||
|
case 'check':
|
||||||
|
result = await this.checkItems(act.items);
|
||||||
|
break;
|
||||||
|
case 'get':
|
||||||
|
result = await this.getItems(act.items);
|
||||||
|
break;
|
||||||
|
case 'set':
|
||||||
|
result = await this.setItems(act.items, act.force);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unknown action');
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async checkItems(items) {
|
||||||
|
let result = {state: 'success', items: {}};
|
||||||
|
|
||||||
|
const dbh = await this.storagePool.get();
|
||||||
|
try {
|
||||||
|
for (const id of Object.keys(items)) {
|
||||||
|
const rows = await dbh.all(SQL`SELECT rev FROM storage WHERE id = ${id}`);
|
||||||
|
const rev = (rows.length && rows[0].rev ? rows[0].rev : 0);
|
||||||
|
result.items[id] = {rev};
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
dbh.ret();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getItems(items) {
|
||||||
|
let result = {state: 'success', items: {}};
|
||||||
|
|
||||||
|
const dbh = await this.storagePool.get();
|
||||||
|
try {
|
||||||
|
for (const id of Object.keys(items)) {
|
||||||
|
const rows = await dbh.all(SQL`SELECT rev, data FROM storage WHERE id = ${id}`);
|
||||||
|
const rev = (rows.length && rows[0].rev ? rows[0].rev : 0);
|
||||||
|
const data = (rows.length && rows[0].data ? rows[0].data : '');
|
||||||
|
result.items[id] = {rev, data};
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
dbh.ret();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async setItems(items, force) {
|
||||||
|
let check = await this.checkItems(items);
|
||||||
|
|
||||||
|
//сначала проверим совпадение ревизий
|
||||||
|
for (const id of Object.keys(items)) {
|
||||||
|
if (!_.isString(items[id].data))
|
||||||
|
throw new Error('items.data is not a string');
|
||||||
|
|
||||||
|
if (!force && check.items[id].rev + 1 !== items[id].rev)
|
||||||
|
return {state: 'reject', items: check.items};
|
||||||
|
}
|
||||||
|
|
||||||
|
const dbh = await this.storagePool.get();
|
||||||
|
try {
|
||||||
|
for (const id of Object.keys(items)) {
|
||||||
|
await dbh.run(SQL`INSERT OR REPLACE INTO storage (id, rev, data) VALUES (${id}, ${items[id].rev}, ${items[id].data})`);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
dbh.ret();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {state: 'success'};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const readerStorage = new ReaderStorage();
|
||||||
|
|
||||||
|
module.exports = readerStorage;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
module.exports = `
|
module.exports = `
|
||||||
-- Up
|
-- Up
|
||||||
CREATE TABLE storage (id2 INTEGER PRIMARY KEY, name TEXT);
|
CREATE TABLE storage (id TEXT PRIMARY KEY, rev INTEGER, data TEXT);
|
||||||
|
|
||||||
-- Down
|
-- Down
|
||||||
DROP TABLE storage;
|
DROP TABLE storage;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ function initRoutes(app, config) {
|
|||||||
const routes = [
|
const routes = [
|
||||||
['POST', '/api/config', misc.getConfig.bind(misc), [aAll], {}],
|
['POST', '/api/config', misc.getConfig.bind(misc), [aAll], {}],
|
||||||
['POST', '/api/reader/load-book', reader.loadBook.bind(reader), [aAll], {}],
|
['POST', '/api/reader/load-book', reader.loadBook.bind(reader), [aAll], {}],
|
||||||
|
['POST', '/api/reader/storage', reader.storage.bind(reader), [aAll], {}],
|
||||||
['POST', '/api/reader/upload-file', [upload.single('file'), reader.uploadFile.bind(reader)], [aAll], {}],
|
['POST', '/api/reader/upload-file', [upload.single('file'), reader.uploadFile.bind(reader)], [aAll], {}],
|
||||||
['POST', '/api/worker/get-state', worker.getState.bind(worker), [aAll], {}],
|
['POST', '/api/worker/get-state', worker.getState.bind(worker), [aAll], {}],
|
||||||
];
|
];
|
||||||
@@ -60,7 +61,7 @@ function initRoutes(app, config) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
callbacks.push(callback);
|
callbacks.push(callback);
|
||||||
|
|
||||||
switch (httpMethod) {
|
switch (httpMethod) {
|
||||||
case 'GET' :
|
case 'GET' :
|
||||||
app.get(path, ...callbacks);
|
app.get(path, ...callbacks);
|
||||||
|
|||||||
Reference in New Issue
Block a user