UNPKG

offshore

Version:
178 lines (164 loc) 5.12 kB
/** * * ROOT LEVEL * +--------------+ * | ADAPTER EXEC | * +------+-------+ * v * +--------------+ * | PARENTS | * +--------------+ INDEX REFERENCES * | CHILDREENS +-------+ BY PATH/PK * +--------------+ | * | * GET LEVEL n v CURSOR * PARENTS PK +----+----+ * BY +----------+ INDEX | * PATH | +----+----+ * v ^ * +------+-------+ | * | ADAPTER EXEC | | * +------+-------+ | * v | * +--------------+ | * | PARENTS | | * +--------------|-------+ * | CHILDREENS | MERGE PARENTS IN REFERENCES * +--------------+ AND * INDEX CHILDREENS BY PATH/PK * */ var _ = require('lodash'); var DeepCursor = module.exports = function(path, data, paths) { this.path = path; this.paths = paths; if (data) { this.root = data; this.parents = {}; this.deepIndex(this.root); } }; DeepCursor.prototype.deepIndex = function(data) { var child; var alias; // many if (Array.isArray(data)) { for (var i in data) { for (alias in data[i]) { if (_.isObject(data[i][alias]) && !_.isDate(data[i][alias]) && this.paths[this.path].children[alias]) { // to many if (_.isArray(data[i][alias])) { for (j in data[i][alias]) { child = data[i][alias][j]; if (!_.isFunction(child)) { this.index(alias, child[this.paths[this.path].children[alias].primaryKey], child); } } } else { // to one child = data[i][alias]; if (child) { this.index(alias, child[this.paths[this.path].children[alias].primaryKey], child); } } } } } } else { // one for (alias in data) { if (_.isObject(data[alias]) && !_.isDate(data[alias]) && this.paths[this.path].children[alias]) { // to many if (_.isArray(data[alias])) { for (var j in data[alias]) { child = data[alias][j]; if (!_.isFunction(child)) { this.index(alias, child[this.paths[this.path].children[alias].primaryKey], child); } } } else { // to one child = data[alias]; if (child) { this.index(alias, child[this.paths[this.path].children[alias].primaryKey], child); } } } } } }; DeepCursor.prototype.index = function(alias, pk, dest) { var path = this.path + '.' + alias; if (!this.paths[path]) { return; } if (!this.paths[path].refs) { this.paths[path].refs = {}; } if (!this.paths[path].refs[pk]) { this.paths[path].refs[pk] = [dest]; } else { this.paths[path].refs[pk].push(dest); } // add to path parents if (!this.parents[path]) { this.parents[path] = []; } this.parents[path].push(pk); }; DeepCursor.prototype.extend = function(pk, object) { this.paths[this.path].refs[pk].forEach(function(ref) { _.extend(ref, object); }); }; DeepCursor.prototype.zip = function(data) { var currentAlias = this.path.substring(this.path.lastIndexOf('.') + 1, this.path.length); var previousPath = this.path.substring(0, this.path.lastIndexOf('.')); var parentPk = this.paths[previousPath].children[currentAlias].primaryKey; var parents = data; if (!Array.isArray(parents)) { parents = [parents]; } for (var parentIterator in parents) { var parentData = data[parentIterator]; var parentPkVal = parentData[parentPk]; // insert new parents' data in previous child this.extend(parentPkVal, parentData); for (var attribute in parentData) { // if attribute is an association then index childs if (this.paths[this.path].children[attribute]) { var childs = parentData[attribute]; if (childs && _.isObject(childs) && !_.isArray(childs)) { childs = [childs]; } for (var childIterator in childs) { var child = childs[childIterator]; if (!_.isFunction(child)) { this.index(attribute, child[this.paths[this.path].children[attribute].primaryKey], child); } } } } } }; DeepCursor.prototype.getParents = function() { return this.parents[this.path]; }; DeepCursor.prototype.getChildPath = function(path) { var pathCursor = new DeepCursor(path); pathCursor.paths = this.paths; pathCursor.parents = this.parents; pathCursor.root = this.root; return pathCursor; }; DeepCursor.prototype.getRoot = function() { return this.root; }; /** * CURSOR * +------------|-----------------+ * / ROOT LEVEL v \ * +/\/ /\/ /\/####HHH/ /\/ /\/ /\/ /\+ * /-MERGED-----###c***O) \ * +/\ \/\ \/\ \/####HHH -----------------+ * / INDEXED LEVEL n ZIPING PATH ---> * +/\ \/\ \/\ \/\ \/\ \/\ -------------------+ * */