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

Commit 295d0c25 by Sascha Depold

Merge branch 'blob' of https://github.com/janmeier/sequelize into janmeier-blob

2 parents 6a831c54 f70f068e
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
- [FEATURE] bulkCreate() now has a third argument which gives you the ability to validate each row before attempting to bulkInsert [#797](https://github.com/sequelize/sequelize/pull/797). thanks to durango - [FEATURE] bulkCreate() now has a third argument which gives you the ability to validate each row before attempting to bulkInsert [#797](https://github.com/sequelize/sequelize/pull/797). thanks to durango
- [FEATURE] Added `isDirty` to model instances. [#798](https://github.com/sequelize/sequelize/pull/798). Thanks to mstorgaard - [FEATURE] Added `isDirty` to model instances. [#798](https://github.com/sequelize/sequelize/pull/798). Thanks to mstorgaard
- [FEATURE] Added possibility to use env variable for the database connection. [#784](https://github.com/sequelize/sequelize/pull/784). Thanks to sykopomp. - [FEATURE] Added possibility to use env variable for the database connection. [#784](https://github.com/sequelize/sequelize/pull/784). Thanks to sykopomp.
- [FEATURE] Blob support. janmeier
- [REFACTORING] hasMany now uses a single SQL statement when creating and destroying associations, instead of removing each association seperately [690](https://github.com/sequelize/sequelize/pull/690). Inspired by [#104](https://github.com/sequelize/sequelize/issues/104). janmeier - [REFACTORING] hasMany now uses a single SQL statement when creating and destroying associations, instead of removing each association seperately [690](https://github.com/sequelize/sequelize/pull/690). Inspired by [#104](https://github.com/sequelize/sequelize/issues/104). janmeier
- [REFACTORING] Consistent handling of offset across dialects. Offset is now always applied, and limit is set to max table size of not limit is given [#725](https://github.com/sequelize/sequelize/pull/725). janmeier - [REFACTORING] Consistent handling of offset across dialects. Offset is now always applied, and limit is set to max table size of not limit is given [#725](https://github.com/sequelize/sequelize/pull/725). janmeier
- [REFACTORING] Moved Jasmine to Buster and then Buster to Mocha + Chai. sdepold and durango - [REFACTORING] Moved Jasmine to Buster and then Buster to Mocha + Chai. sdepold and durango
......
var STRING = function(length, binary) { var STRING = function(length, binary) {
if (this instanceof STRING) { if (this instanceof STRING) {
this._binary = !!binary; this._binary = !!binary
if (typeof length === 'number') { if (typeof length === 'number') {
this._length = length; this._length = length
} else { } else {
this._length = 255; this._length = 255
} }
} else { } else {
return new STRING(length, binary); return new STRING(length, binary)
} }
}; }
STRING.prototype = { STRING.prototype = {
get BINARY() { get BINARY() {
this._binary = true; this._binary = true
return this; return this
}, },
get type() { get type() {
return this.toString(); return this.toString()
}, },
toString: function() { toString: function() {
return 'VARCHAR(' + this._length + ')' + ((this._binary) ? ' BINARY' : ''); return 'VARCHAR(' + this._length + ')' + ((this._binary) ? ' BINARY' : '')
} }
}; }
Object.defineProperty(STRING, 'BINARY', { Object.defineProperty(STRING, 'BINARY', {
get: function() { get: function() {
return new STRING(undefined, true); return new STRING(undefined, true)
} }
}); })
var INTEGER = function() { var INTEGER = function() {
return INTEGER.prototype.construct.apply(this, [INTEGER].concat(Array.prototype.slice.apply(arguments))); return INTEGER.prototype.construct.apply(this, [INTEGER].concat(Array.prototype.slice.apply(arguments)))
}; }
var BIGINT = function() { var BIGINT = function() {
return BIGINT.prototype.construct.apply(this, [BIGINT].concat(Array.prototype.slice.apply(arguments))); return BIGINT.prototype.construct.apply(this, [BIGINT].concat(Array.prototype.slice.apply(arguments)))
}; }
var FLOAT = function() { var FLOAT = function() {
return FLOAT.prototype.construct.apply(this, [FLOAT].concat(Array.prototype.slice.apply(arguments))); return FLOAT.prototype.construct.apply(this, [FLOAT].concat(Array.prototype.slice.apply(arguments)))
}; }
FLOAT._type = FLOAT; var BLOB = function() {
FLOAT._typeName = 'FLOAT'; return BLOB.prototype.construct.apply(this, [BLOB].concat(Array.prototype.slice.apply(arguments)))
INTEGER._type = INTEGER; }
INTEGER._typeName = 'INTEGER';
BIGINT._type = BIGINT; FLOAT._type = FLOAT
BIGINT._typeName = 'BIGINT'; FLOAT._typeName = 'FLOAT'
STRING._type = STRING; INTEGER._type = INTEGER
STRING._typeName = 'VARCHAR'; INTEGER._typeName = 'INTEGER'
BIGINT._type = BIGINT
STRING.toString = INTEGER.toString = FLOAT.toString = BIGINT.toString = function() { BIGINT._typeName = 'BIGINT'
return new this._type().toString(); STRING._type = STRING
}; STRING._typeName = 'VARCHAR'
BLOB._type = BLOB
BLOB._typeName = 'BLOB'
BLOB.toString = STRING.toString = INTEGER.toString = FLOAT.toString = BIGINT.toString = function() {
return new this._type().toString()
}
BLOB.prototype = {
construct: function(RealType, length) {
if (this instanceof RealType) {
this._typeName = RealType._typeName
if (typeof length === 'string') {
this._length = length
} else {
this._length = ''
}
} else {
return new RealType(length)
}
},
get type() {
return this.toString()
},
toString: function() {
switch (this._length.toLowerCase()) {
case 'tiny':
return 'TINYBLOB'
case 'medium':
return 'MEDIUMBLOB'
case 'long':
return 'LONGBLOB'
default:
return this._typeName
}
}
}
FLOAT.prototype = BIGINT.prototype = INTEGER.prototype = { FLOAT.prototype = BIGINT.prototype = INTEGER.prototype = {
construct: function(RealType, length, decimals, unsigned, zerofill) { construct: function(RealType, length, decimals, unsigned, zerofill) {
if (this instanceof RealType) { if (this instanceof RealType) {
this._typeName = RealType._typeName; this._typeName = RealType._typeName
this._unsigned = !!unsigned; this._unsigned = !!unsigned
this._zerofill = !!zerofill; this._zerofill = !!zerofill
if (typeof length === 'number') { if (typeof length === 'number') {
this._length = length; this._length = length
} }
if (typeof decimals === 'number') { if (typeof decimals === 'number') {
this._decimals = decimals; this._decimals = decimals
} }
} else { } else {
return new RealType(length, decimals, unsigned, zerofill); return new RealType(length, decimals, unsigned, zerofill)
} }
}, },
get type() { get type() {
return this.toString(); return this.toString()
}, },
get UNSIGNED() { get UNSIGNED() {
this._unsigned = true; this._unsigned = true
return this; return this
}, },
get ZEROFILL() { get ZEROFILL() {
this._zerofill = true; this._zerofill = true
return this; return this
}, },
toString: function() { toString: function() {
var result = this._typeName; var result = this._typeName
if (this._length) { if (this._length) {
result += '(' + this._length; result += '(' + this._length
if (typeof this._decimals === 'number') { if (typeof this._decimals === 'number') {
result += ',' + this._decimals; result += ',' + this._decimals
} }
result += ')'; result += ')'
} }
if (this._unsigned) { if (this._unsigned) {
result += ' UNSIGNED'; result += ' UNSIGNED'
} }
if (this._zerofill) { if (this._zerofill) {
result += ' ZEROFILL'; result += ' ZEROFILL'
} }
return result; return result
} }
}; }
var unsignedDesc = { var unsignedDesc = {
get: function() { get: function() {
return new this._type(undefined, undefined, true); return new this._type(undefined, undefined, true)
} }
}; }
var zerofillDesc = { var zerofillDesc = {
get: function() { get: function() {
return new this._type(undefined, undefined, undefined, true); return new this._type(undefined, undefined, undefined, true)
} }
}; }
var typeDesc = { var typeDesc = {
get: function() { get: function() {
return new this._type().toString(); return new this._type().toString()
} }
}; }
Object.defineProperty(STRING, 'type', typeDesc); Object.defineProperty(STRING, 'type', typeDesc)
Object.defineProperty(INTEGER, 'type', typeDesc); Object.defineProperty(INTEGER, 'type', typeDesc)
Object.defineProperty(BIGINT, 'type', typeDesc); Object.defineProperty(BIGINT, 'type', typeDesc)
Object.defineProperty(FLOAT, 'type', typeDesc); Object.defineProperty(FLOAT, 'type', typeDesc)
Object.defineProperty(BLOB, 'type', typeDesc)
Object.defineProperty(INTEGER, 'UNSIGNED', unsignedDesc); Object.defineProperty(INTEGER, 'UNSIGNED', unsignedDesc)
Object.defineProperty(BIGINT, 'UNSIGNED', unsignedDesc); Object.defineProperty(BIGINT, 'UNSIGNED', unsignedDesc)
Object.defineProperty(FLOAT, 'UNSIGNED', unsignedDesc); Object.defineProperty(FLOAT, 'UNSIGNED', unsignedDesc)
Object.defineProperty(INTEGER, 'ZEROFILL', zerofillDesc); Object.defineProperty(INTEGER, 'ZEROFILL', zerofillDesc)
Object.defineProperty(BIGINT, 'ZEROFILL', zerofillDesc); Object.defineProperty(BIGINT, 'ZEROFILL', zerofillDesc)
Object.defineProperty(FLOAT, 'ZEROFILL', zerofillDesc); Object.defineProperty(FLOAT, 'ZEROFILL', zerofillDesc)
module.exports = { module.exports = {
STRING: STRING, STRING: STRING,
...@@ -147,6 +187,7 @@ module.exports = { ...@@ -147,6 +187,7 @@ module.exports = {
BOOLEAN: 'TINYINT(1)', BOOLEAN: 'TINYINT(1)',
FLOAT: FLOAT, FLOAT: FLOAT,
NOW: 'NOW', NOW: 'NOW',
BLOB: BLOB,
get ENUM() { get ENUM() {
var result = function() { var result = function() {
......
...@@ -795,6 +795,10 @@ module.exports = (function() { ...@@ -795,6 +795,10 @@ module.exports = (function() {
dataType = dataType.replace(/NOT NULL/, '') dataType = dataType.replace(/NOT NULL/, '')
} }
if (dataType.lastIndexOf('BLOB') !== -1) {
dataType = 'bytea'
}
if (dataType.match(/^ENUM\(/)) { if (dataType.match(/^ENUM\(/)) {
dataType = dataType.replace(/^ENUM\(.+\)/, this.pgEscapeAndQuote("enum_" + tableName + "_" + attr)) dataType = dataType.replace(/^ENUM\(.+\)/, this.pgEscapeAndQuote("enum_" + tableName + "_" + attr))
} }
......
...@@ -29,7 +29,7 @@ module.exports = (function() { ...@@ -29,7 +29,7 @@ module.exports = (function() {
this.options.logging('Executing: ' + this.sql) this.options.logging('Executing: ' + this.sql)
} }
var columnTypes = {}; var columnTypes = {}
this.database.serialize(function() { this.database.serialize(function() {
var executeSql = function() { var executeSql = function() {
self.database[getDatabaseMethod.call(self)](self.sql, function(err, results) { self.database[getDatabaseMethod.call(self)](self.sql, function(err, results) {
...@@ -48,16 +48,16 @@ module.exports = (function() { ...@@ -48,16 +48,16 @@ module.exports = (function() {
self.database.all("PRAGMA table_info(" + tableName + ")", function(err, results) { self.database.all("PRAGMA table_info(" + tableName + ")", function(err, results) {
if (!err) { if (!err) {
for (var i=0, l=results.length; i<l; i++) { for (var i=0, l=results.length; i<l; i++) {
columnTypes[results[i].name] = results[i].type; columnTypes[results[i].name] = results[i].type
} }
} }
executeSql(); executeSql()
}); });
} else { } else {
executeSql(); executeSql()
} }
} else { } else {
executeSql(); executeSql()
} }
}) })
...@@ -85,15 +85,18 @@ module.exports = (function() { ...@@ -85,15 +85,18 @@ module.exports = (function() {
if (this.sql.indexOf('sqlite_master') !== -1) { if (this.sql.indexOf('sqlite_master') !== -1) {
result = results.map(function(resultSet) { return resultSet.name }) result = results.map(function(resultSet) { return resultSet.name })
} else if (this.send('isSelectQuery')) { } else if (this.send('isSelectQuery')) {
// we need to convert the timestamps into actual date objects
if(!this.options.raw) { if(!this.options.raw) {
results = results.map(function(result) { results = results.map(function(result) {
for (var name in result) { for (var name in result) {
if (result.hasOwnProperty(name) && (metaData.columnTypes[name] === 'DATETIME')) { if (result.hasOwnProperty(name) && metaData.columnTypes[name]) {
var val = result[name]; if (metaData.columnTypes[name] === 'DATETIME') {
if(val !== null) { // we need to convert the timestamps into actual date objects
result[name] = new Date(val+'Z'); // Z means UTC var val = result[name]
if (val !== null) {
result[name] = new Date(val+'Z') // Z means UTC
}
} else if (metaData.columnTypes[name].lastIndexOf('BLOB') !== -1) {
result[name] = new Buffer(result[name])
} }
} }
} }
......
...@@ -41,7 +41,7 @@ SqlString.escape = function(val, stringifyObjects, timeZone, dialect, field) { ...@@ -41,7 +41,7 @@ SqlString.escape = function(val, stringifyObjects, timeZone, dialect, field) {
} }
if (Buffer.isBuffer(val)) { if (Buffer.isBuffer(val)) {
return SqlString.bufferToString(val); return SqlString.bufferToString(val, dialect);
} }
if (Array.isArray(val)) { if (Array.isArray(val)) {
...@@ -137,7 +137,7 @@ SqlString.dateToString = function(date, timeZone, dialect) { ...@@ -137,7 +137,7 @@ SqlString.dateToString = function(date, timeZone, dialect) {
return moment(dt).format("YYYY-MM-DD HH:mm:ss"); return moment(dt).format("YYYY-MM-DD HH:mm:ss");
}; };
SqlString.bufferToString = function(buffer) { SqlString.bufferToString = function(buffer, dialect) {
var hex = ''; var hex = '';
try { try {
hex = buffer.toString('hex'); hex = buffer.toString('hex');
...@@ -149,6 +149,10 @@ SqlString.bufferToString = function(buffer) { ...@@ -149,6 +149,10 @@ SqlString.bufferToString = function(buffer) {
} }
} }
if (dialect === 'postgres') {
// bytea hex format http://www.postgresql.org/docs/current/static/datatype-binary.html
return "E'\\\\x" + hex+ "'";
}
return "X'" + hex+ "'"; return "X'" + hex+ "'";
}; };
......
...@@ -2898,4 +2898,64 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -2898,4 +2898,64 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
}) })
}) })
}) })
describe("blob", function() {
beforeEach(function(done) {
this.BlobUser = this.sequelize.define("blobUser", {
data: Sequelize.BLOB
})
this.BlobUser.sync({ force: true }).success(function() {
done()
})
})
describe("buffers", function () {
it("should be able to take a buffer as parameter to a BLOB field", function (done) {
this.BlobUser.create({
data: new Buffer('Sequelize')
}).success(function (user) {
expect(user).to.be.ok
done()
})
})
it("should return a buffer when fetching a blob", function (done) {
var self = this
this.BlobUser.create({
data: new Buffer('Sequelize')
}).success(function (user) {
self.BlobUser.find(user.id).success(function (user) {
expect(user.data).to.be.an.instanceOf(Buffer)
expect(user.data.toString()).to.have.string('Sequelize')
done()
})
})
})
})
describe("strings", function () {
it("should be able to take a string as parameter to a BLOB field", function (done) {
this.BlobUser.create({
data: 'Sequelize'
}).success(function (user) {
expect(user).to.be.ok
done()
})
})
it("should return a buffer when fetching a BLOB, even when the BLOB was inserted as a string", function (done) {
var self = this
this.BlobUser.create({
data: 'Sequelize'
}).success(function (user) {
self.BlobUser.find(user.id).success(function (user) {
expect(user.data).to.be.an.instanceOf(Buffer)
expect(user.data.toString()).to.have.string('Sequelize')
done()
})
})
})
})
})
}) })
...@@ -27,6 +27,11 @@ describe(Support.getTestDialectTeaser('DataTypes'), function() { ...@@ -27,6 +27,11 @@ describe(Support.getTestDialectTeaser('DataTypes'), function() {
[Sequelize.NOW, 'NOW', 'NOW'], [Sequelize.NOW, 'NOW', 'NOW'],
[Sequelize.BOOLEAN, 'BOOLEAN', 'TINYINT(1)'], [Sequelize.BOOLEAN, 'BOOLEAN', 'TINYINT(1)'],
[Sequelize.BLOB, 'BLOB', 'BLOB'],
[Sequelize.BLOB('tiny'), 'BLOB(\'tiny\')', 'TINYBLOB'],
[Sequelize.BLOB('medium'), 'BLOB(\'medium\')', 'MEDIUMBLOB'],
[Sequelize.BLOB('long'), 'BLOB(\'long\')', 'LONGBLOB'],
[Sequelize.INTEGER, 'INTEGER', 'INTEGER'], [Sequelize.INTEGER, 'INTEGER', 'INTEGER'],
[Sequelize.INTEGER.UNSIGNED, 'INTEGER.UNSIGNED', 'INTEGER UNSIGNED'], [Sequelize.INTEGER.UNSIGNED, 'INTEGER.UNSIGNED', 'INTEGER UNSIGNED'],
[Sequelize.INTEGER(11), 'INTEGER(11)','INTEGER(11)'], [Sequelize.INTEGER(11), 'INTEGER(11)','INTEGER(11)'],
......
...@@ -85,6 +85,14 @@ if (dialect.match(/^mysql/)) { ...@@ -85,6 +85,14 @@ if (dialect.match(/^mysql/)) {
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` INTEGER) COMMENT 'I\\'m a comment!' ENGINE=InnoDB;" expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` INTEGER) COMMENT 'I\\'m a comment!' ENGINE=InnoDB;"
}, },
{ {
arguments: ['myTable', {data: "BLOB"}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`data` BLOB) ENGINE=InnoDB;"
},
{
arguments: ['myTable', {data: "LONGBLOB"}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`data` LONGBLOB) ENGINE=InnoDB;"
},
{
arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)'}, {engine: 'MyISAM'}], arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)'}, {engine: 'MyISAM'}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` VARCHAR(255), `name` VARCHAR(255)) ENGINE=MyISAM;" expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` VARCHAR(255), `name` VARCHAR(255)) ENGINE=MyISAM;"
}, },
...@@ -220,6 +228,9 @@ if (dialect.match(/^mysql/)) { ...@@ -220,6 +228,9 @@ if (dialect.match(/^mysql/)) {
arguments: ['myTable', {name: 'foo', foo: 1}], arguments: ['myTable', {name: 'foo', foo: 1}],
expectation: "INSERT INTO `myTable` (`name`,`foo`) VALUES ('foo',1);" expectation: "INSERT INTO `myTable` (`name`,`foo`) VALUES ('foo',1);"
}, { }, {
arguments: ['myTable', {data: new Buffer('Sequelize') }],
expectation: "INSERT INTO `myTable` (`data`) VALUES (X'53657175656c697a65');"
}, {
arguments: ['myTable', {name: 'foo', foo: 1, nullValue: null}], arguments: ['myTable', {name: 'foo', foo: 1, nullValue: null}],
expectation: "INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ('foo',1,NULL);" expectation: "INSERT INTO `myTable` (`name`,`foo`,`nullValue`) VALUES ('foo',1,NULL);"
}, { }, {
......
...@@ -126,6 +126,14 @@ if (dialect.match(/^postgres/)) { ...@@ -126,6 +126,14 @@ if (dialect.match(/^postgres/)) {
expectation: "CREATE TABLE IF NOT EXISTS \"myTable\" (\"title\" INTEGER); COMMENT ON TABLE \"myTable\" IS 'I''m a comment!';", expectation: "CREATE TABLE IF NOT EXISTS \"myTable\" (\"title\" INTEGER); COMMENT ON TABLE \"myTable\" IS 'I''m a comment!';",
}, },
{ {
arguments: ['myTable', {data: "BLOB"}],
expectation: "CREATE TABLE IF NOT EXISTS \"myTable\" (\"data\" bytea);"
},
{
arguments: ['myTable', {data: "LONGBLOB"}],
expectation: "CREATE TABLE IF NOT EXISTS \"myTable\" (\"data\" bytea);"
},
{
arguments: ['mySchema.myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)'}], arguments: ['mySchema.myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)'}],
expectation: "CREATE TABLE IF NOT EXISTS \"mySchema\".\"myTable\" (\"title\" VARCHAR(255), \"name\" VARCHAR(255));" expectation: "CREATE TABLE IF NOT EXISTS \"mySchema\".\"myTable\" (\"title\" VARCHAR(255), \"name\" VARCHAR(255));"
}, },
...@@ -350,6 +358,9 @@ if (dialect.match(/^postgres/)) { ...@@ -350,6 +358,9 @@ if (dialect.match(/^postgres/)) {
arguments: ['myTable', {name: 'foo', birthday: moment("2011-03-27 10:01:55 +0000", "YYYY-MM-DD HH:mm:ss Z").toDate()}], arguments: ['myTable', {name: 'foo', birthday: moment("2011-03-27 10:01:55 +0000", "YYYY-MM-DD HH:mm:ss Z").toDate()}],
expectation: "INSERT INTO \"myTable\" (\"name\",\"birthday\") VALUES ('foo','2011-03-27 10:01:55.000 +00:00') RETURNING *;" expectation: "INSERT INTO \"myTable\" (\"name\",\"birthday\") VALUES ('foo','2011-03-27 10:01:55.000 +00:00') RETURNING *;"
}, { }, {
arguments: ['myTable', {data: new Buffer('Sequelize') }],
expectation: "INSERT INTO \"myTable\" (\"data\") VALUES (E'\\\\x53657175656c697a65') RETURNING *;"
}, {
arguments: ['myTable', {name: 'foo', foo: 1}], arguments: ['myTable', {name: 'foo', foo: 1}],
expectation: "INSERT INTO \"myTable\" (\"name\",\"foo\") VALUES ('foo',1) RETURNING *;" expectation: "INSERT INTO \"myTable\" (\"name\",\"foo\") VALUES ('foo',1) RETURNING *;"
}, { }, {
......
...@@ -79,6 +79,14 @@ if (dialect === 'sqlite') { ...@@ -79,6 +79,14 @@ if (dialect === 'sqlite') {
createTableQuery: [ createTableQuery: [
{ {
arguments: ['myTable', {data: "BLOB"}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`data` BLOB);"
},
{
arguments: ['myTable', {data: "LONGBLOB"}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`data` LONGBLOB);"
},
{
arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)'}], arguments: ['myTable', {title: 'VARCHAR(255)', name: 'VARCHAR(255)'}],
expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` VARCHAR(255), `name` VARCHAR(255));" expectation: "CREATE TABLE IF NOT EXISTS `myTable` (`title` VARCHAR(255), `name` VARCHAR(255));"
}, },
...@@ -104,6 +112,9 @@ if (dialect === 'sqlite') { ...@@ -104,6 +112,9 @@ if (dialect === 'sqlite') {
arguments: ['myTable', { name: "'bar'" }], arguments: ['myTable', { name: "'bar'" }],
expectation: "INSERT INTO `myTable` (`name`) VALUES ('''bar''');" expectation: "INSERT INTO `myTable` (`name`) VALUES ('''bar''');"
}, { }, {
arguments: ['myTable', {data: new Buffer('Sequelize') }],
expectation: "INSERT INTO `myTable` (`data`) VALUES (X'53657175656c697a65');"
}, {
arguments: ['myTable', { name: "bar", value: null }], arguments: ['myTable', { name: "bar", value: null }],
expectation: "INSERT INTO `myTable` (`name`,`value`) VALUES ('bar',NULL);" expectation: "INSERT INTO `myTable` (`name`,`value`) VALUES ('bar',NULL);"
}, { }, {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!