Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Rename `id` method to `identify`; Also the creation of records with a…

… defined identifier; Optimize id incremental creation
  • Loading branch information...
commit e8404e48c6890362aed55d5360efee978413420e 1 parent 92b4adf
@wdavidw authored
View
63 lib/Records.coffee
@@ -223,27 +223,31 @@ module.exports = class Records extends Schema
# Get current date once if schema is temporal
date = new Date Date.now() if temporal?
# Generate new identifiers
- multi.incr "#{db}:#{name}_incr" for x in records
- multi.exec (err, recordIds) =>
+ incr = 0
+ for record in records then incr++ unless record[identifier]
+ multi.incrby "#{db}:#{name}_incr", incr
+ multi.exec (err, recordId) =>
+ recordId = recordId - incr
return callback err if err
multi = redis.multi()
for record, i in records
+ recordId++ unless record[identifier]
# Enrich the record with its identifier
- record[identifier] = recordId = recordIds[i]
+ record[identifier] = recordId unless record[identifier]
# Enrich the record with a creation date
record[temporal.creation] = date if temporal?.creation? and not record[temporal.creation]?
# Enrich the record with a creation date
record[temporal.modification] = date if temporal?.modification? and not record[temporal.modification]?
# Register new identifier
- multi.sadd "#{db}:#{name}_#{identifier}", recordId
+ multi.sadd "#{db}:#{name}_#{identifier}", record[identifier]
# Deal with Unique
for property of unique
- multi.hset "#{db}:#{name}_#{property}", record[property], recordId if record[property]
+ multi.hset "#{db}:#{name}_#{property}", record[property], record[identifier] if record[property]
# Deal with Index
for property of index
value = record[property]
value = hash value
- multi.sadd "#{db}:#{name}_#{property}:#{value}", recordId
+ multi.sadd "#{db}:#{name}_#{property}:#{value}", record[identifier]
#multi.zadd "#{s.db}:#{s.name}_#{property}", 0, record[property]
# Store the record
r = {}
@@ -253,7 +257,7 @@ module.exports = class Records extends Schema
# Filter null values
r[property] = value if value?
@serialize r
- multi.hmset "#{db}:#{name}:#{recordId}", r
+ multi.hmset "#{db}:#{name}:#{record[identifier]}", r
multi.exec (err, results) =>
return callback err if err
for result in results
@@ -313,7 +317,7 @@ module.exports = class Records extends Schema
`options` All options are optional. Options properties include:
- * `properties` Array of properties to fetch, all properties if not defined.
+ * `properties` Array of properties to fetch, all properties unless defined.
* `force` Force the retrieval of properties even if already present in the record objects.
* `accept_null` Skip objects if they are provided as null.
* `object` If `true`, return an object where keys are the identifier and value are the fetched records
@@ -338,7 +342,7 @@ module.exports = class Records extends Schema
if options.accept_null? and not records.some((record) -> record isnt null)
return callback null, if isArray then records else records[0]
# Retrieve records identifiers
- @id records, {object: true, accept_null: options.accept_null?}, (err, records) =>
+ @identify records, {object: true, accept_null: options.accept_null?}, (err, records) =>
return callback err if err
cmds = []
records.forEach (record, i) ->
@@ -374,8 +378,8 @@ module.exports = class Records extends Schema
callback null, if isArray then records else records[0]
###
- `id(records, [options], callback)`
- ----------------------------------
+ `identify(records, [options], callback)`
+ ----------------------------------------
Extract record identifiers or set the identifier to null if its associated record could not be found.
The method doesn't hit the database to validate record values and if an id is
@@ -414,7 +418,7 @@ module.exports = class Records extends Schema
console.log ids
###
- id: (records, options, callback) ->
+ identify: (records, options, callback) ->
if arguments.length is 2
callback = options
options = {}
@@ -447,20 +451,19 @@ module.exports = class Records extends Schema
records[i][identifier] = record
else
return callback new Error 'Invalid id, got ' + (JSON.stringify record)
- # No need to hit redis if no comand are registered
- if cmds.length is 0
- if not options.object
+ finalize = ->
+ unless options.object
records = for record in records
if record? then record[identifier] else record
- return callback null, if isArray then records else records[0]
+ callback null, if isArray then records else records[0]
+ # No need to hit redis if there is no command
+ return finalize() if cmds.length is 0
# Run the commands
multi = redis.multi cmds
multi.exec (err, results) =>
- unless options.object
- records = for record in records
- record[identifier]
+ return callback err if err
@unserialize records
- callback null, if isArray then records else records[0]
+ finalize()
###
`list([options], callback)`
@@ -566,7 +569,7 @@ module.exports = class Records extends Schema
multi.del tempkey if tempkey
multi.exec()
###
-
+
`remove(records, callback)`
---------------------------
Remove one or several records from the database. The function will also
@@ -598,24 +601,24 @@ module.exports = class Records extends Schema
return callback err if err
callback null, records.length
###
-
+
`update(records, [options], callback)`
--------------------------------------
Update one or several records. 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.
@@ -625,7 +628,7 @@ module.exports = class Records extends Schema
username: 'my_username'
age: 28
, (err, user) -> console.log user
-
+
###
update: (records, options, callback) ->
if arguments.length is 2
@@ -644,7 +647,7 @@ module.exports = class Records extends Schema
# 2.1 Make sure the new property is not assigned to another record
# 2.2 Erase old index & Create new index
# 3. Save the record
- @id records, {object: true}, (err, records) =>
+ @identify records, {object: true}, (err, records) =>
return callback err if err
# Stop here if a record is invalid
for record in records
View
51 test/create.coffee
@@ -26,8 +26,8 @@ describe 'create', ->
it 'Test create # one user', (next) ->
Users.create
- username: 'my_username',
- email: 'my@email.com',
+ username: 'my_username'
+ email: 'my@email.com'
password: 'my_password'
, (err, user) ->
should.not.exist err
@@ -38,12 +38,12 @@ describe 'create', ->
it 'Test create # multiple users', (next) ->
Users.create [
- username: 'my_username_1',
- email: 'my_first@email.com',
+ username: 'my_username_1'
+ email: 'my_first@email.com'
password: 'my_password'
,
- username: 'my_username_2',
- email: 'my_second@email.com',
+ username: 'my_username_2'
+ email: 'my_second@email.com'
password: 'my_password'
], (err, users) ->
should.not.exist err
@@ -54,8 +54,8 @@ describe 'create', ->
it 'Test create # existing id', (next) ->
Users.create
- username: 'my_username',
- email: 'my@email.com',
+ username: 'my_username'
+ email: 'my@email.com'
password: 'my_password'
, (err, user) ->
should.not.exist err
@@ -76,8 +76,8 @@ describe 'create', ->
, (err, user) ->
should.not.exist err
Users.create
- username: 'my_username',
- email: 'my@email.com',
+ username: 'my_username'
+ email: 'my@email.com'
password: 'my_password'
, (err, user) ->
err.message.should.eql 'Record 1 already exists'
@@ -85,12 +85,12 @@ describe 'create', ->
it 'should only return the newly created identifiers', (next) ->
Users.create [
- username: 'my_username_1',
- email: 'my_first@email.com',
+ username: 'my_username_1'
+ email: 'my_first@email.com'
password: 'my_password'
,
- username: 'my_username_2',
- email: 'my_second@email.com',
+ username: 'my_username_2'
+ email: 'my_second@email.com'
password: 'my_password'
], identifiers: true, (err, ids) ->
should.not.exist err
@@ -100,12 +100,12 @@ describe 'create', ->
it 'should only return selected properties', (next) ->
Users.create [
- username: 'my_username_1',
- email: 'my_first@email.com',
+ username: 'my_username_1'
+ email: 'my_first@email.com'
password: 'my_password'
,
- username: 'my_username_2',
- email: 'my_second@email.com',
+ username: 'my_username_2'
+ email: 'my_second@email.com'
password: 'my_password'
], properties: ['email'], (err, users) ->
should.not.exist err
@@ -115,14 +115,23 @@ describe 'create', ->
it 'should only insert defined properties', (next) ->
Users.create
- username: 'my_username_1',
- email: 'my_first@email.com',
- password: 'my_password'
+ username: 'my_username_1'
+ email: 'my_first@email.com'
zombie: 'e.t. maison'
, (err, user) ->
Users.get user.user_id, (err, user) ->
should.not.exist user.zombie
Users.clear next
+ it 'should let you pass your own identifiers', (next) ->
+ Users.create
+ user_id: 1
+ username: 'my_username_1'
+ , (err, user) ->
+ Users.get 1, (err, user) ->
+ user.username.should.equal 'my_username_1'
+ Users.clear next
+
+
View
44 test/id.coffee → test/identify.coffee
@@ -25,19 +25,19 @@ describe 'id', ->
client.quit next
it 'Test id # number', (next) ->
- Users.id 3, (err, userId) ->
+ Users.identify 3, (err, userId) ->
should.not.exist err
userId.should.eql 3
- Users.id [3], (err, userId) ->
+ Users.identify [3], (err, userId) ->
should.not.exist err
userId.should.eql [3]
next()
it 'Test id # user.user_id', (next) ->
- Users.id {user_id: 3}, (err, userId) ->
+ Users.identify {user_id: 3}, (err, userId) ->
should.not.exist err
userId.should.eql 3
- Users.id [{user_id: 3, username: 'my_username'}], (err, userId) ->
+ Users.identify [{user_id: 3, username: 'my_username'}], (err, userId) ->
should.not.exist err
userId.should.eql [3]
next()
@@ -49,11 +49,11 @@ describe 'id', ->
password: 'my_password'
, (err, user) ->
# Pass an object
- Users.id {username: 'my_username'}, (err, userId) ->
+ Users.identify {username: 'my_username'}, (err, userId) ->
should.not.exist err
userId.should.eql user.user_id
# Pass an array of ids and objects
- Users.id [1, {username: 'my_username'}, 2], (err, userId) ->
+ Users.identify [1, {username: 'my_username'}, 2], (err, userId) ->
should.not.exist err
userId.should.eql [1, user.user_id, 2]
Users.clear next
@@ -61,9 +61,9 @@ describe 'id', ->
it 'Test id # invalid object empty', (next) ->
# Test an array of 3 arguments,
# but the second is invalid since it's an empty object
- Users.id [1, {}, {user_id: 2}], (err, user) ->
+ Users.identify [1, {}, {user_id: 2}], (err, user) ->
err.message.should.eql 'Invalid record, got {}'
- Users.id {}, (err, user) ->
+ Users.identify {}, (err, user) ->
err.message.should.eql 'Invalid record, got {}'
Users.clear next
@@ -75,7 +75,7 @@ describe 'id', ->
{ username: 'my_username_2', email: 'my2@mail.com' }
], (err, users) ->
# Test return id
- Users.id [
+ Users.identify [
{ username: users[1].username } # By unique
{ user_id: users[0].user_id } # By identifier
{ username: 'who are you' } # Alien
@@ -92,7 +92,7 @@ describe 'id', ->
{ username: 'my_username_1', email: 'my1@mail.com' }
{ username: 'my_username_2', email: 'my2@mail.com' }
], (err, users) ->
- Users.id [
+ Users.identify [
{ username: users[1].username } # By unique
{ user_id: users[0].user_id } # By identifier
{ username: 'who are you' } # Alien
@@ -106,46 +106,46 @@ describe 'id', ->
it 'Test id # invalid type id', (next) ->
# Test an array of 3 arguments,
# but the second is invalid since it's a boolean
- Users.id [1, true, {user_id: 2}], (err, user) ->
+ Users.identify [1, true, {user_id: 2}], (err, user) ->
err.message.should.eql 'Invalid id, got true'
- Users.id false, (err, user) ->
+ Users.identify false, (err, user) ->
err.message.should.eql 'Invalid id, got false'
Users.clear next
it 'Test id # invalid type null', (next) ->
# Test an array of 3 arguments,
# but the second is invalid since it's a boolean
- Users.id [1, null, {user_id: 2}], (err, users) ->
+ Users.identify [1, null, {user_id: 2}], (err, users) ->
err.message.should.eql 'Null record'
- Users.id null, (err, user) ->
+ Users.identify null, (err, user) ->
err.message.should.eql 'Null record'
Users.clear next
it 'Test id # accept null', (next) ->
# Test an array of 3 arguments,
# but the second is invalid since it's a boolean
- Users.id [1, null, {user_id: 2}], {accept_null: true}, (err, users) ->
+ Users.identify [1, null, {user_id: 2}], {accept_null: true}, (err, users) ->
should.not.exist err
users.length.should.eql 3
should.exist users[0]
should.not.exist users[1]
should.exist users[2]
# Test null
- Users.id null, {accept_null: true}, (err, user) ->
+ Users.identify null, {accept_null: true}, (err, user) ->
should.not.exist err
should.not.exist user
Users.clear next
it 'Test id # accept null return object', (next) ->
# Same test than 'Test id # accept null' with the 'object' option
- Users.id [1, null, {user_id: 2}], {accept_null: true, object: true}, (err, users) ->
+ Users.identify [1, null, {user_id: 2}], {accept_null: true, object: true}, (err, users) ->
should.not.exist err
users.length.should.eql 3
users[0].user_id.should.eql 1
should.not.exist users[1]
users[2].user_id.should.eql 2
# Test null
- Users.id null, {accept_null: true, object: true}, (err, user) ->
+ Users.identify null, {accept_null: true, object: true}, (err, user) ->
should.not.exist err
should.not.exist user
Users.clear next
@@ -157,11 +157,11 @@ describe 'id', ->
password: 'my_password'
}, (err, orgUser) ->
# Pass an id
- Users.id orgUser.user_id, {object: true}, (err, user) ->
+ Users.identify orgUser.user_id, {object: true}, (err, user) ->
should.not.exist err
user.should.eql {user_id: orgUser.user_id}
# Pass an array of ids
- Users.id [orgUser.user_id, orgUser.user_id], {object: true}, (err, user) ->
+ Users.identify [orgUser.user_id, orgUser.user_id], {object: true}, (err, user) ->
user.should.eql [{user_id: orgUser.user_id}, {user_id: orgUser.user_id}]
Users.clear next
@@ -172,11 +172,11 @@ describe 'id', ->
password: 'my_password'
}, (err, orgUser) ->
# Pass an object
- Users.id {username: 'my_username'}, {object: true}, (err, user) ->
+ Users.identify {username: 'my_username'}, {object: true}, (err, user) ->
should.not.exist err
user.should.eql {username: 'my_username', user_id: orgUser.user_id}
# Pass an array of ids and objects
- Users.id [1, {username: 'my_username'}, 2], {object: true}, (err, user) ->
+ Users.identify [1, {username: 'my_username'}, 2], {object: true}, (err, user) ->
should.not.exist err
user.should.eql [{user_id: 1}, {username: 'my_username', user_id: orgUser.user_id}, {user_id: 2}]
Users.clear next
Please sign in to comment.
Something went wrong with that request. Please try again.