npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

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).