Permalink
Browse files

Add validate method, email now a type

  • Loading branch information...
1 parent d195ebb commit 93325beca8620956f6c1dc9e4a37b6459a294e4d @wdavidw wdavidw committed Mar 6, 2012
View
@@ -1,9 +1,6 @@
Schema = require './Schema'
-isEmail = (email) ->
- /^[a-z0-9,!#\$%&'\*\+\/\=\?\^_`\{\|}~\-]+(\.[a-z0-9,!#\$%&'\*\+\/\=\?\^_`\{\|}~\-]+)*@[a-z0-9\-]+(\.[a-z0-9\-]+)*\.([a-z]{2,})$/.test(email)
-
###
Records
=======
@@ -16,10 +13,10 @@ Identifier
Auto generated identifiers are incremented integers. The next identifier is stored in
a key named as `{s.db}:{s.name}_incr`.
-Records
--------
+Data
+----
-Records are stored as a single hash named as `{s.db}:{s.name}:{idenfitier}`. The hash
+Records data is stored as a single hash named as `{s.db}:{s.name}:{idenfitier}`. The hash
keys map to the record properties and the hash value map to the values associated with
each properties.
@@ -142,7 +139,7 @@ module.exports = class Records extends Schema
###
`create(records, [options], callback)` Create new records
----------------------------------------------
- Take a record object or multiple records and insert them. The records must no
+ Take a record object or multiple records and insert them. The records must not
exists in the database or an error will be returned in the callback. The records objects
passed in the function are returned in the callback with their new identifier property.
@@ -151,12 +148,15 @@ module.exports = class Records extends Schema
`options` Options properties include:
* `identifiers` Return only the created identifiers instead of the records.
+ * `validate` Validate the records.
`callback` Called on success or failure. Received parameters are:
* `err` Error object if any.
* `records` Records with their newly created identifier.
+ Records are not validated, it is the responsability of the client program calling `create` to either
+ call `validate` before calling `create` or to passs the `validate` options.
###
create: (records, options, callback) ->
@@ -167,15 +167,10 @@ module.exports = class Records extends Schema
{db, name, temporal, properties, identifier, index, unique} = @data
isArray = Array.isArray records
records = [records] unless isArray
- # Sanitize records
- for record in records
- # Apply property definitions
- for property, def of properties
- # Validation check
- if def.required and not record[property]?
- return callback new Error "Required property #{property}"
- else if def.email and not isEmail record.email
- return callback new Error "Invalid email #{record.email}"
+ # Validate records
+ if options.validate
+ try @validate records, throw: true
+ catch e then return callback e, (if isArray then records else records[0])
# Persist
@exists records, (err, recordIds) =>
return callback err if err
@@ -482,13 +477,46 @@ module.exports = class Records extends Schema
callback null, records.length
###
- Update one or several records
+
+ `update(records, [options], callback)` Update one or several records
+ --------------------------------------------------------------------
+ Take a record object or multiple records and insert them. The records must
+ exists in the database or an error will be returned in the callback. The existence
+ of a record may be discovered through its identifier or the presence of a unique property.
+
+ `records` Record object or array of record objects.
+
+ `options` Options properties include:
+
+ * `validate` Validate the records.
+
+ `callback` Called on success or failure. Received parameters are:
+
+ * `err` Error object if any.
+ * `records` Records with their newly created identifier.
+
+ Records are not validated, it is the responsability of the client program calling `create` to either
+ call `validate` before calling `create` or to passs the `validate` options.
+
+ Updating a single record
+ Users.update
+ username: 'my_username'
+ age: 28
+ , (err, user) -> console.log user
+
###
- update: (records, callback) ->
+ update: (records, options, callback) ->
+ if arguments.length is 2
+ callback = options
+ options = {}
{redis, hash} = @
{db, name, temporal, properties, identifier, unique, index} = @data
isArray = Array.isArray records
records = [records] unless isArray
+ # Validate records
+ if options.validate
+ try @validate records, {throw: true, skip_required: true}
+ catch e then return callback e, (if isArray then records else records[0])
# 1. Get values of indexed properties
# 2. If indexed properties has changed
# 2.1 Make sure the new property is not assigned to another record
View
@@ -1,6 +1,9 @@
crypto = require 'crypto'
+isEmail = (email) ->
+ /^[a-z0-9,!#\$%&'\*\+\/\=\?\^_`\{\|}~\-]+(\.[a-z0-9,!#\$%&'\*\+\/\=\?\^_`\{\|}~\-]+)*@[a-z0-9\-]+(\.[a-z0-9\-]+)*\.([a-z]{2,})$/.test(email)
+
###
Schema
======
@@ -15,7 +18,7 @@ Define a new schema.
Record properties may be defined by the following keys:
-* `type` Use to cast the value inside Redis, one of `string`, `int` or `date`.
+* `type` Use to cast the value inside Redis, one of `string`, `int`, `date` or `email`.
* `identifier` Mark this property as the identifier, only one property may be an identifier.
* `index` Create an index on the property.
* `unique` Create a unique index on the property.
@@ -241,6 +244,42 @@ module.exports = class Schema
else
[ @data.temporal.creation, @data.temporal. modification ]
+ ###
+
+ `validate(records, [options])` Validate
+ ---------------------------------------
+ Validate the properties of one or more records. Return a validation
+ object or an array of validation objects depending on the provided
+ records arguments. Keys of a validation object are the name of the invalid
+ properties and their value is a string indicating the type of error.
+
+ `records` Record object or array of record objects.
+
+ `options` Options include:
+
+ * `throw` Throw errors on first invalid property instead of returning a validation object.
+ * `skip_required` Doesn't validate missing properties defined as `required`, usefull for partial update.
+
+ ###
+ validate: (records, options = {}) ->
+ {db, name, properties} = @data
+ # console.log 'records', records
+ isArray = Array.isArray records
+ records = [records] unless isArray
+ validations = for record in records
+ validation = {}
+ for x, property of properties
+ if not options.skip_required and property.required and not record[property.name]?
+ if options.throw
+ then throw new Error "Required property #{property.name}"
+ else validation[property.name] = 'required'
+ else if property.type is 'email' and not isEmail record[property.name]
+ if options.throw
+ then throw new Error "Invalid email #{record[property.name]}"
+ else validation[property.name] = 'invalid_email'
+ validation
+ if isArray then validations else validations[0]
+
###
Define a property as unique
---------------------------
@@ -1,34 +0,0 @@
-
-should = require 'should'
-
-try config = require '../conf/test' catch e
-ron = require '../index'
-
-describe 'create_validation', ->
-
- client = Users = null
-
- before (next) ->
- client = ron config
- Users = client.get
- name: 'users'
- properties:
- user_id: identifier: true
- username: unique: true
- email: {index: true, email: true}
- next()
-
- beforeEach (next) ->
- Users.clear next
-
- after (next) ->
- client.quit next
-
- it 'Test create validate # email with record', (next) ->
- Users.create
- username: 'my_username',
- email: 'invalid_email.com',
- password: 'my_password'
- , (err, user) ->
- err.message.should.eql 'Invalid email invalid_email.com'
- Users.clear next
File renamed without changes.
File renamed without changes.
File renamed without changes.
View
@@ -0,0 +1,56 @@
+
+should = require 'should'
+
+try config = require '../conf/test' catch e
+ron = require '../index'
+
+describe 'create_validation', ->
+
+ client = Users = null
+
+ before (next) ->
+ client = ron config
+ Users = client.get
+ name: 'users'
+ properties:
+ user_id: identifier: true
+ email: {type: 'email', index: true}
+ next()
+
+ beforeEach (next) ->
+ Users.clear next
+
+ after (next) ->
+ client.quit next
+
+ it 'should validate email on creation', (next) ->
+ Users.create
+ email: 'invalid_email.com'
+ , validate: true, (err, user) ->
+ err.message.should.eql 'Invalid email invalid_email.com'
+ user.email.should.eql 'invalid_email.com'
+ Users.create
+ email: 'valid@email.com'
+ , validate: true, (err, user) ->
+ should.not.exist err
+ Users.clear next
+
+ it 'should validate email on update', (next) ->
+ Users.create
+ email: 'valid@email.com'
+ , (err, user) ->
+ Users.update
+ user_id: user.user_id
+ email: 'invalid_email.com'
+ , validate: true, (err, user) ->
+ err.message.should.eql 'Invalid email invalid_email.com'
+ Users.update
+ user_id: user.user_id
+ email: 'valid@email.com'
+ , validate: true, (err, user) ->
+ should.not.exist err
+ Users.clear next
+
+
+
+

0 comments on commit 93325be

Please sign in to comment.