diff --git a/docs/models-definition.md b/docs/models-definition.md index 4883fcb866ad..bb2679749300 100644 --- a/docs/models-definition.md +++ b/docs/models-definition.md @@ -150,6 +150,10 @@ Sequelize.BLOB('tiny') // TINYBLOB (bytea for PostgreSQL. Other o Sequelize.UUID // UUID datatype for PostgreSQL and SQLite, CHAR(36) BINARY for MySQL (use defaultValue: Sequelize.UUIDV1 or Sequelize.UUIDV4 to make sequelize generate the ids automatically) +Sequelize.CIDR // CIDR datatype for PostgreSQL +Sequelize.INET // INET datatype for PostgreSQL +Sequelize.MACADDR // MACADDR datatype for PostgreSQL + Sequelize.RANGE(Sequelize.INTEGER) // Defines int4range range. PostgreSQL only. Sequelize.RANGE(Sequelize.BIGINT) // Defined int8range range. PostgreSQL only. Sequelize.RANGE(Sequelize.DATE) // Defines tstzrange range. PostgreSQL only. diff --git a/lib/data-types.js b/lib/data-types.js index 96d0351b4af2..2af7e1ee1425 100644 --- a/lib/data-types.js +++ b/lib/data-types.js @@ -751,6 +751,51 @@ GEOGRAPHY.prototype._bindParam = function _bindParam(value, options) { return 'GeomFromText(' + options.bindParam(wkx.Geometry.parseGeoJSON(value).toWkt()) + ')'; }; +function CIDR() { + if (!(this instanceof CIDR)) return new CIDR(); +} +inherits(CIDR, ABSTRACT); + +CIDR.prototype.key = CIDR.key = 'CIDR'; + +CIDR.prototype.validate = function validate(value) { + if (!_.isString(value) || !Validator.isIPRange(value)) { + throw new sequelizeErrors.ValidationError(util.format('%j is not a valid CIDR', value)); + } + + return true; +}; + +function INET() { + if (!(this instanceof INET)) return new INET(); +} +inherits(INET, ABSTRACT); + +INET.prototype.key = INET.key = 'INET'; + +INET.prototype.validate = function validate(value) { + if (!_.isString(value) || !Validator.isIP(value)) { + throw new sequelizeErrors.ValidationError(util.format('%j is not a valid INET', value)); + } + + return true; +}; + +function MACADDR() { + if (!(this instanceof MACADDR)) return new MACADDR(); +} +inherits(MACADDR, ABSTRACT); + +MACADDR.prototype.key = MACADDR.key = 'MACADDR'; + +MACADDR.prototype.validate = function validate(value) { + if (!_.isString(value) || !Validator.isMACAddress(value)) { + throw new sequelizeErrors.ValidationError(util.format('%j is not a valid MACADDR', value)); + } + + return true; +}; + for (const helper of Object.keys(helpers)) { for (const DataType of helpers[helper]) { if (!DataType[helper]) { @@ -952,7 +997,10 @@ const DataTypes = module.exports = { DOUBLE, 'DOUBLE PRECISION': DOUBLE, GEOMETRY, - GEOGRAPHY + GEOGRAPHY, + CIDR, + INET, + MACADDR }; _.each(DataTypes, dataType => { diff --git a/lib/dialects/postgres/data-types.js b/lib/dialects/postgres/data-types.js index 820452d7cbed..d985aed3980a 100644 --- a/lib/dialects/postgres/data-types.js +++ b/lib/dialects/postgres/data-types.js @@ -21,6 +21,21 @@ module.exports = BaseTypes => { array_oids: [2951] }; + BaseTypes.CIDR.types.postgres = { + oids: [650], + array_oids: [651] + }; + + BaseTypes.INET.types.postgres = { + oids: [869], + array_oids: [1041] + }; + + BaseTypes.MACADDR.types.postgres = { + oids: [829], + array_oids: [1040] + }; + BaseTypes.JSON.types.postgres = { oids: [114], array_oids: [199] diff --git a/package.json b/package.json index 1588bf6e9640..4691d3858588 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "semver": "^5.5.0", "toposort-class": "^1.0.1", "uuid": "^3.2.1", - "validator": "^10.0.0", + "validator": "^10.4.0", "wkx": "^0.4.5" }, "devDependencies": { diff --git a/test/integration/data-types.test.js b/test/integration/data-types.test.js index 516a3aafaa57..8b007cd89baa 100644 --- a/test/integration/data-types.test.js +++ b/test/integration/data-types.test.js @@ -262,6 +262,36 @@ describe(Support.getTestDialectTeaser('DataTypes'), () => { } }); + it('calls parse and stringify for CIDR', () => { + const Type = new Sequelize.CIDR(); + + if (['postgres'].indexOf(dialect) !== -1) { + return testSuccess(Type, '10.1.2.3/32'); + } else { + testFailure(Type); + } + }); + + it('calls parse and stringify for INET', () => { + const Type = new Sequelize.INET(); + + if (['postgres'].indexOf(dialect) !== -1) { + return testSuccess(Type, '127.0.0.1'); + } else { + testFailure(Type); + } + }); + + it('calls parse and stringify for MACADDR', () => { + const Type = new Sequelize.MACADDR(); + + if (['postgres'].indexOf(dialect) !== -1) { + return testSuccess(Type, '01:23:45:67:89:ab'); + } else { + testFailure(Type); + } + }); + it('calls parse and stringify for ENUM', () => { const Type = new Sequelize.ENUM('hat', 'cat');