Comparing version 2.0.0-rc8 to 2.0.0-rc9
@@ -25,3 +25,5 @@ 'use strict'; | ||
schema : Joi.object(), | ||
timestamps : Joi.boolean().default(false) | ||
timestamps : Joi.boolean().default(false), | ||
createdAt : Joi.alternatives().try(Joi.string(), Joi.boolean()), | ||
updatedAt : Joi.alternatives().try(Joi.string(), Joi.boolean()) | ||
}).required(); | ||
@@ -95,2 +97,4 @@ | ||
self.timestamps = data.timestamps; | ||
self.createdAt = data.createdAt; | ||
self.updatedAt = data.updatedAt; | ||
@@ -109,7 +113,28 @@ if(data.indexes) { | ||
if(self.timestamps) { | ||
var extended = self._modelSchema.keys({ | ||
createdAt : Joi.date(), | ||
updatedAt : Joi.date() | ||
}); | ||
var valids = {}; | ||
var createdAtParamName = 'createdAt'; | ||
var updatedAtParamName = 'updatedAt'; | ||
if(self.createdAt) { | ||
if(_.isString(self.createdAt)) { | ||
createdAtParamName = self.createdAt; | ||
} | ||
} | ||
if(self.updatedAt) { | ||
if(_.isString(self.updatedAt)) { | ||
updatedAtParamName = self.updatedAt; | ||
} | ||
} | ||
if(self.createdAt !== false) { | ||
valids[createdAtParamName] = Joi.date(); | ||
} | ||
if(self.updatedAt !== false) { | ||
valids[updatedAtParamName] = Joi.date(); | ||
} | ||
var extended = self._modelSchema.keys(valids); | ||
self._modelSchema = extended; | ||
@@ -116,0 +141,0 @@ } |
@@ -107,4 +107,6 @@ 'use strict'; | ||
if(self.schema.timestamps && !_.has(data, 'createdAt')) { | ||
data.createdAt = Date.now(); | ||
var paramName = _.isString(self.schema.createdAt) ? self.schema.createdAt : 'createdAt'; | ||
if(self.schema.timestamps && self.schema.createdAt !== false && !_.has(data, paramName)) { | ||
data[paramName] = Date.now(); | ||
} | ||
@@ -195,4 +197,6 @@ | ||
var start = function (callback) { | ||
if(self.schema.timestamps && !_.has(item, 'updatedAt')) { | ||
item.updatedAt = Date.now(); | ||
var paramName = _.isString(self.schema.updatedAt) ? self.schema.updatedAt : 'updatedAt'; | ||
if(self.schema.timestamps && self.schema.updatedAt !== false && !_.has(item, paramName)) { | ||
item[paramName] = Date.now(); | ||
} | ||
@@ -199,0 +203,0 @@ |
{ | ||
"name": "vogels", | ||
"version": "2.0.0-rc8", | ||
"version": "2.0.0-rc9", | ||
"author": "Ryan Fitzgerald <ryan@codebrewstudios.com>", | ||
@@ -5,0 +5,0 @@ "description": "DynamoDB data mapper", |
@@ -100,2 +100,73 @@ # vogels [![Build Status](https://travis-ci.org/ryanfitz/vogels.png?branch=master)](https://travis-ci.org/ryanfitz/vogels) | ||
### Configuration | ||
You can configure vogels to automatically add `createdAt` and `updatedAt` timestamp attributes when | ||
saving and updating a model. `updatedAt` will only be set when updating a record and will not be set on initial creation of the model. | ||
```js | ||
var Account = vogels.define('Account', { | ||
hashKey : 'email', | ||
// add the timestamp attributes (updatedAt, createdAt) | ||
timestamps : true, | ||
schema : { | ||
email : Joi.string().email(), | ||
} | ||
}); | ||
``` | ||
If you want vogels to handle timestamps, but only want some of them, or want your | ||
timestamps to be called something else, you can override each attribute individually: | ||
```js | ||
var Account = vogels.define('Account', { | ||
hashKey : 'email', | ||
// enable timestamps support | ||
timestamps : true, | ||
// I don't want createdAt | ||
createdAt: false, | ||
// I want updatedAt to actually be called updateTimestamp | ||
updatedAt: 'updateTimestamp' | ||
schema : { | ||
email : Joi.string().email(), | ||
} | ||
}); | ||
``` | ||
You can override the table name the model will use. | ||
```js | ||
var Event = vogels.define('Event', { | ||
hashkey : 'name', | ||
schema : { | ||
name : Joi.string(), | ||
total : Joi.number() | ||
}, | ||
tableName: 'deviceEvents' | ||
}); | ||
``` | ||
if you set the tableName to a function, vogels will use the result of the function as the active table to use. | ||
Useful for storing time series data. | ||
```js | ||
var Event = vogels.define('Event', { | ||
hashkey : 'name', | ||
schema : { | ||
name : Joi.string(), | ||
total : Joi.number() | ||
}, | ||
// store monthly event data | ||
tableName: function () { | ||
var d = new Date(); | ||
return ['events', d.getFullYear(), d.getMonth() + 1].join('_'); | ||
} | ||
}); | ||
``` | ||
After you've defined your model you can configure the table name to use. | ||
@@ -897,7 +968,15 @@ By default, the table name used will be the lowercased and pluralized version | ||
## TODO | ||
### Support | ||
* Batch Write Items | ||
* Streaming api support for all operations | ||
Vogels is provided as-is, free of charge. For support, you have a few choices: | ||
- Ask your support question on [Stackoverflow.com](http://stackoverflow.com), and tag your question with **vogels**. | ||
- If you believe you have found a bug in vogels, please submit a support ticket on the [Github Issues page for vogels](http://github.com/ryanfitz/vogels/issues). We'll get to them as soon as we can. | ||
- For general feedback message me on [twitter](https://twitter.com/theryanfitz) | ||
- For more personal or immediate support, I’m available for hire to consult on your project. [Contact](mailto:ryan.fitz1@gmail.com) me for more detals. | ||
### Maintainers | ||
- [Ryan Fitzgerald](http://github.com/ryanfitz) ([@ryanfitz](https://twitter.com/theryanfitz)) | ||
### License | ||
@@ -904,0 +983,0 @@ |
@@ -684,2 +684,3 @@ 'use strict'; | ||
var Model; | ||
var ModelCustomTimestamps; | ||
@@ -695,2 +696,13 @@ before(function (done) { | ||
ModelCustomTimestamps = vogels.define('vogels-int-test-timestamp-custom', { | ||
hashKey : 'id', | ||
timestamps : true, | ||
createdAt : 'created', | ||
updatedAt : 'updated', | ||
schema : { | ||
id : Joi.string() | ||
} | ||
}); | ||
return vogels.createTables(done); | ||
@@ -730,2 +742,34 @@ }); | ||
}); | ||
it('should add custom createdAt param', function (done) { | ||
ModelCustomTimestamps.create({id : 'test-1'}, function (err) { | ||
expect(err).to.not.exist; | ||
ModelCustomTimestamps.get('test-1', function (err2, data) { | ||
expect(err2).to.not.exist; | ||
expect(data.get('id')).to.eql('test-1'); | ||
expect(data.get('created')).to.exist; | ||
return done(); | ||
}); | ||
}); | ||
}); | ||
it('should add custom updatedAt param', function (done) { | ||
ModelCustomTimestamps.update({id : 'test-2'}, function (err) { | ||
expect(err).to.not.exist; | ||
ModelCustomTimestamps.get('test-2', function (err2, data) { | ||
expect(err2).to.not.exist; | ||
expect(data.get('id')).to.eql('test-2'); | ||
expect(data.get('updated')).to.exist; | ||
return done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
@@ -732,0 +776,0 @@ |
@@ -79,3 +79,89 @@ 'use strict'; | ||
it('should add timestamps with custom names to schema', function () { | ||
var config = { | ||
hashKey : 'id', | ||
timestamps : true, | ||
createdAt : 'created', | ||
updatedAt : 'updated', | ||
schema : { | ||
id : Joi.string() | ||
} | ||
}; | ||
var s = new Schema(config); | ||
s.timestamps.should.be.true; | ||
expect(s._modelSchema.describe().children).to.have.keys(['id', 'created', 'updated']); | ||
s._modelDatatypes.should.eql({ | ||
id : 'S', | ||
created : 'DATE', | ||
updated : 'DATE', | ||
}); | ||
}); | ||
it('should only add createdAt timestamp ', function () { | ||
var config = { | ||
hashKey : 'id', | ||
timestamps : true, | ||
updatedAt : false, | ||
schema : { | ||
id : Joi.string() | ||
} | ||
}; | ||
var s = new Schema(config); | ||
s.timestamps.should.be.true; | ||
expect(s._modelSchema.describe().children).to.have.keys(['id', 'createdAt']); | ||
s._modelDatatypes.should.eql({ | ||
id : 'S', | ||
createdAt : 'DATE' | ||
}); | ||
}); | ||
it('should only add updatedAt timestamp ', function () { | ||
var config = { | ||
hashKey : 'id', | ||
timestamps : true, | ||
createdAt : false, | ||
schema : { | ||
id : Joi.string() | ||
} | ||
}; | ||
var s = new Schema(config); | ||
s.timestamps.should.be.true; | ||
expect(s._modelSchema.describe().children).to.have.keys(['id', 'updatedAt']); | ||
s._modelDatatypes.should.eql({ | ||
id : 'S', | ||
updatedAt : 'DATE' | ||
}); | ||
}); | ||
it('should only add custom created timestamp ', function () { | ||
var config = { | ||
hashKey : 'id', | ||
timestamps : true, | ||
createdAt : 'fooCreate', | ||
updatedAt : false, | ||
schema : { | ||
id : Joi.string() | ||
} | ||
}; | ||
var s = new Schema(config); | ||
s.timestamps.should.be.true; | ||
expect(s._modelSchema.describe().children).to.have.keys(['id', 'fooCreate']); | ||
s._modelDatatypes.should.eql({ | ||
id : 'S', | ||
fooCreate : 'DATE' | ||
}); | ||
}); | ||
it('should throw error when hash key is not present', function () { | ||
@@ -82,0 +168,0 @@ var config = {rangeKey : 'foo'}; |
@@ -366,2 +366,70 @@ 'use strict'; | ||
it('should create item with custom createdAt attribute name', function (done) { | ||
var config = { | ||
hashKey: 'email', | ||
timestamps : true, | ||
createdAt : 'created', | ||
schema : { | ||
email : Joi.string(), | ||
} | ||
}; | ||
var s = new Schema(config); | ||
table = new Table('accounts', s, realSerializer, docClient); | ||
var request = { | ||
TableName: 'accounts', | ||
Item : { | ||
email : 'test@test.com', | ||
created : sinon.match.string | ||
} | ||
}; | ||
docClient.putItem.withArgs(request).yields(null, {}); | ||
table.create({email : 'test@test.com'}, function (err, account) { | ||
expect(err).to.not.exist; | ||
account.should.be.instanceof(Item); | ||
account.get('email').should.equal('test@test.com'); | ||
account.get('created').should.exist; | ||
done(); | ||
}); | ||
}); | ||
it('should create item without createdAt param', function (done) { | ||
var config = { | ||
hashKey: 'email', | ||
timestamps : true, | ||
createdAt : false, | ||
schema : { | ||
email : Joi.string(), | ||
} | ||
}; | ||
var s = new Schema(config); | ||
table = new Table('accounts', s, realSerializer, docClient); | ||
var request = { | ||
TableName: 'accounts', | ||
Item : { | ||
email : 'test@test.com' | ||
} | ||
}; | ||
docClient.putItem.withArgs(request).yields(null, {}); | ||
table.create({email : 'test@test.com'}, function (err, account) { | ||
expect(err).to.not.exist; | ||
account.should.be.instanceof(Item); | ||
account.get('email').should.equal('test@test.com'); | ||
expect(account.get('createdAt')).to.not.exist; | ||
done(); | ||
}); | ||
}); | ||
it('should create item with expected option', function (done) { | ||
@@ -368,0 +436,0 @@ var config = { |
286041
7614
1011