FuseDB is an ORM with traditional ActiveRecord approach, that provides a simple yet powerful API. FuseDB stores data in the filesystem (nedb) or MongoDB. You write your own adapter 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
The project is at a very early stage of development, so please, feel free to contribute and extend the functionality. Besides, we don't have any other drivers but nedb. MongoDb Adapter is required.
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
import { FuseDB, FileAdapter } from "fusedb"
FuseDB.setup({ adapter : FileAdapter({ path: "/path/to/folder/", database: "test" }) });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
import { Field, Model } from "fusedb";
class Author extends Model<Author> {
@Field()
public name: string;
@Field()
public books: Book[];
}
class Book extends Model<Book> {
@Field()
public name: string;
@Field()
public author: Author;
}Field decorator tells fusedb to serialize the field. There are a few reserved methods:
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
First record:
const author = await Author.find<Author>({ name: "john" }).first();All records:
const authors = await Author.find<Author>({
name : {$in : ["a", "b"]}
}).all();Count:
const num = await Author.find<Author>().count();const authors
= await Author.find<Author>({active : true})
.sort("name", "desc")
.limit(4)
.skip(2)
.all()FuseDB can automatically join referenced fields by making optimised requests (collecting all ids and making additional queries to the database) e.g
const books = await Book.find<Book>().with("author", Author).all();const author = new Author();
author.name = "john"
await autor.save() const author = await Author.find({name : "john"});
await author.remove()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)
import { enableDefaultDecorators } from "fusedb"
enableDefaultDecorators();Now you can start using them in your models, like that:
class FooBarMax extends Model<FooBarMin> {
@Field() @Validate({max : 3})
public name: string;
}Default validators can assert a custom message
@Validate({nameOftheValidator : { message :"Failed", value : 3}})class FooBarMin extends Model<FooBarMin> {
@Field() @Validate({min : 3})
public name: string;
}class FooBarMax extends Model<FooBarMax> {
@Field() @Validate({max : 3})
public name: string;
}class FooBarEmail extends Model<FooBarEmail> {
@Field() @Validate({email : true})
public name: string;
}class FooBarRegExp extends Model<FooBarRegExp> {
@Field() @Validate({regExp : /\d{2}/})
public name: string;
}const seasons = {
SUMMER: 'summer',
WINTER: 'winter',
SPRING: 'spring'
}class FooBarEnum extends Model<FooBarEnum> {
@Field() @Validate({enum : seasons})
public season: string;
}class FooBarCustom extends Model<FooBarCustom> {
@Field()
@Validate({fn : value => {
if( value !== "foo") throw new Error("Value should be foo only")
}})
public name: string;
}Define a class with Validator
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
class Hello extends Model<Hello> {
@Field() @Validate({oops : true})
public name: string;
}