unique-model
v0.0.25
Published
The unique data model layer(synchronized using Fibers)
Downloads
12
Readme
UniqueModel.js
UniqueModel.Js is a abstract layer of data model.
Important! It is not a stable package now.
Important! All the session operation must be in the Fibers environment. Like this:
Fiber(function() {
let user = UserDao.findOne({
name: 'ttt'
});
process.exit();
}).run();
Node The README written in difference languages are in doc/README directory of source codehere.
Features
- Use the unique front end to operate the data model.
- Use the extendable backend to support many databases(Only support the MongoDB now).
- Use the Fibers to convert all asynchronous operations to synchronous operations.
Background
When I use Node.js, I always encounter two problems.
- When I use Node.js to process the complex logical problem, I find that it is very difficult to use asynchronous code(even use the promise) to write the maintainable code. A lot of beginners can't comprehend the process of asynchronous. And I feel that the synchronous code always be readable and maintainable.
- If I use two databases or switch the database of program, I must implement the data operations again, because the interfaces of different databases are different.
- If one datum contains other datum(associate with object id), I must query the associated datum manully and it is very boring.
So I plan to write a library to solve these problems.
Installation
First install node.js. Because I use some features of ES6, so it is preferred to use the latest stable version of Node.js. Then:
$ npm install unique-model
Overview
Create the persistent session
The UniqueModel is divided to two layers:
- Unique model layer
- Persistent session layer
The unique model layer is used to define model and operate the model instance. The persistent session layer is used to manage the model instance which is persisted in somewhere.
You can use SQL databases or NoSQL databases like MongoDB to persist the model instance. But we only support MongoDB now(Because I am using MongoDB).
If you want to persist the model instance into database, you must define a persistent session:
let um = require('..');
um.enablePersist();
let session = um.createSession({
backend: 'mongodb',
uri: 'mongodb://localhost/userman',
options: {
user: 'user',
pass: '123456'
}
});
You must call enablePersist function to enable the persist module of UniqueModel because It is off-by-default. Or you can not create the persistent session.
The argument of createSession is an object which has three properties:
- backend: The name of backend. We only support mongodb now.
- uri: The uri of the database you want to connected to, it's format is decided by the backend of session.
- options: The options of session backend. It is required by session backend. And different backend may have different options.
After create the persistent session, UniqueModel will create the session backend and connect to database.
Define model
The next step is to define the model. Unique model will create the model class which record the information of fields.
let Types = um.Types;
let Tag = um.model.createModel('Tag', {
name: Types.Text()
});
let Image = um.model.createModel('Image', {
path: Types.Text(),
type: Types.Text(),
width: Types.Integer(),
height: Types.Integer(),
tags: Types.UObjectArray({
type: 'Tag'
})
});
let User = um.model.createModel('User', {
name: Types.Text(),
age: Types.Integer(),
height: Types.Double(),
weight: Types.Double(),
photo: Types.UObject({
type: 'Image'
})
});
The first argument is the name of model.
The second argument is the fields information. UniqueModel use the function under um.Types to define types. Every type can have some options which is specified in the argument of function.
Now we support following types:
- Text: String field
- Integer: Number field which is an integer
- Double: Number field
- UObject: An object associated with other model(1/N ... 1).
- UObjectArray: An array of objects associated with other model whose type are identical(1/N ... N).
UObject and UObjectArray have a option called type. It is used to specify the name of associated model.
Create the model instance
Then we use new to create the model instance. You can create an empty object and specify the property like following code:
let user = new User();
user.name = 'kkk';
user.age = 28;
You can also use the JavaScript object the specify the initial value of fields. It also support create model recursivly(auto create sub models).
let user = new User({
name: 'ttt',
age: 20,
height: 155,
weight: 50.5,
photo: new Image({
path: 'map.png',
type: 'png',
width: 500,
height: 400,
tags: [
new Tag({
name: 'Color'
}),
new Tag({
name: 'High'
})
]
})
});
Get the DAO(Data Access Object)
Now we can persist the created model instance into databases. But I seperate the persist operations into DAO objects. Every model will have one DAO object. We can use the getDao method of session object to get DAO.
let TagDao = session.getDao(Tag);
let ImageDao = session.getDao(Image);
let UserDao = session.getDao(User);
Every DAO object will be associated with one session. So you can use different session backend in one project.
Persist model instance into database
We can persist the model instance now. The method to persist model instances is create method of DAO:
user.photo.tags.forEach(tag => {
TagDao.create(tag);
});
ImageDao.create(user.photo);
UserDao.create(user);
console.log(user.toString());
console.log(user.photo.toString());
user.photo.tags.forEach(tag => {
console.log(tag.toString());
});
The DAO object do not persist sub model instances recursivly! So you must persist all the models manully. Now the user instance and the associated photo and tags have been persisted into database.
Find users
Then let's find the persisted user in the database. The find method is used to find all model instances by query conditions. The query conditions is passed to the backend now. So if you use mongodb backend, the format query conditions is identical to Mongoose. mongoosejs.com
The return value of find is an array of objects. We use forEach methods to ergodic the array.
let users = UserDao.find({
name: 'ttt'
});
console.log(users.length);
users.forEach(user => {
console.log(user.toString());
});
You can also use findOne method to get one of the objects which match query conditions.
let user = UserDao.findOne({
name: 'ttt'
});
if ( user != null ) {
console.log(user.toString());
}
else {
console.log(null);
}
If there are any matched objects in database, it will return null.
Update user
If you want to update model instance, you can use the update method.
OK. Let's find and update the user information.
let user = UserDao.findOne({
name: 'ttt'
});
console.log(user.toString());
user.age = 25;
UserDao.update(user);
console.log(user.toString());
After calling update, UniqueModel will replaces the model data in databases with new data.
Remove user
Removing model from database is very easy, too.
let user = new User({
id: userId
});
UserDao.remove(user);
After calling remove, the model has been removed from database.
More
The DAO object has more methods to update and remove model instances. You can read the test/test.js in the source directory.
Changelog
- 2015/10/26: Create the project.
- 2015/10/28: Support the unique model.
- 2015/11/02: Implement the persistent backend of Mongoose.
- 2015/11/02: Support basic CRUD of simple model using persist session.
- 2015/11/05: Support lazy load and auto query.
- 2015/11/20: Support Array of Object.
- 2015/11/23: Adjust the fromValue of UObject and UObjectArray.
- 2015/11/24: Support update model directly.
- 2015/11/25: Finish the basic README.
- 2015/11/27: Support toObject.
- 2015/11/27: Support Boolean and Date.
- 2015/12/01: Support Model.toObjectArray util method.
- 2015/12/01: Fix the bug when convert the Object property which is null.
- 2015/12/01: Fix the bug when recursive parse Object.
- 2015/12/05: Support user to specify the field to parse in toObject method.
- 2015/12/05: Replace the name of id of Object.
- 2015/12/07: Support the options in toObjectArray.
- 2106/08/20: Support $offset/$limit/$sort in query.
- 2106/11/11: Support distinct and aggregate operation.
- 2017/01/14: Support insertMany.
- 2017/01/14: Fix bugs of updateOne.
- 2017/02/13: Fix bugs of updateOne(When can not find any objects).