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)

304 lines (254 loc) 14.1 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.YQL.YQLCompiler', _core2.default.Expressions.EntityExpressionVisitor, null, { constructor: function constructor() { this.provider = {}; this.cTypeCache = {}; }, 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); if (context.projectionSql.sql == '') context.projectionSql.sql = "SELECT *"; if (context.orderSql.sql) context.orderSql.sql = " | sort(" + context.orderSql.sql + ')'; //special skip-take logic if (context.skipSql.value && context.takeSql.value) { var skipVal = context.skipSql.value; context.skipSql.value = context.takeSql.value; context.takeSql.value = context.takeSql.value + skipVal; } if (context.skipSql.value) context.skipSql.sql = context.skipSql.sqlPre + context.skipSql.value + context.skipSql.sqlSuf; if (context.takeSql.value) context.takeSql.sql = context.takeSql.sqlPre + context.takeSql.value + context.takeSql.sqlSuf; return { queryText: context.projectionSql.sql + ' FROM ' + context.tableName + context.filterSql.sql + context.orderSql.sql + context.takeSql.sql + (context.takeSql.sql ? context.skipSql.sql : ''), selectMapping: context.projectionSql.selectFields, params: [] }; }, 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; var orderContext = { sql: '' }; this.Visit(expression.selector, orderContext); context.orderSql.sql = "field='" + orderContext.sql + "', descending='" + (expression.nodeType == _core2.default.Expressions.ExpressionType.OrderByDescending) + "'" + (context.orderSql.sql != '' ? ', ' + context.orderSql.sql : ''); }, 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.sqlPre = ' | tail(count='; this.Visit(expression.amount, context.skipSql); context.skipSql.sqlSuf = ')'; } else if (expression.nodeType == _core2.default.Expressions.ExpressionType.Take) { context.takeSql.type = expression.nodeType; context.takeSql.sqlPre = ' | truncate(count='; this.Visit(expression.amount, context.takeSql); context.takeSql.sqlSuf = ')'; } }, 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) { this.Visit(expression.source, context); this.Visit(expression.selector, context); }, VisitMemberInfoExpression: function VisitMemberInfoExpression(expression, context) { var memberName; if (context.wasComplex === true) context.sql += '.'; context.sql += expression.memberName; if (context.isComplex == true) { context.complex += expression.memberName; context.wasComplex = true; } else { context.wasComplex = false; if (context.complex) memberName = context.complex + expression.memberName;else memberName = expression.memberName; context.complex = null; //context.sql += memberName; //context.fieldName = memberName; context.fieldData = { name: memberName, dataType: expression.memberDefinition.dataType }; if (context.type == 'Projection' && !context.selectFields) 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) { context.value = expression.value; var expressionValueType = _core.Container.resolveType(expression.type); //Container.resolveType(Container.getTypeName(expression.value)); if (expression.value instanceof _core2.default.Queryable) { context.sql += '(' + expression.value.toTraceString().queryText + ')'; } else 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) { if (context.type == 'Projection') { this.Visit(expression.expression, context); if (expression.expression instanceof _core2.default.Expressions.ComplexTypeExpression) { context.selectFields = context.selectFields || []; var type = expression.expression.entityType; var includes = this._getComplexTypeIncludes(type); context.selectFields.push({ from: context.complex, type: type, includes: includes }); } } else { var exp = this.Visit(expression.expression, context); context.parameters = expression.parameters; } }, VisitEntitySetExpression: function VisitEntitySetExpression(expression, context) { if (context.type) { if (!context.complex) context.complex = ''; } else { 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 mapping = { from: context.fieldData.name, to: context.mappingPrefix instanceof Array ? context.mappingPrefix.join('.') + '.' + member.fieldName : member.fieldName }; if (context.selectType) { mapping.type = context.selectType; var includes = this._getComplexTypeIncludes(context.selectType); mapping.includes = includes; } else { mapping.dataType = context.fieldData.dataType; } context.selectFields.push(mapping); delete context.fieldData; delete context.selectType; } }, this); }, VisitObjectFieldExpression: function VisitObjectFieldExpression(expression, context) { this.Visit(expression.expression, context); if (expression.expression instanceof _core2.default.Expressions.ComplexTypeExpression) { context.fieldData = context.fieldData || {}; context.fieldData.name = context.complex; context.selectType = expression.expression.entityType; } }, 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; var paramCounter = 0; var params = opDef.parameters || []; var args = params.map(function (item, index) { var result = { dataType: item.dataType, prefix: item.prefix, suffix: item.suffix }; 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 += ", "; }; var funcContext = { sql: '' }; this.Visit(arg.value, funcContext); if (opName == ' LIKE ') { var valueType = _core.Container.getTypeName(funcContext.value); context.sql += valueType == 'string' ? "'" : ""; context.sql += (arg.prefix ? arg.prefix : '') + funcContext.value + (arg.suffix ? arg.suffix : ''); context.sql += valueType == 'string' ? "'" : ""; } else { context.sql += funcContext.sql; } } else _core.Guard.raise(new _core.Exception(itemType + " not allowed in '" + expression.operation.memberName + "' statement", "invalid operation")); }, this); if (opDef.rigthValue) context.sql += opDef.rigthValue;else context.sql += ""; context.sql += ')'; }, VisitComplexTypeExpression: function VisitComplexTypeExpression(expression, context) { this.Visit(expression.source, context); context.isComplex = true; this.Visit(expression.selector, context); context.isComplex = false; if (context.complex != '' /*&& context.isComplex*/) context.complex += '.'; }, VisitEntityExpression: function VisitEntityExpression(expression, context) { this.Visit(expression.source, context); }, _findComplexType: function _findComplexType(type, result, depth) { type.memberDefinitions.getPublicMappedProperties().forEach(function (memDef) { var dataType = _core.Container.resolveType(memDef.dataType); if (dataType.isAssignableTo && !dataType.isAssignableTo(_core2.default.EntitySet)) { var name = depth ? depth + '.' + memDef.name : memDef.name; result.push({ name: name, type: dataType }); this._findComplexType(dataType, result, name); } }, this); }, _getComplexTypeIncludes: function _getComplexTypeIncludes(type) { if (!this.cTypeCache[type.name]) { var inc = []; this._findComplexType(type, inc); this.cTypeCache[type.name] = inc; } return this.cTypeCache[type.name]; } }, null);