Introducing Rowquill

Brand new ORM for Zuzu just dropped!

Why would they change math?

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, and delete.
  • Generated column accessors with optional alternate names.
  • Primary key lookup by scalar, array, or dictionary.
  • Dirty tracking so update only writes changed non-primary-key fields, plus is_dirty, dirty_fields, mark_clean, and reload.
  • Raw column storage in column_data.
  • Inflate and deflate callbacks for structured values such as JSON.
  • length, pattern, validate, required, default, readonly, unique, and exists_in column checks.
  • search supports equality, common comparison operators, LIKE, NOT LIKE, ILIKE, IN, NOT IN, BETWEEN, AND, OR, and NOT.
  • has_one and has_many relationships with multi-column joins and optional search-style where filters.
  • Assigning has_one relationships with relationship(set: row).
  • Custom row helper methods and static table-class methods.
  • Lifecycle hooks for insert, update, and delete.
  • Schema registry helpers: has_table and table_names.
  • Schema-level create, find, search, and insert shortcuts for dynamic table names.
  • Schema.transaction with 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

Leave a Reply

Your email address will not be published. Required fields are marked *