nodebook-nbql
Version:
Filter query language for nodebook
111 lines (97 loc) • 3.05 kB
JavaScript
// lodash statement
var _ = require('lodash'),
matchStatement,
eachStatement,
findStatement,
rejectStatements,
mergeStatements,
printStatements;
// Match Statement
matchStatement = function matchStatement(statement, match) {
return _.every(match, function (value, key) {
if (_.isRegExp(value)) {
return _.has(statement, key) && value.test(statement[key]);
} else {
return _.has(statement, key) && value === statement[key];
}
});
};
// Each Statement
eachStatement = function eachStatement(statements, func, groupFunc) {
_.each(statements, function (statement, index) {
if (_.has(statement, 'group')) {
if (groupFunc) {
groupFunc(statement, index);
} else {
eachStatement(statement.group, func, groupFunc);
}
} else {
func(statement, index);
}
});
};
// Recursively find if any statement in the array matches the given match object
findStatement = function findStatement(statements, match, keys) {
return _.some(statements, function (statement) {
if (_.has(statement, 'group')) {
return findStatement(statement.group, match, keys);
} else {
return matchStatement(statement, keys ? _.pick(match, keys) : match);
}
});
};
// Reject Statements
rejectStatements = function rejectStatements(statements, func) {
return _.reject(statements, function (statement, index) {
var result;
if (_.has(statement, 'group')) {
statement.group = rejectStatements(statement.group, func);
result = _.isEmpty(statement.group);
} else {
result = func(statement);
}
if (result && index === 0 && statements[index + 1] && statements[index + 1].func) {
delete statements[index + 1].func;
}
return result;
});
};
// Merge Statements
mergeStatements = function mergeStatements(/* statements */) {
var statementsArray = _.reduce(arguments, function (array, arg) {
if (!arg) { return array; }
if (_.has(arg, 'statements')) {
if (array.length !== 0 && !_.isEmpty(arg.statements)) {
arg.statements[0].func = 'and';
}
array = array.concat(arg.statements);
} else {
if (array.length !== 0) { arg.func = 'and'; }
array.push(arg);
}
return array;
}, []);
return {statements: statementsArray};
};
// Print statements
printStatements = function printStatements(statements, indent) {
indent = indent || 0;
function print(indent /* strs */) {
var strs = [_.fill(new Array(indent), ' ').join('')].concat(Array.prototype.slice.call(arguments, 1));
console.log.apply(this, strs);
}
eachStatement(statements, function single(statement) {
print(indent, statement);
}, function group(statement) {
print(indent, 'group', statement.func);
printStatements(statement.group, indent + 1);
});
};
module.exports = {
matchStatement: matchStatement,
eachStatement: eachStatement,
findStatement: findStatement,
rejectStatements: rejectStatements,
mergeStatements: mergeStatements,
printStatements: printStatements
};