不要怂,就是干,撸起袖子干!

Commit 916a803f by Rafael Martins

Filter through relations working on postgres

1 parent ea8dba06
......@@ -365,12 +365,12 @@ module.exports = (function() {
joinQuery = ""
options = options || {}
options.table = table = Array.isArray(tableName) ? tableName.map(function(t) { return this.quoteIdentifier(t)}.bind(this)).join(", ") : this.quoteIdentifier(tableName)
options.table = table = Array.isArray(tableName) ? tableName.map(function(t) { return this.quoteIdentifiers(t) }.bind(this)).join(", ") : this.quoteIdentifiers(tableName)
options.attributes = options.attributes && options.attributes.map(function(attr){
if(Array.isArray(attr) && attr.length == 2) {
return [attr[0], this.quoteIdentifier(attr[1])].join(' as ')
} else {
return attr.indexOf(Utils.TICK_CHAR) < 0 ? this.quoteIdentifiers(attr) : attr
return attr.indexOf(Utils.TICK_CHAR) < 0 && attr.indexOf('"') < 0 ? this.quoteIdentifiers(attr) : attr
}
}.bind(this)).join(", ")
options.attributes = options.attributes || '*'
......@@ -615,6 +615,14 @@ module.exports = (function() {
return joins;
},
arrayValue: function(value, key, _key){
var _value = null;
if (value.length === 0) { value = [null] }
_value = "(" + value.map(function(v) { return this.escape(v) }.bind(this)).join(',') + ")"
return [_key, _value].join(" IN ")
},
/*
Takes a hash and transforms it into a mysql where condition: {key: value, key2: value2} ==> key=value AND key2=value2
The values are transformed by the relevant datatype.
......@@ -634,11 +642,7 @@ module.exports = (function() {
, _value = null
if (Array.isArray(value)) {
// is value an array?
if (value.length === 0) { value = [null] }
_value = "(" + value.map(function(v) { return this.escape(v) }.bind(this)).join(',') + ")"
result.push([_key, _value].join(" IN "))
result.push(this.arrayValue(value, key, _key, dao))
} else if ((value) && (typeof value == 'object') && !(value instanceof Date)) {
if (!!value.join) {
//using as sentinel for join column => value
......
......@@ -144,6 +144,27 @@ module.exports = (function() {
attributes: attrString.join(', ') })
},
arrayValue: function(value, key, _key, factory){
if (value.length === 0) { value = [null] }
var col = null, coltype = null
// Special conditions for searching within an array column type
var _realKey = key.split('.').pop()
if (!!factory && !!factory.rawAttributes[_realKey]) {
col = factory.rawAttributes[_realKey]
coltype = col.type
if(coltype && !(typeof coltype == 'string')) {
coltype = coltype.toString();
}
}
if ( col && ((!!coltype && coltype.match(/\[\]$/) !== null) || (col.toString().match(/\[\]$/) !== null))) {
_value = 'ARRAY[' + value.map(this.escape).join(',') + ']::' + (!!col.type ? col.type : col.toString())
return [_key, _value].join(" && ")
} else {
_value = "(" + value.map(this.escape).join(',') + ")"
return [_key, _value].join(" IN ")
}
},
removeColumnQuery: function(tableName, attributeName) {
var query = "ALTER TABLE <%= tableName %> DROP COLUMN <%= attributeName %>;"
return Utils._.template(query)({
......@@ -230,100 +251,6 @@ module.exports = (function() {
})
},
selectQuery: function(tableName, options, factory) {
var query = "SELECT <%= attributes %> FROM <%= table %>",
table = null
options = options || {}
options.table = table = Array.isArray(tableName) ? tableName.map(function(t) { return this.quoteIdentifiers(t) }.bind(this)).join(", ") : this.quoteIdentifiers(tableName)
options.attributes = options.attributes && options.attributes.map(function(attr) {
if (Array.isArray(attr) && attr.length === 2) {
return [attr[0], this.quoteIdentifier(attr[1])].join(' as ')
} else {
return attr.indexOf('"') < 0 ? this.quoteIdentifiers(attr) : attr
}
}.bind(this)).join(", ")
options.attributes = options.attributes || '*'
if (options.include) {
var optAttributes = options.attributes === '*' ? [options.table + '.*'] : [options.attributes]
options.include.forEach(function(include) {
var attributes = include.attributes.map(function(attr) {
return this.quoteIdentifier(include.as) + "." + this.quoteIdentifier(attr) + " AS " + this.quoteIdentifier(include.as + "." + attr, true)
}.bind(this))
optAttributes = optAttributes.concat(attributes)
var joinQuery = ' LEFT OUTER JOIN <%= table %> AS <%= as %> ON <%= tableLeft %>.<%= attrLeft %> = <%= tableRight %>.<%= attrRight %>'
if (!include.association.connectorDAO) {
var primaryKeysLeft = ((include.association.associationType === 'BelongsTo') ? Object.keys(include.association.target.primaryKeys) : Object.keys(include.association.source.primaryKeys))
query += Utils._.template(joinQuery)({
table: this.quoteIdentifiers(include.daoFactory.tableName),
as: this.quoteIdentifier(include.as),
tableLeft: this.quoteIdentifier((include.association.associationType === 'BelongsTo') ? include.as : tableName),
attrLeft: this.quoteIdentifier(((primaryKeysLeft.length !== 1) ? 'id' : primaryKeysLeft[0])),
tableRight: this.quoteIdentifiers((include.association.associationType === 'BelongsTo') ? tableName : include.as),
attrRight: this.quoteIdentifier(include.association.identifier)
})
} else {
var primaryKeysSource = Object.keys(include.association.source.primaryKeys)
, primaryKeysTarget = Object.keys(include.association.target.primaryKeys)
query += Utils._.template(joinQuery)({
table: this.quoteIdentifiers(include.association.connectorDAO.tableName),
as: this.quoteIdentifier(include.association.connectorDAO.tableName),
tableLeft: this.quoteIdentifiers(tableName),
attrLeft: this.quoteIdentifier(((!include.association.source.hasPrimaryKeys || primaryKeysSource.length !== 1) ? 'id' : primaryKeysSource[0])),
tableRight: this.quoteIdentifiers(include.association.connectorDAO.tableName),
attrRight: this.quoteIdentifier(include.association.identifier)
})
query += Utils._.template(joinQuery)({
table: this.quoteIdentifiers(include.daoFactory.tableName),
as: this.quoteIdentifier(include.as),
tableLeft: this.quoteIdentifiers(include.as),
attrLeft: this.quoteIdentifier(((!include.association.target.hasPrimaryKeys || primaryKeysTarget.length !== 1) ? 'id' : primaryKeysTarget[0])),
tableRight: this.quoteIdentifiers(include.association.connectorDAO.tableName),
attrRight: this.quoteIdentifier(include.association.foreignIdentifier)
})
}
}.bind(this))
options.attributes = optAttributes.join(', ')
}
if(options.hasOwnProperty('where')) {
options.where = this.getWhereConditions(options.where, tableName, factory)
query += " WHERE <%= where %>"
}
if(options.group) {
options.group = Array.isArray(options.group) ? options.group.map(function (t) { return this.quote(t) }.bind(this)).join(', ') : options.group
query += " GROUP BY <%= group %>"
}
if(options.order) {
options.order = Array.isArray(options.order) ? options.order.map(function (t) { return this.quote(t) }.bind(this)).join(', ') : options.order
query += " ORDER BY <%= order %>"
}
if (!(options.include && (options.limit === 1))) {
if (options.limit) {
query += " LIMIT <%= limit %>"
}
if (options.offset) {
query += " OFFSET <%= offset %>"
}
}
query += ";"
return Utils._.template(query)(options)
},
insertQuery: function(tableName, attrValueHash, attributes) {
attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull)
......@@ -522,96 +449,18 @@ module.exports = (function() {
})
},
getWhereConditions: function(smth, tableName, factory) {
var result = null
, where = {}
if (Utils.isHash(smth)) {
smth = Utils.prependTableNameToHash(tableName, smth)
result = this.hashToWhereConditions(smth, factory)
} else if (typeof smth === 'number') {
var primaryKeys = !!factory ? Object.keys(factory.primaryKeys) : []
if (primaryKeys.length > 0) {
// Since we're just a number, assume only the first key
primaryKeys = primaryKeys[0]
} else {
primaryKeys = 'id'
addLimitAndOffset: function(options, query){
if (!(options.include && (options.limit === 1))) {
if (options.limit) {
query += " LIMIT " + options.limit
}
where[primaryKeys] = smth
smth = Utils.prependTableNameToHash(tableName, where)
result = this.hashToWhereConditions(smth)
} else if (typeof smth === "string") {
result = smth
}
else if (Array.isArray(smth)) {
result = Utils.format(smth, "postgres")
}
return result
},
hashToWhereConditions: function(hash, factory) {
var result = []
for (var key in hash) {
var value = hash[key]
//handle qualified key names
var _key = this.quoteIdentifiers(key)
, _value = null
if (Array.isArray(value)) {
if (value.length === 0) { value = [null] }
var col = null, coltype = null
// Special conditions for searching within an array column type
var _realKey = key.split('.').pop()
if (!!factory && !!factory.rawAttributes[_realKey]) {
col = factory.rawAttributes[_realKey]
coltype = col.type
if(coltype && !(typeof coltype == 'string')) {
coltype = coltype.toString();
}
}
if ( col && ((!!coltype && coltype.match(/\[\]$/) !== null) || (col.toString().match(/\[\]$/) !== null))) {
_value = 'ARRAY[' + value.map(this.escape).join(',') + ']::' + (!!col.type ? col.type : col.toString())
result.push([_key, _value].join(" && "))
} else {
_value = "(" + value.map(this.escape).join(',') + ")"
result.push([_key, _value].join(" IN "))
}
}
else if ((value) && (typeof value === "object")) {
if (!!value.join) {
//using as sentinel for join column => value
_value = this.quoteIdentifiers(value.join)
result.push([_key, _value].join("="))
} else {
for (var logic in value) {
var logicResult = Utils.getWhereLogic(logic)
if (logic === "IN" || logic === "NOT IN") {
var values = Array.isArray(where[i][ii]) ? where[i][ii] : [where[i][ii]]
_where[_where.length] = i + ' ' + logic + ' (' + values.map(function(){ return '?' }).join(',') + ')'
_whereArgs = _whereArgs.concat(values)
}
else if (logicResult === "BETWEEN" || logicResult === "NOT BETWEEN") {
_value = this.escape(value[logic][0])
var _value2 = this.escape(value[logic][1])
result.push(' (' + _key + ' ' + logicResult + ' ' + _value + ' AND ' + _value2 + ') ')
} else {
_value = this.escape(value[logic])
result.push([_key, _value].join(' ' + logicResult + ' '))
}
}
}
} else {
_value = this.escape(value)
result.push((_value == 'NULL') ? _key + " IS NULL" : [_key, _value].join("="))
if (options.offset) {
query += " OFFSET " + options.offset
}
}
return result.join(' AND ')
return query;
},
attributesToSQL: function(attributes) {
......
......@@ -21,36 +21,27 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
this.sequelize.sync({ force: true }).success(function() {
User.bulkCreate([{
id: 101,
username: 'leia'
}, {
id: 102,
username: 'vader'
}]).success(function() {
Project.bulkCreate([{
id: 201,
UserId: 101,
UserId: 1,
title: 'republic'
},{
id: 202,
UserId: 102,
title: 'empire'
}]).success(function() {
Task.bulkCreate([{
id: 301,
ProjectId: 201,
ProjectId: 1,
title: 'fight empire'
},{
id: 302,
ProjectId: 201,
ProjectId: 1,
title: 'stablish republic'
},{
id: 303,
ProjectId: 202,
ProjectId: 2,
title: 'destroy rebel alliance'
},{
id: 304,
ProjectId: 202,
ProjectId: 2,
title: 'rule everything'
}]).success(function() {
Task.findAll({
......@@ -87,42 +78,34 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
this.sequelize.sync({ force: true }).success(function() {
User.bulkCreate([{
id: 101,
username: 'leia'
}, {
id: 102,
username: 'vader'
}]).success(function() {
Project.bulkCreate([{
id: 201,
UserId: 101,
UserId: 1,
title: 'republic'
},{
id: 202,
UserId: 102,
UserId: 2,
title: 'empire'
}]).success(function() {
Task.bulkCreate([{
id: 301,
ProjectId: 201,
ProjectId: 1,
title: 'fight empire'
},{
id: 302,
ProjectId: 201,
ProjectId: 1,
title: 'stablish republic'
},{
id: 303,
ProjectId: 202,
ProjectId: 2,
title: 'destroy rebel alliance'
},{
id: 304,
ProjectId: 202,
ProjectId: 2,
title: 'rule everything'
}]).success(function() {
Task.findAll({
where: {
'project.user.username': 'leia',
'project.user.id': 101
'project.user.id': 1
}
}).success(function(tasks){
try{
......@@ -154,36 +137,28 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
this.sequelize.sync({ force: true }).success(function() {
User.bulkCreate([{
id: 101,
username: 'leia'
}, {
id: 102,
username: 'vader'
}]).success(function() {
Project.bulkCreate([{
id: 201,
UserId: 101,
UserId: 1,
title: 'republic'
},{
id: 202,
UserId: 102,
UserId: 2,
title: 'empire'
}]).success(function() {
Task.bulkCreate([{
id: 301,
ProjectId: 201,
ProjectId: 1,
title: 'fight empire'
},{
id: 302,
ProjectId: 201,
ProjectId: 1,
title: 'stablish republic'
},{
id: 303,
ProjectId: 202,
ProjectId: 2,
title: 'destroy rebel alliance'
},{
id: 304,
ProjectId: 202,
ProjectId: 2,
title: 'rule everything'
}]).success(function() {
User.findAll({
......@@ -214,25 +189,21 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
this.sequelize.sync({ force: true }).success(function() {
User.bulkCreate([{
id: 101,
username: 'leia'
}, {
id: 102,
username: 'vader'
}]).success(function() {
Project.bulkCreate([{
id: 201,
title: 'republic'
},{
id: 202,
title: 'empire'
}]).success(function() {
User.find(101).success(function(user){
Project.find(201).success(function(project){
User.find(1).success(function(user){
Project.find(1).success(function(project){
user.setProjects([project]).success(function(){
User.find(102).success(function(user){
Project.find(202).success(function(project){
User.find(2).success(function(user){
Project.find(2).success(function(project){
user.setProjects([project]).success(function(){
User.findAll({
where: {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!