0.0.16 • Published 8 years ago

entitype v0.0.16

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

Entitype

Build Status Coverage Status Dependencies Chat

Entitype is an ORM framework that provides a strong-typed, fluent programming interface. You can query the database of your choice with the help of IntelliSense without having to write any SQL or any other DSL.

The project is heavily influenced by other ORM frameworks like TypeORM and Entity Frameork. Its API is designed to resemble Entity Framework but also to conform to TypeScript coding conventions and make IntelliSense possible.

Entitype can be used in any JavaScript environment supporting ES6.

This is a work in progress. By now, only the querying is completed. If you are looking for a more mature project, try TypeORM.

Table of Contents

Installation

Install the npm package with:

npm install --save entitype

Select a plugin for database adapters and install it as well:

npm install --save entitype-mysql

Quick Start

Defining a Model

Entitype models are classes where the class and its properties are "decorated".

import { Column, Entity } from 'entitype';

@Entity('customers')
export class Customer {

  @Column().type.int().primaryKey(true)
  id: number;

  @Column(`last_name`).type.varchar(50).index()
  name?: string;
}

Defining Relationships

Relationships on a table are defined by putting decorators on navigation properties.

The valid navigation property decorators are OneToOne, OneToMany, ManyToOne and ManyToMany.

Defining a One-to-Many Relationship

A One-to-Many relationship is defined by using OneToMany and ManyToOne decorators. For first parameter, the entity type which owns the foreign key for this relationship is passed. The second parameter is for declaring the foreign key.

export class Customer {
  /* ........... */

  @OneToMany(type => Order, x => x.customerId)
  orders: Order[];
}

@Entity('orders')
export class Order {
  @Column().type.int().primaryKey(true)
  id: number;

  @Column(`customer_id`)
  customerId: number;

  @ManyToOne(type => Order, x => x.customerId)
  customer: Customer;
}

Defining a One-to-One Relationship

A One-to-One relationship is a special case of One-to-Many relationship and is not much different. Instead of an array for property type, a singular value is used. OneToOne decorator is used to specify this kind of relationship.

export class Customer {
  /* ........... */

  @OneToOne(type => Order, x => x.customerId)
  orders: Order;  // <------ Note the difference here
}

@Entity('orders')
export class Order {
  @Column().type.int().primaryKey(true)
  id: number;

  @Column(`customer_id`)
  customerId: number;

  @OneToOne(type => Order, x => x.customerId)
  customer: Customer;
}

Defining a Many-to-Many Relationship

A Many-to-Many relationship can also be defined in Entitype. For this relationship, a mapping entity must be defined like any other entity.

@Entity('employee_privileges_mapping_table')
export class EmployeePrivilege {

  @Column('employee_id').primaryKey()
  employeeId: number;

  @Column('privilege_id').primaryKey()
  privilegeId: number;
}

The entities to be mapped can be decorated with ManyToMany decorator using the mapping entity defined above. First parameter is for array type, second parameter is the mapping entity type. Third and fourth parameters are for left key and right key respectively.

@Entity('employees')
export class Employee {
  /* ---- Other properties, including the primary key ----  */

  @ManyToMany(type => Privilege, joinType => EmployeePrivilege, x => x.employeeId, x => x.privilegeId)
  employeePrivileges: Privilege[];
}

@Entity('privileges')
export class Privilege {
  /* ---- Other properties, including the primary key ----  */

  @ManyToMany(type => Employee, joinType => EmployeePrivilege, x => x.privilegeId, x => x.employeeId)
  employeePrivileges: Employee[];
}

Defining the Context

A context must be defined before starting using Entitype.

import { DbCollection, EntitypeContext, DbSet } from 'entitype';

export class MyContext extends EntitypeContext {

  @DbCollection(() => Customer)
  customers: DbSet<Customer>;

  @DbCollection(() => Order)
  orders: DbSet<Order>;
}

Configuring the Connection

You can specify the configuration which Entitype will use to connect to database. This must be done only once in the lifecycle of your program.

Also the plugin must be imported atleast once to resolve dependencies. The plugin to be used is specified with adapter property of the options object. Plugins are conventionally named entitype-[pluginName].

import { useConfiguration } from 'entitype';
import { MysqlConnectionOptions } from 'entitype-mysql';

useConfiguration(<MysqlConnectionOptions>{
  adapter: 'mysql',
  database: 'mydb',
  host: 'localhost',
  port: 3306,
  password: '*********',
  user: 'root'
})

Querying API

The query interface of Entitype will be available over the context class. The IntelliSense helps along while writing a query so the queries can be written like a native language.

Firstly, create an instance of the context:

let ctx = new MyContext();
let customers = await ctx.customers.toList();
// name is of type 'string'
let name = await ctx.customers
  .select(x => x.name)
  .first();
ctx.customers
  .select(x => x.name)
  .first()
  .then(name => console.log(`My first customer's name is ` + name));
// names is of type 'string[]'
let names = await ctx.customers
  .select(x => x.name)
  .toList();
// namesAndOrders is of type '{ name: string, orders: Order[] }'
let namesAndOrders = await ctx.customers
  .select(x => ({name: x.name, orders: x.orders }))
  .toList();
let customers = await ctx.customers
  .where(x => x.name).not.isNull()
  .or
  .where(x => x.id).in([5,6,7])
  .toList();
let customerNamesOrdered = await ctx.customers
  .orderByAscending(x => x.name)
  .skip(5)
  .take(10)
  .toList();
let customerNamesOrdered = await ctx.customers
  .include(x => x.orders)
  .toList();

CLI

Entitype-CLI is a tool that provides utilities like automatically creating models from database, or doing migrations.

Examples

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

8 years ago

0.0.6-1

8 years ago

0.0.6

8 years ago

0.0.5

8 years ago

0.0.4-alpha.2

8 years ago

0.0.4-alpha.1

8 years ago

0.0.2-1

8 years ago

0.0.2-0

8 years ago

0.0.1-0

8 years ago