The object model¶
To access and manipulate your normalized state redux-db provides you with a simple “Object-relational mapping” (ORM).
Database¶
Your schema definition must be provided to a Database class instance:
import { createDatabase } from "redux-db";
const schema = {
...
};
export const db = createDatabase( schema, /*options*/ );
Session¶
redux-db uses the concept of a session where each “table” is wrapped in a TableModel class. The TableModel class helps to query and perform CRUD operations easily.
To begin a new session and perform some action:
import { db } from "./schema";
const session = db.createSession(state /* not defined here */);
// your TableModels are properties in the session "tables" object.
const { BlogPost, Comment, User } = session.tables;
// the "get" method retrives a RecordModel by it's primary key.
// the "update" method allows for partial updates of record data.
BlogPost.get("post1").update({ body: "new text" });
// commit the session
const newState = session.commit();
TableModel¶
The Table class provides several methods and properties for accessing the table records. Each method will return table rows wrapped in a RecordModel class.
Methods and propertes:
/// gets the number of records in the table.
length : number;
/// gets all raw record values
/// equivalent to all().map( r => r.value )
getValues() : any[];
/// returns all records in table.
all() : RecordModel[];
/// returns all records matching a given filter.
filter( predicate: ( record: RecordModel ) => boolean ) : RecordModel[];
/// returns a single record by id.
get( id:string|number ) : RecordModel;
/// returns a single record by id. null if not found.
getOrDefault(id: number | string) : RecordModel | null;
/// checks whether a record exists.
exists(id: number | string) : bool;
/// inserts one or more records.
/// returns the first inserted record.
insert( data: any ) : RecordModel;
/// inserts one or more records.
/// returns the inserted records.
insertMany( data: any ) : RecordModel[];
/// updates one or more records.
/// returns the first updated record.
update( data: any ) : RecordModel;
/// updates one or more records.
/// returns the updated records.
updateMany( data: any ) : RecordModel[];
/// upserts one or more records.
/// returns the first upserted record.
upsert( data: any ) : RecordModel;
/// deletes a single record by it's primary key.
delete( id: string ) : boolean;
/// deletes all records in table.
deleteAll() : void;
/// get a single record value
value( id:number | string ) : any | undefined;
Note
The update/insert/upsert operations accepts nested data and will be normalized according to your schema definition. The normalized relations will also be updated/inserted to its respective tables.
RecordModel¶
The RecordModel class wraps an table row and provides methods and propertes for the given row/entity.
Methods and propertes:
/// gets the record primary key value
id: string;
/// gets the raw record value
value : any;
/// updates the record with new data.
update( data: any ) : this;
/// deletes the record
delete() : void;
In addition to the methods and propertes defined above, the RecordModel class will also contain properties for accessing foreign relations. Given the following schema:
{
"Table1" : {
"id": { type: "PK" }
},
"Table2" : {
"id": { type: "PK" },
"ref": { references: "Table1", relationName: "rels" }
}
};
The Record class for “Table1” will contain a property “rels” of type RecordSetModel. The RecordSetModel wraps all records in “Table2” relating to “Table1” by its PK. The Record class for “Table2” will contain a property named “ref” which holds a Record of “Table1”.
Table1.insert( {
id: 1,
body: "some text"
});
Table2.insert( [
{ id: 1, ref: 1 },
{ id: 2, ref: 1 },
{ id: 3, ref: 2 }
]);
const table1Record = Table1.get( 1 );
// table1Record will have the property "rels"
table1Record.rels;
// the rels property is a RecordSet of Records from "Table2"
/* table1Record.rels.value => [
{ id: 1, ref: 1 },
{ id: 2, ref: 1 }
]; */
// Table2 records has the "ref" property.
Table2.get(1).ref.value.body === "some text";
---
// Since we have defined the relationName "rels" on the "Table2.ref" field, the following insert is equivalent to the first two.
Table1.insert({
id: 1,
body: "some text",
rels: [
{ id: 1, ref: 1 },
{ id: 2, ref: 1 },
{ id: 3, ref: 2 }
]
});
RecordSetModel¶
The RecordSetModel class wraps a relation between two tables.
Methods and propertes:
/// gets the primary keys of the records in the set.
ids : string[];
/// gets the raw array of record values.
value : any[];
/// gets the number of records in the set.
length : number;
/// returns all records in the set.
all() : RecordModel[];
/// updates the records with new data.
update( data: any ) : this;
/// deletes all records in the set.
delete() : void;