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

You need to sign in or sign up before continuing.
Commit 3cd38910 by Simon Schick Committed by Sushant

refactor(data-types): move to classes (#10495)

1 parent 1b4a7bf8
...@@ -105,7 +105,8 @@ ...@@ -105,7 +105,8 @@
"camelcase": "warn", "camelcase": "warn",
"prefer-template": "error", "prefer-template": "error",
"no-else-return": ["error", { "allowElseIf": false }], "no-else-return": ["error", { "allowElseIf": false }],
"no-lonely-if": "error" "no-lonely-if": "error",
"no-this-before-super": "error"
}, },
"parserOptions": { "parserOptions": {
"ecmaVersion": 6, "ecmaVersion": 6,
......
...@@ -196,51 +196,49 @@ modules.exports = function sequelizeAdditions(Sequelize) { ...@@ -196,51 +196,49 @@ modules.exports = function sequelizeAdditions(Sequelize) {
/* /*
* Create new types * Create new types
*/ */
class NEWTYPE extends DataTypes.ABSTRACT {
// Mandatory, complete definition of the new type in the database
toSql() {
return 'INTEGER(11) UNSIGNED ZEROFILL'
}
// Create new type // Optional, validator function
DataTypes.NEWTYPE = function NEWTYPE() { validate(value, options) {
if (!(this instanceof DataTypes.NEWTYPE)) return new DataTypes.NEWTYPE() return (typeof value === 'number') && (! Number.isNaN(value))
} }
inherits(DataTypes.NEWTYPE, DataTypes.ABSTRACT)
// Mandatory, set key // Optional, sanitizer
DataTypes.NEWTYPE.prototype.key = DataTypes.NEWTYPE.key = 'NEWTYPE' _sanitize(value) {
// Force all numbers to be positive
if (value < 0) {
value = 0
}
// Mandatory, complete definition of the new type in the database return Math.round(value)
DataTypes.NEWTYPE.prototype.toSql = function toSql() { }
return 'INTEGER(11) UNSIGNED ZEROFILL'
}
// Optional, validator function
DataTypes.NEWTYPE.prototype.validate = function validate(value, options) {
return (typeof value === 'number') && (! Number.isNaN(value))
}
// Optional, sanitizer // Optional, value stringifier before sending to database
DataTypes.NEWTYPE.prototype._sanitize = function _sanitize(value) { _stringify(value) {
// Force all numbers to be positive return value.toString()
if (value < 0) {
value = 0
} }
return Math.round(value) // Optional, parser for values received from the database
static parse(value) {
return Number.parseInt(value)
}
} }
// Optional, value stringifier before sending to database // Mandatory, set key
DataTypes.NEWTYPE.prototype._stringify = function _stringify(value) { DataTypes.NEWTYPE.prototype.key = DataTypes.NEWTYPE.key = 'NEWTYPE'
return value.toString()
}
// Optional, disable escaping after stringifier. Not recommended. // Optional, disable escaping after stringifier. Not recommended.
// Warning: disables Sequelize protection against SQL injections // Warning: disables Sequelize protection against SQL injections
//DataTypes.NEWTYPE.escape = false //DataTypes.NEWTYPE.escape = false
// Optional, parser for values received from the database
DataTypes.NEWTYPE.parse = function parse(value) {
return Number.parseInt(value)
}
// For convenience // For convenience
Sequelize.NEWTYPE = DataTypes.NEWTYPE // `inferNew` allows you to use the datatype without `new`
Sequelize.NEWTYPE = Sequelize.Utils.inferNew(DataTypes.NEWTYPE)
} }
``` ```
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
const _ = require('lodash'); const _ = require('lodash');
const moment = require('moment-timezone'); const moment = require('moment-timezone');
const inherits = require('../../utils/inherits');
module.exports = BaseTypes => { module.exports = BaseTypes => {
BaseTypes.ABSTRACT.prototype.dialectTypes = 'https://mariadb.com/kb/en/library/resultset/#field-types'; BaseTypes.ABSTRACT.prototype.dialectTypes = 'https://mariadb.com/kb/en/library/resultset/#field-types';
...@@ -35,138 +34,83 @@ module.exports = BaseTypes => { ...@@ -35,138 +34,83 @@ module.exports = BaseTypes => {
BaseTypes.GEOMETRY.types.mariadb = ['GEOMETRY']; BaseTypes.GEOMETRY.types.mariadb = ['GEOMETRY'];
BaseTypes.JSON.types.mariadb = ['JSON']; BaseTypes.JSON.types.mariadb = ['JSON'];
function DECIMAL(precision, scale) { class DECIMAL extends BaseTypes.DECIMAL {
if (!(this instanceof DECIMAL)) { toSql() {
return new DECIMAL(precision, scale); let definition = super.toSql();
if (this._unsigned) {
definition += ' UNSIGNED';
}
if (this._zerofill) {
definition += ' ZEROFILL';
}
return definition;
} }
BaseTypes.DECIMAL.apply(this, arguments);
} }
inherits(DECIMAL, BaseTypes.DECIMAL); class DATE extends BaseTypes.DATE {
toSql() {
DECIMAL.prototype.toSql = function toSql() { return `DATETIME${this._length ? `(${this._length})` : ''}`;
let definition = BaseTypes.DECIMAL.prototype.toSql.apply(this);
if (this._unsigned) {
definition += ' UNSIGNED';
} }
_stringify(date, options) {
if (this._zerofill) { date = this._applyTimezone(date, options);
definition += ' ZEROFILL'; return date.format('YYYY-MM-DD HH:mm:ss.SSS');
} }
static parse(value, options) {
return definition; value = value.string();
}; if (value === null) {
return value;
function DATE(length) { }
if (!(this instanceof DATE)) { if (moment.tz.zone(options.timezone)) {
return new DATE(length); value = moment.tz(value, options.timezone).toDate();
} }
BaseTypes.DATE.apply(this, arguments); else {
} value = new Date(`${value} ${options.timezone}`);
}
inherits(DATE, BaseTypes.DATE);
DATE.prototype.toSql = function toSql() {
return `DATETIME${this._length ? `(${this._length})` : ''}`;
};
DATE.prototype._stringify = function _stringify(date, options) {
date = BaseTypes.DATE.prototype._applyTimezone(date, options);
return date.format('YYYY-MM-DD HH:mm:ss.SSS');
};
DATE.parse = function parse(value, options) {
value = value.string();
if (value === null) {
return value; return value;
} }
if (moment.tz.zone(options.timezone)) {
value = moment.tz(value, options.timezone).toDate();
} else {
value = new Date(`${value} ${options.timezone}`);
}
return value;
};
function DATEONLY() {
if (!(this instanceof DATEONLY)) {
return new DATEONLY();
}
BaseTypes.DATEONLY.call(this);
} }
inherits(DATEONLY, BaseTypes.DATEONLY); class DATEONLY extends BaseTypes.DATEONLY {
static parse(value) {
DATEONLY.parse = function parse(value) { return value.string();
return value.string(); };
}; }
function UUID() { class UUID extends BaseTypes.UUID {
if (!(this instanceof UUID)) { toSql() {
return new UUID(); return 'CHAR(36) BINARY';
} }
BaseTypes.UUID.call(this);
} }
inherits(UUID, BaseTypes.UUID); class GEOMETRY extends BaseTypes.GEOMETRY {
constructor(type, srid) {
UUID.prototype.toSql = function toSql() { super(type, srid);
return 'CHAR(36) BINARY'; if (_.isEmpty(this.type)) {
}; this.sqlType = this.key;
}
function GEOMETRY(type, srid) { else {
if (!(this instanceof GEOMETRY)) { this.sqlType = this.type;
return new GEOMETRY(type, srid); }
} }
BaseTypes.GEOMETRY.apply(this, arguments); toSql() {
return this.sqlType;
if (_.isEmpty(this.type)) {
this.sqlType = this.key;
} else {
this.sqlType = this.type;
} }
} }
inherits(GEOMETRY, BaseTypes.GEOMETRY); class ENUM extends BaseTypes.ENUM {
toSql(options) {
GEOMETRY.prototype.toSql = function toSql() { return `ENUM(${this.values.map(value => options.escape(value)).join(', ')})`;
return this.sqlType;
};
function ENUM() {
if (!(this instanceof ENUM)) {
const obj = Object.create(ENUM.prototype);
ENUM.apply(obj, arguments);
return obj;
} }
BaseTypes.ENUM.apply(this, arguments);
} }
inherits(ENUM, BaseTypes.ENUM); class JSONTYPE extends BaseTypes.JSON {
_stringify(value, options) {
ENUM.prototype.toSql = function toSql(options) { return options.operation === 'where' && typeof value === 'string' ? value
return `ENUM(${this.values.map(value => options.escape(value)).join(', ')})`; : JSON.stringify(value);
};
function JSONTYPE() {
if (!(this instanceof JSONTYPE)) {
return new JSONTYPE();
} }
BaseTypes.JSON.call(this);
} }
inherits(JSONTYPE, BaseTypes.JSON); return {
JSONTYPE.prototype._stringify = function _stringify(value, options) {
return options.operation === 'where' && typeof value === 'string' ? value
: JSON.stringify(value);
};
const exports = {
ENUM, ENUM,
DATE, DATE,
DATEONLY, DATEONLY,
...@@ -175,17 +119,4 @@ module.exports = BaseTypes => { ...@@ -175,17 +119,4 @@ module.exports = BaseTypes => {
DECIMAL, DECIMAL,
JSON: JSONTYPE JSON: JSONTYPE
}; };
_.forIn(exports, (DataType, key) => {
if (!DataType.key) {
DataType.key = key;
}
if (!DataType.extend) {
DataType.extend = function extend(oldType) {
return new DataType(oldType.options);
};
}
});
return exports;
}; };
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
const wkx = require('wkx'); const wkx = require('wkx');
const _ = require('lodash'); const _ = require('lodash');
const moment = require('moment-timezone'); const moment = require('moment-timezone');
const inherits = require('../../utils/inherits');
module.exports = BaseTypes => { module.exports = BaseTypes => {
BaseTypes.ABSTRACT.prototype.dialectTypes = 'https://dev.mysql.com/doc/refman/5.7/en/data-types.html'; BaseTypes.ABSTRACT.prototype.dialectTypes = 'https://dev.mysql.com/doc/refman/5.7/en/data-types.html';
...@@ -36,143 +34,101 @@ module.exports = BaseTypes => { ...@@ -36,143 +34,101 @@ module.exports = BaseTypes => {
BaseTypes.GEOMETRY.types.mysql = ['GEOMETRY']; BaseTypes.GEOMETRY.types.mysql = ['GEOMETRY'];
BaseTypes.JSON.types.mysql = ['JSON']; BaseTypes.JSON.types.mysql = ['JSON'];
function DECIMAL(precision, scale) { class DECIMAL extends BaseTypes.DECIMAL {
if (!(this instanceof DECIMAL)) return new DECIMAL(precision, scale); toSql() {
BaseTypes.DECIMAL.apply(this, arguments); let definition = super.toSql();
} if (this._unsigned) {
inherits(DECIMAL, BaseTypes.DECIMAL); definition += ' UNSIGNED';
}
DECIMAL.prototype.toSql = function toSql() { if (this._zerofill) {
let definition = BaseTypes.DECIMAL.prototype.toSql.apply(this); definition += ' ZEROFILL';
}
if (this._unsigned) { return definition;
definition += ' UNSIGNED';
}
if (this._zerofill) {
definition += ' ZEROFILL';
} }
return definition;
};
function DATE(length) {
if (!(this instanceof DATE)) return new DATE(length);
BaseTypes.DATE.apply(this, arguments);
} }
inherits(DATE, BaseTypes.DATE);
DATE.prototype.toSql = function toSql() { class DATE extends BaseTypes.DATE {
return `DATETIME${this._length ? `(${this._length})` : ''}`; toSql() {
}; return `DATETIME${this._length ? `(${this._length})` : ''}`;
DATE.prototype._stringify = function _stringify(date, options) {
date = BaseTypes.DATE.prototype._applyTimezone(date, options);
// Fractional DATETIMEs only supported on MySQL 5.6.4+
if (this._length) {
return date.format('YYYY-MM-DD HH:mm:ss.SSS');
} }
_stringify(date, options) {
return date.format('YYYY-MM-DD HH:mm:ss'); date = this._applyTimezone(date, options);
}; // Fractional DATETIMEs only supported on MySQL 5.6.4+
if (this._length) {
DATE.parse = function parse(value, options) { return date.format('YYYY-MM-DD HH:mm:ss.SSS');
value = value.string(); }
return date.format('YYYY-MM-DD HH:mm:ss');
if (value === null) { }
static parse(value, options) {
value = value.string();
if (value === null) {
return value;
}
if (moment.tz.zone(options.timezone)) {
value = moment.tz(value, options.timezone).toDate();
}
else {
value = new Date(`${value} ${options.timezone}`);
}
return value; return value;
} }
}
if (moment.tz.zone(options.timezone)) { class DATEONLY extends BaseTypes.DATEONLY {
value = moment.tz(value, options.timezone).toDate(); static parse(value) {
} else { return value.string();
value = new Date(`${value} ${options.timezone}`);
} }
return value;
};
function DATEONLY() {
if (!(this instanceof DATEONLY)) return new DATEONLY();
BaseTypes.DATEONLY.call(this);
} }
inherits(DATEONLY, BaseTypes.DATEONLY); class UUID extends BaseTypes.UUID {
toSql() {
DATEONLY.parse = function parse(value) { return 'CHAR(36) BINARY';
return value.string(); }
};
function UUID() {
if (!(this instanceof UUID)) return new UUID();
BaseTypes.UUID.call(this);
} }
inherits(UUID, BaseTypes.UUID);
UUID.prototype.toSql = function toSql() {
return 'CHAR(36) BINARY';
};
const SUPPORTED_GEOMETRY_TYPES = ['POINT', 'LINESTRING', 'POLYGON']; const SUPPORTED_GEOMETRY_TYPES = ['POINT', 'LINESTRING', 'POLYGON'];
function GEOMETRY(type, srid) { class GEOMETRY extends BaseTypes.GEOMETRY {
if (!(this instanceof GEOMETRY)) return new GEOMETRY(type, srid); constructor(type, srid) {
BaseTypes.GEOMETRY.apply(this, arguments); super(type, srid);
if (_.isEmpty(this.type)) {
if (_.isEmpty(this.type)) { this.sqlType = this.key;
this.sqlType = this.key; return;
} else if (SUPPORTED_GEOMETRY_TYPES.includes(this.type)) { }
this.sqlType = this.type; if (SUPPORTED_GEOMETRY_TYPES.includes(this.type)) {
} else { this.sqlType = this.type;
return;
}
throw new Error(`Supported geometry types are: ${SUPPORTED_GEOMETRY_TYPES.join(', ')}`); throw new Error(`Supported geometry types are: ${SUPPORTED_GEOMETRY_TYPES.join(', ')}`);
} }
} static parse(value) {
inherits(GEOMETRY, BaseTypes.GEOMETRY); value = value.buffer();
// Empty buffer, MySQL doesn't support POINT EMPTY
GEOMETRY.parse = GEOMETRY.prototype.parse = function parse(value) { // check, https://dev.mysql.com/worklog/task/?id=2381
value = value.buffer(); if (!value || value.length === 0) {
return null;
// Empty buffer, MySQL doesn't support POINT EMPTY }
// check, https://dev.mysql.com/worklog/task/?id=2381 // For some reason, discard the first 4 bytes
if (!value || value.length === 0) { value = value.slice(4);
return null; return wkx.Geometry.parse(value).toGeoJSON();
} }
toSql() {
// For some reason, discard the first 4 bytes return this.sqlType;
value = value.slice(4);
return wkx.Geometry.parse(value).toGeoJSON();
};
GEOMETRY.prototype.toSql = function toSql() {
return this.sqlType;
};
function ENUM() {
if (!(this instanceof ENUM)) {
const obj = Object.create(ENUM.prototype);
ENUM.apply(obj, arguments);
return obj;
} }
BaseTypes.ENUM.apply(this, arguments);
} }
inherits(ENUM, BaseTypes.ENUM);
ENUM.prototype.toSql = function toSql(options) {
return `ENUM(${this.values.map(value => options.escape(value)).join(', ')})`;
};
function JSONTYPE() { class ENUM extends BaseTypes.ENUM {
if (!(this instanceof JSONTYPE)) return new JSONTYPE(); toSql(options) {
BaseTypes.JSON.call(this); return `ENUM(${this.values.map(value => options.escape(value)).join(', ')})`;
}
} }
inherits(JSONTYPE, BaseTypes.JSON);
JSONTYPE.prototype._stringify = function _stringify(value, options) { class JSONTYPE extends BaseTypes.JSON {
return options.operation === 'where' && typeof value === 'string' ? value : JSON.stringify(value); _stringify(value, options) {
}; return options.operation === 'where' && typeof value === 'string' ? value : JSON.stringify(value);
}
}
const exports = { return {
ENUM, ENUM,
DATE, DATE,
DATEONLY, DATEONLY,
...@@ -181,15 +137,4 @@ module.exports = BaseTypes => { ...@@ -181,15 +137,4 @@ module.exports = BaseTypes => {
DECIMAL, DECIMAL,
JSON: JSONTYPE JSON: JSONTYPE
}; };
_.forIn(exports, (DataType, key) => {
if (!DataType.key) DataType.key = key;
if (!DataType.extend) {
DataType.extend = function extend(oldType) {
return new DataType(oldType.options);
};
}
});
return exports;
}; };
'use strict'; 'use strict';
const _ = require('lodash');
const inherits = require('../../utils/inherits');
module.exports = BaseTypes => { module.exports = BaseTypes => {
const warn = BaseTypes.ABSTRACT.warn.bind(undefined, 'https://www.sqlite.org/datatype3.html'); const warn = BaseTypes.ABSTRACT.warn.bind(undefined, 'https://www.sqlite.org/datatype3.html');
...@@ -45,235 +42,155 @@ module.exports = BaseTypes => { ...@@ -45,235 +42,155 @@ module.exports = BaseTypes => {
BaseTypes.GEOMETRY.types.sqlite = false; BaseTypes.GEOMETRY.types.sqlite = false;
BaseTypes.JSON.types.sqlite = ['JSON', 'JSONB']; BaseTypes.JSON.types.sqlite = ['JSON', 'JSONB'];
function JSONTYPE() { class JSONTYPE extends BaseTypes.JSON {
if (!(this instanceof JSONTYPE)) return new JSONTYPE(); static parse(data) {
BaseTypes.JSON.call(this); return JSON.parse(data);
}
} }
inherits(JSONTYPE, BaseTypes.JSON);
JSONTYPE.parse = function parse(data) { class DATE extends BaseTypes.DATE {
return JSON.parse(data); static parse(date, options) {
}; if (!date.includes('+')) {
// For backwards compat. Dates inserted by sequelize < 2.0dev12 will not have a timestamp set
function DATE(length) { return new Date(date + options.timezone);
if (!(this instanceof DATE)) return new DATE(length); }
BaseTypes.DATE.apply(this, arguments); return new Date(date); // We already have a timezone stored in the string
}
} }
inherits(DATE, BaseTypes.DATE);
DATE.parse = function parse(date, options) { class DATEONLY extends BaseTypes.DATEONLY {
if (!date.includes('+')) { static parse(date) {
// For backwards compat. Dates inserted by sequelize < 2.0dev12 will not have a timestamp set return date;
return new Date(date + options.timezone);
} }
return new Date(date); // We already have a timezone stored in the string
};
function DATEONLY() {
if (!(this instanceof DATEONLY)) return new DATEONLY();
BaseTypes.DATEONLY.call(this);
} }
inherits(DATEONLY, BaseTypes.DATEONLY);
DATEONLY.parse = function parse(date) {
return date;
};
function STRING(length, binary) { class STRING extends BaseTypes.STRING {
if (!(this instanceof STRING)) return new STRING(length, binary); toSql() {
BaseTypes.STRING.apply(this, arguments); if (this._binary) {
return `VARCHAR BINARY(${this._length})`;
}
return super.toSql(this);
}
} }
inherits(STRING, BaseTypes.STRING);
STRING.prototype.toSql = function toSql() { class TEXT extends BaseTypes.TEXT {
if (this._binary) { toSql() {
return `VARCHAR BINARY(${this._length})`; if (this._length) {
warn('SQLite does not support TEXT with options. Plain `TEXT` will be used instead.');
this._length = undefined;
}
return 'TEXT';
} }
return BaseTypes.STRING.prototype.toSql.call(this);
};
function TEXT(length) {
if (!(this instanceof TEXT)) return new TEXT(length);
BaseTypes.TEXT.apply(this, arguments);
} }
inherits(TEXT, BaseTypes.TEXT);
TEXT.prototype.toSql = function toSql() { class CITEXT extends BaseTypes.CITEXT {
if (this._length) { toSql() {
warn('SQLite does not support TEXT with options. Plain `TEXT` will be used instead.'); return 'TEXT COLLATE NOCASE';
this._length = undefined;
} }
return 'TEXT';
};
function CITEXT() {
if (!(this instanceof CITEXT)) return new CITEXT();
BaseTypes.CITEXT.call(this);
} }
inherits(CITEXT, BaseTypes.CITEXT);
CITEXT.prototype.toSql = function toSql() { class CHAR extends BaseTypes.CHAR {
return 'TEXT COLLATE NOCASE'; toSql() {
}; if (this._binary) {
return `CHAR BINARY(${this._length})`;
function CHAR(length, binary) { }
if (!(this instanceof CHAR)) return new CHAR(length, binary); return super.toSql();
BaseTypes.CHAR.apply(this, arguments); }
} }
inherits(CHAR, BaseTypes.CHAR);
CHAR.prototype.toSql = function toSql() { class NUMBER extends BaseTypes.NUMBER {
if (this._binary) { toSql() {
return `CHAR BINARY(${this._length})`; let result = this.key;
if (this._unsigned) {
result += ' UNSIGNED';
}
if (this._zerofill) {
result += ' ZEROFILL';
}
if (this._length) {
result += `(${this._length}`;
if (typeof this._decimals === 'number') {
result += `,${this._decimals}`;
}
result += ')';
}
return result;
} }
return BaseTypes.CHAR.prototype.toSql.call(this);
};
function NUMBER(options) {
if (!(this instanceof NUMBER)) return new NUMBER(options);
BaseTypes.NUMBER.apply(this, arguments);
} }
inherits(NUMBER, BaseTypes.NUMBER);
NUMBER.prototype.toSql = function toSql() { class TINYINT extends BaseTypes.TINYINT {
let result = this.key; constructor(length) {
super(length);
if (this._unsigned) { removeUnsupportedIntegerOptions(this);
result += ' UNSIGNED';
}
if (this._zerofill) {
result += ' ZEROFILL';
} }
}
if (this._length) { class SMALLINT extends BaseTypes.SMALLINT {
result += `(${this._length}`; constructor(length) {
if (typeof this._decimals === 'number') { super(length);
result += `,${this._decimals}`; removeUnsupportedIntegerOptions(this);
}
result += ')';
} }
return result;
};
function TINYINT(length) {
if (!(this instanceof TINYINT)) return new TINYINT(length);
BaseTypes.TINYINT.apply(this, arguments);
removeUnsupportedIntegerOptions(this);
} }
inherits(TINYINT, BaseTypes.TINYINT);
TINYINT.prototype.toSql = function toSql() {
return NUMBER.prototype.toSql.call(this);
};
function SMALLINT(length) {
if (!(this instanceof SMALLINT)) return new SMALLINT(length);
BaseTypes.SMALLINT.apply(this, arguments);
removeUnsupportedIntegerOptions(this); class MEDIUMINT extends BaseTypes.MEDIUMINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
} }
inherits(SMALLINT, BaseTypes.SMALLINT);
SMALLINT.prototype.toSql = function toSql() {
return NUMBER.prototype.toSql.call(this);
};
function MEDIUMINT(length) { class INTEGER extends BaseTypes.INTEGER {
if (!(this instanceof MEDIUMINT)) return new MEDIUMINT(length); constructor(length) {
BaseTypes.MEDIUMINT.apply(this, arguments); super(length);
removeUnsupportedIntegerOptions(this);
removeUnsupportedIntegerOptions(this); }
} }
inherits(MEDIUMINT, BaseTypes.MEDIUMINT);
MEDIUMINT.prototype.toSql = function toSql() {
return NUMBER.prototype.toSql.call(this);
};
function INTEGER(length) { class BIGINT extends BaseTypes.BIGINT {
if (!(this instanceof INTEGER)) return new INTEGER(length); constructor(length) {
BaseTypes.INTEGER.apply(this, arguments); super(length);
removeUnsupportedIntegerOptions(this);
removeUnsupportedIntegerOptions(this); }
} }
inherits(INTEGER, BaseTypes.INTEGER);
INTEGER.prototype.toSql = function toSql() { class FLOAT extends BaseTypes.FLOAT {
return NUMBER.prototype.toSql.call(this); }
};
function BIGINT(length) {
if (!(this instanceof BIGINT)) return new BIGINT(length);
BaseTypes.BIGINT.apply(this, arguments);
removeUnsupportedIntegerOptions(this); class DOUBLE extends BaseTypes.DOUBLE {
} }
inherits(BIGINT, BaseTypes.BIGINT);
BIGINT.prototype.toSql = function toSql() { class REAL extends BaseTypes.REAL { }
return NUMBER.prototype.toSql.call(this);
};
function FLOAT(length, decimals) { function parseFloating(value) {
if (!(this instanceof FLOAT)) return new FLOAT(length, decimals); if (typeof value !== 'string') {
BaseTypes.FLOAT.apply(this, arguments); return value;
}
if (value === 'NaN') {
return NaN;
}
if (value === 'Infinity') {
return Infinity;
}
if (value === '-Infinity') {
return -Infinity;
}
} }
inherits(FLOAT, BaseTypes.FLOAT); for (const floating of [FLOAT, DOUBLE, REAL]) {
FLOAT.prototype.toSql = function toSql() { floating.parse = parseFloating;
return NUMBER.prototype.toSql.call(this);
}; };
function DOUBLE(length, decimals) {
if (!(this instanceof DOUBLE)) return new DOUBLE(length, decimals);
BaseTypes.DOUBLE.apply(this, arguments);
}
inherits(DOUBLE, BaseTypes.DOUBLE);
DOUBLE.prototype.toSql = function toSql() {
return NUMBER.prototype.toSql.call(this);
};
function REAL(length, decimals) { for (const num of [FLOAT, DOUBLE, REAL, TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT]) {
if (!(this instanceof REAL)) return new REAL(length, decimals); num.prototype.toSql = NUMBER.prototype.toSql;
BaseTypes.REAL.apply(this, arguments);
}
inherits(REAL, BaseTypes.REAL);
REAL.prototype.toSql = function toSql() {
return NUMBER.prototype.toSql.call(this);
}; };
[FLOAT, DOUBLE, REAL].forEach(floating => { class ENUM extends BaseTypes.ENUM {
floating.parse = function parse(value) { toSql() {
if (typeof value === 'string') { return 'TEXT';
if (value === 'NaN') {
return NaN;
}
if (value === 'Infinity') {
return Infinity;
}
if (value === '-Infinity') {
return -Infinity;
}
}
return value;
};
});
function ENUM() {
if (!(this instanceof ENUM)) {
const obj = Object.create(ENUM.prototype);
ENUM.apply(obj, arguments);
return obj;
} }
BaseTypes.ENUM.apply(this, arguments);
} }
inherits(ENUM, BaseTypes.ENUM);
ENUM.prototype.toSql = function toSql() {
return 'TEXT';
};
const exports = { return {
DATE, DATE,
DATEONLY, DATEONLY,
STRING, STRING,
...@@ -292,16 +209,4 @@ module.exports = BaseTypes => { ...@@ -292,16 +209,4 @@ module.exports = BaseTypes => {
JSON: JSONTYPE, JSON: JSONTYPE,
CITEXT CITEXT
}; };
_.forIn(exports, (DataType, key) => {
if (!DataType.key) DataType.key = key;
if (!DataType.extend) {
DataType.extend = oldType => {
return new DataType(oldType.options);
};
}
});
return exports;
}; };
...@@ -11,6 +11,8 @@ const operatorsArray = _.values(operators); ...@@ -11,6 +11,8 @@ const operatorsArray = _.values(operators);
let inflection = require('inflection'); let inflection = require('inflection');
exports.classToInvokable = require('./utils/classToInvokable').classToInvokable;
exports.Promise = Promise; exports.Promise = Promise;
function useInflection(_inflection) { function useInflection(_inflection) {
...@@ -595,15 +597,6 @@ function defaults(object) { ...@@ -595,15 +597,6 @@ function defaults(object) {
} }
exports.defaults = defaults; exports.defaults = defaults;
function classToInvokable(Class) {
return new Proxy(Class, {
apply(Target, thisArg, args) {
return new Target(...args);
}
});
}
exports.classToInvokable = classToInvokable;
/** /**
* *
* @param {Object} index * @param {Object} index
......
'use strict';
/**
* Wraps a constructor to not need the `new` keyword using a proxy.
* Only used for data types.
* @param {Function} ctor
* @return {Proxy}
*/
function classToInvokable(Class) {
return new Proxy(Class, {
apply(Target, thisArg, args) {
return new Target(...args);
}
});
}
exports.classToInvokable = classToInvokable;
'use strict';
const util = require('util');
/**
* like util.inherits, but also copies over static properties. Inherit child constructor
* to have properties from super constructor
*
* @param {Function} constructor the child constructor
* @param {Function} superConstructor the super constructor
*
* @private
*/
function inherits(constructor, superConstructor) {
util.inherits(constructor, superConstructor); // Instance (prototype) methods
Object.assign(constructor, superConstructor); // Static methods
}
module.exports = inherits;
module.exports.inherits = inherits;
module.exports.default = inherits;
...@@ -890,7 +890,6 @@ describe(Support.getTestDialectTeaser('BelongsTo'), () => { ...@@ -890,7 +890,6 @@ describe(Support.getTestDialectTeaser('BelongsTo'), () => {
dataTypes.forEach(dataType => { dataTypes.forEach(dataType => {
const tableName = `TaskXYZ_${dataType.key}`; const tableName = `TaskXYZ_${dataType.key}`;
Tasks[dataType] = this.sequelize.define(tableName, { title: DataTypes.STRING }); Tasks[dataType] = this.sequelize.define(tableName, { title: DataTypes.STRING });
Tasks[dataType].belongsTo(User, { foreignKey: 'userId', keyType: dataType, constraints: false }); Tasks[dataType].belongsTo(User, { foreignKey: 'userId', keyType: dataType, constraints: false });
}); });
......
...@@ -64,6 +64,14 @@ export const TICK_CHAR: string; ...@@ -64,6 +64,14 @@ export const TICK_CHAR: string;
export function addTicks(s: string, tickChar?: string): string; export function addTicks(s: string, tickChar?: string): string;
export function removeTicks(s: string, tickChar?: string): string; export function removeTicks(s: string, tickChar?: string): string;
/**
* Wraps a constructor to not need the `new` keyword using a proxy.
* Only used for data types.
*/
export function classToInvokable<T extends new (...args: any[]) => any>(ctor: T): T & {
(...args: ConstructorParameters<T>): T;
}
export class SequelizeMethod { export class SequelizeMethod {
} }
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!