pd-redis-base-record
Simple ORM record model with auto-increment sid
Installation
$ npm install -save pd-redis-base-record
## Starting
```javascript
var User = require('pd-redis-base-record')('user');
```
'user' is the code name of the model, for the code below
```javascript
var User = require('pd-redis-base-record')('USER');
```
It is equivalent to
```javascript
require('pd-redis-base-record')('user')
```
It is converting any model name into lower-case letters.
## To create: Model.create(JSON)
```javascript
var profile = {
email : 'myletter@email.com',
name : 'John Doe',
password : 'abc123'
};
var creatingPromise = User.create(profile);
```
The returning value of User.create is a [q.Promise](https://github.com/kriskowal/q)
The newly created record will have an auto-generated sequence id which is unique of the type.
It can be fetched by using 'then' of the promise as follows
```javascript
creatingPromise.then(function(sid){
//do something to the returned sid...
});
```
q.Promise is also used in other CRUD methods or modules as shown below
To modify: Model.modify(JSON)
var profileToModify = {
'pd-sid' : '12' ,
name : 'Jane Doe',
gender : 'female'
};
User.modify(profileToModify).then(function(){
});
'pd-sid' is not a changeable field, but it has to be assigned to specify which record to be modified.
To remove: Model.remove(sid)
var sid = '12';
User.remove(sid).then(function(){
});
To read
To get total amount of records of a model: Model.amount()
User.amount().then(function(amount){
});
To get a record by specifying sid: Model.findBySid(sid)
User.findBySid(12).then(function(record){
});
To get a list of records: Model.range(option)
User.range({
latest: (new Date()).getTime(),
earliest: 0 ,
limit : [0, 50],
}).then(function(records){
});
To decide if a record is brand new: Model.checkAbsence(sid)
User.checkAbsence(sid).then(function(){
}).fail(function(err){
var announcer = require('pd-api-announcer');
if(announcer.isClientErrorFor(err, 'user', 'taken')) {
}
});
###To decide if a record already existed: Model.checkPresence(sid)
User.checkPresence(sid).then(function(){
}).fail(function(err){
var announcer = require('pd-api-announcer');
if(announcer.isClientErrorFor(err, 'user', 'gone')){
}
});
To lock
To lock a type of records: Model.lock.sidSet(onLockCallback, expiredAfterMilliseconds)
Where the lock is used, every time the same routine visits the locked sid-set, if there is still a locked routine,
it will wait until the previous routine is done
var onLockCallback = function(){
return User.create({
email: 'myletter@email.com',
password: 'abc123'
});
};
User.lock.sidSet(onLockCallback);
If asynchronous operation is to be added in onLockCallback,
the return value of onLockCallback should be a q.Promise object,
so that the lock will wait until all operations are over then release the lock.
The returning value of User.lock.sidSet() is also a q.Promise,
all code in User.lock.sidSet().then() will be executed after the lock is released
User.lock.sidSet(function(){...}).then(function(){
});
To lock one record: Model.lock.dataForSid(sid, onLockCallback, expiredAfterMilliseconds)
Similar to lock.sidSet(), but it only locks operations on a single record, or to be specific,
dependent on one sid of a type of records
var sid = '12';
var onLockCallback = function(){
return User.modify({
'pd-sid' : sid,
email: 'myletter@email.com',
password: 'abc123'
});
};
User.lock.dataForSid(sid, onLockCallback);
check pd-redis-lock for more details about lock
## More CRUD functions
### To read
#### User.findBySid(sid, option)
It is available to get data from only specific fields with option.fields
```javascript
User.findBySid(12, { fields: ['name', 'email'] }).then(function(record){
//record => ['Jane Doe', 'myletter@email.com']
});
```
It is also available to show 'createdAt' by setting option.withCreatedAt to true
```javascript
User.findBySid(12, { withCreatedAt : true }).then(function(record){
//record => { email: 'myletter@email.com', name: 'Jane Doe', updatedAt : '12345678901', createdAt : '1234567777' }
});
User.findBySid(12, { fields: ['name', 'email'], withCreatedAt: true }).then(function(record){
//record => ['Jane Doe', 'myletter@email.com', '123456788888']
});
```
option.fields and option.withCreatedAt are also available for User.range(option);
### To create, modify or remove
#### User.create(profile, onGeneratingMultiList)
It is available to add a set of redis commands so that when the record is created,
they run together as MULTI commands of the creating action to guarantee the atomicity of the creating operation
```javascript
var hashPwd = function(pwd){ .... }
var password = 'abc123'
var hashedPwd = hashPwd(password);
var onGeneratingMultiList = function(multi, profile){
var sid = profile['pd-sid'];
var newCmd = ['hmset', User.nm.dataForSid(sid), 'password', hashedPwd )];
multi.add(newCmd);
return multi; //must return the MULTI list or a q.Promise that returns a MULTI list
};
User.create({
email : 'myletter@email.com',
password : password
}, onGeneratingMultiList);
```
The 'multi' in onGeneratingMultiList() is an array which looks like the following
```javascript
[
[ 'zadd', 'pd-sids-of:user', 1430675568559, 1 ],
[ 'hmset',
'model:user:withsid:1',
{ email: 'myletter@email.com', password: 'abc123', 'pd-sid': 1 } ] ]
[ 'hmset',
'model:user:withsid:1',
{ email: 'myletter@email.com', password: '[encoded pwd]', 'pd-sid': 1 } ]
]
```
The record will be finally created by executing all the commands in a MULTI in Redis
#### User.modify(profile, onGeneratingMultiList)
For on GeneratingMultiList, it is similar to User.create
#### User.remove(sid, onGeneratingMultiList)
For on GeneratingMultiList, it is similar to User.create
Check pd-node-redis for details of Redis-client implementation