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

Commit 5a266dcb by Sushant Committed by Jan Aagaard Meier

DATEONLY is now actually date only (#6709)

1 parent dd984e8e
# Future
- [FIXED] `DATEONLY` now returns `YYYY-MM-DD` date string [#4858] (https://github.com/sequelize/sequelize/issues/4858)
- [FIXED] Issues with `createFunction` and `dropFunction` (PostgresSQL)
- [FIXED] Issue with belongsTo association and foreign keys [#6400](https://github.com/sequelize/sequelize/issues/6400)
- [FIXED] Issue with query generation in MSSQL, an identifier was not escaped [#6686] (https://github.com/sequelize/sequelize/pull/6686)
- [FIXED] GroupedLimit when foreignKey has a field alias
- [FIXED] groupedLimit.through.where support
## BC breaks:
- `DATEONLY` now returns string in `YYYY-MM-DD` format rather than `Date` type
# 4.0.0-2
- [ADDED] include now supports string as an argument (on top of model/association), string will expand into an association matched literally from Model.associations
- [FIXED] Accept dates as string while using `typeValidation` [#6453](https://github.com/sequelize/sequelize/issues/6453)
......
......@@ -476,6 +476,10 @@ DATEONLY.prototype.toSql = function() {
return 'DATE';
};
DATEONLY.prototype._stringify = function _stringify(date) {
return moment(date).format('YYYY-MM-DD');
};
/**
* A key / value column. Only available in postgres.
*
......
'use strict';
const _ = require('lodash');
const moment = require('moment');
const inherits = require('../../utils/inherits');
module.exports = BaseTypes => {
......@@ -135,6 +136,16 @@ module.exports = BaseTypes => {
return date.format('YYYY-MM-DD HH:mm:ss.SSS');
};
function DATEONLY() {
if (!(this instanceof DATEONLY)) return new DATEONLY();
BaseTypes.DATEONLY.apply(this, arguments);
}
inherits(DATEONLY, BaseTypes.DATEONLY);
DATEONLY.parse = function (value) {
return moment(value).format('YYYY-MM-DD');
};
function INTEGER(length) {
if (!(this instanceof INTEGER)) return new INTEGER(length);
BaseTypes.INTEGER.apply(this, arguments);
......@@ -225,6 +236,7 @@ module.exports = BaseTypes => {
STRING,
UUID,
DATE,
DATEONLY,
NOW,
INTEGER,
BIGINT,
......
......@@ -24,6 +24,7 @@ module.exports = BaseTypes => {
BaseTypes.ENUM.types.mysql = false;
BaseTypes.REAL.types.mysql = ['DOUBLE'];
BaseTypes.DOUBLE.types.mysql = ['DOUBLE'];
BaseTypes.GEOMETRY.types.mysql = ['GEOMETRY'];
function BLOB(length) {
if (!(this instanceof BLOB)) return new BLOB(length);
......@@ -62,7 +63,7 @@ module.exports = BaseTypes => {
};
function DATE(length) {
if (!(this instanceof DATE)) return new Date(length);
if (!(this instanceof DATE)) return new DATE(length);
BaseTypes.DATE.apply(this, arguments);
}
inherits(DATE, BaseTypes.DATE);
......@@ -97,6 +98,16 @@ module.exports = BaseTypes => {
return value;
};
function DATEONLY() {
if (!(this instanceof DATEONLY)) return new DATEONLY();
BaseTypes.DATEONLY.apply(this, arguments);
}
inherits(DATEONLY, BaseTypes.DATEONLY);
DATEONLY.parse = function parse(value) {
return value.string();
};
function UUID() {
if (!(this instanceof UUID)) return new UUID();
BaseTypes.UUID.apply(this, arguments);
......@@ -157,11 +168,10 @@ module.exports = BaseTypes => {
return 'ENUM(' + _.map(this.values, value => options.escape(value)).join(', ') + ')';
};
BaseTypes.GEOMETRY.types.mysql = ['GEOMETRY'];
const exports = {
ENUM,
DATE,
DATEONLY,
UUID,
GEOMETRY,
DECIMAL,
......
......@@ -93,7 +93,7 @@ class Query extends AbstractQuery {
this.handleInsertQuery(data);
if (!this.instance) {
// handle bulkCreate AI primiary key
// handle bulkCreate AI primiary key
if (
data.constructor.name === 'ResultSetHeader'
&& this.model
......
......@@ -24,16 +24,26 @@ module.exports = BaseTypes => {
array_oids: [3807]
};
BaseTypes.DATEONLY.types.postgres = {
oids: [1082],
array_oids: [1182]
};
BaseTypes.TIME.types.postgres = {
oids: [1083],
array_oids: [1183]
};
function DATEONLY() {
if (!(this instanceof DATEONLY)) return new DATEONLY();
BaseTypes.DATEONLY.apply(this, arguments);
}
inherits(DATEONLY, BaseTypes.DATEONLY);
DATEONLY.parse = function parse(value) {
return value;
};
BaseTypes.DATEONLY.types.postgres = {
oids: [1082],
array_oids: [1182]
};
function DECIMAL(precision, scale) {
if (!(this instanceof DECIMAL)) return new DECIMAL(precision, scale);
BaseTypes.DECIMAL.apply(this, arguments);
......@@ -461,6 +471,7 @@ module.exports = BaseTypes => {
INTEGER,
BOOLEAN,
DATE,
DATEONLY,
BIGINT,
REAL,
'DOUBLE PRECISION': DOUBLE,
......
......@@ -39,6 +39,16 @@ module.exports = BaseTypes => {
}
};
function DATEONLY() {
if (!(this instanceof DATEONLY)) return new DATEONLY();
BaseTypes.DATEONLY.apply(this, arguments);
}
inherits(DATEONLY, BaseTypes.DATEONLY);
DATEONLY.parse = function parse(date) {
return date;
};
function STRING(length, binary) {
if (!(this instanceof STRING)) return new STRING(length, binary);
BaseTypes.STRING.apply(this, arguments);
......@@ -185,6 +195,7 @@ module.exports = BaseTypes => {
const exports = {
DATE,
DATEONLY,
STRING,
CHAR,
NUMBER,
......
......@@ -126,9 +126,8 @@ class Query extends AbstractQuery {
// add the inserted row id to the instance
if (query.isInsertQuery(results, metaData)) {
query.handleInsertQuery(results, metaData);
if (!query.instance) {
// handle bulkCreate AI primiary key
// handle bulkCreate AI primary key
if (
metaData.constructor.name === 'Statement'
&& query.model
......@@ -138,7 +137,7 @@ class Query extends AbstractQuery {
) {
const startId = metaData[query.getInsertIdField()] - metaData.changes + 1;
result = [];
for (let i = startId; i< startId + metaData.changes; i++) {
for (let i = startId; i < startId + metaData.changes; i++) {
result.push({ [query.model.rawAttributes[query.model.primaryKeyAttribute].field]: i });
}
} else {
......@@ -180,21 +179,9 @@ class Query extends AbstractQuery {
});
}
let type = tableTypes[name];
if (type) {
if (type.indexOf('(') !== -1) {
// Remove the lenght part
type = type.substr(0, type.indexOf('('));
}
type = type.replace('UNSIGNED', '').replace('ZEROFILL', '');
type = type.trim().toUpperCase();
const parse = parserStore.get(type);
if (value !== null && parse) {
return parse(value, { timezone: query.sequelize.options.timezone});
}
}
return value;
return tableTypes[name]
? query.applyParsers(tableTypes[name], value)
: value;
});
});
}
......@@ -306,6 +293,21 @@ class Query extends AbstractQuery {
});
}
applyParsers(type, value) {
if (type.indexOf('(') !== -1) {
// Remove the length part
type = type.substr(0, type.indexOf('('));
}
type = type.replace('UNSIGNED', '').replace('ZEROFILL', '');
type = type.trim().toUpperCase();
const parse = parserStore.get(type);
if (value !== null && parse) {
return parse(value, { timezone: this.sequelize.options.timezone });
}
return value;
}
formatError(err) {
switch (err.code) {
......
......@@ -9,6 +9,7 @@ const sequelizeErrors = require('./errors');
const Dottie = require('dottie');
const Promise = require('./promise');
const _ = require('lodash');
const moment = require('moment');
const Association = require('./associations/base');
const HasMany = require('./associations/has-many');
const DataTypes = require('./data-types');
......@@ -3085,14 +3086,23 @@ class Model {
// Convert date fields to real date objects
if (this.constructor._hasDateAttributes && this.constructor._isDateAttribute(key) && !!value && !value._isSequelizeMethod) {
if (!(value instanceof Date)) {
value = new Date(value);
}
if (!(originalValue instanceof Date)) {
originalValue = new Date(originalValue);
}
if (originalValue && value.getTime() === originalValue.getTime()) {
return this;
// Dont parse DATEONLY to new Date, keep them as string
if (this.rawAttributes[key].type instanceof DataTypes.DATEONLY) {
if (originalValue && originalValue === value) {
return this;
} else {
value = moment(value).format('YYYY-MM-DD');
}
} else { // go ahread and parse as Date if required
if (!(value instanceof Date)) {
value = new Date(value);
}
if (!(originalValue instanceof Date)) {
originalValue = new Date(originalValue);
}
if (originalValue && value.getTime() === originalValue.getTime()) {
return this;
}
}
}
}
......
......@@ -156,7 +156,7 @@ describe(Support.getTestDialectTeaser('DataTypes'), function() {
it('calls parse and stringify for DATEONLY', function () {
var Type = new Sequelize.DATEONLY();
return testSuccess(Type, new Date());
return testSuccess(Type, moment(new Date()).format('YYYY-MM-DD'));
});
it('calls parse and stringify for TIME', function () {
......@@ -438,4 +438,22 @@ describe(Support.getTestDialectTeaser('DataTypes'), function() {
});
});
it('should return YYYY-MM-DD format string for DATEONLY', function () {
const Model = this.sequelize.define('user', {
stamp: Sequelize.DATEONLY
});
const testDate = moment().format('YYYY-MM-DD');
return Model.sync({ force: true})
.then(() => Model.create({ stamp: testDate }))
.then(record => {
expect(typeof record.stamp).to.be.eql('string');
expect(record.stamp).to.be.eql(testDate);
return Model.findById(record.id);
}).then(record => {
expect(typeof record.stamp).to.be.eql('string');
expect(record.stamp).to.be.eql(testDate);
});
});
});
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!