Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/fuse-box/fusedb
FuseDB - blazing fast ORM with simplicity in mind with love from FuseBox
https://github.com/fuse-box/fusedb
Last synced: about 1 month ago
JSON representation
FuseDB - blazing fast ORM with simplicity in mind with love from FuseBox
- Host: GitHub
- URL: https://github.com/fuse-box/fusedb
- Owner: fuse-box
- Created: 2017-11-03T13:47:02.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2022-12-10T20:31:17.000Z (about 2 years ago)
- Last Synced: 2024-04-24T13:45:55.713Z (8 months ago)
- Language: TypeScript
- Homepage:
- Size: 203 KB
- Stars: 29
- Watchers: 5
- Forks: 4
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-blazingly-fast - fusedb - FuseDB - blazing fast ORM with simplicity in mind with love from FuseBox (TypeScript)
README
[![Build Status](https://travis-ci.org/fuse-box/fusedb.svg?branch=master)](https://travis-ci.org/fuse-box/fusedb)
# FuseDB
FuseDB is an ORM with traditional ActiveRecord approach, that provides a simple yet powerful API. FuseDB stores data in the filesystem ([nedb](https://github.com/louischatriot/nedb)) or MongoDB. You write your own [adapter](https://github.com/fuse-box/fusedb/blob/master/src/adapters/Adapter.ts) and implement a different database suppport.
It's perfectly suitable for medium scale databases or Electron apps and takes 5 minutes to dive in.
Checkout this [example](https://github.com/fuse-box/fusedb-example)
## Setting up a connection
Everything works by default, and the files will be stored in your home folder e.g `/home/user/.fusedb` on linux or `/Users/user/.fusedb` on mac. In order to customise it, do the following
### File database
```js
import { FuseDB, FileAdapter } from "fusedb"
FuseDB.setup({ adapter :
FileAdapter({ path: "/path/to/folder/", database: "test" }) });
```### MongoDB database
Install mongo module first
```bash
npm install mongodb --save
``````js
import { FuseDB, MongoAdapter } from "fusedb";
FuseDB.setup({
adapter: MongoAdapter({
url : "mongodb://localhost:27017/fusedb",
dbName : "myProject"
})
});
```## Models
Models contain essential methods to talk to the database, methods like `save`, `find`, `remove` are reserved. Therefore we don't need any "repositories" and connection pools as everything is handled internally
```js
import { Field, Model } from "fusedb";class Author extends Model {
@Field()
public name: string;@Field()
public books: Book[];
}class Book extends Model {
@Field()
public name: string;@Field()
public author: Author;
}
````Field` decorator tells fusedb to serialize the field. There are a few reserved methods:
### Creating records
```js
const john = new Author({ name: "John" });
await john.save();const book1 = new Book({ name: "book1", author: john });
const book2 = new Book({ name: "book2", author: john });await book1.save();
await book2.save();john.books = [book1, book2];
await john.save();
```FuseDB will save references as `ids` and it won't store the entire model
### Field decorator
Field decorator has a few properties you might find useful
#### hidden
Hiding your field when sending to view
```ts
@Field({ hidden : true })
public password: string;
```#### toJSON
Define custom serialiser when sending to view
```ts
@Field({
toJSON : value => moment(value).format("LLLL")
})
public date: Date;
```### Finding
First record:
```js
const author = await Author.find({ name: "john" }).first();
```All records:
```js
const authors = await Author.find({
name : {$in : ["a", "b"]}
}).all();
```Count:
```js
const num = await Author.find().count();
```### Query normalization
#### ObjectID
You don't need to convert strings to ObjectID When you using MongoAdapter. FuseDB does it for you.for example:
```ts
const record = await Foo.findById("5b290c188e9f69ab51c3bd41");
```It will be applied for `find` method recursively for example
```ts
await Foo.find({
_id : $in : ["5b290c188e9f69ab51c3bd41", "5b290c188e9f69ab51c3bd42"]
}).first()
```#### Passing real objects to query
Instead of extracting IDs you can pass a real FuseDB Model to the query. For example
```ts
const group = await Group.find({name : "admin"}).first();
const adminUsers = await Users.find({group : group}).all(); // will fetch all users that belong to admin group
```### Chaining query
```js
const authors
= await Author.find({active : true})
.sort("name", "desc")
.limit(4)
.skip(2)
.all()
```### Joining references
FuseDB can automatically join referenced fields by making optimised requests (collecting all ids and making additional queries to the database)
e.g```js
const books = await Book.find().with("author", Author).all();
```## Saving
```js
const author = new Author();
author.name = "john"
await autor.save()
```## Removing
```js
const author = await Author.find({name : "john"});
await author.remove()
```## Model event hooks
Defining the following hooks will allow you to intercept model events
```ts
export class Foo extends Model {
@Field()
public name: string;
// before updating or creating a record
async onBeforeSave() {}
// after creating or updating a record
async onAfterSave() {}
// before updating a record
async onBeforeUpdate() {}
// after creating a record
async onBeforeCreate() {}
}
```## Validators
Validators in FuseDb are quite easy to use and implement. The framework offers a few default validators,
in order to enable them call a function in your entry point (before you start importing your models)```js
import { enableDefaultDecorators } from "fusedb"
enableDefaultDecorators();
```Now you can start using them in your models, like that:
```js
class FooBarMax extends Model {
@Field() @Validate({max : 3})
public name: string;
}
```Default validators can assert a custom message
```js
@Validate({nameOftheValidator : { message :"Failed", value : 3}})
```### Min Symbols Validator
```js
class FooBarMin extends Model {
@Field() @Validate({min : 3})
public name: string;
}
```### Max Symbols Validator
```js
class FooBarMax extends Model {
@Field() @Validate({max : 3})
public name: string;
}
```### Email Validator
```js
class FooBarEmail extends Model {
@Field() @Validate({email : true})
public name: string;
}
```### RegExp Validator
```js
class FooBarRegExp extends Model {
@Field() @Validate({regExp : /\d{2}/})
public name: string;
}
```### Enum Validator
```js
const seasons = {
SUMMER: 'summer',
WINTER: 'winter',
SPRING: 'spring'
}
``````js
class FooBarEnum extends Model {
@Field() @Validate({enum : seasons})
public season: string;
}
```### Function validator
```js
class FooBarCustom extends Model {
@Field()
@Validate({fn : value => {
if( value !== "foo") throw new Error("Value should be foo only")
}})
public name: string;
}
```## Your own validators
Define a class with `Validator`
```js
import { Validator, FieldValidator } from "fusedb";@Validator()
export class OopsValidator implements FieldValidator {
validate(field: string, props: any, value: any) {
throw "Somethign wentWrong"
}
}
```A validator with name `oops` has be registered, how you can use it in your models
```js
class Hello extends Model {
@Field() @Validate({oops : true})
public name: string;
}
```