const std = @import("std"); const util = @import("util"); const memdb = @import("./memdb.zig"); const db = @import("./db.zig"); pub const models = @import("./models.zig"); pub const free = memdb.free; pub const Uuid = util.Uuid; pub fn CreateInfo(comptime T: type) type { const t_fields = std.meta.fields(T); var fields: [t_fields.len - 1]std.builtin.Type.StructField = undefined; var count = 0; inline for (t_fields) |f| { if (std.mem.eql(u8, f.name, "id")) continue; fields[count] = f; count += 1; } return @Type(.{ .Struct = .{ .layout = .Auto, .fields = &fields, .decls = &[0]std.builtin.Type.Declaration{}, .is_tuple = false, } }); } fn reify(comptime T: type, id: Uuid, val: CreateInfo(T)) T { var result: T = undefined; result.id = id; inline for (std.meta.fields(CreateInfo(T))) |f| { @field(result, f.name) = @field(val, f.name); } return result; } pub const ApiServer = struct { memdb: memdb.Database, prng: std.rand.DefaultPrng, last_id: u64 = 0, db: db.Database, pub fn init(alloc: std.mem.Allocator) !ApiServer { return ApiServer{ .memdb = try memdb.Database.init(alloc), .prng = std.rand.DefaultPrng.init(1998), .db = try db.Database.init(), }; } fn genUuid(self: *ApiServer, alloc: std.mem.Allocator) ![]const u8 { self.last_id += 1; return std.fmt.allocPrint(alloc, "{}", .{self.last_id}); } pub fn createNote(self: *ApiServer, info: CreateInfo(models.Note)) !models.Note { const id = Uuid.randV4(self.prng.random()); // TODO: check for dupes const note = reify(models.Note, id, info); try self.db.insertNote(note); //try self.memdb.notes.put(note); return note; } pub fn createUser(self: *ApiServer, info: CreateInfo(models.User)) !models.User { try self.memdb.users.lock(); defer self.memdb.users.unlock(); // TODO; real queries const id = Uuid.randV4(self.prng.random()); // check for handle dupes var iter = self.memdb.users.data.iterator(); while (iter.next()) |it| { if (std.mem.eql(u8, it.value_ptr.handle, info.handle)) { return error.DuplicateHandle; } } // TODO: check for id dupes const user = reify(models.User, id, info); try self.memdb.users.put(user); return user; } pub fn getNote(self: *ApiServer, id: Uuid, alloc: std.mem.Allocator) !?models.Note { return self.db.getNoteById(id, alloc); //return self.memdb.notes.get(id, alloc); } };