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

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,28 +196,19 @@ modules.exports = function sequelizeAdditions(Sequelize) { ...@@ -196,28 +196,19 @@ modules.exports = function sequelizeAdditions(Sequelize) {
/* /*
* Create new types * Create new types
*/ */
class NEWTYPE extends DataTypes.ABSTRACT {
// Create new type
DataTypes.NEWTYPE = function NEWTYPE() {
if (!(this instanceof DataTypes.NEWTYPE)) return new DataTypes.NEWTYPE()
}
inherits(DataTypes.NEWTYPE, DataTypes.ABSTRACT)
// Mandatory, set key
DataTypes.NEWTYPE.prototype.key = DataTypes.NEWTYPE.key = 'NEWTYPE'
// Mandatory, complete definition of the new type in the database // Mandatory, complete definition of the new type in the database
DataTypes.NEWTYPE.prototype.toSql = function toSql() { toSql() {
return 'INTEGER(11) UNSIGNED ZEROFILL' return 'INTEGER(11) UNSIGNED ZEROFILL'
} }
// Optional, validator function // Optional, validator function
DataTypes.NEWTYPE.prototype.validate = function validate(value, options) { validate(value, options) {
return (typeof value === 'number') && (! Number.isNaN(value)) return (typeof value === 'number') && (! Number.isNaN(value))
} }
// Optional, sanitizer // Optional, sanitizer
DataTypes.NEWTYPE.prototype._sanitize = function _sanitize(value) { _sanitize(value) {
// Force all numbers to be positive // Force all numbers to be positive
if (value < 0) { if (value < 0) {
value = 0 value = 0
...@@ -227,20 +218,27 @@ modules.exports = function sequelizeAdditions(Sequelize) { ...@@ -227,20 +218,27 @@ modules.exports = function sequelizeAdditions(Sequelize) {
} }
// Optional, value stringifier before sending to database // Optional, value stringifier before sending to database
DataTypes.NEWTYPE.prototype._stringify = function _stringify(value) { _stringify(value) {
return value.toString() return value.toString()
} }
// Optional, disable escaping after stringifier. Not recommended.
// Warning: disables Sequelize protection against SQL injections
//DataTypes.NEWTYPE.escape = false
// Optional, parser for values received from the database // Optional, parser for values received from the database
DataTypes.NEWTYPE.parse = function parse(value) { static parse(value) {
return Number.parseInt(value) return Number.parseInt(value)
} }
}
// Mandatory, set key
DataTypes.NEWTYPE.prototype.key = DataTypes.NEWTYPE.key = 'NEWTYPE'
// Optional, disable escaping after stringifier. Not recommended.
// Warning: disables Sequelize protection against SQL injections
//DataTypes.NEWTYPE.escape = false
// 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();
}
BaseTypes.DECIMAL.apply(this, arguments);
}
inherits(DECIMAL, BaseTypes.DECIMAL);
DECIMAL.prototype.toSql = function toSql() {
let definition = BaseTypes.DECIMAL.prototype.toSql.apply(this);
if (this._unsigned) { if (this._unsigned) {
definition += ' UNSIGNED'; definition += ' UNSIGNED';
} }
if (this._zerofill) { if (this._zerofill) {
definition += ' ZEROFILL'; definition += ' ZEROFILL';
} }
return definition; return definition;
};
function DATE(length) {
if (!(this instanceof DATE)) {
return new DATE(length);
} }
BaseTypes.DATE.apply(this, arguments);
} }
inherits(DATE, BaseTypes.DATE); class DATE extends BaseTypes.DATE {
toSql() {
DATE.prototype.toSql = function toSql() {
return `DATETIME${this._length ? `(${this._length})` : ''}`; return `DATETIME${this._length ? `(${this._length})` : ''}`;
}; }
_stringify(date, options) {
DATE.prototype._stringify = function _stringify(date, options) { date = this._applyTimezone(date, options);
date = BaseTypes.DATE.prototype._applyTimezone(date, options);
return date.format('YYYY-MM-DD HH:mm:ss.SSS'); return date.format('YYYY-MM-DD HH:mm:ss.SSS');
}; }
static parse(value, options) {
DATE.parse = function parse(value, options) {
value = value.string(); value = value.string();
if (value === null) { if (value === null) {
return value; return value;
} }
if (moment.tz.zone(options.timezone)) { if (moment.tz.zone(options.timezone)) {
value = moment.tz(value, options.timezone).toDate(); value = moment.tz(value, options.timezone).toDate();
} else { }
else {
value = new Date(`${value} ${options.timezone}`); value = new Date(`${value} ${options.timezone}`);
} }
return value; 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() {
if (!(this instanceof UUID)) {
return new UUID();
}
BaseTypes.UUID.call(this);
} }
inherits(UUID, BaseTypes.UUID); class UUID extends BaseTypes.UUID {
toSql() {
UUID.prototype.toSql = function toSql() {
return 'CHAR(36) BINARY'; return 'CHAR(36) BINARY';
};
function GEOMETRY(type, srid) {
if (!(this instanceof GEOMETRY)) {
return new GEOMETRY(type, srid);
} }
BaseTypes.GEOMETRY.apply(this, arguments); }
class GEOMETRY extends BaseTypes.GEOMETRY {
constructor(type, srid) {
super(type, srid);
if (_.isEmpty(this.type)) { if (_.isEmpty(this.type)) {
this.sqlType = this.key; this.sqlType = this.key;
} else { }
else {
this.sqlType = this.type; this.sqlType = this.type;
} }
} }
toSql() {
inherits(GEOMETRY, BaseTypes.GEOMETRY);
GEOMETRY.prototype.toSql = function toSql() {
return this.sqlType; 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 ENUM extends BaseTypes.ENUM {
toSql(options) {
ENUM.prototype.toSql = function toSql(options) {
return `ENUM(${this.values.map(value => options.escape(value)).join(', ')})`; return `ENUM(${this.values.map(value => options.escape(value)).join(', ')})`;
};
function JSONTYPE() {
if (!(this instanceof JSONTYPE)) {
return new JSONTYPE();
} }
BaseTypes.JSON.call(this);
} }
inherits(JSONTYPE, BaseTypes.JSON); class JSONTYPE extends BaseTypes.JSON {
_stringify(value, options) {
JSONTYPE.prototype._stringify = function _stringify(value, options) {
return options.operation === 'where' && typeof value === 'string' ? value return options.operation === 'where' && typeof value === 'string' ? value
: JSON.stringify(value); : JSON.stringify(value);
}; }
}
const exports = { return {
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;
}; };
'use strict'; 'use strict';
const _ = require('lodash');
const moment = require('moment'); const moment = require('moment');
const inherits = require('../../utils/inherits');
module.exports = BaseTypes => { module.exports = BaseTypes => {
const warn = BaseTypes.ABSTRACT.warn.bind(undefined, 'https://msdn.microsoft.com/en-us/library/ms187752%28v=sql.110%29.aspx'); const warn = BaseTypes.ABSTRACT.warn.bind(undefined, 'https://msdn.microsoft.com/en-us/library/ms187752%28v=sql.110%29.aspx');
...@@ -50,13 +48,8 @@ module.exports = BaseTypes => { ...@@ -50,13 +48,8 @@ module.exports = BaseTypes => {
// BaseTypes.GEOMETRY.types.mssql = [240]; // not yet supported // BaseTypes.GEOMETRY.types.mssql = [240]; // not yet supported
BaseTypes.GEOMETRY.types.mssql = false; BaseTypes.GEOMETRY.types.mssql = false;
function BLOB(length) { class BLOB extends BaseTypes.BLOB {
if (!(this instanceof BLOB)) return new BLOB(length); toSql() {
BaseTypes.BLOB.apply(this, arguments);
}
inherits(BLOB, BaseTypes.BLOB);
BLOB.prototype.toSql = function toSql() {
if (this._length) { if (this._length) {
if (this._length.toLowerCase() === 'tiny') { // tiny = 2^8 if (this._length.toLowerCase() === 'tiny') { // tiny = 2^8
warn('MSSQL does not support BLOB with the `length` = `tiny` option. `VARBINARY(256)` will be used instead.'); warn('MSSQL does not support BLOB with the `length` = `tiny` option. `VARBINARY(256)` will be used instead.');
...@@ -65,43 +58,35 @@ module.exports = BaseTypes => { ...@@ -65,43 +58,35 @@ module.exports = BaseTypes => {
warn('MSSQL does not support BLOB with the `length` option. `VARBINARY(MAX)` will be used instead.'); warn('MSSQL does not support BLOB with the `length` option. `VARBINARY(MAX)` will be used instead.');
} }
return 'VARBINARY(MAX)'; return 'VARBINARY(MAX)';
}; }
_hexify(hex) {
BLOB.prototype._hexify = function _hexify(hex) {
return `0x${hex}`; return `0x${hex}`;
};
function STRING(length, binary) {
if (!(this instanceof STRING)) return new STRING(length, binary);
BaseTypes.STRING.apply(this, arguments);
} }
inherits(STRING, BaseTypes.STRING); }
STRING.prototype.toSql = function toSql() {
class STRING extends BaseTypes.STRING {
toSql() {
if (!this._binary) { if (!this._binary) {
return `NVARCHAR(${this._length})`; return `NVARCHAR(${this._length})`;
} }
return `BINARY(${this._length})`; return `BINARY(${this._length})`;
}; }
_stringify(value, options) {
STRING.prototype.escape = false;
STRING.prototype._stringify = function _stringify(value, options) {
if (this._binary) { if (this._binary) {
return BLOB.prototype._stringify(value); return BLOB.prototype._stringify(value);
} }
return options.escape(value); return options.escape(value);
}; }
STRING.prototype._bindParam = function _bindParam(value, options) { _bindParam(value, options) {
return options.bindParam(this._binary ? Buffer.from(value) : value); return options.bindParam(this._binary ? Buffer.from(value) : value);
};
function TEXT(length) {
if (!(this instanceof TEXT)) return new TEXT(length);
BaseTypes.TEXT.apply(this, arguments);
} }
inherits(TEXT, BaseTypes.TEXT); }
STRING.prototype.escape = false;
TEXT.prototype.toSql = function toSql() { class TEXT extends BaseTypes.TEXT {
toSql() {
// TEXT is deprecated in mssql and it would normally be saved as a non-unicode string. // TEXT is deprecated in mssql and it would normally be saved as a non-unicode string.
// Using unicode is just future proof // Using unicode is just future proof
if (this._length) { if (this._length) {
...@@ -112,93 +97,66 @@ module.exports = BaseTypes => { ...@@ -112,93 +97,66 @@ module.exports = BaseTypes => {
warn('MSSQL does not support TEXT with the `length` option. `NVARCHAR(MAX)` will be used instead.'); warn('MSSQL does not support TEXT with the `length` option. `NVARCHAR(MAX)` will be used instead.');
} }
return 'NVARCHAR(MAX)'; return 'NVARCHAR(MAX)';
};
function BOOLEAN() {
if (!(this instanceof BOOLEAN)) return new BOOLEAN();
BaseTypes.BOOLEAN.call(this);
} }
inherits(BOOLEAN, BaseTypes.BOOLEAN); }
BOOLEAN.prototype.toSql = function toSql() { class BOOLEAN extends BaseTypes.BOOLEAN {
toSql() {
return 'BIT'; return 'BIT';
};
function UUID() {
if (!(this instanceof UUID)) return new UUID();
BaseTypes.UUID.call(this);
} }
inherits(UUID, BaseTypes.UUID); }
UUID.prototype.toSql = function toSql() { class UUID extends BaseTypes.UUID {
toSql() {
return 'CHAR(36)'; return 'CHAR(36)';
};
function NOW() {
if (!(this instanceof NOW)) return new NOW();
BaseTypes.NOW.call(this);
} }
inherits(NOW, BaseTypes.NOW); }
NOW.prototype.toSql = function toSql() { class NOW extends BaseTypes.NOW {
toSql() {
return 'GETDATE()'; return 'GETDATE()';
};
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 {
toSql() {
return 'DATETIMEOFFSET'; return 'DATETIMEOFFSET';
};
function DATEONLY() {
if (!(this instanceof DATEONLY)) return new DATEONLY();
BaseTypes.DATEONLY.call(this);
} }
inherits(DATEONLY, BaseTypes.DATEONLY); }
DATEONLY.parse = function(value) { class DATEONLY extends BaseTypes.DATEONLY {
static parse(value) {
return moment(value).format('YYYY-MM-DD'); return moment(value).format('YYYY-MM-DD');
}; };
}
function INTEGER(length) { class INTEGER extends BaseTypes.INTEGER {
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); }
class TINYINT extends BaseTypes.TINYINT {
function TINYINT(length) { constructor(length) {
if (!(this instanceof TINYINT)) return new TINYINT(length); super(length);
BaseTypes.TINYINT.apply(this, arguments);
removeUnsupportedIntegerOptions(this); removeUnsupportedIntegerOptions(this);
} }
inherits(TINYINT, BaseTypes.TINYINT); }
class SMALLINT extends BaseTypes.SMALLINT {
function SMALLINT(length) { constructor(length) {
if (!(this instanceof SMALLINT)) return new SMALLINT(length); super(length);
BaseTypes.SMALLINT.apply(this, arguments);
removeUnsupportedIntegerOptions(this); removeUnsupportedIntegerOptions(this);
} }
inherits(SMALLINT, BaseTypes.SMALLINT); }
class BIGINT extends BaseTypes.BIGINT {
function BIGINT(length) { constructor(length) {
if (!(this instanceof BIGINT)) return new BIGINT(length); super(length);
BaseTypes.BIGINT.apply(this, arguments);
removeUnsupportedIntegerOptions(this); removeUnsupportedIntegerOptions(this);
} }
inherits(BIGINT, BaseTypes.BIGINT); }
class REAL extends BaseTypes.REAL {
function REAL(length, decimals) { constructor(length, decimals) {
if (!(this instanceof REAL)) return new REAL(length, decimals); super(length, decimals);
BaseTypes.REAL.apply(this, arguments);
// MSSQL does not support any options for real // MSSQL does not support any options for real
if (this._length || this.options.length || this._unsigned || this._zerofill) { if (this._length || this.options.length || this._unsigned || this._zerofill) {
warn('MSSQL does not support REAL with options. Plain `REAL` will be used instead.'); warn('MSSQL does not support REAL with options. Plain `REAL` will be used instead.');
...@@ -208,12 +166,10 @@ module.exports = BaseTypes => { ...@@ -208,12 +166,10 @@ module.exports = BaseTypes => {
this._zerofill = undefined; this._zerofill = undefined;
} }
} }
inherits(REAL, BaseTypes.REAL); }
class FLOAT extends BaseTypes.FLOAT {
function FLOAT(length, decimals) { constructor(length, decimals) {
if (!(this instanceof FLOAT)) return new FLOAT(length, decimals); super(length, decimals);
BaseTypes.FLOAT.apply(this, arguments);
// MSSQL does only support lengths as option. // MSSQL does only support lengths as option.
// Values between 1-24 result in 7 digits precision (4 bytes storage size) // Values between 1-24 result in 7 digits precision (4 bytes storage size)
// Values between 25-53 result in 15 digits precision (8 bytes storage size) // Values between 25-53 result in 15 digits precision (8 bytes storage size)
...@@ -232,23 +188,14 @@ module.exports = BaseTypes => { ...@@ -232,23 +188,14 @@ module.exports = BaseTypes => {
this._zerofill = undefined; this._zerofill = undefined;
} }
} }
inherits(FLOAT, BaseTypes.FLOAT);
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 ENUM extends BaseTypes.ENUM {
toSql() {
ENUM.prototype.toSql = function toSql() {
return 'VARCHAR(255)'; return 'VARCHAR(255)';
}; }
}
const exports = { return {
BLOB, BLOB,
BOOLEAN, BOOLEAN,
ENUM, ENUM,
...@@ -265,15 +212,4 @@ module.exports = BaseTypes => { ...@@ -265,15 +212,4 @@ module.exports = BaseTypes => {
FLOAT, FLOAT,
TEXT TEXT
}; };
_.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();
}
inherits(DECIMAL, BaseTypes.DECIMAL);
DECIMAL.prototype.toSql = function toSql() {
let definition = BaseTypes.DECIMAL.prototype.toSql.apply(this);
if (this._unsigned) { if (this._unsigned) {
definition += ' UNSIGNED'; definition += ' UNSIGNED';
} }
if (this._zerofill) { if (this._zerofill) {
definition += ' ZEROFILL'; definition += ' ZEROFILL';
} }
return definition; 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 {
toSql() {
return `DATETIME${this._length ? `(${this._length})` : ''}`; return `DATETIME${this._length ? `(${this._length})` : ''}`;
}; }
_stringify(date, options) {
DATE.prototype._stringify = function _stringify(date, options) { date = this._applyTimezone(date, options);
date = BaseTypes.DATE.prototype._applyTimezone(date, options);
// Fractional DATETIMEs only supported on MySQL 5.6.4+ // Fractional DATETIMEs only supported on MySQL 5.6.4+
if (this._length) { if (this._length) {
return date.format('YYYY-MM-DD HH:mm:ss.SSS'); return date.format('YYYY-MM-DD HH:mm:ss.SSS');
} }
return date.format('YYYY-MM-DD HH:mm:ss'); return date.format('YYYY-MM-DD HH:mm:ss');
}; }
static parse(value, options) {
DATE.parse = function parse(value, options) {
value = value.string(); value = value.string();
if (value === null) { if (value === null) {
return value; return value;
} }
if (moment.tz.zone(options.timezone)) { if (moment.tz.zone(options.timezone)) {
value = moment.tz(value, options.timezone).toDate(); value = moment.tz(value, options.timezone).toDate();
} else { }
else {
value = new Date(`${value} ${options.timezone}`); value = new Date(`${value} ${options.timezone}`);
} }
return value; return value;
};
function DATEONLY() {
if (!(this instanceof DATEONLY)) return new DATEONLY();
BaseTypes.DATEONLY.call(this);
} }
inherits(DATEONLY, BaseTypes.DATEONLY); }
DATEONLY.parse = function parse(value) { class DATEONLY extends BaseTypes.DATEONLY {
static parse(value) {
return value.string(); return value.string();
};
function UUID() {
if (!(this instanceof UUID)) return new UUID();
BaseTypes.UUID.call(this);
} }
inherits(UUID, BaseTypes.UUID); }
class UUID extends BaseTypes.UUID {
UUID.prototype.toSql = function toSql() { toSql() {
return 'CHAR(36) BINARY'; 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;
} else if (SUPPORTED_GEOMETRY_TYPES.includes(this.type)) { return;
}
if (SUPPORTED_GEOMETRY_TYPES.includes(this.type)) {
this.sqlType = this.type; this.sqlType = this.type;
} else { return;
throw new Error(`Supported geometry types are: ${SUPPORTED_GEOMETRY_TYPES.join(', ')}`);
} }
throw new Error(`Supported geometry types are: ${SUPPORTED_GEOMETRY_TYPES.join(', ')}`);
} }
inherits(GEOMETRY, BaseTypes.GEOMETRY); static parse(value) {
GEOMETRY.parse = GEOMETRY.prototype.parse = function parse(value) {
value = value.buffer(); value = value.buffer();
// Empty buffer, MySQL doesn't support POINT EMPTY // Empty buffer, MySQL doesn't support POINT EMPTY
// check, https://dev.mysql.com/worklog/task/?id=2381 // check, https://dev.mysql.com/worklog/task/?id=2381
if (!value || value.length === 0) { if (!value || value.length === 0) {
return null; return null;
} }
// For some reason, discard the first 4 bytes // For some reason, discard the first 4 bytes
value = value.slice(4); value = value.slice(4);
return wkx.Geometry.parse(value).toGeoJSON(); return wkx.Geometry.parse(value).toGeoJSON();
}; }
toSql() {
GEOMETRY.prototype.toSql = function toSql() {
return this.sqlType; 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) { class ENUM extends BaseTypes.ENUM {
toSql(options) {
return `ENUM(${this.values.map(value => options.escape(value)).join(', ')})`; return `ENUM(${this.values.map(value => options.escape(value)).join(', ')})`;
};
function JSONTYPE() {
if (!(this instanceof JSONTYPE)) return new JSONTYPE();
BaseTypes.JSON.call(this);
} }
inherits(JSONTYPE, BaseTypes.JSON); }
JSONTYPE.prototype._stringify = function _stringify(value, options) { class JSONTYPE extends BaseTypes.JSON {
_stringify(value, options) {
return options.operation === 'where' && typeof value === 'string' ? value : JSON.stringify(value); 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,106 +42,71 @@ module.exports = BaseTypes => { ...@@ -45,106 +42,71 @@ 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);
}
inherits(JSONTYPE, BaseTypes.JSON);
JSONTYPE.parse = function parse(data) {
return JSON.parse(data); return JSON.parse(data);
};
function DATE(length) {
if (!(this instanceof DATE)) return new DATE(length);
BaseTypes.DATE.apply(this, arguments);
} }
inherits(DATE, BaseTypes.DATE); }
DATE.parse = function parse(date, options) { class DATE extends BaseTypes.DATE {
static parse(date, options) {
if (!date.includes('+')) { if (!date.includes('+')) {
// For backwards compat. Dates inserted by sequelize < 2.0dev12 will not have a timestamp set // For backwards compat. Dates inserted by sequelize < 2.0dev12 will not have a timestamp set
return new Date(date + options.timezone); return new Date(date + options.timezone);
} }
return new Date(date); // We already have a timezone stored in the string 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) { class DATEONLY extends BaseTypes.DATEONLY {
static parse(date) {
return date; return date;
};
function STRING(length, binary) {
if (!(this instanceof STRING)) return new STRING(length, binary);
BaseTypes.STRING.apply(this, arguments);
} }
inherits(STRING, BaseTypes.STRING); }
STRING.prototype.toSql = function toSql() { class STRING extends BaseTypes.STRING {
toSql() {
if (this._binary) { if (this._binary) {
return `VARCHAR BINARY(${this._length})`; return `VARCHAR BINARY(${this._length})`;
} }
return BaseTypes.STRING.prototype.toSql.call(this); return super.toSql(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 TEXT extends BaseTypes.TEXT {
toSql() {
if (this._length) { if (this._length) {
warn('SQLite does not support TEXT with options. Plain `TEXT` will be used instead.'); warn('SQLite does not support TEXT with options. Plain `TEXT` will be used instead.');
this._length = undefined; this._length = undefined;
} }
return 'TEXT'; 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 CITEXT extends BaseTypes.CITEXT {
toSql() {
return 'TEXT COLLATE NOCASE'; return 'TEXT COLLATE NOCASE';
};
function CHAR(length, binary) {
if (!(this instanceof CHAR)) return new CHAR(length, binary);
BaseTypes.CHAR.apply(this, arguments);
} }
inherits(CHAR, BaseTypes.CHAR); }
CHAR.prototype.toSql = function toSql() { class CHAR extends BaseTypes.CHAR {
toSql() {
if (this._binary) { if (this._binary) {
return `CHAR BINARY(${this._length})`; return `CHAR BINARY(${this._length})`;
} }
return BaseTypes.CHAR.prototype.toSql.call(this); return super.toSql();
}; }
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 NUMBER extends BaseTypes.NUMBER {
toSql() {
let result = this.key; let result = this.key;
if (this._unsigned) { if (this._unsigned) {
result += ' UNSIGNED'; result += ' UNSIGNED';
} }
if (this._zerofill) { if (this._zerofill) {
result += ' ZEROFILL'; result += ' ZEROFILL';
} }
if (this._length) { if (this._length) {
result += `(${this._length}`; result += `(${this._length}`;
if (typeof this._decimals === 'number') { if (typeof this._decimals === 'number') {
...@@ -153,98 +115,56 @@ module.exports = BaseTypes => { ...@@ -153,98 +115,56 @@ module.exports = BaseTypes => {
result += ')'; result += ')';
} }
return result; return result;
}; }
}
function TINYINT(length) {
if (!(this instanceof TINYINT)) return new TINYINT(length);
BaseTypes.TINYINT.apply(this, arguments);
class TINYINT extends BaseTypes.TINYINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this); 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);
class SMALLINT extends BaseTypes.SMALLINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this); removeUnsupportedIntegerOptions(this);
} }
inherits(SMALLINT, BaseTypes.SMALLINT); }
SMALLINT.prototype.toSql = function toSql() {
return NUMBER.prototype.toSql.call(this);
};
function MEDIUMINT(length) {
if (!(this instanceof MEDIUMINT)) return new MEDIUMINT(length);
BaseTypes.MEDIUMINT.apply(this, arguments);
class MEDIUMINT extends BaseTypes.MEDIUMINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this); removeUnsupportedIntegerOptions(this);
} }
inherits(MEDIUMINT, BaseTypes.MEDIUMINT); }
MEDIUMINT.prototype.toSql = function toSql() {
return NUMBER.prototype.toSql.call(this);
};
function INTEGER(length) {
if (!(this instanceof INTEGER)) return new INTEGER(length);
BaseTypes.INTEGER.apply(this, arguments);
class INTEGER extends BaseTypes.INTEGER {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this); removeUnsupportedIntegerOptions(this);
} }
inherits(INTEGER, BaseTypes.INTEGER); }
INTEGER.prototype.toSql = function toSql() {
return NUMBER.prototype.toSql.call(this);
};
function BIGINT(length) {
if (!(this instanceof BIGINT)) return new BIGINT(length);
BaseTypes.BIGINT.apply(this, arguments);
class BIGINT extends BaseTypes.BIGINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this); removeUnsupportedIntegerOptions(this);
} }
inherits(BIGINT, BaseTypes.BIGINT);
BIGINT.prototype.toSql = function toSql() {
return NUMBER.prototype.toSql.call(this);
};
function FLOAT(length, decimals) {
if (!(this instanceof FLOAT)) return new FLOAT(length, decimals);
BaseTypes.FLOAT.apply(this, arguments);
} }
inherits(FLOAT, BaseTypes.FLOAT);
FLOAT.prototype.toSql = function toSql() {
return NUMBER.prototype.toSql.call(this);
};
function DOUBLE(length, decimals) { class FLOAT extends BaseTypes.FLOAT {
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) { class DOUBLE extends BaseTypes.DOUBLE {
if (!(this instanceof REAL)) return new REAL(length, decimals);
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 REAL extends BaseTypes.REAL { }
floating.parse = function parse(value) {
if (typeof value === 'string') { function parseFloating(value) {
if (typeof value !== 'string') {
return value;
}
if (value === 'NaN') { if (value === 'NaN') {
return NaN; return NaN;
} }
...@@ -255,25 +175,22 @@ module.exports = BaseTypes => { ...@@ -255,25 +175,22 @@ module.exports = BaseTypes => {
return -Infinity; return -Infinity;
} }
} }
return value; for (const floating of [FLOAT, DOUBLE, REAL]) {
floating.parse = parseFloating;
}; };
});
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() { for (const num of [FLOAT, DOUBLE, REAL, TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT]) {
return 'TEXT'; num.prototype.toSql = NUMBER.prototype.toSql;
}; };
const exports = { class ENUM extends BaseTypes.ENUM {
toSql() {
return 'TEXT';
}
}
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!