Coder Social home page Coder Social logo

thinodium / thinodium Goto Github PK

View Code? Open in Web Editor NEW
5.0 2.0 0.0 106 KB

Light-weight, pluggable ODM for Node.js. Supports MongoDB, RethinkDB, SQL databases, etc

Home Page: https://thinodium.github.io/

License: MIT License

JavaScript 100.00%
nodejs mongodb rethinkdb sql odm adapter database schema-validation

thinodium's Introduction

Thinodium

Build Status npm Join the chat at https://discord.gg/bYt4tWB Follow on Twitter

A "thin ODM" which is less opinionated and tries to give you query flexibility whilst still providing helpful document handling.

Features:

  • ES6-ready with Promises, no callbacks
  • Allows you to handle connections yourself
  • Add virtual fields to documents
  • Fully pluggable - easy to add support for your DB of choice
  • Listen to before and after events on internal asynchronous methods
  • Schema validation (sjv).

Read the documentation for more.

Installation

This package requires Node 4 or above

$ npm install thinodium

This package provides the core infrastructure. To actually access a particular database you will need to additionally install one of the following adapters:

NOTE: Please raise a PR if you want me to add your adapter to the above list.

Basic usage

Let's first create a database connection:

// thinodium instance
const Thinodium = require('thinodium');

// create the connection
const db = yield Thinodium.connect('rethinkdb', {
  db: 'mydb',
});

Thinodium will try to load an NPM module called thinodium-rethinkdb (which is our intention in this example). If not available it will try to load a module called rethinkdb. Once loaded it will instantiate a database connection through that module, passing in the second parameter to connect().

If we wished to add a custom adapter but not as an NPM module we could simply provide its path to connect():

// connect using custom adatper
const db = yield Thinodium.connect('path/to/custom/adapter', {
  db: 'mydb',
});

Models

Once we have our database connection setup we can access models (i.e. tables) within the database:

// get the model
const model = yield db.model('User');

// insert a new user
let user = yield model.insert({
  name: 'john'
});

// change the name
user.name = 'mark';
yield user.save();

// load user with id
let user2 = yield model.get(user.id);

console.log(user2.name); /* mark */

Both get() and insert() return Thinodium.Document instances. These internally call through to the methods prefixed with raw - methods which you can also use directly if you do not wish to deal with Documents. These are documented in the API docs.

Document customization

Model documents (each representing a row in the table) can be customized. We can add virtual fields and additional methods:

// create the model
const model = yield db.model('User', {
  docMethods: {
    padName: function(str) {
      this.name += str;
    }
  },
  docVirtuals: {
    fullName: {
      get: function() {
        return this.name + ' smith';
      }
    }
  }
});

// insert a new user
let user = yield model.insert({
  name: 'john'
});

console.log(user2.fullName); /* mark smith */

user.padName('test');

console.log(user2.fullName); /* marktest smith */

Note that you can access the parent model for a document using getModel():

let user = yield model.insert({
  name: 'john'
});

console.log( user.getModel() === model ) /* true */

Schema validation

Schema validation is performed by simple-nosql-schema, and is used if a schema is provided in the initial model config:

// create the model
const model = yield db.model('User', {
  // tell Thinodium to validate all updates and inserts against the given schema
  schema: {
    age: {
      type: Number,
      required: true,
    },
  }
});

// insert a new user
let user1 = yield model.insert({ name: 'john', }); /* throws Error since age is missing */

let user2 = yield model.insert({
  name: 'john',
  age: 23,
});
user2.age = 'test';

yield user2.save();  /* throws Error since age must be a number */

Note that schema validation is partial. If the insert or update contains a key that is not mentioned within the schema then that key gets passed through without any checks. This allows for flexibility - you only need to vaildate the parts of a model's schema you're interested in.

API

Check out the API docs for information on supported methods.

Creating an Adapter

An adapter has to extend the base Database and Model classes and override the necessary internal methods:

"use strict";

const Thinodium = require('thinodium');

class Database extends Thinodium.Database {
  _connect (options) {
    return new Promise((resolve, reject) => {
      // do what's needed for connection here and save into "connection" var
      resolve(connection);      
    });
  }

  _disconnect (connection) {
    return new Promise((resolve, reject) => {
      // disconnect connection
      resolve();
    });
  }

  _model (connection, name, config) {
    return new Model(connection, name, config);
  }
}



class Model extends thinodium.Model {
  rawQry() {
    // return object for doing raw querying
  }

  rawGet (id) {
    return new Promise((resolve, reject) => {
      // fetch doc with given id
      resolve(doc);      
    });
  }

  rawGetAll (id) {
    return new Promise((resolve, reject) => {
      // fetch all docs
      resolve(docs);      
    });
  }

  rawInsert (attrs) {
    return new Promise((resolve, reject) => {
      // insert doc
      resolve(doc);      
    });
  }

  rawUpdate (id, changes, document) {
    return new Promise((resolve, reject) => {
      // update doc
      resolve();
    });
  }

  rawRemove (id) {
    return new Promise((resolve, reject) => {
      // remove doc with id
      resolve();      
    });
  }
}


module.exports = Database;

Building

To run the tests:

$ npm install
$ npm test

Contributing

Contributions are welcome! Please see CONTRIBUTING.md.

License

MIT - see LICENSE.md

thinodium's People

Contributors

hiddentao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

thinodium's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.