Introducing Rowquill
Brand new ORM for Zuzu just dropped!
Rowquill is an ORM for ZuzuScript, allowing you to declare classes for your database tables, and perform searches, inserts, updates, and deletes in an object-oriented manner. It takes inspiration from Perl's DBIx::Class and other popular ORMs.
Features
create,find,search,all,first,count,exists,find_or_create,create_or_update,insert,update,insert_or_update, anddelete.- Generated column accessors with optional alternate names.
- Primary key lookup by scalar, array, or dictionary.
- Dirty tracking so
updateonly writes changed non-primary-key fields, plusis_dirty,dirty_fields,mark_clean, andreload. - Raw column storage in
column_data. - Inflate and deflate callbacks for structured values such as JSON.
length,pattern,validate,required,default,readonly,unique, andexists_incolumn checks.searchsupports equality, common comparison operators,LIKE,NOT LIKE,ILIKE,IN,NOT IN,BETWEEN,AND,OR, andNOT.has_oneandhas_manyrelationships with multi-column joins and optional search-stylewherefilters.- Assigning
has_onerelationships withrelationship(set: row). - Custom row helper methods and static table-class methods.
- Lifecycle hooks for insert, update, and delete.
- Schema registry helpers:
has_tableandtable_names. - Schema-level
create,find,search, andinsertshortcuts for dynamic table names. Schema.transactionwith nested transaction savepoints.
Example
from db/rowquill import Schema;
from std/db import DB;
let schema := new Schema( dbh: DB.temp() );
schema.get_dbh().prepare("""
CREATE TABLE department (
id int,
name varchar(200),
PRIMARY KEY (id, company)
);
""").execute();
schema.add_table( "department", function ( tab ) {
tab.add_column( "id", "int", primary: true );
tab.add_column( "name", "varchar", required: true );
tab.has_many(
accessor: "employees",
table: "employee",
join: { id: "dept" },
where: { is_deleted: false },
);
} );
schema.get_dbh().prepare("""
CREATE TABLE employee (
id int PRIMARY KEY,
fullname varchar(200),
dept int,
is_deleted bool
);
""").execute();
schema.add_table( "employee", function ( tab ) {
tab.add_column( "id", "int", primary: true );
tab.add_column(
"fullname",
"varchar",
required: true,
accessor: "name",
);
tab.add_column( "dept", "int" );
tab.add_column( "is_deleted", "bool" );
tab.has_one(
accessor: "department",
table: "department",
join: { dept: "id" },
);
tab.add_helper( "is_accountant", function ( employee ) {
return employee.department().name() eq "Accounts";
} );
} );
let accounts := schema.table("department").create(
id: 3,
name: "Accounts",
);
accounts.insert();
let bob := schema.table("employee").create(
id: 42,
name: "Bob",
dept: 3,
is_deleted: false,
);
bob.insert();
say( bob.department().name() ); // Accounts
say( accounts.employees()[0].name() ); // Bob
say( bob.is_accountant() ); // true
Get Rowquill 0.0.2