@gecogvidanto/plugin-nedb
Version:
Nebd local database management plugin for ĞecoĞvidanto
177 lines • 5.78 kB
JavaScript
;
/*
* This file is part of @gecogvidanto/plugin-nedb.
* Copyright (C) 2020 Stéphane Veyret
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const crypto = require("crypto");
const BinaryStore_1 = require("./BinaryStore");
/**
* Test if the value is a litteral object.
*
* @param value - The value to test.
* @returns True if value is object.
*/
function isLitteral(value) {
if (!value || typeof value !== 'object') {
return false;
}
let proto = value;
while (Object.getPrototypeOf((proto = Object.getPrototypeOf(proto))) !== null) {
// Loop until last prototype found
}
return Object.getPrototypeOf(value) === proto;
}
/**
* Create a binary data identifier for the given hash.
*
* @param hash - The hash.
* @returns The binary data identifier.
*/
function createBinaryData(hash) {
return {
type: '$$BinaryData$$',
hash,
};
}
/**
* Calculate the hash for the given data.
*
* @param data - The data to calculate hash for.
* @returns The hash for the binary data.
*/
function calculateHash(data) {
return crypto.createHash('sha256').update(data).digest('hex');
}
/**
* This class manages the binary data. Binary data are transformed into an object for identification while
* the real data is managed by the binary store.
*/
class BinaryDataManager {
/**
* Create a binary data manager.
*
* @param binaryStore - The binary store.
* @param storeName - The name of the store creating this manager.
*/
constructor(binaryStore, storeName) {
this.binaryStore = binaryStore;
this.storeName = storeName;
this.binaries = [];
}
/**
* Filter which should be input for a database calling method to replace binary data. Real binary data
* will be ready to be saved.
*
* @param input - The input to filter.
* @returns The filtered input.
*/
async inputFilter(input) {
let filtered;
if (input instanceof Buffer) {
const hash = calculateHash(input);
filtered = createBinaryData(hash);
this.binaries.push({ hash, data: input });
}
else if (Array.isArray(input)) {
filtered = (await Promise.all(input.map(value => this.inputFilter(value))));
}
else if (isLitteral(input)) {
filtered = {};
for (const key in input) {
filtered[key] = (await this.inputFilter(input[key]));
}
}
else {
filtered = input;
}
return filtered;
}
/**
* Filter all which should be output for a database calling method to replace hash with binary data. Data
* will first be searched in filtered input data.
*
* @param outputs - The output to filter.
* @returns The filtered output.
*/
async outputFilterAll(outputs) {
const filtered = [];
await Promise.all(outputs.map(async (output) => filtered.push(await this.outputFilter(output))));
return filtered;
}
/**
* Filter which should be output for a database calling method to replace hash with binary data. Data will
* first be searched in filtered input data.
*
* @param output - The output to filter.
* @returns The filtered output.
*/
async outputFilter(output) {
let filtered;
if (BinaryStore_1.isBinaryData(output)) {
filtered = (await this.searchData(output.hash));
}
else if (Array.isArray(output)) {
filtered = (await Promise.all(output.map(value => this.outputFilter(value))));
}
else if (isLitteral(output)) {
filtered = {};
for (const key in output) {
filtered[key] = (await this.outputFilter(output[key]));
}
}
else {
filtered = output;
}
return filtered;
}
/**
* Save the binary data seen while filtering input.
*
* @param recordId - The identifier of the current record to associate to binary data.
*/
async save(recordId) {
await Promise.all(this.binaries.map(binary => {
this.binaryStore.save(this.storeName, recordId, binary.hash, binary.data);
}));
}
/**
* Indicate if a given input has been transformed, meaning if binary data need to be (or already have
* been) saved.
*
* @returns True if data need to be saved.
*/
get transformed() {
return this.binaries.length > 0;
}
/**
* Search the binary data with the given hash.
*
* @param hash - The hash of the binary data to search for.
* @returns The binary data for the hash.
*/
searchData(hash) {
const quickFound = this.binaries.find(binary => hash === binary.hash);
if (quickFound) {
return Promise.resolve(quickFound.data);
}
else {
return this.binaryStore.read(hash);
}
}
}
exports.default = BinaryDataManager;
//# sourceMappingURL=BinaryDataManager.js.map