v10.1.4
RED:VARS's ORM (Object–relational mapping) tool is built for Deno and provides transparent persistence for JavaScript objects to Postgres database.
Attributes
Includes Deno configuration
Repository
Current version released
12 hours ago
Dependencies
Versions
- v10.1.4Latest
- v10.1.3
- v10.1.2
- v10.1.0
- v10.0.0
- v10.0.0-pre.2
- v10.0.0-pre.1
- v10.0.0-pre.0
- v9.1.2
- v9.1.1
- v9.1.0
- v9.1.0
- v9.0.1
- v9.0.0
- v8.0.0
- v8.0.0
- v8.0.0-pre.9
- v8.0.0-pre.9
- v8.0.0-pre.8
- v8.0.0-pre.7
- v8.0.0-pre.6
- v8.0.0-pre.5
- v8.0.0-pre.5
- v8.0.0-pre.4
- v8.0.0-pre.3
- v8.0.0-pre.2
- v8.0.0-pre.1
- v7.2.0-pre.0
- v7.1.1
- v7.1.1
- v7.1.1-pre.3
- v7.1.1-pre.3
- v7.1.1-pre.2
- v7.1.1-pre.1
- v7.1.1-pre.0
- v7.1.1-pre.0
- v7.1.0
- v7.0.1
- v6.4.0
- v6.3.0
- v6.2.0
- v6.1.0
- v5.13.0
- v5.14.0
- v5.12.0
- v5.11.0
- v5.10.0
- v5.9.0
- v5.8.0
- v5.7.0
- v5.6.3
- v5.6.2
- v5.6.1
- v5.6.0
- v5.5.10
- v5.5.9
- v5.5.8
- v5.5.7
- v5.5.6
- v5.5.5
- v5.5.4
- v5.5.3
- v5.5.2
- v5.5.1
- v5.5.0
- v5.4.11
- v5.4.10
- v5.4.9
- v5.4.8
- v5.4.7
- v5.4.6
- v5.4.5
- v5.4.4
- v5.4.3
- v5.4.2
- v5.4.1
- v5.4.0
- v5.3.0
- v5.2.7
- v5.2.6
- v5.2.5
- v5.2.3
- v5.2.4
- v5.2.2
- v5.2.1
- v5.2.0
- v5.1.0
- v5.0.2
- v5.0.1
- v5.0.0
- v4.11.0
- v4.10.2
RESVARS ORM
RESVARS ORM (Object Relational Mapping) tool is built for Deno and provides transparent persistence for JavaScript objects to Postgres database.
- Supports all primitive data types (string, integer, float, boolean, date, object, array, etc.).
- Supports custom data types.
- Supports table with multi-level inheritance.
- Also supports interception on operations (create, read, update and delete).
import { ORM } from "jsr:@redvars/orm";Database connection
const odm = new ORM({
database: "school-database",
username: "postgres",
password: "postgres",
hostname: "localhost",
port: 5432,
});
try {
const client: ORMClient = await odm.connect(
true, /* create database if not exists */
);
console.log("Client connected successfully");
client.closeConnection();
} catch (error) {
console.log("Error while establishing connection", error);
}Defining tables
Definition automatically includes id and _table fields on every table.
await client.defineTable({
name: "department",
columns: [
{
name: "name",
type: "string",
},
{
name: "code",
type: "string",
},
],
});
await client.defineTable({
name: "teacher",
columns: [
{
name: "name",
type: "string",
},
{
name: "badge_number",
type: "integer",
},
{
name: "age",
type: "integer",
},
{
name: "date_of_joining",
type: "date",
},
{
name: "department",
type: "uuid",
foreign_key: {
table: "department",
column: "id",
},
},
],
});Unique constraint
await client.defineTable({
name: "student",
columns: [
{
name: "name",
type: "string",
},
{
name: "roll_no",
type: "integer",
unique: true,
},
{
name: "age",
type: "integer",
},
],
unique: [["name", "age"]],
});Querying
const teacherTable = client.table("teacher");
for (let i = 0; i < 10; i++) {
const teacher = teacherTable.createNewRecord();
teacher.set("name", randomNames());
teacher.set("badge_number", i + 1);
teacher.set("age", 10 * ((i + 1) % 2));
await teacher.insert();
}
let records = await teacherTable.orderBy("badge_number", "DESC").toArray();
for (const record of records) {
console.log(record.get("name") + " :: " + record.get("badge_number"));
}
console.log("Count :: " + (await teacherTable.count()));Querying with compound ‘OR’ and ‘AND’ conditions
// Where 'age' is 10 and (name is 'a1' or 'roll_no' is 5)
// SELECT * FROM public.teacher WHERE "age" = 10 AND ("name" = 'a1' OR "roll_no" = 5)
const selectQuery = teacherTable
.where("age", 10)
.andWhere((compoundQuery) => {
compoundQuery
.where("name", "a1")
.orWhere("badge_number", "5");
});
records = await selectQuery.toArray();
console.log(records.map((t) => t.toJSON()));Using cursor
const recordCursor = await teacherTable
.select()
.orderBy("roll_no", "DESC")
.execute();
for await (const record of recordCursor) {
console.log(record.get("name") + " :: " + record.get("roll_no"));
}Intercepting database operations
Intercept and compute student full name before insert and print all records after
const client = await odm.connect(true);
await client.defineTable({
name: "student",
columns: [
{
name: "first_name",
type: "string",
},
{
name: "last_name",
type: "string",
},
{
name: "full_name", /* Value computed in intercept */
type: "string",
},
],
});
class FullNameIntercept extends RecordInterceptor {
getName() {
return "full-name-intercept";
}
async intercept(
table: Table,
interceptType: TRecordInterceptorType,
records: Record[],
_context: TRecordInterceptorContext,
) {
if (table.getName() === "student") {
console.log(`[collectionName=${table.getName()}, when=${interceptType}]`);
if (interceptType === "BEFORE_INSERT") {
for (const record of records) {
console.log(
`Full name field updated for :: ${record.get("first_name")}`,
);
record.set(
"full_name",
`${record.get("first_name")} ${record.get("last_name")}`,
);
}
}
if (interceptType === "AFTER_SELECT") {
for (const record of records) {
console.log(JSON.stringify(record.toJSON(), null, 4));
}
}
}
return records;
}
}
odm.addInterceptor(new FullNameIntercept());
const studentTable = client.table("student");
const studentRecord = studentTable.createNewRecord();
studentRecord.set("first_name", "John");
studentRecord.set("last_name", "Doe");
await studentRecord.insert();
await studentTable.toArray();
/* This will print the following:
[collectionName=student, operation=INSERT, when=BEFORE]
Full name field updated for :: John
[collectionName=student, operation=INSERT, when=AFTER]
[collectionName=student, operation=SELECT, when=BEFORE]
[collectionName=student, operation=SELECT, when=AFTER]
{
"id": "653c21bb-7d92-435e-a742-1da749f914dd",
"_table": "student",
"first_name": "John",
"last_name": "Doe",
"full_name": "John Doe"
}
*/
client.closeConnection();Define custom field type
After connection established, you can define custom field type.
const client = await odm.connect(true);
class EmailType extends IDataType {
constructor() {
super("email");
}
getNativeType(_definition: TColumnDefinition): TColumnDataType {
return "VARCHAR";
}
toJSONValue(value: string | null): string | null {
return value;
}
validateDefinition(_columnDefinition: TColumnDefinition) {
// Throw an error if something in definition is not meeting your expectation.
}
setValueIntercept(newValue: any): any {
return newValue;
}
async validateValue(value: unknown): Promise<void> {
const pattern = "(.+)@(.+){2,}\\.(.+){2,}";
if (
value &&
typeof value === "string" &&
!new RegExp(pattern).test(value)
) {
throw new Error("Not a valid email");
}
}
}
odm.addDataType(new EmailType());
await client.defineTable({
name: "employee",
columns: [
{
name: "name",
type: "string",
},
{
name: "personal_contact",
type: "email",
},
{
name: "emp_no",
type: "uuid",
},
{
name: "salary",
type: "integer",
},
{
name: "birth_date",
type: "date",
},
{
name: "gender",
type: "boolean",
},
],
});
const studentTable = client.table("employee");
const student = studentTable.createNewRecord();
student.set("personal_contact", "NOT_EMAIL_VALUE");
student.set("birth_date", new Date());
try {
await student.insert(); // this will throw an error, because email is not valid
console.log("Student created");
} catch (error) {
console.log(error);
}
client.closeConnection();Inheritance
const client = await odm.connect(true);
await client.defineTable({
name: "animal",
columns: [
{
name: "name",
type: "string",
},
],
});
const animalTable = client.table("animal");
const animal = animalTable.createNewRecord();
animal.set("name", "Puppy");
await animal.insert();
await client.defineTable({
name: "dog",
inherits: "animal",
final: true,
columns: [
{
name: "breed",
type: "string",
},
],
});
const dogTable = client.table("dog");
const husky = dogTable.createNewRecord();
husky.set("name", "Jimmy");
husky.set("breed", "Husky");
await husky.insert();
const animalCursor = await animalTable.execute();
for await (const animal of animalCursor()) {
console.log(animal.toJSON());
}
client.closeConnection();Known limitations:
Data types
| Data type | Record.get | Record.getJSONValue |
|---|---|---|
| boolean | boolean | boolean |
| date | Temporal.PlainDate | string |
| datetime | Temporal.PlainDateTime | string |
| integer | number | number |
| json | {} | {} |
| number | number | number |
| string | string | string |
| uuid | string | string |
Check the examples >> here <<