Ideas For a Project to Learn Zig

In-memory relational database with a comptime based ORM?

Something like this:

const std = @import("std");

fn DBType(comptime schema: anytype) type {
    // comptime magic here
}

const Account = struct {
    id: ID,
    balance: u128,

    const ID = enum(u64) { _ };
};

const Transfer = struct {
    id: ID,
    amount: u128,
    debit_account: Account.ID,
    credit_account: Account.ID,

    const ID = enum(u64) { _ };
};

// This is our database
const DB = DBType(.{
    .tables = .{
        .account = Account,
        .transfer = Transfer,
    },
    .indexes = .{
        .transfer = .{
            .debit_account, .credit_account,
        },
    },
});

pub fn main() void {
    var gpa_allocator: std.heap.GeneralPurposeAllocator(.{}) = .{};
    const gpa = gpa_allocator.allocator();

    var db = DB.init(gpa);
    defer db.deinit(gpa);

    // Create individual objects
    const alice = db.accont().create(.{ .balance = 100 });
    const bob = db.accont().create(.{ .balance = 200 });
    transfer(db, alice, bob, 100);

    // Index-based lookups
    var alice_transfers_itertor = db.transfer().filter(.{ .debit_account = alice });
    while (alice_transfers_itertor.next()) {}
}

fn transfer(
    db: *DB,
    debit_account: Account.ID,
    credit_account: Account.ID,
    amount: u128,
) ?Transfer.ID {
    // Point lookups
    const dr = db.account().get(debit_account) orelse return null;
    const cr = db.account().get(credit_account) orelse return null;
    if (dr.balance >= amount and cr.balance <= std.math.maxInt(u128) - amount) {
        // Point updates
        db.account().update(debit_account, .{ .balance = dr.balance - amount });
        db.account().update(credit_account, .{ .balance = dr.balance - amount });
        return db.transfer().create(.{
            .debit_account = debit_account,
            .credit_account = credit_account,
            .amount = amount,
        });
    }
    return null;
}
3 Likes