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

Commit a96308d6 by Jan Aagaard Meier

test(datatypes) Tests for new data-type system

1 parent 4f74575a
......@@ -515,11 +515,7 @@ JSONB.prototype.key = JSONB.key = 'JSONB';
* A default value of the current timestamp
* @property NOW
*/
var NOW = function() {
if (!(this instanceof NOW)) return new NOW();
ABSTRACT.apply(this, arguments);
};
util.inherits(NOW, ABSTRACT);
var NOW = ABSTRACT.inherits();
NOW.prototype.key = NOW.key = 'NOW';
......@@ -730,7 +726,7 @@ VIRTUAL.prototype.key = VIRTUAL.key = 'VIRTUAL';
*
* @property ENUM
*/
var ENUM = function(value) {
var ENUM = ABSTRACT.inherits(function(value) {
var options = typeof value === 'object' && !Array.isArray(value) && value || {
values: Array.prototype.slice.call(arguments).reduce(function(result, element) {
return result.concat(Array.isArray(element) ? element : [element]);
......@@ -738,8 +734,7 @@ var ENUM = function(value) {
};
if (!(this instanceof ENUM)) return new ENUM(options);
this.values = options.values;
};
util.inherits(ENUM, ABSTRACT);
});
ENUM.prototype.key = ENUM.key = 'ENUM';
ENUM.prototype.validate = function(value) {
......
......@@ -1125,7 +1125,6 @@ var QueryGenerator = {
// includeIgnoreAttributes is used by aggregate functions
if (options.includeIgnoreAttributes !== false) {
attributes = include.attributes.map(function(attr) {
var attrAs = attr,
verbatim = false;
......
......@@ -20,6 +20,12 @@ ConnectionManager = function(dialect, sequelize) {
Utils._.extend(ConnectionManager.prototype, AbstractConnectionManager.prototype);
// Expose this as a method so that the parsing may be updated when the user has added additional, custom types
ConnectionManager.prototype.refreshTypeParser = function (dataTypes) {
require('../parsing').refresh(dataTypes, 'mssql');
};
ConnectionManager.prototype.connect = function(config) {
var self = this;
return new Promise(function (resolve, reject) {
......
......@@ -5,7 +5,45 @@ var _ = require('lodash');
module.exports = function (BaseTypes) {
BaseTypes.ABSTRACT.prototype.dialectTypes = 'https://msdn.microsoft.com/en-us/library/ms187752%28v=sql.110%29.aspx';
var STRING = BaseTypes.STRING.inherits;
BaseTypes.DATE.types.mssql = [42];
BaseTypes.STRING.types.mssql = [231, 173];
BaseTypes.CHAR.types.mssql = [175];
BaseTypes.TEXT.types.mssql = [];
BaseTypes.INTEGER.types.mssql = [38];
BaseTypes.BIGINT.types.mssql = [127];
BaseTypes.FLOAT.types.mssql = [109];
BaseTypes.TIME.types.mssql = [41];
BaseTypes.DATEONLY.types.mssql = [40];
BaseTypes.BOOLEAN.types.mssql = [104];
BaseTypes.BLOB.types.mssql = [165];
BaseTypes.DECIMAL.types.mssql = [106];
BaseTypes.UUID.types.mssql = [];
BaseTypes.ENUM.types.mssql = []; // Questionable .. overwritten by text
BaseTypes.REAL.types.mssql = [109];
BaseTypes.DOUBLE.types.mssql = [109];
BaseTypes.GEOMETRY.types.mssql = [240];
var BLOB = BaseTypes.BLOB.inherits();
BLOB.prototype.toSql = function() {
if (this._length) {
if (this._length.toLowerCase() === 'tiny') { // tiny = 2^8
this.warn('MSSQL does not support BLOB with the `length` = `tiny` option. `VARBINARY(256)` will be used instead.');
return 'VARBINARY(256)';
}
this.warn('MSSQL does not support BLOB with the `length` option. `VARBINARY(MAX)` will be used instead.');
}
return 'VARBINARY(MAX)';
};
BLOB.prototype.escape = false;
BLOB.prototype.$stringify = function (value) {
var hex = value.toString('hex');
return '0x' + hex;
};
var STRING = BaseTypes.STRING.inherits();
STRING.prototype.toSql = function() {
if (!this._binary) {
......@@ -15,6 +53,16 @@ module.exports = function (BaseTypes) {
}
};
STRING.prototype.$stringify = function (value) {
if (this._binary) {
this.escape = false;
return BLOB.prototype.$stringify(value);
} else {
this.escape = true;
return value;
}
};
var TEXT = BaseTypes.TEXT.inherits();
TEXT.prototype.toSql = function() {
......@@ -36,25 +84,6 @@ module.exports = function (BaseTypes) {
return 'BIT';
};
var BLOB = BaseTypes.BLOB.inherits();
BLOB.prototype.toSql = function() {
if (this._length) {
if (this._length.toLowerCase() === 'tiny') { // tiny = 2^8
this.warn('MSSQL does not support BLOB with the `length` = `tiny` option. `VARBINARY(256)` will be used instead.');
return 'VARBINARY(256)';
}
this.warn('MSSQL does not support BLOB with the `length` option. `VARBINARY(MAX)` will be used instead.');
}
return 'VARBINARY(MAX)';
};
BLOB.prototype.$stringify = function (value) {
var hex = value.toString('hex');
return '0x' + hex;
};
var UUID = BaseTypes.UUID.inherits();
UUID.prototype.toSql = function() {
......
......@@ -2,7 +2,8 @@
var Utils = require('../../utils')
, AbstractQuery = require('../abstract/query')
, sequelizeErrors = require('../../errors.js');
, sequelizeErrors = require('../../errors.js')
, parsers = require('../parsing').parsers.mssql;
var Query = function(connection, sequelize, options) {
this.connection = connection;
......@@ -73,7 +74,18 @@ Query.prototype.run = function(sql, parameters) {
request.on('row', function(columns) {
var row = {};
columns.forEach(function(column) {
row[column.metadata.colName] = column.value;
if (['constraint_name', 'TABLE_SCHEMA', 'TABLE_NAME'].indexOf(column.metadata.colName) === -1) {
// console.log(column.metadata.colName)
// console.log(column.metadata.type)
}
var typeid = column.metadata.type.id
, value = column.value;
if (typeid in parsers) {
value = parsers[typeid](value);
}
row[column.metadata.colName] = value;
});
results.push(row);
......
......@@ -2,13 +2,16 @@
var _ = require('lodash');
module.exports.parsers = {};
module.exports.parsers = {
sqlite: {},
mssql: {}
};
module.exports.refresh = function (dataTypes) {
module.exports.refresh = function (dataTypes, dialect) {
_.each(dataTypes, function (dataType, key) {
if (dataType.parse && dataType.types.sqlite) {
dataType.types.sqlite.forEach(function (type) {
module.exports.parsers[type] = dataType.parse;
dataType.types[dialect].forEach(function (type) {
module.exports.parsers[dialect][type] = dataType.parse;
});
}
});
......
......@@ -27,9 +27,10 @@ ConnectionManager = function(dialect, sequelize) {
Utils._.extend(ConnectionManager.prototype, AbstractConnectionManager.prototype);
// Expose this as a method so that the parsing may be updated when the user has added additional, custom types
ConnectionManager.prototype.refreshTypeParser = require('./parsing').refresh;
ConnectionManager.prototype.refreshTypeParser = function (dataTypes) {
require('../parsing').refresh(dataTypes, 'sqlite');
};
ConnectionManager.prototype.getConnection = function(options) {
var self = this;
......
......@@ -21,6 +21,7 @@ module.exports = function (BaseTypes) {
BaseTypes.ENUM.types.sqlite = ['TEXT']; // Questionable .. overwritten by text
BaseTypes.REAL.types.sqlite = ['REAL'];
BaseTypes.DOUBLE.types.sqlite = ['DOUBLE PRECISION'];
BaseTypes.GEOMETRY.types.mssql = [];
var DATE = BaseTypes.DATE.inherits();
DATE.parse = function (date, options) {
......
......@@ -5,7 +5,7 @@ var Utils = require('../../utils')
, AbstractQuery = require('../abstract/query')
, QueryTypes = require('../../query-types')
, sequelizeErrors = require('../../errors.js')
, parsers = require('./parsing').parsers;
, parsers = require('../parsing').parsers.sqlite;
var Query = function(database, sequelize, options) {
this.database = database;
......
......@@ -6,18 +6,14 @@ var chai = require('chai')
, Sequelize = require('../../index')
, expect = chai.expect
, Support = require(__dirname + '/support')
, DataTypes = require(__dirname + '/../../lib/data-types')
, dialect = Support.getTestDialect()
, sinon = require('sinon')
, _ = require('lodash')
, dataTypes = require('../../lib/data-types')
, moment = require('moment')
, current = Support.sequelize;
, current = Support.sequelize
, dialect = Support.getTestDialect();
describe.only(Support.getTestDialectTeaser('DataTypes'), function() {
it('allows me to use a custom parse function', function () {
// var parseStub = sinon.stub(this.sequelize.DATE, 'parse', function (value) {
// new moment(value);
// });
it('allows me to return values from a custom parse function', function () {
var parse = Sequelize.DATE.parse = sinon.spy(function (value) {
return moment(value, 'YYYY-MM-DD HH:mm:ss Z');
});
......@@ -29,15 +25,15 @@ describe.only(Support.getTestDialectTeaser('DataTypes'), function() {
return value.format('YYYY-MM-DD HH:mm:ss Z');
});
this.sequelize.refreshTypes();
current.refreshTypes();
var User = this.sequelize.define('user', {
var User = current.define('user', {
dateField: Sequelize.DATE
}, {
timestamps: false
});
return this.sequelize.sync({ force: true }).then(function () {
return current.sync({ force: true }).then(function () {
return User.create({
dateField: moment("2011 10 31", 'YYYY MM DD')
});
......@@ -51,25 +47,26 @@ describe.only(Support.getTestDialectTeaser('DataTypes'), function() {
});
});
var testType = function (Type, value) {
it((new Type()).toSql(), function () {
var parse = Type.parse = sinon.spy(function (value) {
var testType = function (Type, value, options) {
options = options || {};
it('calls parse and stringify for ' + Type.toSql(), function () {
var parse = Type.constructor.parse = sinon.spy(options.parse || function (value) {
return value;
});
var stringify = Type.prototype.stringify = sinon.spy(function (value) {
var stringify = Type.constructor.prototype.stringify = sinon.spy(options.$stringify || function (value) {
return value;
});
this.sequelize.refreshTypes();
current.refreshTypes();
var User = this.sequelize.define('user', {
field: new Type()
var User = current.define('user', {
field: Type
}, {
timestamps: false
});
return this.sequelize.sync({ force: true }).then(function () {
return current.sync({ force: true }).then(function () {
return User.create({
field: value
});
......@@ -82,11 +79,23 @@ describe.only(Support.getTestDialectTeaser('DataTypes'), function() {
});
};
[Sequelize.TEXT, Sequelize.STRING, Sequelize.CHAR].forEach(function (Type) {
testType(Type, 'foobar');
});
// [new Sequelize.TEXT(), new Sequelize.STRING(), new Sequelize.CHAR(), new Sequelize.CHAR().BINARY].forEach(function (Type) {
// testType(Type, 'foobar');
// });
[Sequelize.BOOLEAN, Sequelize.DOUBLE, Sequelize.REAL, Sequelize.INTEGER].forEach(function (Type) {
testType(Type, 1);
});
// [new Sequelize.BOOLEAN(), new Sequelize.DOUBLE(), new Sequelize.REAL(), new Sequelize.INTEGER(), new Sequelize.DECIMAL()].forEach(function (Type) {
// testType(Type, 1);
// });
// [new Sequelize.REAL(), new Sequelize.FLOAT()].forEach(function (Type) {
// testType(Type, 1);
// });
var blobStringify = ('BLOB' in dataTypes[dialect]) ? dataTypes[dialect].BLOB : dataTypes.BLOB;
blobStringify = blobStringify.prototype.$stringify;
// testType(new Sequelize.BLOB(), new Buffer('hej'), { $stringify: blobStringify });
testType(new Sequelize.STRING().BINARY, 'foo');
var stringBinary = new Sequelize.STRING().BINARY;
testType(stringBinary, new Buffer('foo'), { $stringify: blobStringify.bind(stringBinary)});
});
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!