diff --git a/Changelog.md b/Changelog.md index 18cddeca..57df3cc3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,8 +1,17 @@ +### v6.0.0 +- [POSSIBLY BREAKING] Set internal default property value to `undefined` instead of `null` ([855](../../pull/855)). + - This will prevent `null` values being explicitly sent to the database when no value was assigned and instead result in the database setting the column to null, or generating a default value. + - Properties with an internal value of `undefined` will still return `null` when accessed. + - Setting a previously filled property to `undefined` will still set it to null in the DB. + - No ORM tests were broken by this change, and as such, the impact of this should be limited to a very small number of corner cases. +- Add PostgreSQL `uuid` column support ([855](../../pull/855)). +- Allow specifying `defaultExpression` (eg. `uuid_generate_v4()` for PostgreSQL or `uuid()` for MySQL) to be executed by the database engine for generating default values ([855](../../pull/855)). + ### v5.0.9 -- Add async versions of driver functions ([851](../../pull/851) +- Add async versions of driver functions ([851](../../pull/851)) ### v5.0.8 -- Improve Typescript typings - add offset prop to find options ([850](../../pull/850) +- Improve Typescript typings - add offset prop to find options ([850](../../pull/850)) ### v5.0.7 - Resolve security vulnerabilities @@ -13,12 +22,12 @@ - If using Postgres and Nodejs v14+, you must use `pg` driver >= 8.1. The cause of this is unclear, but tests timeout. ### v5.0.5 -- Update lodash & sql-ddl-sync version to address security vulnerabilities ([845](../../pull/845) +- Update lodash & sql-ddl-sync version to address security vulnerabilities ([845](../../pull/845)) - Node 11+ support (stable sort; see https://github.com/nodejs/node/issues/24294 for details) - Test against node 12 & 13 ### v5.0.4 -- Update sql-query version to address security vulnerabilities ([841](../../pull/841) +- Update sql-query version to address security vulnerabilities ([841](../../pull/841)) ### v5.0.3 - Update dependencies to address security vulnerabilities diff --git a/lib/Instance.js b/lib/Instance.js index e0778fda..2ad70443 100755 --- a/lib/Instance.js +++ b/lib/Instance.js @@ -153,9 +153,11 @@ function Instance(Model, opts) { prop = Model.allProperties[k]; if (prop) { + /* if (opts.data[k] == null && (prop.type == 'serial' || typeof prop.defaultValue == 'function')) { continue; } + */ if (opts.driver.propertyToValue) { data[k] = opts.driver.propertyToValue(opts.data[k], prop); @@ -484,7 +486,7 @@ function Instance(Model, opts) { } var addInstanceProperty = function (key) { - var defaultValue = null; + var defaultValue = undefined; var prop = Model.allProperties[key]; // This code was first added, and then commented out in a later commit. @@ -502,7 +504,13 @@ function Instance(Model, opts) { Object.defineProperty(instance, key, { get: function () { - return opts.data[key]; + var val = opts.data[key]; + + if (val === undefined) { + return null; + } else { + return opts.data[key]; + } }, set: function (val) { if (prop.key === true) { @@ -731,7 +739,7 @@ function Instance(Model, opts) { if (!asc.reversed && !asc.extension) { for (k in asc.field) { - if (!opts.data.hasOwnProperty(k)) { + if (!instance.hasOwnProperty(k)) { addInstanceProperty(k); } } diff --git a/lib/Property.js b/lib/Property.js index 9fb6ae78..29cab0af 100644 --- a/lib/Property.js +++ b/lib/Property.js @@ -3,7 +3,7 @@ var ORMError = require("./Error"); var KNOWN_TYPES = [ "text", "number", "integer", "boolean", "date", "enum", "object", - "binary", "point", "serial" + "binary", "point", "serial", "uuid" ]; exports.normalize = function (opts) { diff --git a/package-lock.json b/package-lock.json index 63f2cb7e..8f372ea1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "orm", - "version": "5.0.9", + "version": "6.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -2905,11 +2905,11 @@ "dev": true }, "sql-ddl-sync": { - "version": "0.3.16", - "resolved": "https://registry.npmjs.org/sql-ddl-sync/-/sql-ddl-sync-0.3.16.tgz", - "integrity": "sha512-6uiVLN1UAkL2UFpFLjACLYZkzdkPjtRYAgN0jeJWGE/oNzMFabdYZF26IFcXBgobVZ0g8GLagQTI+b9GNKOV2w==", + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/sql-ddl-sync/-/sql-ddl-sync-0.3.18.tgz", + "integrity": "sha512-KZ+7qa4MIIoZZWDzWijMGheMLPkn/58WHt9//UzF84P1XFqsJ4Xk5Xfg8LlWovFXhoi2SRynX1nRw7zXTV9Yig==", "requires": { - "lodash": "~4.17.15" + "lodash": "~4.17.21" } }, "sql-query": { diff --git a/package.json b/package.json index 13adb7bf..c0c6b6a1 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "sqlite", "mongodb" ], - "version": "5.0.9", + "version": "6.0.0", "license": "MIT", "homepage": "http://dresende.github.io/node-orm2", "repository": "http://github.com/dresende/node-orm2.git", @@ -67,7 +67,7 @@ "hat": "0.0.3", "lodash": "^4.17.21", "path-is-absolute": "1.0.1", - "sql-ddl-sync": "0.3.16", + "sql-ddl-sync": "0.3.18", "sql-query": "0.1.27" }, "devDependencies": { diff --git a/test/integration/property-uuid.js b/test/integration/property-uuid.js new file mode 100644 index 00000000..2bc60f1b --- /dev/null +++ b/test/integration/property-uuid.js @@ -0,0 +1,115 @@ +var _ = require('lodash'); +var should = require('should'); +var helper = require('../support/spec_helper'); +var common = require('../common'); +var ORM = require('../../'); + +if (common.protocol() !== "postgres") return; + +describe("Property", function() { + describe("type uuid", function () { + var db = null; + + before(function (done) { + helper.connect(function (connection) { + db = connection; + + done(); + }); + }); + + after(function () { + db.close(); + }); + + var Thing = null; + + before(function (done) { + db.driver.execQuery('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";', function (err) { + should.not.exist(err); + + Thing = db.define('thing', { + id: { type: 'uuid', key: true, defaultExpression: 'uuid_generate_v4()' }, + //id: { type: 'serial' }, + name: { type: 'text' } + }); + + helper.dropSync(Thing, done); + }); + }); + + it("should create the table", function () { + should(true); + }); + + var infoSQL = "SELECT * FROM information_schema.columns WHERE table_name = 'thing' AND column_name = 'id'"; + + it("should have the correct type", function (done) { + db.driver.execQuery(infoSQL, function (err, cols) { + should.not.exist(err); + + var uuidCol = cols[0]; + + should.exist(uuidCol); + should.equal(uuidCol.data_type, 'uuid'); + done(); + }); + }); + + it("should have the correct default value", function (done) { + db.driver.execQuery(infoSQL, function (err, cols) { + should.not.exist(err); + + var uuidCol = cols[0]; + + should.exist(uuidCol); + should.equal(uuidCol.column_default, 'uuid_generate_v4()'); + done(); + }); + }); + + it("should set id automatically", function (done) { + var chair = new Thing({ name: 'chair' }); + + chair.save(function (err) { + should.not.exist(err); + + Thing.find().all(function (err, items) { + should.not.exist(err); + should.equal(items.length, 1); + should.equal(items[0].name, 'chair'); + items[0].id.should.match(/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i); + + done(); + }); + }); + }); + + it("should save", function (done) { + var horse = new Thing({ name: 'horse' }); + + horse.save(function (err) { + should.not.exist(err); + + Thing.get(horse.id, function (err, item) { + should.not.exist(err); + + item.name = 'horsey'; + + item.save(function (err) { + should.not.exist(err); + + Thing.get(horse.id, function (err, item) { + should.not.exist(err); + should.equal(item.id, horse.id); + should.equal(item.name, 'horsey'); + + done(); + }); + }); + }); + }); + }); + + }); +});