From 29f6393115891d1d9ad8dbf14ab57bc2d52e97db Mon Sep 17 00:00:00 2001 From: Ritish Gumber Date: Tue, 27 Jun 2017 11:07:51 +0530 Subject: [PATCH 1/2] funnel changes --- helpers/cloudTable.js | 115 ++++++++++++++++++++++++++++++----- services/app.js | 125 +++++++++++++++++++++------------------ services/cloudObjects.js | 2 + 3 files changed, 169 insertions(+), 73 deletions(-) diff --git a/helpers/cloudTable.js b/helpers/cloudTable.js index 972feee3..1e402c04 100644 --- a/helpers/cloudTable.js +++ b/helpers/cloudTable.js @@ -580,8 +580,97 @@ module.exports = { "editableByMasterKey": false } ], - Custom: [ - { + _Funnel: [ + { + "name": "id", + "_type": "column", + "dataType": "Id", + "required": true, + "unique": true, + "relatedTo": null, + "relationType": null, + "isDeletable": false, + "isEditable": false, + "isRenamable": false, + "editableByMasterKey": false, + "defaultValue": null + }, { + "name": "updatedAt", + "_type": "column", + "dataType": "DateTime", + "required": true, + "unique": false, + "relatedTo": null, + "relationType": null, + "isDeletable": false, + "isEditable": false, + "isRenamable": false, + "editableByMasterKey": false + }, { + "name": "createdAt", + "_type": "column", + "dataType": "DateTime", + "required": true, + "unique": false, + "relatedTo": null, + "relationType": null, + "isDeletable": false, + "isEditable": false, + "isRenamable": false, + "editableByMasterKey": false + }, { + "name": "expires", + "_type": "column", + "dataType": "DateTime", + "required": false, + "unique": false, + "relatedTo": null, + "relationType": null, + "isDeletable": false, + "isEditable": false, + "isRenamable": false, + "editableByMasterKey": false + }, { + "name": "ACL", + "_type": "column", + "dataType": "ACL", + "required": true, + "unique": false, + "relatedTo": null, + "relationType": null, + "isDeletable": false, + "isEditable": false, + "isRenamable": false, + "editableByMasterKey": false + }, { + "name": "name", + "_type": "column", + "dataType": "Text", + "required": true, + "unique": false, + "relatedTo": "Text", + "relationType": null, + "isDeletable": false, + "isEditable": false, + "isRenamable": false, + "editableByMasterKey": false, + "defaultValue": null + }, { + "name": "data", + "_type": "column", + "dataType": "Object", + "required": true, + "unique": false, + "relatedTo": null, + "relationType": null, + "isDeletable": false, + "isEditable": false, + "isRenamable": false, + "editableByMasterKey": false + } + ], + Custom: [ + { name: 'id', _type: 'column', dataType: 'Id', @@ -593,9 +682,8 @@ module.exports = { isEditable: false, isRenamable: false, editableByMasterKey: false, - defaultValue: null - }, - { + defaultValue: null + }, { name: 'expires', _type: 'column', dataType: 'DateTime', @@ -607,9 +695,8 @@ module.exports = { isEditable: false, isRenamable: false, editableByMasterKey: false, - defaultValue: null - }, - { + defaultValue: null + }, { name: 'updatedAt', _type: 'column', dataType: 'DateTime', @@ -622,8 +709,7 @@ module.exports = { isRenamable: false, editableByMasterKey: false, defaultValue: null - }, - { + }, { name: 'createdAt', _type: 'column', dataType: 'DateTime', @@ -635,9 +721,8 @@ module.exports = { isEditable: false, isRenamable: false, editableByMasterKey: false, - defaultValue: null - }, - { + defaultValue: null + }, { name: 'ACL', _type: 'column', dataType: 'ACL', @@ -650,6 +735,6 @@ module.exports = { isRenamable: false, editableByMasterKey: false, defaultValue: null - } + } ] -}; \ No newline at end of file +}; diff --git a/services/app.js b/services/app.js index be06ebe0..1cd6985d 100644 --- a/services/app.js +++ b/services/app.js @@ -14,7 +14,7 @@ var util = require('../helpers/util.js'); var tablesData = require('../helpers/cloudTable'); var json2csv = require('json2csv'); var jsonToXlsx = require('json2xlsx'); -var jsonXlsxWriteFile = require('icg-json-to-xlsx'); +var jsonXlsxWriteFile = require('icg-json-to-xlsx'); var fs = require('fs'); module.exports = function() { @@ -456,7 +456,7 @@ module.exports = function() { if (project.keys.master === key) { deferred.resolve(true); } else { - if (project.keys.js === key){ + if (project.keys.js === key) { deferred.resolve(false); } else { deferred.resolve(false); @@ -502,36 +502,42 @@ module.exports = function() { return deferred.promise; }, - isClientAuthorized : function(appId,appKey,level,table){ + isClientAuthorized: function(appId, appKey, level, table) { var deferred = q.defer(); var self = this - self.isKeyValid(appId, appKey).then(function(isValidKey){ - if(isValidKey){ + self.isKeyValid(appId, appKey).then(function(isValidKey) { + if (isValidKey) { self.isMasterKey(appId, appKey).then(function(isMasterKey) { // resolve if masterKey - if(isMasterKey){ + if (isMasterKey) { deferred.resolve(true) } else { // else check with client keys acc to auth level // levels = table level or app level // for app level check in app settings , for table level check in table schema - if(level === 'table'){ - if(table) { + if (level === 'table') { + if (table) { deferred.resolve(!!table.isEditableByClientKey) - } else deferred.resolve(false); - } else { - self.getAllSettings(appId).then(function(settings){ - if(settings){ + } else + deferred.resolve(false); + } + else { + self.getAllSettings(appId).then(function(settings) { + if (settings) { // check for clientkey flag in genral settings - let generalSetting = settings.filter((function(x){ + let generalSetting = settings.filter((function(x) { return x.category === 'general' })) - if(generalSetting[0]){ + if (generalSetting[0]) { deferred.resolve(!!generalSetting[0].settings.isTableEditableByClientKey) - } else deferred.resolve(false); - } else deferred.resolve(false); - - }, function(error) { + } else + deferred.resolve(false); + } + else + deferred.resolve(false); + + } + , function(error) { deferred.reject(error); }); } @@ -542,7 +548,7 @@ module.exports = function() { } else { deferred.reject('Unauthorized'); } - },function(err){ + }, function(err) { deferred.reject(err); }) @@ -552,8 +558,10 @@ module.exports = function() { upsertTable: function(appId, tableName, schema, tableProps) { var deferred = global.q.defer(); - tableProps = tableProps || { isEditableByClientKey : false } - + tableProps = tableProps || { + isEditableByClientKey: false + } + try { var self = this; @@ -583,11 +591,13 @@ module.exports = function() { tableType = "file"; } else if (tableName === "_Event") { tableType = "event"; + } else if (tableName === "_Funnel") { + tableType = "funnel"; } else { tableType = "custom"; } - if (tableType === 'user' || tableType === 'role' || tableType === 'device' || tableType === 'file' || tableType === 'event') { + if (tableType === 'user' || tableType === 'role' || tableType === 'device' || tableType === 'file' || tableType === 'event' || tableType === 'funnel') { maxCount = 1; } else { maxCount = 99999; @@ -794,7 +804,8 @@ module.exports = function() { global.appService.upsertTable(appId, 'Device', tablesData.Device), global.appService.upsertTable(appId, 'User', tablesData.User), global.appService.upsertTable(appId, '_File', tablesData._File), - global.appService.upsertTable(appId, '_Event', tablesData._Event) + global.appService.upsertTable(appId, '_Event', tablesData._Event), + global.appService.upsertTable(appId, '_Funnel', tablesData._Funnel) ]); }, @@ -1027,42 +1038,40 @@ module.exports = function() { return deferred.promise; }, - exportTable : function(appId,tableName,exportType,isMasterKey,accessList){ + exportTable: function(appId, tableName, exportType, isMasterKey, accessList) { var deferred = q.defer(); - global.customService.find(appId, tableName,{},null, null, null, null, accessList, isMasterKey).then(function(tables){ - - if(exportType === 'csv') - { - var result = json2csv({ data: tables}); - deferred.resolve(result); - }else if(exportType === 'xlsx' || exportType === 'xls') - { - var random = util.getId(); - var fileName = '/tmp/tempfile'+random+'.xlsx'; - var converted = convertObjectToString(tables); - var outputFile = jsonXlsxWriteFile.writeFile(fileName, converted); + global.customService.find(appId, tableName, {}, null, null, null, null, accessList, isMasterKey).then(function(tables) { + + if (exportType === 'csv') { + var result = json2csv({data: tables}); + deferred.resolve(result); + } else if (exportType === 'xlsx' || exportType === 'xls') { + var random = util.getId(); + var fileName = '/tmp/tempfile' + random + '.xlsx'; + var converted = convertObjectToString(tables); + var outputFile = jsonXlsxWriteFile.writeFile(fileName, converted); fs.readFile(fileName, function read(err, data) { if (err) { - deferred.reject("Error : Failed to convert the table."); + deferred.reject("Error : Failed to convert the table."); } - fs.unlink(fileName,function(err){ - if(err){ + fs.unlink(fileName, function(err) { + if (err) { deferred.reject(err); - } + } deferred.resolve(data); - }); + }); }); - }else if(exportType === 'json'){ + } else if (exportType === 'json') { deferred.resolve(tables); - } else{ + } else { deferred.reject('Invalid exportType ,exportType should be csv,xls,xlsx,json') } - },function(err){ + }, function(err) { deferred.reject(err); }); - return deferred.promise; + return deferred.promise; } }; }; @@ -1137,6 +1146,8 @@ function _getDefaultColumnList(type) { defaultColumn.concat(['name', 'contentType', 'path', 'url', 'size']); } else if (type == 'event') { defaultColumn.concat(['user', 'type', 'name', 'data']); + } else if (type == 'funnel') { + defaultColumn.concat(['name', 'data']); } return defaultColumn; @@ -1243,7 +1254,7 @@ function _checkValidDataType(columns, deafultDataType, tableType) { return false; } //name for event table - if (key === 'name' && tableType === 'event') { + if (key === 'name' && (tableType === 'event' || tableType === 'funnel')) { if (columns[index].relationType != null || columns[index].required != true || columns[index].unique != false || columns[index].dataType != 'Text') return false; } @@ -1367,8 +1378,7 @@ function _checkValidDataType(columns, deafultDataType, tableType) { } } else if (columns[i].dataType === 'Email') { if (columns[i].defaultValue.match(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/i)[0] !== columns[i].defaultValue) { - return - false; // if the set dataType is not other string Datatypes (Text, EncryptedText, DateTime) available in cloudboost; + return false; // if the set dataType is not other string Datatypes (Text, EncryptedText, DateTime) available in cloudboost; } } else if (['Text', 'EncryptedText', 'DateTime'].indexOf(columns[i].dataType) === -1) { return false; @@ -1477,6 +1487,9 @@ function _getDefaultColumnWithDataType(type) { defaultColumn['type'] = 'Text'; defaultColumn['name'] = 'Text'; defaultColumn['data'] = 'Object'; + } else if (type == 'funnel') { + defaultColumn['name'] = 'Text'; + defaultColumn['data'] = 'Object'; } return defaultColumn; @@ -1513,18 +1526,14 @@ function deleteAppFromRedis(appId) { return deferred.promise; } -function convertObjectToString(arr) -{ - for(let j in arr) - { +function convertObjectToString(arr) { + for (let j in arr) { let data = arr[j]; - for(let i in data) - { - if(typeof data[i] == 'object') - { - data[i] = JSON.stringify(data[i]); + for (let i in data) { + if (typeof data[i] == 'object') { + data[i] = JSON.stringify(data[i]); } - + } } return arr; diff --git a/services/cloudObjects.js b/services/cloudObjects.js index 7dc07ce5..d731c077 100644 --- a/services/cloudObjects.js +++ b/services/cloudObjects.js @@ -719,6 +719,8 @@ function _getTableType(tableName) { tableType = "file"; } else if (tableName === "_Event") { tableType = "event"; + } else if (tableName === "_Funnel") { + tableType = "funnel"; } return tableType; } From 86b9a224979d553d81ea61be852ccc58b509387b Mon Sep 17 00:00:00 2001 From: Ritish Gumber Date: Tue, 27 Jun 2017 11:49:27 +0530 Subject: [PATCH 2/2] default sort moved to service --- api/tables/CloudObjects.js | 10 ---------- databases/mongo.js | 7 +++++++ services/cloudObjects.js | 16 +++++++++------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/api/tables/CloudObjects.js b/api/tables/CloudObjects.js index 96a1b717..86534003 100644 --- a/api/tables/CloudObjects.js +++ b/api/tables/CloudObjects.js @@ -87,16 +87,6 @@ function _getData(req, res) { //get document(s) object based on query and variou var appKey = req.body.key || req.param('key'); var sdk = req.body.sdk || "REST"; - //default sort added - /* - without sort if limit and skip are used, the records are returned out of order. To solve this default sort in ascending order of 'createdAt' is added - */ - - if (Object.keys(sort).length === 0 && sort.constructor === Object) - sort = { - createdAt: 1 - } - global.appService.isMasterKey(appId, appKey).then(function(isMasterKey) { return global.customService.find(appId, collectionName, query, select, sort, limit, skip, customHelper.getAccessList(req), isMasterKey); }).then(function(results) { diff --git a/databases/mongo.js b/databases/mongo.js index 393bbe80..9aa1d9eb 100644 --- a/databases/mongo.js +++ b/databases/mongo.js @@ -295,6 +295,13 @@ module.exports = function() { if (!sort) { sort = {}; } + //default sort added + /* + without sort if limit and skip are used, the records are returned out of order. To solve this default sort in ascending order of 'createdAt' is added + */ + + if (!sort['createdAt']) + sort['createdAt'] = 1 if (!limit || limit === -1) { limit = 20; diff --git a/services/cloudObjects.js b/services/cloudObjects.js index a8305742..8f63e6f7 100644 --- a/services/cloudObjects.js +++ b/services/cloudObjects.js @@ -1290,7 +1290,7 @@ function _getSchema(appId, collectionName) { return deferred.promise; } -//this function encrypts the password, if the password is passed in the Query. +//this function modifies the fields ['password','datetime'] passed in the Query. function _modifyFieldsInQuery(appId, collectionName, query) { var deferred = global.q.defer(); @@ -1318,8 +1318,10 @@ function _modifyFieldsInQuery(appId, collectionName, query) { deferred.resolve(query); } else { //or modify the query and resolve it. - if(passwordColumnNames.length ) query = _recursiveModifyQuery(query, passwordColumnNames, 'encrypt'); - if(dateTimeColumnNames.length ) query = _recursiveModifyQuery(query, dateTimeColumnNames, 'datetime'); + if (passwordColumnNames.length) + query = _recursiveModifyQuery(query, passwordColumnNames, 'encrypt'); + if (dateTimeColumnNames.length) + query = _recursiveModifyQuery(query, dateTimeColumnNames, 'datetime'); deferred.resolve(query); } @@ -1362,14 +1364,14 @@ function _recursiveModifyQuery(query, columnNames, type) { return _.mapObject(query, function(val, key) { if (columnNames.indexOf(key) > -1) { if (typeof val !== 'object') { - if(type === 'encrypt'){ + if (type === 'encrypt') { return _encrypt(val); } } else { // for datetime fields convert them to a fomat which mongodb can query - if( type === 'datetime'){ - try{ - Object.keys(val).map(function(x){ + if (type === 'datetime') { + try { + Object.keys(val).map(function(x) { val[x] = new Date(val[x]); }) return val;