https://github.com/leoc11/elcy
ORM for Typescript and Javascript with Linq-like query syntax.
https://github.com/leoc11/elcy
database elcy entity-framework javascript linq linq-to-entities mssql orm sqlite sqlserver typescript
Last synced: 10 months ago
JSON representation
ORM for Typescript and Javascript with Linq-like query syntax.
- Host: GitHub
- URL: https://github.com/leoc11/elcy
- Owner: leoc11
- License: mit
- Created: 2017-09-05T00:29:03.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2025-06-28T06:47:46.000Z (10 months ago)
- Last Synced: 2025-06-28T07:36:27.399Z (10 months ago)
- Topics: database, elcy, entity-framework, javascript, linq, linq-to-entities, mssql, orm, sqlite, sqlserver, typescript
- Language: TypeScript
- Homepage:
- Size: 2.39 MB
- Stars: 10
- Watchers: 0
- Forks: 0
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Elcy
[](https://codecov.io/gh/leoc11/elcy)
[](https://travis-ci.org/leoc11/elcy)
[](https://cla-assistant.io/leoc11/elcy)
[](https://david-dm.org/leoc11/elcy)
[](https://david-dm.org/leoc11/elcy#info=devDependencies)
Elcy is an [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping)
for typescript and javascript. Elcy is highly influenced by [Entity Framework](https://www.asp.net/entity-framework) and [NHibernate](http://nhibernate.info/).
## Installation
To be updated...
## Supported Database
- Sql Server
- Sqlite (not yet)
## How to use
### Create the Model
Entity on your model is mark with `@Entity` class decorator.
To add database columns, you simply need to add decorator to your entity properties. Elcy has several column decorator for defining your column with specific column type:
- `@StringColumn` : string column type.
- `@BooleanColumn` : boolean column type.
- `@NumberColumn` : integer column type.
- `@DecimalColumn` : decimal column type.
- `@ApproximateNumberColumn` : approximate number column type. ex: float
- `@IdentifierColumn` : uuid column type.
- `@DateColumn` : date column type.
- `@EnumColumn` : *not implemented yet*
- `@EmbeddedColumn` : *not implemented yet*
Here several other decorator for entity property:
- `@CreatedDate`: a date column type used to store entity creation date.
- `@ModifiedDate`: a date column type used to store entity last modified date.
- `@ColumnDescription`: add description to column.
- `@DeletedColumn`: a boolean column type used for soft delete indicator.
- `@NullableColumn`: mark column nullable.
- `@PrimaryKey`: mark column as one of the entity primary key.
Example:
```typescript
import {Entity} from "elcy/Decorator/Entity";
import { PrimaryKey } from "Elcy/Decorator/Column/PrimaryKey";
import { NumberColumn } from "Elcy/Decorator/Column/NumberColumn";
import { DateColumn } from "Elcy/Decorator/Column/DateColumn";
import { IdentifierColumn } from "Elcy/Decorator/Column/IdentifierColumn";
import { UUID } from "Elcy/Data/UUID";
@Entity()
export class Order {
@PrimaryKey()
@IdentifierColumn()
public OrderId: UUID;
@NumberColumn({ columnType: "bigint" })
public Amount: number;
@DateColumn()
public OrderDate: Date;
@CreatedDate()
public CreatedDate: Date;
@ModifiedDate()
public ModifiedDate: Date;
@DeletedColumn()
public isDeleted: boolean;
}
```
### Create a Context
a Context represents a session with the database, allowing us to query and save data. Define a context that derives from `Elcy/Data/DbContext` and exposes a typed DbSet for each class in our model. Elcy has defined DbContext that you could used for each support db under `Elcy/Driver`.
Example:
```typescript
import { MssqlDbContext } from "Elcy/Driver/Mssql";
export class MyDb extends MssqlDbContext {
constructor() {
super(() => new MssqlDriver({
host: "localhost\\SQLSERVER",
database: "mydb",
port: 1433, // example
user: "xxx",
password: "xxx",
}));
}
public entityTypes = [Order]; // all entities that will be loaded using this context.
public orders: DbSet = this.set(Order); // exposed typed DbSet for Order model.
}
```
### Reading Data
Elcy used Linq-like syntax to read data from database. Example:
```typescript
(
async() => {
const db = new MyDb();
// select top 10 order with Amount > 10 order by amount desc.
const orders = await db.orders.take(10).where(o => o.Amount > 10).orderBy([o => o.Amount, "DESC"]).toArray();
// count all orders
const count = await db.orders.count();
// where with parameter
const maxAmount = 10;
const count = await db.orders.parameters({ maxAmount }).where(o => o.Amount < maxAmount).count();
}
)();
```
Below are the supported query expression syntax:
- `where(predicate: (item: T) => boolean): Queryable`
- `distinct(): Queryable`
- `include(...includes: Array<(item: T) => any>): Queryable`
- `orderBy(...selectors: IQueryableOrderDefinition[]): Queryable`
- `skip(skip: number): Queryable`
- `take(take: number): Queryable`
- `select(selector: ((item: T) => TReturn)): Queryable`
- `selectMany(selector: (item: T) => TReturn[]): Queryable`
- `groupBy(keySelector: (item: T) => K): Queryable>`: limitation. groupBy(..).toArray() will not work.
- `union(array2: Queryable, isUnionAll?: boolean): Queryable`
- `intersect(array2: Queryable): Queryable`
- `except(array2: Queryable): Queryable`
- `toArray()`
- `sum()`
- `count()`
- `max()`
- `min()`
- `avg()`
- `all()`
- `any()`
- `first()`
- `innerJoin`: *not yet supported*
- `rightJoin`: *not yet supported*
- `leftJoin`: *not yet supported*
- `fullJoin`: *not yet supported*
- `pivot`: *not yet supported*
### Writing Data
Create:
```typescript
(
async() => {
const db = new MyDb();
// example 1: create and attach
const order = new Order();
order.OrderId = UUID.new();
order.Amount = 10;
db.add(order);
// example 2
const order2 = db.orders.new(UUID.new());
order2.Amount = 10;
db.saveChanges();
}
)();
```
Update
```typescript
(
async() => {
const db = new MyDb();
const order = db.orders.first();
order.Amount += 1;
await db.saveChanges();
}
)();
```
Delete
```typescript
(
async() => {
const db = new MyDb();
const order = db.orders.first();
db.delete(order);
await db.saveChanges();
}
)();
```
### Transaction
```typescript
(
async() => {
const db = new MyDb();
await db.transaction(o => {
// your code goes here
});
}
)();
```