diff --git a/lib/model.js b/lib/model.js index 0bda2ab7..b5be726c 100644 --- a/lib/model.js +++ b/lib/model.js @@ -16,6 +16,7 @@ var validations = require('./validations'); var _extend = util._extend; var utils = require('./utils'); var fieldsToArray = utils.fieldsToArray; +var uuid = require('node-uuid'); // Set up an object for quick lookup var BASE_TYPES = { @@ -228,10 +229,34 @@ ModelBaseClass.prototype._initProperties = function (data, options) { } // FIXME: We should coerce the value // will implement it after we refactor the PropertyDefinition - self.__data[p] = def; + self.__data[p] = propVal = def; } } + // Set default value using a named function + if (propVal === undefined) { + var defn = properties[p].defaultFn; + switch (defn) { + case undefined: + break; + case 'guid': + case 'uuid': + // Generate a v1 (time-based) id + propVal = uuid.v1(); + break; + case 'now': + propVal = new Date(); + break; + default: + // TODO Support user-provided functions via a registry of functions + console.warn('Unknown default value provider ' + defn); + } + // FIXME: We should coerce the value + // will implement it after we refactor the PropertyDefinition + if (propVal !== undefined) + self.__data[p] = propVal; + } + // Handle complex types (JSON/Object) if (!BASE_TYPES[type.name]) { diff --git a/package.json b/package.json index e4a7091e..a1a0fb0d 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "inflection": "^1.6.0", "lodash": "~3.0.1", "loopback-connector": "1.x", + "node-uuid": "^1.4.2", "qs": "^2.3.3", "traverse": "^0.6.6" }, diff --git a/test/manipulation.test.js b/test/manipulation.test.js index 03a42d41..df92680c 100644 --- a/test/manipulation.test.js +++ b/test/manipulation.test.js @@ -4,6 +4,8 @@ var should = require('./init.js'); var db, Person; var ValidationError = require('..').ValidationError; +var UUID_REGEXP = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + describe('manipulation', function () { before(function (done) { @@ -471,6 +473,42 @@ describe('manipulation', function () { done(); }); + + it('should generate a new id when "defaultFn" is "guid"', function (done) { + var CustomModel = db.define('CustomModel', { + guid: { type: String, defaultFn: 'guid' } + }); + + var inst = CustomModel.create(function (err, m) { + m.guid.should.match(UUID_REGEXP); + done(); + }); + }); + + it('should generate a new id when "defaultfn" is "uuid"', function (done) { + var CustomModel = db.define('custommodel', { + guid: { type: String, defaultFn: 'uuid' } + }); + + var inst = CustomModel.create(function (err, m) { + m.guid.should.match(UUID_REGEXP); + done(); + }); + }); + + it('should generate current time when "defaultFn" is "now"', function (done) { + var CustomModel = db.define('CustomModel', { + now: { type: Date, defaultFn: 'now' } + }); + + var now = Date.now(); + var inst = CustomModel.create(function (err, m) { + m.now.should.be.instanceOf(Date); + m.now.should.be.within(now, now + 200); + done(); + }); + }); + // it('should work when constructor called as function', function() { // var p = Person({name: 'John Resig'}); // p.should.be.an.instanceOf(Person);