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;
}