data-defender
Advanced tools
Comparing version 0.0.2 to 0.0.3
@@ -10,3 +10,4 @@ 'use strict'; | ||
'DATE', | ||
'BOOL' | ||
'BOOL', | ||
'MOD' | ||
]; | ||
@@ -21,2 +22,3 @@ | ||
exports.BOOL = 6; | ||
exports.MOD = 7; | ||
@@ -23,0 +25,0 @@ exports.isValidType = function (type) { |
{ | ||
"name": "data-defender", | ||
"description": "A database-agnostic simple data schema enforcer for node.js", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"author": "Nobuyori Takahashi <voltrue2@yahoo.com>", | ||
@@ -6,0 +6,0 @@ "repository": { |
@@ -96,6 +96,12 @@ # data-defender | ||
defender.DATATYPE.BOOL; | ||
// modified time type | ||
defender.DATATYPE.MOD; | ||
``` | ||
**NOTE**: `UNIQUE` data type's value cannot be updated. | ||
**NOTE 1**: `UNIQUE` and `MOD` data type's value cannot be updated. | ||
**NOTE 2**: `MOD` data type property will be updated automatically by updating other properties. | ||
##### default [*default value] | ||
@@ -102,0 +108,0 @@ |
@@ -18,3 +18,3 @@ 'use strict'; | ||
for (var name in data) { | ||
this.update(name, data[name]); | ||
this._update(name, data[name]); | ||
} | ||
@@ -26,12 +26,25 @@ this.emit('load', data); | ||
Data.prototype.update = function (name, value) { | ||
this._update(name, value); | ||
var list = this._struct._getModtimeList(); | ||
for (var i = 0, len = list.length; i < len; i++) { | ||
this._props[list[i]] = Date.now(); | ||
} | ||
this.emit('update', name, value); | ||
this.emit('update.' + name, value); | ||
}; | ||
Data.prototype._update = function (name, value) { | ||
var data = this._struct._update(name, value); | ||
var hasProp = this._props.hasOwnProperty(name); | ||
if (data.unique && hasProp && this._props[name] !== value) { | ||
throw new Error(ERROR.VAL_CHANGE_NOT_ALLOWED); | ||
if (data.noChange && hasProp && this._props[name] !== value) { | ||
throw new Error(ERROR.VAL_CHANGE_NOT_ALLOWED(name)); | ||
} | ||
// auto-convert | ||
if (value instanceof Date) { | ||
value = value.getTime(); | ||
} | ||
this._props[name] = value; | ||
this.emit('update', name, value); | ||
this.emit('update.' + name, value); | ||
}; | ||
@@ -38,0 +51,0 @@ |
@@ -14,2 +14,3 @@ 'use strict'; | ||
this._uniqueList = []; | ||
this._modtimeList = []; | ||
this._lock = false; | ||
@@ -88,2 +89,5 @@ } | ||
} | ||
if (valMap.type === DATATYPE.MOD) { | ||
this._modtimeList.push(name); | ||
} | ||
}; | ||
@@ -127,3 +131,3 @@ | ||
var constraint = this._constraints[name]; | ||
if (constraint.type === DATATYPE.DATE) { | ||
if (constraint.type === DATATYPE.DATE || constraint.type === DATATYPE.MOD) { | ||
return new Date(value); | ||
@@ -142,4 +146,7 @@ } | ||
if (this._constraints[name].type === DATATYPE.UNIQUE) { | ||
return { name: name, value: value, unique: true }; | ||
return { name: name, value: value, noChange: true }; | ||
} | ||
if (this._constraints[name].type === DATATYPE.MOD) { | ||
return { name: name, value: value, noChange: true }; | ||
} | ||
if (this._constraints[name].type === DATATYPE.DATE && value instanceof Date) { | ||
@@ -151,2 +158,6 @@ value = value.getTime(); | ||
Struct.prototype._getModtimeList = function () { | ||
return this._modtimeList; | ||
}; | ||
Struct.prototype._toJSON = function (props) { | ||
@@ -215,2 +226,3 @@ var parser = function (obj) { | ||
case DATATYPE.DATE: | ||
case DATATYPE.MOD: | ||
if (!value instanceof Date) { | ||
@@ -217,0 +229,0 @@ return false; |
@@ -550,2 +550,99 @@ var assert = require('assert'); | ||
var testTwo; | ||
var testTwoMap; | ||
it('can define a schema and another schema as a property', function () { | ||
testTwo = defender.create('testTwo'); | ||
testTwo.define('id', { | ||
type: defender.DATATYPE.UNIQUE | ||
}); | ||
testTwo.define('text', { | ||
type: defender.DATATYPE.STR, | ||
max: 10, | ||
min: 0 | ||
}); | ||
testTwo.define('map', { | ||
type: defender.DATATYPE.OBJ, | ||
min: 2 | ||
}); | ||
testTwo.define('modtime', { | ||
type: defender.DATATYPE.MOD, | ||
default: Date.now | ||
}); | ||
var now = Date.now(); | ||
var d = testTwo.load(); | ||
assert(d.get('id')); | ||
assert.equal(now, d.get('modtime').getTime()); | ||
testTwoMap = defender.create('testTwoMap'); | ||
testTwoMap.define('name', { | ||
type: defender.DATATYPE.STR, | ||
max: 4, | ||
min: 1 | ||
}); | ||
testTwoMap.define('list', { | ||
type: defender.DATATYPE.ARR, | ||
max: 4, | ||
min: 1 | ||
}); | ||
}); | ||
it('can update a propaty that w/ schema constraints', function () { | ||
var d = testTwo.load(); | ||
var map = testTwoMap.load(); | ||
var data = { | ||
name: 'ABCD', | ||
list: [1, 2] | ||
}; | ||
map.update('name', data.name); | ||
map.update('list', data.list); | ||
d.update('map', map.toJSON()); | ||
var json = d.toJSON(); | ||
for (var i in data) { | ||
assert.equal(JSON.stringify(data[i]), JSON.stringify(json.map[i])); | ||
} | ||
}); | ||
it('can load an existing data and keep the mod type data as loaded', function () { | ||
var then = new Date('2000-10-28 00:00:00').getTime(); | ||
var data = { | ||
text: 'EFCG', | ||
map: { one: 1, two: 2 }, | ||
modtime: new Date(then) | ||
}; | ||
var d = testTwo.load(data); | ||
assert.equal(then, d.get('modtime').getTime()); | ||
}); | ||
it('cannot update mod type property', function () { | ||
var then = new Date('2000-10-28 00:00:00').getTime(); | ||
var data = { | ||
text: 'EFCG', | ||
map: { one: 1, two: 2 }, | ||
modtime: new Date(then) | ||
}; | ||
var d = testTwo.load(data); | ||
var error = true; | ||
assert.equal(then, d.get('modtime').getTime()); | ||
try { | ||
d.update('modtime', Date.now()); | ||
} catch (e) { | ||
error = false; | ||
} | ||
assert.equal(then, d.get('modtime').getTime()); | ||
}); | ||
it('can update mod type property automatically by updating other properties', function () { | ||
var then = new Date('2000-10-28 00:00:00').getTime(); | ||
var data = { | ||
text: 'EFCG', | ||
map: { one: 1, two: 2 }, | ||
modtime: new Date(then) | ||
}; | ||
var d = testTwo.load(data); | ||
var error = true; | ||
assert.equal(then, d.get('modtime').getTime()); | ||
d.update('text', 'HIJK'); | ||
assert.notEqual(then, d.get('modtime').getTime()); | ||
}); | ||
}); |
33732
968
200