0.0.16 • Published 8 years ago

krypton-orm v0.0.16

Weekly downloads
2
License
MIT
Repository
github
Last release
8 years ago

Build Status Code Climate Test Coverage NPM

Krypton ORM

Krypton is a full featured Javascript ORM for SQL Databases

Krypton Features:

  • Declarative way of defining models
  • Mechanism to eager load relations *
  • Use the full feature-set of Knex.js *
  • Easy to use transactions *
  • Easy to declare validations
  • Promise based

* Work in progress

Constraints

  • Build arround Neon
  • Use Knex as the query builder
  • DB column_names must be snake_case
  • Don't handle migrations
  • Don't handle database schema creation

TODO

  • This README
  • Add more relation types, currently there are HasOne, HasMany and HasManyThrough.
  • Add transactions

Examples

var Knex = require('knex');

// Create a knex instance
var knex = Knex({
  client: 'postgres',
  connection: {
    database: 'database-name',
    user:     'DBUser',
    password: 'DBPass'
  }
});

// Log queries
knex.on('query', function(data) {
  console.log(data);
});

// Bind the knex instance to the Krypton Base Model Class
// (Yes you can have multiple knex instances binded to different Models :) )
Krypton.Model.knex(knex);

// Create some Models
Class('Voice').inherits(Krypton.Model)({
  tableName : 'Voices',

  /*
    attributes are used for validation (whitelist) at saving. Whenever a
    model instance is saved it is checked against this schema.
  */
  attributes : ['id', 'title', 'description', 'createdAt', 'updatedAt']
});

Class('Entity').inherits(Krypton.Model)({
  tableName : 'Entities',

  attributes : ['id', ..., 'createdAt', 'updatedAt']
})

// This object defines the relations to other models.
// I intentionaly declared this outside the Entity Class because it has a circular
// relation ('organizations')
Entity.relations = {
  voices : {
    type : 'HasMany',
    relatedModel : Voice,
    ownerCol : 'id',
    relatedCol : 'owner_id'
  },

  organizations : {
    type : 'HasManyThrough',
    relatedModel : Entity,
    ownerCol : 'id',
    relatedCol : 'id',
    scope : ['Entities.type', '=', 'organization'],
    through : {
        tableName : 'EntityOwner',
        ownerCol : 'owner_id',
        relatedCol : 'owned_id'
        scope : null
    }
  }
}

Class('User').inherits(Krypton.Model)({
  tableName : 'Users',

  attributes : ['id', ..., 'createdAt', 'updatedAt'],

  relations : {
    entity : {
      type : 'HasOne',
      relatedModel : Entity,
      ownerCol : 'entity_id',
      relatedCol : 'id'
    }
  }
});

Queries

var userQuery = User.query();
// => returns a QueryBuilder instance

userQuery.where({id : 1});
// or userQuery.where('id', '<', 5) or whatever knex expression you want to use.


// include(relationExpression)
// Relation expression is a simple DSL for expressing relation trees.
userQuery.include('entity.[voices, organizations]');
// This means: Load the User(s) and its entity and the voices of its entity and the organizations of its entity

userQuery.then(function(result) {
  console.log(result)
});

ActiveRecord Style callbacks

Callbacks are hooks into the life cycle of an Krypton Model instance that allow you to trigger logic before or after an alteration of the object state.

  • Implemented callbacks:
    • beforeValidation
    • afterValidation
    • beforeSave
    • beforeCreate
    • beforeUpdate
    • afterCreate
    • afterUpdate
    • afterSave
    • beforeDestroy
    • afterDestroy

API:

// @property on <public> [Function]
// @method
// @argument hook <required> [String]
// @argument handler(callback) <required> [Function]
// @return this;

Examples:

Model('User').inherits(Krypton.Model)({
    prototype : {
        init : function(config) {
            Krypton.Model.prototype.init.call(this, config);

            var model = this;

            model.on('beforeValidation', function(next) {
                bcrypt.hash(model.password, null, null, function(err, hash) {
                    model.encryptedPassword = hash;
                    delete model.password;
                    next();
                });
            });

            model.on('beforeValidation', function(next) {
                model.count++
            });
        }
    }
});

OR

var user = new User();

user.on('beforeUpdate', handler(callback))

Note on Krypton Knex instance handling

Krypton.Model defines a class method named ::knex(), this method returns the Knex instance that has been assigned to the Class (with ::knex(knex)) or throws an error if none is available.

Internally #create(), #query(), #update() and #destroy() all use the provided Knex instance (in their params), the model instance's ._knex or the instance returned by ::knex().

If one of those methods receives a Knex instance they will set the model instance's ._knex property, which the model stuff can make use of. Before this happens the model instance's ._knex property is undefined.

0.0.16

8 years ago

0.0.15

8 years ago

0.0.14

8 years ago

0.0.13

8 years ago

0.0.12

8 years ago

0.0.11

8 years ago

0.0.10

8 years ago

0.0.9

8 years ago

0.0.8

8 years ago

0.0.6

8 years ago

0.0.5

8 years ago

0.0.4

8 years ago

0.0.3

8 years ago

0.0.2

9 years ago

0.0.1

9 years ago