vulcain-corejs
Version:
Vulcain micro-service framework
217 lines • 7.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const mongoQueryParser_1 = require("./mongoQueryParser");
const conventions_1 = require("../../utils/conventions");
const applicationRequestError_1 = require("../../pipeline/errors/applicationRequestError");
const queryResult_1 = require("../../pipeline/handlers/query/queryResult");
/**
* Default memory provider
*/
class MemoryProvider {
/**
* Create a memory provider instance.
* @param dataFolder : (optional) if provided, data will be persisted on disk on EVERY create, update or delete
*/
constructor(dataFolder) {
this.dataFolder = dataFolder;
}
get address() {
return "memory";
}
initialize(tenant) {
if (!tenant)
throw new Error("Tenant can not be null");
let folder = this.dataFolder;
if (this.dataFolder) {
if (!fs.existsSync(folder))
fs.mkdirSync(folder);
folder = folder + '/' + tenant;
if (!fs.existsSync(folder))
fs.mkdirSync(folder);
}
this.state = { schemas: new Map(), folder };
return () => { this.state = null; };
}
ensureSchema(schema) {
let schemaInfo = this.state.schemas.get(schema.name);
if (!schemaInfo) {
schemaInfo = { data: { entities: {}, count: 0 } };
if (this.state.folder) {
schemaInfo.saveToFile = this.state.folder + "/" + schema.info.storageName + ".json";
if (fs.existsSync(schemaInfo.saveToFile)) {
schemaInfo.data = JSON.parse(fs.readFileSync(schemaInfo.saveToFile, "UTF-8"));
}
}
this.state.schemas.set(schema.name, schemaInfo);
}
return schemaInfo;
}
save(schema) {
let schemaInfo = this.state.schemas.get(schema.name);
if (!schemaInfo.saveToFile)
return;
fs.writeFileSync(schemaInfo.saveToFile, JSON.stringify(schemaInfo.data), { encoding: "UTF-8" });
}
/**
* Return a list of entities
* @param options
* @returns {Promise}
*/
getAll(ctx, schema, options) {
let data = this.ensureSchema(schema).data;
options = options || { pageSize: -1 };
return new Promise((resolve, reject) => {
try {
let result = MemoryProvider.Query(data.entities, (options.query && options.query.filter) || options.query, options.page, options.pageSize);
resolve(new queryResult_1.QueryResult(result, data.count));
}
catch (err) {
reject(err);
}
});
}
static Query(list, query, page, pageSize, cloneResult = true) {
return Array.from(MemoryProvider.take(MemoryProvider.filter(list, query, cloneResult), page, pageSize));
}
static *filter(list, query, cloneResult) {
let cx = 0;
if (list) {
const queryParser = new mongoQueryParser_1.MongoQueryParser(query);
for (let k in list) {
let v = list[k];
if (!v || !queryParser.execute(v))
continue;
cx++;
yield cloneResult ? conventions_1.Conventions.clone(v) : v;
}
}
}
static *take(iterator, page, pageSize) {
if (iterator) {
let take = pageSize || -1;
let skip = take * (page > 0 ? page - 1 : 0 || 0);
let cx = 0;
for (let v of iterator) {
if (cx < skip) {
cx++;
continue;
}
if (take < 0 || cx < skip + take) {
cx++;
yield v;
}
else
break;
}
}
}
/**
* Read an entity
* @param name
* @returns {Promise}
*/
get(ctx, schema, id) {
let data = this.ensureSchema(schema).data;
const self = this;
return new Promise((resolve, reject) => {
try {
let list = data.entities;
resolve(list && conventions_1.Conventions.clone(list[id]));
}
catch (err) {
reject(err);
}
});
}
/**
* Delete an entity
* @param id
* @returns {Promise}
*/
delete(ctx, schema, id) {
if (!id)
throw new Error("Id is required");
let data = this.ensureSchema(schema).data;
let self = this;
return new Promise((resolve, reject) => {
try {
let list = data.entities;
if (list && list[id]) {
resolve(list[id]);
delete list[id];
data.count--;
self.save(schema);
}
else {
reject(new Error(`${schema.name} with id: ${id} not found`));
}
}
catch (err) {
reject(err);
}
});
}
/**
* Persist an entity
* @param entity
* @returns {Promise}
*/
create(ctx, schema, entity) {
if (!entity)
throw new Error("Entity is required");
let data = this.ensureSchema(schema).data;
const self = this;
entity._created = new Date().toUTCString();
return new Promise((resolve, reject) => {
try {
let list = data.entities;
let name = schema.getId(entity);
if (!name)
throw new Error(`Can not create a ${schema.name} entity with undefined id : ${schema.getIdProperty()} `);
if (list[name]) {
reject(new applicationRequestError_1.ApplicationError(`Can not add existing ${schema.name} ${name}`));
return;
}
list[name] = conventions_1.Conventions.clone(entity);
data.count++;
self.save(schema);
resolve(entity);
}
catch (err) {
reject(err);
}
});
}
/**
* Update an entity
* @param entity
* @returns {Promise<T>}
*/
update(ctx, schema, entity) {
if (!entity)
throw new Error("Entity is required");
let data = this.ensureSchema(schema).data;
entity._updated = new Date().toUTCString();
let self = this;
return new Promise((resolve, reject) => {
try {
let list = data.entities;
let name = schema.getId(entity);
if (!list || !list[name]) {
reject("Entity doesn't exist. " + name);
return;
}
entity = schema.deepAssign(list[name], entity);
list[name] = conventions_1.Conventions.clone(entity);
self.save(schema);
resolve(entity);
}
catch (err) {
reject(err);
}
});
}
}
exports.MemoryProvider = MemoryProvider;
//# sourceMappingURL=provider.js.map