import { IChassisContext, IChassisDataStore, IOperation } from "../interfaces"; import assert = require("assert"); import _ = require("lodash"); // import { Vars } from "../helpers"; import { CRUDMiddleware } from "./CRUDMiddleware"; /************************************************************************* * * Troven CONFIDENTIAL * __________________ * * (c) 2017-2020 Troven Ventures Pty Ltd. All Rights Reserved. * * NOTICE: All information contained herein is, and remains * the property of Troven Pty Ltd and its licensors, * if any. The intellectual and technical concepts contained * herein are proprietary to Troven Pty Ltd * and its suppliers and may be covered by International and Regional Patents, * patents in process, and are protected by trade secret or copyright law. * Dissemination of this information or reproduction of this material * is strictly forbidden unless prior written permission is obtained * from Troven Pty Ltd. */ export class NestedTreeStore implements IChassisDataStore { name: string = "datatree"; store: IChassisDataStore = null; id_field_name: string = "items"; collection_field_name: string = "items"; public options: any = null; public context: IChassisContext = null; constructor() {} getIDField(): string { return this.id_field_name; } getCollectionField(): string { return this.collection_field_name; } getStoreMiddleware() { return new CRUDMiddleware(this); } install(context: IChassisContext, options: any) { assert(options.store, "missing options.store"); this.context = context; this.options = options; this.id_field_name = options.id_field || this.id_field_name; this.collection_field_name = options.via || this.collection_field_name; let store_options = options[options.store] || false; let store = context.plugins.get(options.store); assert(this.store, "unknown options.store: " + options.store); assert(store_options, "unknown store.options: " + options.store); store.install(context, store_options); this.store = (store as any) as IChassisDataStore; // force type coercion context.middleware.set(this.getStoreMiddleware()); context.log({ code: "treestore:installed", database: this.options.database, id_field: this.id_field_name, collection_field: this.collection_field_name, }); return this; } redact(meta: any) { delete meta[this.collection_field_name]; return meta; } nestedCallback( oper: IOperation, meta: any, req_options: any, options: any, callback: Function ) { false && meta; false && req_options; assert(callback, "missing nested.callback"); assert(_.isFunction(callback), "invalid.callback"); // let self = this; return (err, items) => { false && err; // TODO: iterate 'read' for each item let item = items[0]; // copy data's id into meta and req_options let nested_meta = _.extend({}, meta); nested_meta[this.id_field_name] = item[this.id_field_name]; let nested_options = _.extend({}, req_options); nested_options[this.id_field_name] = item[this.id_field_name]; // iterate over items this.read(oper, meta, nested_options, options, callback); }; } healthy(req_options: any, callback: Function) { return this.store.healthy(req_options, callback); } query( oper: IOperation, meta: any, req_options: any, options: any, callback: Function ) { this.store.list( oper, meta, req_options, options, this.nestedCallback(oper, meta, req_options, options, callback) ); } create( oper: IOperation, meta: any, req_options: any, options: any, callback: Function ) { meta = this.redact(meta); req_options = this.redact(req_options); // TODO: handle arrays as set of creates this.store.create(oper, meta, req_options, options, callback); } read( oper: IOperation, meta: any, req_options: any, options: any, callback: Function ) { this.store.read( oper, meta, req_options, options, this.nestedCallback(oper, meta, req_options, options, callback) ); } list( oper: IOperation, meta: any, req_options: any, options: any, callback: Function ) { this.store.list( oper, meta, req_options, options, this.nestedCallback(oper, meta, req_options, options, callback) ); } aggregate( oper: IOperation, meta: any, req_options: any, options: any, callback: Function ) { this.store.aggregate( oper, meta, req_options, options, this.nestedCallback(oper, meta, req_options, options, callback) ); } update( oper: IOperation, meta: any, req_options: any, options: any, callback: Function ) { meta = this.redact(meta); req_options = this.redact(req_options); // TODO: handle arrays as set of creates this.store.update(oper, meta, req_options, options, callback); } delete( oper: IOperation, meta: any, req_options: any, options: any, callback: Function ) { // TODO: handle arrays as set of creates this.store.delete(oper, meta, req_options, options, callback); } bulk( oper: IOperation, delete_first: boolean, meta: any, req_options: any, options: any, callback: Function ) { // TODO: handle arrays as set of creates this.store.bulk(oper, delete_first, meta, req_options, options, callback); } }