From 6ff67b6bfc44effce62e5aa58f1a8156490d3f4c Mon Sep 17 00:00:00 2001 From: Diogo Doreto Date: Fri, 16 Oct 2015 01:55:34 -0300 Subject: [PATCH] First working prototype --- lib/sql.js | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/lib/sql.js b/lib/sql.js index 948afe1..2190cc1 100644 --- a/lib/sql.js +++ b/lib/sql.js @@ -229,7 +229,7 @@ SQLConnector.prototype.tableEscaped = function(model) { * @returns {String} The escaped column name */ SQLConnector.prototype.columnEscaped = function(model, property) { - return this.escapeName(this.column(model, property)); + return this.tableEscaped(model) + '.' + this.escapeName(this.column(model, property)); }; /*! @@ -737,11 +737,17 @@ SQLConnector.prototype._buildWhere = function(model, where) { return new ParameterizedSQL(''); } var self = this; - var props = self.getModelDefinition(model).properties; + var modelDef = self.getModelDefinition(model); + var props = modelDef.properties; + var relations = modelDef.model.relations; var whereStmts = []; for (var key in where) { var stmt = new ParameterizedSQL('', []); + if (relations && key in relations) { + // relationships are handled on joins + continue; + } // Handle and/or operators if (key === 'and' || key === 'or') { var branches = []; @@ -990,11 +996,30 @@ SQLConnector.prototype.buildSelect = function(model, filter, options) { } } - var selectStmt = new ParameterizedSQL('SELECT ' + + var haveRelationFilters = false; + if (filter.where) { + var relations = this.getModelDefinition(model).model.relations; + if (relations) { + for (var key in filter.where) { + if (key in relations) { + haveRelationFilters = true; + break; + } + } + } + } + var distinct = haveRelationFilters ? 'DISTINCT ' : ''; + + var selectStmt = new ParameterizedSQL('SELECT ' + distinct + this.buildColumnNames(model, filter) + ' FROM ' + this.tableEscaped(model) ); + if (haveRelationFilters) { + var joinsStmts = this.buildJoins(model, filter.where); + selectStmt.merge(joinsStmts); + } + if (filter) { if (filter.where) { @@ -1015,6 +1040,41 @@ SQLConnector.prototype.buildSelect = function(model, filter, options) { return this.parameterize(selectStmt); }; +SQLConnector.prototype.buildJoins = function(model, where) { + var modelDef = this.getModelDefinition(model); + var relations = modelDef.model.relations; + var stmt = new ParameterizedSQL('', []); + + for (var key in where) { + if (!(key in relations)) continue; + + var rel = relations[key]; + var keyFrom = rel.keyFrom; + var modelTo = rel.modelTo.definition.name; + var modelToEscaped = this.tableEscaped(modelTo); + var keyTo = rel.keyTo; + + var innerWhere = Object.assign({}, where[key]); + var innerIdField = {}; + innerIdField[keyTo] = true; + innerWhere.fields = Object.assign({}, innerWhere.fields, innerIdField); + + var condition = this.columnEscaped(model, keyFrom) + '=' + + this.columnEscaped(modelTo, keyTo); + + var innerSelect = this.buildSelect(modelTo, innerWhere); + + stmt + .merge('INNER JOIN (') + .merge(innerSelect) + .merge(') AS ' + modelToEscaped) + .merge('ON ' + condition); + + } + + return stmt; +}; + /** * Transform the row data into a model data object * @param {string} model Model name