UNPKG

fql-workbench

Version:

A FQL Workbench tool

478 lines (389 loc) 11.4 kB
/* * FQL-Workbench * Copyright 2012 Joseph Werle (joseph.werle@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** @module functions **/ var tables = require('./tables') , schema = require('./schema') , nonSupported = ['.*'] , _import = require('./tables/_import') , yaml = require('yamljs') , emit , filterTable filterTable = function(table, args) { var selected = {} , ret = {} , params , params , prop , arg , fields , field , i , val if (args.length) { ret.name = table.name; for (i = 0; i < args.length; i++) { arg = args[i].match(/([a-z]+)\s?:?\[?['|"]?([a-z|,\s?|_?|.?]+)?['|"]?\]?/); if (arg == null) { continue; } switch (arg[1]) { case 'find': break; case 'fields': fields = table.fields; if (arg[2] && !!~ args[i].indexOf(':') && (params = arg[2].split(/,/))) { for (field in fields) { selected[field] = {}; for (i = 0; i < params.length; i++) { if (fields[field][params[i]]) { if (params.length > 1) { selected[field][params[i]] = yaml.stringify(fields[field][params[i]].toString()); } else { selected[field] = yaml.stringify(fields[field][params[i]].toString()); } } } } fields = selected; } ret.fields = fields; break; case 'field': fields = table.fields; ret.fields = {}; if (arg[2] && !!~ args[i].indexOf(':') && (params = arg[2].split(/,/))) { for (i = 0; i < params.length; i++) { param = params[i].split('.')[0] prop = params[i].split('.')[1] val = (typeof prop === 'string' && fields[param][prop]? fields[param][prop] : fields[param]); ret.fields[param] = (typeof ret.fields[param] === 'object' ? ret.fields[param] : []); if (prop) { ret.fields[param][prop] = val; } else { ret.fields[param].push(val) } } } break; case 'perms': case 'permissions': ret.permissions = table.permissions break; } } } else { ret = table; } return ret; }; emit = function(callback) { return setTimeout(function(){ if (typeof callback === 'function') { callback(); } }, 0); } /** @namespace functions **/ var functions = function Functions(){}; functions.prototype._args = []; functions.prototype.defineUsage = function(def, func) { var i if (typeof this[def] === 'function') { this[def].usage = (typeof func === 'function'? func(def) : func); } else if (typeof def === 'object' && def.length) { for (i = 0; i < def.length; i++) { this.defineUsage(def[i], func); } } return this; }; functions.prototype.registerArguments = function(args) { this._args = this._args.concat(args); return this; }; functions.prototype.bind = function(cmd, func) { var self = this; if (typeof cmd === 'object' && cmd.length) { for (var i = 0; i < cmd.length; i++) { this.bind(cmd[i], func); } } else { this[cmd] = func; this[cmd].defineUsage = function(def) { self.defineUsage(cmd, def); return self[cmd]; }; this[cmd].registerArguments = function(args) { self.registerArguments(args); return self[cmd] } } return (typeof this[cmd] === 'function'? this[cmd] : this) }; functions.prototype.getUsage = function(command) { var usage if (typeof this[command] === 'function' && typeof this[command].usage === 'string') { return this[command].usage; } else { return "No usage found for :" + command; } }; functions.prototype.call = function() { var self = this , args = Array.prototype.map.apply(arguments, [function(){ return arguments[0]}]) , func = args.shift().replace(':','') if (!!~ this.getNames().indexOf(func)) { return this[func].apply(this[func], args); } return false }; functions.prototype.getNames = function() { var func, funcs = [] for (func in this) { if (this.hasOwnProperty(func)) { funcs.push(func); } } return funcs; }; functions.prototype.getArguments = function() { return this._args; }; functions.prototype.exists = function(name) { return !!~ this.getNames().indexOf(name) ? true : false }; functions.prototype.getNonSupported = function() { return nonSupported; }; functions.prototype.getKeywords = function(supported, not) { return new RegExp('('+ (supported || this.getNames()) .concat(not || this.getNonSupported()) .map(function(val){ return ':' + val; }).join('|') + ')', 'gi'); }; functions.prototype.parseInput = function(input) { var args = input.split(/\s/) return { cmd : args.shift().replace(':',''), args : args } }; /** @namespace functions **/ functions = new functions(); /** @function print **/ functions.bind('print', function(scope) { var args = Array.prototype.map.apply(arguments, [function(val){ return val; }]) , help = "" args.shift(); if (args.length) { emit(function(){ scope.emit('query.ready', args.join(' ')) }); return args.join(' '); } else { help = functions.call('help', scope, 'print'); emit(function(){ scope.emit('query.ready', help) }); return help } }).defineUsage(function(){ return ":print <string> - Prints a string to the buffer"; }); /** @function describe **/ functions.bind(['describe', 'desc'], function() { var scope = Array.prototype.shift.call(arguments) , table = Array.prototype.shift.call(arguments) , args = Array.prototype.map.apply(arguments, [function(val){ return val }]) , shim = tables.getShim(table) if (tables.hasTable(shim || table)) { if ((table = tables.getTable(shim || table)) && (shim ||table) !== null) { emit(function(){ scope.emit('query.ready', filterTable(table, args)); }); } } else { _import.getTableDefinition(shim || table).done(function(fields, permissions){ if (! fields) { scope.emit('query.ready', { data : ["Unsupported table."] }) } var ddl = {} , fieldObject = {} , i , field , prop , ret = {} , arg , params , selected = {} for (i = 0; i < fields.length; i++) { fieldObject[fields[i].name] = { indexable : fields[i].indexable === '*' ? true : false, type : fields[i].type, description : (fields[i].description.match(/<[a-z]+?\s?>/i) ? require('jquery')(fields[i].description).text() : fields[i].description) }; } table = shim? shim : table; table = schema.create('table', { name : table, permissions : permissions, fields : fieldObject }); if (args.length) { table = filterTable(table, args); } scope.emit('query.ready', table); }); } }).defineUsage(['desc', 'describe'], function(alias){ return [ ":" + alias + " <table> <filter>:,<filterargs> - Shows a table definition" , " example:" , ":describe insights fields" , ":describe user permissions", , ":describe application fields:type", , ":describe "].join('\n') }).registerArguments(['fields', 'field', 'find']); /** @function invalid **/ functions.bind('invalid', function(scope, arg){ emit(function() { scope.emit('query.ready', "Not a supported command"); }); }); /** @function exit **/ functions.bind('exit', function(){ process.exit(); }).defineUsage(function(){ return "Exits the session"; }); /** @function help **/ functions.bind('help' , function(scope, command){ command = command? command : 'help'; var usage = functions.getUsage(command) emit(function(){ scope.emit('query.ready', usage); }); return usage; }).defineUsage(function(){ return ":help <command> - Displays usage on a given command" }).registerArguments(functions.getNames()); /** @function eval **/ functions.bind('eval' , function(){ var scope = Array.prototype.shift.call(arguments) , args = Array.prototype.map.apply(arguments, [function(val){ return val }]) , ret = eval(args.join(' ')) emit(function(){ try { console.log(ret); scope.emit('query.ready', {data: void 0}); } catch (e) { scope.emit('query.ready', {_error: true, data: e}); } }); return ret; }).defineUsage(function(){ return ":eval <command> - evals given javascript" }).registerArguments([]); /** @function show **/ functions.bind('show', function(){ var scope = Array.prototype.shift.call(arguments) , args = Array.prototype.map.apply(arguments, [function(val){ return val }]) , flags = args.filter(function(val){ return val.indexOf('-') == 0; }).map(function(val){ return val.replace(/^-/,''); }) , args = args.filter(function(val){ return val.indexOf('-') != 0; }) , action = args.shift() , i , x , index , completions = [] switch (action) { case 'tables': if (scope.tables && typeof scope.tables === 'object') { emit(function(){ scope.emit('query.ready', scope.tables); }); } else { _import.getTables().done(function(tables){ scope.emit('query.ready', tables.tables || {}); }); } break; case 'completions': if (flags && flags.length) { for (i = 0; i < flags.length; i++) { switch (flags[i]) { case 'find': if (args.length) { for (x = 0; i < args.length; i++) { if ((index = scope.completions.indexOf(args[x]))) { completions.push(args[x]); } } } else { completions = scope.completions; } break; default: } } } else { completions = scope.completions; } emit(function(){ scope.emit('query.ready', completions) }) break; } }).defineUsage(function(){ return ":show table - Shows all possible tables to query" }).registerArguments(['tables', 'completions']);; module.exports = functions;