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

Commit 6a3b49f0 by Sascha Depold

correctly scoping table names and attributes in accents

1 parent 0fc1fd9b
...@@ -70,6 +70,8 @@ ...@@ -70,6 +70,8 @@
- remove the usage of an array => Sequelize.chainQueries({save: a}, {destroy: b}, callback) - remove the usage of an array => Sequelize.chainQueries({save: a}, {destroy: b}, callback)
# v0.4.4 - in development # # v0.4.4 - in development #
- TODO: Wrap queries correctly using `foo` - select now supports array usage of fields
- select now supports hash usage of where
- Wrapped queries correctly using `foo`
- TODO: Add method for adding and deleting single associations - TODO: Add method for adding and deleting single associations
- TODO: Add option for using camel case or underscorízed tablenames/table fields - TODO: Add option for using camel case or underscorízed tablenames/table fields
\ No newline at end of file
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
*/ */
var Sequelize = require(__dirname + "/../../lib/sequelize/Sequelize").Sequelize, var Sequelize = require(__dirname + "/../../lib/sequelize/Sequelize").Sequelize,
sequelize = new Sequelize("sequelize_test", "root", null, {disableLogging: true}), sequelize = new Sequelize("sequelize_test", "root", null, {disableLogging: false}),
Person = sequelize.define('person', { Person = sequelize.define('person', {
name: Sequelize.STRING name: Sequelize.STRING
}), }),
...@@ -31,7 +31,7 @@ Sequelize.chainQueries([{drop: sequelize}, {sync: sequelize}], function() { ...@@ -31,7 +31,7 @@ Sequelize.chainQueries([{drop: sequelize}, {sync: sequelize}], function() {
sister = new Person({ name: 'Sister' }), sister = new Person({ name: 'Sister' }),
pet = new Pet({ name: 'Bob' }) pet = new Pet({ name: 'Bob' })
Sequelize.chainQueries([{save: person}, {save: mother}, {save: father}, {save: brother}, {save: sister}, {save: pet}], function() { Sequelize.chainQueries({save: [person, mother, father, brother, sister, pet]}, function() {
person.setMother(mother, function(mom) { Sequelize.Helper.log('my mom: ' + mom.name) }) person.setMother(mother, function(mom) { Sequelize.Helper.log('my mom: ' + mom.name) })
person.setFather(father, function(dad) { Sequelize.Helper.log('my dad: ' + dad.name) }) person.setFather(father, function(dad) { Sequelize.Helper.log('my dad: ' + dad.name) })
person.setBrothers([brother], function(bros) { Sequelize.Helper.log("ma bro: " + bros[0].name)}) person.setBrothers([brother], function(bros) { Sequelize.Helper.log("ma bro: " + bros[0].name)})
......
...@@ -59,7 +59,7 @@ module.exports.Factory = function(Sequelize, sequelize) { ...@@ -59,7 +59,7 @@ module.exports.Factory = function(Sequelize, sequelize) {
if(_options.force || !this.hasFetchedAssociationFor(assocName)) { if(_options.force || !this.hasFetchedAssociationFor(assocName)) {
var Association = sequelize.tables[Sequelize.Helper.SQL.manyToManyTableName(assocName, backAssocName)].klass, var Association = sequelize.tables[Sequelize.Helper.SQL.manyToManyTableName(assocName, backAssocName)].klass,
assocNameAsTableIdentifier = Sequelize.Helper.SQL.asTableIdentifier(backAssocName), assocNameAsTableIdentifier = Sequelize.Helper.SQL.asTableIdentifier(backAssocName),
whereConditions = [assocNameAsTableIdentifier, this.id].join("=") whereConditions = ['`'+assocNameAsTableIdentifier+'`', this.id].join("=")
Association.findAll({ where: whereConditions }, function(result) { Association.findAll({ where: whereConditions }, function(result) {
if(result.length > 0) { if(result.length > 0) {
...@@ -67,7 +67,7 @@ module.exports.Factory = function(Sequelize, sequelize) { ...@@ -67,7 +67,7 @@ module.exports.Factory = function(Sequelize, sequelize) {
return resultSet[Sequelize.Helper.SQL.asTableIdentifier(assocName)] return resultSet[Sequelize.Helper.SQL.asTableIdentifier(assocName)]
}) })
table2.findAll({where: "id IN (" + ids.join(",") + ")"}, function(objects) { table2.findAll({where: "`id` IN (" + ids.join(",") + ")"}, function(objects) {
self.setAssociationDataFor(assocName, objects) self.setAssociationDataFor(assocName, objects)
if(_callback) _callback(objects) if(_callback) _callback(objects)
}) })
...@@ -99,8 +99,9 @@ module.exports.Factory = function(Sequelize, sequelize) { ...@@ -99,8 +99,9 @@ module.exports.Factory = function(Sequelize, sequelize) {
else { else {
var deleteOptions = { var deleteOptions = {
table: Association.tableName, table: Association.tableName,
where: Sequelize.Helper.SQL.asTableIdentifier(assocName) + " IN (" + obsoleteIds.join(",") + ") AND " + where:
Sequelize.Helper.SQL.asTableIdentifier(backAssocName) + " = " + self.id, "`" + Sequelize.Helper.SQL.asTableIdentifier(assocName) + "` IN (" + obsoleteIds.join(",") + ") AND " +
"`" + Sequelize.Helper.SQL.asTableIdentifier(backAssocName) + "` = " + self.id,
limit: null limit: null
} }
sequelize.query( Sequelize.sqlQueryFor('delete', deleteOptions), function(){ callback(obsoleteIds) } ) sequelize.query( Sequelize.sqlQueryFor('delete', deleteOptions), function(){ callback(obsoleteIds) } )
...@@ -142,7 +143,7 @@ module.exports.Factory = function(Sequelize, sequelize) { ...@@ -142,7 +143,7 @@ module.exports.Factory = function(Sequelize, sequelize) {
self = this self = this
if(_options.refetchAssociations || !this.hasFetchedAssociationFor(accessKey)) { if(_options.refetchAssociations || !this.hasFetchedAssociationFor(accessKey)) {
var whereConditions = [Sequelize.Helper.SQL.asTableIdentifier(assocName), this.id].join("=") var whereConditions = ['`'+Sequelize.Helper.SQL.asTableIdentifier(assocName)+'`', this.id].join("=")
table2.findAll({where: whereConditions}, function(result) { table2.findAll({where: whereConditions}, function(result) {
self.setAssociationDataFor(accessKey, result) self.setAssociationDataFor(accessKey, result)
if(_callback) _callback(result) if(_callback) _callback(result)
......
module.exports = function(instance) { module.exports = function(instance) {
instance.Hash = { instance.Hash = {
isHash: function(obj) {
return (typeof obj == 'object') && !obj.hasOwnProperty('length')
},
forEach: function(object, func) { forEach: function(object, func) {
instance.Hash.keys(object).forEach(function(key) { instance.Hash.keys(object).forEach(function(key) {
func(object[key], key, object) func(object[key], key, object)
......
...@@ -58,15 +58,18 @@ module.exports = function(instance) { ...@@ -58,15 +58,18 @@ module.exports = function(instance) {
options = options || {} options = options || {}
instance.Hash.forEach(actualValues, function(value, key) { instance.Hash.forEach(actualValues, function(value, key) {
var dataType = object.table.attributes[key] var dataType = object.table.attributes[key],
result.push([key, self.SQL.transformValueByDataType(value, dataType)].join(" = ")) _key = ['', key, ''].join('`')
result.push([_key, self.SQL.transformValueByDataType(value, dataType)].join(" = "))
}) })
return result.join(options.seperator || ", ") return result.join(options.seperator || ", ")
}, },
fieldsForInsertQuery: function(object) { fieldsForInsertQuery: function(object) {
return instance.Hash.keys(object.values).join(", ") return instance.Hash.keys(object.values).map(function(value) {
return ['', value, ''].join('`')
}).join(", ")
}, },
transformValueByDataType: function(value, attributeOptions) { transformValueByDataType: function(value, attributeOptions) {
...@@ -90,17 +93,39 @@ module.exports = function(instance) { ...@@ -90,17 +93,39 @@ module.exports = function(instance) {
return ("'" + value + "'") return ("'" + value + "'")
}, },
getDataTypeForValue: function(value) {
switch(typeof value) {
case 'number':
return (value.toString().indexOf('.') > -1) ? instance.Sequelize.FLOAT : instance.Sequelize.INTEGER
break
case 'boolean':
return instance.Sequelize.BOOLEAN
break
case 'object':
return (value.getMilliseconds) ? instance.Sequelize.DATE : "WTF!"
break
default:
return instance.Sequelize.TEXT
break
}
},
hashToWhereConditions: function(conditions, attributes) { hashToWhereConditions: function(conditions, attributes) {
attributes = attributes || {}
if(typeof conditions == 'number') if(typeof conditions == 'number')
return ('id = ' + conditions) return ('`id`=' + conditions)
else { else {
var result = [] return instance.Hash.map(conditions, function(value, key) {
instance.Hash.forEach(conditions, function(value, key) { var dataType = attributes[key] || {type:instance.SQL.getDataTypeForValue(value)},
var _value = instance.SQL.transformValueByDataType(value, attributes[key]) _value = instance.SQL.transformValueByDataType(value, dataType),
if(_value == 'NULL') result.push(key + " IS NULL") _key = ['', key, ''].join('`')
else result.push(key + "=" + _value)
}) if(_value == 'NULL')
return result.join(" AND ") return _key + " IS NULL"
else
return [_key, _value].join("=")
}).join(" AND ")
} }
} }
} }
......
...@@ -28,17 +28,28 @@ var classMethods = { ...@@ -28,17 +28,28 @@ var classMethods = {
sqlQueryFor: function(command, values) { sqlQueryFor: function(command, values) {
var query = null var query = null
if(values.hasOwnProperty('fields') && Array.isArray(values.fields))
values.fields = values.fields.map(function(field) { return ['', field, ''].join('`') }).join(", ")
switch(command) { switch(command) {
case 'create': case 'create':
query = "CREATE TABLE IF NOT EXISTS %{table} (%{fields})" query = "CREATE TABLE IF NOT EXISTS `%{table}` (%{fields})"
break break
case 'drop': case 'drop':
query = "DROP TABLE IF EXISTS %{table}" query = "DROP TABLE IF EXISTS `%{table}`"
break break
case 'select': case 'select':
values.fields = values.fields || "*" values.fields = values.fields || '*'
query = "SELECT %{fields} FROM %{table}"
if(values.where) query += " WHERE %{where}" query = "SELECT %{fields} FROM `%{table}`"
if(values.where) {
if(Sequelize.Helper.Hash.isHash(values.where))
values.where = Sequelize.Helper.SQL.hashToWhereConditions(values.where)
query += " WHERE %{where}"
}
if(values.order) query += " ORDER BY %{order}" if(values.order) query += " ORDER BY %{order}"
if(values.group) query += " GROUP BY %{group}" if(values.group) query += " GROUP BY %{group}"
if(values.limit) { if(values.limit) {
...@@ -47,14 +58,21 @@ var classMethods = { ...@@ -47,14 +58,21 @@ var classMethods = {
} }
break break
case 'insert': case 'insert':
query = "INSERT INTO %{table} (%{fields}) VALUES (%{values})" query = "INSERT INTO `%{table}` (%{fields}) VALUES (%{values})"
break break
case 'update': case 'update':
query = "UPDATE %{table} SET %{values} WHERE id = %{id}" if(Sequelize.Helper.Hash.isHash(values.values))
values.values = Sequelize.Helper.SQL.hashToWhereConditions(values.values)
query = "UPDATE `%{table}` SET %{values} WHERE `id`=%{id}"
break break
case 'delete': case 'delete':
query = "DELETE FROM %{table} WHERE %{where}" if(Sequelize.Helper.Hash.isHash(values.where))
values.where = Sequelize.Helper.SQL.hashToWhereConditions(values.where)
query = "DELETE FROM `%{table}` WHERE %{where}"
if(typeof values.limit == 'undefined') query += " LIMIT 1" if(typeof values.limit == 'undefined') query += " LIMIT 1"
else if(values.limit != null) query += " LIMIT " + values.limit
break break
} }
......
...@@ -85,9 +85,9 @@ exports.SequelizeTable = function(Sequelize, sequelize, tableName, attributes, o ...@@ -85,9 +85,9 @@ exports.SequelizeTable = function(Sequelize, sequelize, tableName, attributes, o
/* returns: table, error */ /* returns: table, error */
sync: function(callback) { sync: function(callback) {
var fields = ["id INT NOT NULL auto_increment PRIMARY KEY"] var fields = ["`id` INT NOT NULL auto_increment PRIMARY KEY"]
Sequelize.Helper.Hash.forEach(table.attributes, function(options, name) { Sequelize.Helper.Hash.forEach(table.attributes, function(options, name) {
fields.push(name + " " + options.type) fields.push('`' + name + "` " + options.type)
}) })
sequelize.query( sequelize.query(
...@@ -130,12 +130,11 @@ exports.SequelizeTable = function(Sequelize, sequelize, tableName, attributes, o ...@@ -130,12 +130,11 @@ exports.SequelizeTable = function(Sequelize, sequelize, tableName, attributes, o
find: function(conditions, options, callback) { find: function(conditions, options, callback) {
// use the second param as callback if it is no object (hash) // use the second param as callback if it is no object (hash)
var _callback = ((typeof options == 'object') ? callback : options) var _callback = ((typeof options == 'object') ? callback : options)
sequelize.query( sequelize.query(
Sequelize.sqlQueryFor('select', { Sequelize.sqlQueryFor('select', {
table: table.tableName, table: table.tableName,
where: Sequelize.Helper.SQL.hashToWhereConditions(conditions, table.attributes), where: Sequelize.Helper.SQL.hashToWhereConditions(conditions, table.attributes),
order: 'id DESC', order: '`id` DESC',
limit: 1 limit: 1
}), function(result) { }), function(result) {
var _result = result[0] ? table.sqlResultToObject(result[0]) : null var _result = result[0] ? table.sqlResultToObject(result[0]) : null
...@@ -231,7 +230,7 @@ exports.SequelizeTable = function(Sequelize, sequelize, tableName, attributes, o ...@@ -231,7 +230,7 @@ exports.SequelizeTable = function(Sequelize, sequelize, tableName, attributes, o
else else
Factory.addOneToOneMethods(_table, table, assocName, backAssociation.name) Factory.addOneToOneMethods(_table, table, assocName, backAssociation.name)
// TODO: check if the following line is not needed; specs r failing // TODO: check if the following line is not needed; specs r failing
// backAssociation.name = assocName // backAssociation.name = assocName
// end - overwrite the association of the before defined hasOne or hasMany relation, to fit the belongsTo foreign keys // end - overwrite the association of the before defined hasOne or hasMany relation, to fit the belongsTo foreign keys
......
...@@ -33,5 +33,11 @@ module.exports = { ...@@ -33,5 +33,11 @@ module.exports = {
'Hash: without': function(assert) { 'Hash: without': function(assert) {
var hash = {a: 1, b: 2} var hash = {a: 1, b: 2}
assert.eql(h.Hash.without(hash, ["a"]), {b: 2}) assert.eql(h.Hash.without(hash, ["a"]), {b: 2})
},
'Hash: isHash': function(assert) {
assert.eql(h.Hash.isHash([1,2]), false)
assert.eql(h.Hash.isHash(1), false)
assert.eql(h.Hash.isHash("asd"), false)
assert.eql(h.Hash.isHash({a:1}), true)
} }
} }
\ No newline at end of file
...@@ -38,7 +38,7 @@ module.exports = { ...@@ -38,7 +38,7 @@ module.exports = {
var s = new Sequelize('sequelize_test', 'test', 'test') var s = new Sequelize('sequelize_test', 'test', 'test')
var Day = s.define('Day', { name: Sequelize.TEXT }) var Day = s.define('Day', { name: Sequelize.TEXT })
var result = h.SQL.fieldsForInsertQuery(new Day({name: 'asd'})) var result = h.SQL.fieldsForInsertQuery(new Day({name: 'asd'}))
assert.eql(result, 'name, createdAt, updatedAt') assert.eql(result, '`name`, `createdAt`, `updatedAt`')
}, },
'SQL: transformValueByDataType': function(assert) { 'SQL: transformValueByDataType': function(assert) {
assert.equal(h.SQL.transformValueByDataType('asd', {type: Sequelize.STRING}), "'asd'") assert.equal(h.SQL.transformValueByDataType('asd', {type: Sequelize.STRING}), "'asd'")
...@@ -62,11 +62,19 @@ module.exports = { ...@@ -62,11 +62,19 @@ module.exports = {
var s = new Sequelize('sequelize_test', 'test', 'test') var s = new Sequelize('sequelize_test', 'test', 'test')
var Day = s.define('Day', { name: Sequelize.TEXT }) var Day = s.define('Day', { name: Sequelize.TEXT })
var day = new Day({name: 'asd'}) var day = new Day({name: 'asd'})
assert.equal(h.SQL.hashToWhereConditions(5, Day.attributes), 'id = 5') assert.equal(h.SQL.hashToWhereConditions(5, Day.attributes), '`id`=5')
assert.equal(h.SQL.hashToWhereConditions({name: 'asd'}, Day.attributes), "name='asd'") assert.equal(h.SQL.hashToWhereConditions({name: 'asd'}, Day.attributes), "`name`='asd'")
}, },
'SQL: addPrefix': function(assert) { 'SQL: addPrefix': function(assert) {
assert.equal(h.SQL.addPrefix('foo', 'bar', true), 'fooBar') assert.equal(h.SQL.addPrefix('foo', 'bar', true), 'fooBar')
assert.equal(h.SQL.addPrefix('foo', 'bar', false), 'fooBars') assert.equal(h.SQL.addPrefix('foo', 'bar', false), 'fooBars')
},
'getDataTypeForValue': function(assert) {
var fct = h.SQL.getDataTypeForValue
assert.equal(fct(1), Sequelize.INTEGER)
assert.equal(fct(1.2), Sequelize.FLOAT)
assert.equal(fct("1"), Sequelize.TEXT)
assert.equal(fct(new Date()), Sequelize.DATE)
assert.equal(fct(true), Sequelize.BOOLEAN)
} }
} }
\ No newline at end of file
...@@ -4,35 +4,39 @@ var s = new Sequelize('sequelize_test', 'test', 'test') ...@@ -4,35 +4,39 @@ var s = new Sequelize('sequelize_test', 'test', 'test')
module.exports = { module.exports = {
'sqlQueryFor: create': function(assert) { 'sqlQueryFor: create': function(assert) {
var query = Sequelize.sqlQueryFor('create', { table: 'Foo', fields: 'a INT' }) var query = Sequelize.sqlQueryFor('create', { table: 'Foo', fields: 'a INT' })
assert.equal(query, "CREATE TABLE IF NOT EXISTS Foo (a INT)") assert.equal(query, "CREATE TABLE IF NOT EXISTS `Foo` (a INT)")
}, },
'sqlQueryFor: drop': function(assert) { 'sqlQueryFor: drop': function(assert) {
var query = Sequelize.sqlQueryFor('drop', { table: 'Foo' }) var query = Sequelize.sqlQueryFor('drop', { table: 'Foo' })
assert.equal(query, "DROP TABLE IF EXISTS Foo") assert.equal(query, "DROP TABLE IF EXISTS `Foo`")
}, },
'sqlQueryFor: select': function(assert) { 'sqlQueryFor: select': function(assert) {
assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo'}), "SELECT * FROM Foo") assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo'}), "SELECT * FROM `Foo`")
assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo', fields: 'id'}), "SELECT id FROM Foo") assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo', fields: ['id']}), "SELECT `id` FROM `Foo`")
assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo', where: 'id = 1'}), "SELECT * FROM Foo WHERE id = 1") assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo', where: {id: 1}}), "SELECT * FROM `Foo` WHERE `id`=1")
assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo', order: 'id DESC'}), "SELECT * FROM Foo ORDER BY id DESC") assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo', order: 'id DESC'}), "SELECT * FROM `Foo` ORDER BY id DESC")
assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo', group: 'name'}), "SELECT * FROM Foo GROUP BY name") assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo', group: 'name'}), "SELECT * FROM `Foo` GROUP BY name")
assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo', limit: 1}), "SELECT * FROM Foo LIMIT 1") assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo', limit: 1}), "SELECT * FROM `Foo` LIMIT 1")
assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo', offset: 10, limit: 1}), "SELECT * FROM Foo LIMIT 10, 1") assert.equal(Sequelize.sqlQueryFor('select', { table: 'Foo', offset: 10, limit: 1}), "SELECT * FROM `Foo` LIMIT 10, 1")
}, },
'sqlQueryFor: insert': function(assert) { 'sqlQueryFor: insert': function(assert) {
var query = Sequelize.sqlQueryFor('insert', { table: 'Foo', fields: 'foo', values: "'bar'" }) var query = Sequelize.sqlQueryFor('insert', { table: 'Foo', fields: ['foo'], values: "'bar'" })
assert.equal(query, "INSERT INTO Foo (foo) VALUES ('bar')") assert.equal(query, "INSERT INTO `Foo` (`foo`) VALUES ('bar')")
}, },
'sqlQueryFor: update': function(assert) { 'sqlQueryFor: update': function(assert) {
var query = Sequelize.sqlQueryFor('update', { table: 'Foo', values: "foo=1", id: 2 }) var query = Sequelize.sqlQueryFor('update', { table: 'Foo', values: {foo : 1}, id: 2 })
assert.equal(query, "UPDATE Foo SET foo=1 WHERE id = 2") assert.equal(query, "UPDATE `Foo` SET `foo`=1 WHERE `id`=2")
}, },
'sqlQueryFor: delete': function(assert) { 'sqlQueryFor: delete': function(assert) {
var query = Sequelize.sqlQueryFor('delete', {table: 'Foo', where: "id=2"}) var query = Sequelize.sqlQueryFor('delete', {table: 'Foo', where: {id: 2}})
assert.equal(query, "DELETE FROM Foo WHERE id=2 LIMIT 1") assert.equal(query, "DELETE FROM `Foo` WHERE `id`=2 LIMIT 1")
}, },
'sqlQueryFor: delete wihtout limit': function(assert) { 'sqlQueryFor: delete without limit': function(assert) {
var query = Sequelize.sqlQueryFor('delete', {table: 'Foo', where: "id=2", limit: null}) var query = Sequelize.sqlQueryFor('delete', {table: 'Foo', where: {id: 2}, limit: null})
assert.equal(query, "DELETE FROM Foo WHERE id=2") assert.equal(query, "DELETE FROM `Foo` WHERE `id`=2")
},
'sqlQueryFor: delete with limit': function(assert) {
var query = Sequelize.sqlQueryFor('delete', {table: 'Foo', where: {id: 2}, limit: 10})
assert.equal(query, "DELETE FROM `Foo` WHERE `id`=2 LIMIT 10")
} }
} }
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!