UNPKG

zindex

Version:

Data indexing and tranforming libray

208 lines (179 loc) 5.3 kB
/** * Dependencies, it includes the node's util lib. */ var Promise = require('bluebird'); var path = require('path'); var fs = require('fs'); var _ = require('lodash'); var utils = require('util'); var moment = require('moment'); /** * Returns all files in the specified directory. */ utils.getFiles = function(directory) { return utils.getResources(directory, function(stat) { return stat.isFile(); }); }; /** * Returns all directories in the specified directory. */ utils.getDirectories = function(directory) { return utils.getResources(directory, function(stat) { return stat.isDirectory(); }); }; /** * Returns all filesystem resources in the specified * directory. * * If a filter function is specified, it will be used * to filter resources -- the callback receives a stat * instance of each resource in the directory. */ utils.getResources = function(directory, filter) { return new Promise(function(resolve, reject) { fs.readdir(directory, function(err, resources) { if (err) { var logger = include('logger'); logger.error('You are requesting files inside ' + directory + ' but the directory doesn\'t exist'); logger.error('Perhaps you are trying to setup new sources / backends? Then create that folder ;-)'); reject(err); } if (filter) { var files = []; resources.forEach(function(resource) { var stat = fs.lstatSync(path.join(directory, resource)); if (filter(stat)) { files.push(resource); } }); resolve(files); } else { resolve(resources); } }); }); }; /** * Checks if the given instance has the needed properties set. * It will cause a crash (throw) if one of them is missing. * It bails out at the 1st error. * * @param {object} instance * @param {array | string} requires */ utils.checkRequires = function(instance, requires) { requires = (_.isArray(requires)) ? requires : [requires]; requires.forEach(function(requirement) { if (!instance.hasOwnProperty(requirement) || instance[requirement] === undefined || instance[requirement] === null) { var constructorName = (instance.constructor.name !== 'Object') ? '(' + instance.constructor.name + ') ' : ''; throw new Error('The object ' + constructorName + 'needs to have "' + requirement + '" correctly set or it will not run!!!!\n' + 'Please check your code and be sure you correctly called it\'s constructor or it\'s init method.\n' + 'Check the following stack trace, around line 4, for a hint on where it happens: \n'); } }); }; /** * Gets a prototype based objects and returns an * and extension * * @param {Object} ancestor * @returns {Object} */ utils.extend = function(ancestor) { var descendant = function() { ancestor.apply(this, arguments); }; utils.inherits(descendant, ancestor); return descendant; }; /** * Parse a string (ex: 5m) to a moment object * * @param string * @returns {object} */ utils.stringToMoment = function(string) { var stringParts = string.match(/[a-zA-Z]+|[0-9]+/g); if (!stringParts[1]) { stringParts[1] = 's'; } return moment().subtract(stringParts[0], stringParts[1]); }; /** * Return an interval in milliseconds * It receives a moment() object and calculates it distance * from the given Date() object. If no date is provided * it will calculate the interval from 'now'. * * @param {object} interval * @param {object} date * @returns {number} */ utils.getInterval = function(interval, date) { date = date || new Date(); var intervalTimestamp = interval.unix(); var now = parseInt((date.getTime() / 1000), 10); interval = ((now - intervalTimestamp) * 1000); return interval; }; /** * I got annoyed of the `indexOf` thingy * * @param target * @param subject * @returns {*|boolean} */ utils.contains = function(target, subject) { return (target && target.indexOf(subject) > -1); }; /** * Transforms a list of objects to a a series * of arrays convenient for bulk query generation * and extracts the fields list. * * The node-mysql driver is able to run bulk queries * if you provide the fields to update and a list of * values: * * - [name, last_name], [[alex, nadalin], [luciano, colosio]] * * Since we deal with list of entities in the form of * [name: alex, last_name: nadalin] we need to restructure * the data a bit before feeding it to the driver. * * @param entities * @returns {Object} */ utils.prepareForBulkQuery = function(entities) { var fields = Object.keys(entities[0]); var list = _.map(entities, function(entity) { var values = []; fields.forEach(function(fieldName) { values.push(entity[fieldName]); }); return values; }); var fieldsUpdateString = _.map(fields, function(field) { return field + '=VALUES(' + field + ')'; }).join(','); return { list: [list], fields: fields.join(','), updateString: fieldsUpdateString }; }; /** * Takes a general value argument and wraps it into a resolved promise * * @param {Any} value * @return {Promise} */ utils.wrapInPromise = function(value) { return new Promise(function(resolve) { resolve(value); }); }; /** * Exports. */ module.exports = utils;