import lodash from 'lodash';
/**
* This method allows you to use ExistedGraph class to its inheritance chain.
*
* @param {Class} ParentClassGraph
* @return {Class} Graph
* @description `import { factoryExistedGraph } from 'ancient-graph-removed';`
*/
function factoryExistedGraph(ParentClassGraph) {
/**
* Class to inherit. It must be used after adapting to the database..
* Distorts graph logic so that the use of two-stage removal.
* It is a public, not a removed part of the graph.
*
* @class
* @description `var ExistedGraph = factoryExistedGraph(Graph);`
*/
class ExistedGraph extends ParentClassGraph {
/**
* Standard graph insert, but with locked removed field.
*
* @param {Link} link
* @param {ExistedGraph~insertCallback} [callback]
* @param {Object} [context]
* @return {string} [id]
*/
insert(link, callback, context) {
if (link.hasOwnProperty('removed')) delete link.removed;
return super.insert(link, callback, context);
}
/**
* Optional callback. If present, called with an error object as the first argument and, if no error, the unique id of inserted link as the second.
*
* @callback ExistedGraph~insertCallback
* @param {Error} [error]
* @param {string} [id]
*/
/**
* Standard graph update, but with locked removed field in modifier, if context.removed is not true.
*
* @param {string|LinkSelector} selector
* @param {LinkModifier} modifier
* @param {ExistedGraph~updateCallback} [callback]
* @param {Object} [context]
* @return {number} [count]
*/
update(selector, modifier, callback, context) {
if (modifier.hasOwnProperty('removed')) {
delete modifier.removed;
}
if (context) {
if (context.modifier) {
modifier = lodash.assign(modifier, context.modifier);
}
}
return super.update(selector, modifier, callback, context);
}
/**
* Optional callback. If present, called with an error object as the first argument and, if no error, the number of affected documents as the second.
*
* @callback ExistedGraph~updateCallback
* @param {Error} [error]
* @param {number} [count]
*/
/**
* Instead of removing the changes remove field to true.
*
* @param {string|LinkSelector} selector
* @param {ExistedGraph~removeCallback} [callback]
* @param {Object} [context]
*/
remove(selector, callback, context) {
if (!context) var context = {};
if (!context.modifier) context.modifier = {};
context.modifier.removed = true;
this.update(selector, {}, callback, context);
}
/**
* Optional callback. If present, called with an error object as the first argument.
*
* @callback ExistedGraph~removeCallback
* @param {Error} [error]
* @param {number} [count]
*/
/**
* Standard graph query, but visible only links where removed is undefined.
*
* @param {string|LinkSelector} selector
* @return {*} query
*/
query(selector) {
var _selector;
if (typeof(selector) != 'object') {
_selector = {};
if (typeof(selector) != 'undefined') {
_selector.id = selector;
}
}
else _selector = selector;
_selector.removed = undefined;
return super.query(_selector);
}
/**
* Standard graph on method, but considering substitution the remove to the update.
*
* @param {string} event - name
* @param {ExistedGraphonCallback} callback
*/
on(event, callback) {
if (event == 'insert') super.on(event, callback);
if (event == 'update') {
super.on('update', function(oldLink, newLink, context) {
if (!newLink.removed) {
callback(...arguments);
}
});
}
if (event == 'remove') {
super.on('update', function(oldLink, newLink, context) {
if (newLink.removed) {
callback(oldLink, undefined, context);
}
});
}
if (event == 'link') super.on(event, callback);
if (event == 'unlink') super.on(event, callback);
}
/**
* @callback ExistedGraph~onCallback
* @param {Link} [oldLink] - can be undefined on link and insert events
* @param {Link} [newLink] - can be undefined on unlink and remove events
* @param {Object} [context] - additional app information, such as context.userId
*/
};
return ExistedGraph;
}
/**
* This method allows you to use NonExistedGraph class to its inheritance chain.
*
* @param {Class} ParentClassGraph
* @return {Class} Graph
* @description `import { factoryNonExistedGraph } from 'ancient-graph-removed';`
*/
function factoryNonExistedGraph(ParentClassGraph) {
/**
* Class to inherit. It must be used after adapting to the database..
* Distorts graph logic so that the use of two-stage removal.
* It is a private, a removed part of the graph.
*
* @class
* @description `var NonExistedGraph = factoryNonExistedGraph(Graph);`
*/
class NonExistedGraph extends ParentClassGraph {
/**
* Illegal operation!
*/
insert() { throw new Error('Illegal operation.'); }
/**
* Standard graph update, but with locked removed field in modifier.
*
* @param {string|LinkSelector} selector
* @param {LinkModifier} modifier
* @param {ExistedGraph~updateCallback} [callback]
* @param {Object} [context]
* @return {number} [count]
*/
update(selector, modifier, callback, context) {
if (modifier.hasOwnProperty('removed')) delete modifier.removed;
return super.update(selector, modifier, callback, context);
}
/**
* Standard graph query, but visible only links where removed is undefined.
*
* @param {string|LinkSelector} selector
* @return {*} query
*/
query(selector) {
var _selector;
if (typeof(selector) != 'object') {
_selector = {};
if (typeof(selector) != 'undefined') {
_selector.id = selector;
}
}
else _selector = selector;
_selector.removed = true;
return super.query(_selector);
}
/**
* Standard graph on method, but considering substitution the remove to the update.
*
* @param {string} event - name
* @param {ExistedGraphonCallback} callback
*/
on(event, callback) {
if (event == 'insert') {
// Impossible on object adapter of graph, but in real db
super.on('update', function(oldLink, newLink, context) {
if (!oldLink.removed && newLink.removed) {
callback(...arguments);
}
});
}
if (event == 'update') {
super.on('update', function(oldLink, newLink, context) {
if (oldLink.removed && newLink.removed) {
callback(...arguments);
}
});
}
if (event == 'remove') super.on(event, callback);
if (event == 'link') super.on(event, callback);
if (event == 'unlink') super.on(event, callback);
}
/**
* @callback ExistedGraph~onCallback
* @param {Link} [oldLink] - can be undefined on link and insert events
* @param {Link} [newLink] - can be undefined on unlink and remove events
* @param {Object} [context] - additional app information, such as context.userId
*/
};
return NonExistedGraph;
}
export { factoryExistedGraph, factoryNonExistedGraph };