UNPKG

jaydata

Version:

Cross-platform HTML5 data-management, JavaScript Language Query (JSLQ) support for OData, SQLite, WebSQL, IndexedDB, YQL and Facebook (packaged for Node.JS)

265 lines (216 loc) 12.4 kB
'use strict'; var _core = require('../../../../core.js'); var _core2 = _interopRequireDefault(_core); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } //"use strict"; // suspicious code (0, _core.$C)('$data.storageProviders.Facebook.FacebookCompiler', _core2.default.Expressions.EntityExpressionVisitor, null, { constructor: function constructor() { this.provider = {}; }, compile: function compile(query) { this.provider = query.context.storageProvider; var context = { filterSql: { sql: '' }, projectionSql: { sql: '' }, orderSql: { sql: '' }, skipSql: { sql: '' }, takeSql: { sql: '' }, tableName: '' }; this.Visit(query.expression, context); var autoGeneratedSelect = false; if (!context.projectionSql.sql) { context.projectionSql = this.autoGenerateProjection(query); autoGeneratedSelect = true; } if (context.filterSql.sql == '') _core.Guard.raise(new _core.Exception('Filter/where statement is required', 'invalid operation')); return { queryText: context.projectionSql.sql + ' FROM ' + context.tableName + context.filterSql.sql + context.orderSql.sql + context.takeSql.sql + (context.takeSql.sql ? context.skipSql.sql : ''), selectMapping: autoGeneratedSelect == false ? context.projectionSql.selectFields : null, params: [] }; }, autoGenerateProjection: function autoGenerateProjection(query) { var entitySet = query.context.getEntitySetFromElementType(query.defaultType); var newQueryable = new _core2.default.Queryable(query.context, entitySet.expression); //newQueryable._checkRootExpression(entitySet.collectionName); var codeExpression = _core.Container.createCodeExpression(this.generateProjectionFunc(query)); var exp = _core.Container.createProjectionExpression(newQueryable.expression, codeExpression); var q = _core.Container.createQueryable(newQueryable, exp); var expression = q.expression; var preparator = _core.Container.createQueryExpressionCreator(query.context); expression = preparator.Visit(expression); var databaseQuery = { projectionSql: { sql: '' } }; this.Visit(expression, databaseQuery); return databaseQuery.projectionSql; }, generateProjectionFunc: function generateProjectionFunc(query) { var isAuthenticated = this.provider.AuthenticationProvider.Authenticated || this.provider.providerConfiguration.Access_Token; var publicMemberDefinitions = query.defaultType.memberDefinitions.getPublicMappedProperties(); if (!isAuthenticated && publicMemberDefinitions.some(function (memDef) { return memDef.isPublic == true; })) { publicMemberDefinitions = publicMemberDefinitions.filter(function (memDef) { return memDef.isPublic == true; }); } var selectStr = 'function (s){ return {'; publicMemberDefinitions.forEach(function (memDef, i) { if (i != 0) selectStr += ', '; selectStr += memDef.name + ': s.' + memDef.name; }); selectStr += '}; }'; //var projectionFunc = null; //eval(selectStr); return selectStr; }, VisitFilterExpression: function VisitFilterExpression(expression, context) { ///<param name="expression" type="$data.Expressions.FilterExpression" /> this.Visit(expression.source, context); context.filterSql.type = expression.nodeType; if (context.filterSql.sql == '') context.filterSql.sql = ' WHERE ';else context.filterSql.sql += ' AND '; this.Visit(expression.selector, context.filterSql); }, VisitProjectionExpression: function VisitProjectionExpression(expression, context) { ///<param name="expression" type="$data.Expressions.ProjectionExpression" /> this.Visit(expression.source, context); context.projectionSql.type = expression.nodeType; if (context.projectionSql.sql == '') context.projectionSql.sql = 'SELECT ';else _core.Guard.raise(new _core.Exception('Multiple select error')); this.Visit(expression.selector, context.projectionSql); }, VisitOrderExpression: function VisitOrderExpression(expression, context) { ///<param name="expression" type="$data.Expressions.OrderExpression" /> this.Visit(expression.source, context); context.orderSql.type = expression.nodeType; if (context.orderSql.sql == '') context.orderSql.sql = ' ORDER BY ';else _core.Guard.raise(new _core.Exception('Multiple sorting not supported', 'not supported')); this.Visit(expression.selector, context.orderSql); context.orderSql.sql += expression.nodeType == _core2.default.Expressions.ExpressionType.OrderByDescending ? " DESC" : " ASC"; }, VisitPagingExpression: function VisitPagingExpression(expression, context) { ///<param name="expression" type="$data.Expressions.PagingExpression" /> this.Visit(expression.source, context); if (expression.nodeType == _core2.default.Expressions.ExpressionType.Skip) { context.skipSql.type = expression.nodeType; context.skipSql.sql = ' OFFSET '; this.Visit(expression.amount, context.skipSql); } else if (expression.nodeType == _core2.default.Expressions.ExpressionType.Take) { context.takeSql.type = expression.nodeType; context.takeSql.sql = ' LIMIT '; this.Visit(expression.amount, context.takeSql); } }, VisitSimpleBinaryExpression: function VisitSimpleBinaryExpression(expression, context) { context.sql += "("; var left = this.Visit(expression.left, context); context.sql += expression.resolution.mapTo; if (expression.resolution.resolvableType && !_core.Guard.requireType(expression.resolution.mapTo + ' expression.right.value', expression.right.value, expression.resolution.resolvableType)) { _core.Guard.raise(new _core.Exception(expression.right.type + " not allowed in '" + expression.resolution.mapTo + "' statement", "invalid operation")); } if (expression.resolution.name === 'in' && expression.right.value instanceof Array) { var self = this; context.sql += "("; expression.right.value.forEach(function (item, i) { if (i > 0) context.sql += ", "; self.Visit(item, context); }); context.sql += ")"; } else { var right = this.Visit(expression.right, context); } context.sql += ")"; }, VisitEntityFieldExpression: function VisitEntityFieldExpression(expression, context) { var source = this.Visit(expression.selector, context); }, VisitMemberInfoExpression: function VisitMemberInfoExpression(expression, context) { var memberName = expression.memberName; context.sql += memberName; //context.fieldName = memberName; context.fieldData = { name: memberName, dataType: expression.memberDefinition.dataType }; if (context.type == 'Projection' && !context.selectFields) { if (context.fieldOperation === true) context.selectFields = [{ from: 'anon' }];else context.selectFields = [{ from: memberName, dataType: expression.memberDefinition.dataType }]; } }, VisitConstantExpression: function VisitConstantExpression(expression, context) { if (context.type == 'Projection') _core.Guard.raise(new _core.Exception('Constant value is not supported in Projection.', 'Not supported!')); this.VisitQueryParameterExpression(expression, context); }, VisitQueryParameterExpression: function VisitQueryParameterExpression(expression, context) { if (expression.value instanceof _core2.default.storageProviders.Facebook.EntitySets.Command) { context.sql += "" + expression.value + ""; } else if (expression.value instanceof _core2.default.Queryable) { context.sql += '(' + expression.value.toTraceString().queryText + ')'; } else { var expressionValueType = _core.Container.resolveType(expression.type); if (this.provider.supportedDataTypes.indexOf(expressionValueType) != -1) context.sql += this.provider.fieldConverter.toDb[_core.Container.resolveName(expressionValueType)](expression.value);else { context.sql += "" + expression.value + ""; } } }, VisitParametricQueryExpression: function VisitParametricQueryExpression(expression, context) { var exp = this.Visit(expression.expression, context); context.parameters = expression.parameters; }, VisitEntitySetExpression: function VisitEntitySetExpression(expression, context) { context.tableName = expression.instance.tableName; }, VisitObjectLiteralExpression: function VisitObjectLiteralExpression(expression, context) { var self = this; context.selectFields = context.selectFields || []; expression.members.forEach(function (member) { if (member.expression instanceof _core2.default.Expressions.ObjectLiteralExpression) { context.mappingPrefix = context.mappingPrefix || []; context.mappingPrefix.push(member.fieldName); self.Visit(member, context); context.mappingPrefix.pop(); } else { if (context.selectFields.length > 0) context.sql += ', '; self.Visit(member, context); var toProperty = context.mappingPrefix instanceof Array ? context.mappingPrefix.join('.') + '.' + member.fieldName : member.fieldName; context.selectFields.push({ from: context.fieldData.name, to: toProperty, dataType: context.fieldData.dataType }); } }); }, VisitObjectFieldExpression: function VisitObjectFieldExpression(expression, context) { return this.Visit(expression.expression, context); }, VisitEntityFieldOperationExpression: function VisitEntityFieldOperationExpression(expression, context) { _core.Guard.requireType("expression.operation", expression.operation, _core2.default.Expressions.MemberInfoExpression); var opDef = expression.operation.memberDefinition; var opName = opDef.mapTo || opDef.name; context.sql += '('; if (opDef.expressionInParameter == false) this.Visit(expression.source, context); context.sql += opName; context.sql += "("; var paramCounter = 0; var params = opDef.parameters || []; var args = params.map(function (item, index) { var result = { dataType: item.dataType }; if (item.value) { result.value = item.value; } else if (item.name === "@expression") { result.value = expression.source; } else { result.value = expression.parameters[paramCounter]; result.itemType = expression.parameters[paramCounter++].type; }; return result; }); args.forEach(function (arg, index) { var itemType = arg.itemType ? _core.Container.resolveType(arg.itemType) : null; if (!itemType || arg.dataType instanceof Array && arg.dataType.indexOf(itemType) != -1 || arg.dataType == itemType) { if (index > 0) { context.sql += ", "; }; if (context.type == 'Projection') context.fieldOperation = true; this.Visit(arg.value, context); if (context.type == 'Projection') context.fieldOperation = undefined; } else _core.Guard.raise(new _core.Exception(arg.dataType + " not allowed in '" + expression.operation.memberName + "' statement", "invalid operation")); }, this); if (context.fieldData && context.fieldData.name) context.fieldData.name = 'anon'; if (opDef.rigthValue) context.sql += opDef.rigthValue;else context.sql += ")"; context.sql += ')'; } }, null);