Use sql api for users

This commit is contained in:
jaina heartles 2022-07-16 11:41:09 -07:00
parent 40e7037444
commit 74fb8d2574
5 changed files with 49 additions and 33 deletions

View file

@ -47,7 +47,7 @@ pub const ApiServer = struct {
pub fn init(alloc: std.mem.Allocator) !ApiServer {
return ApiServer{
.memdb = try memdb.Database.init(alloc),
.prng = std.rand.DefaultPrng.init(1998),
.prng = std.rand.DefaultPrng.init(@bitCast(u64, std.time.milliTimestamp())),
.db = try db.Database.init(),
};
@ -63,36 +63,34 @@ pub const ApiServer = struct {
// TODO: check for dupes
const note = reify(models.Note, id, info);
try self.db.insertNote(note);
//try self.memdb.notes.put(note);
try self.db.insert(models.Note, 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;
}
}
//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);
try self.db.insert(models.User, 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);
return self.db.getById(models.Note, id, alloc);
}
pub fn getUser(self: *ApiServer, id: Uuid, alloc: std.mem.Allocator) !?models.User {
return self.db.getById(models.User, id, alloc);
}
};

View file

@ -79,6 +79,15 @@ pub fn getNote(srv: *RequestServer, ctx: *http.server.Context, args: RouteArgs)
try utils.respondJson(ctx, .ok, note, srv.alloc);
}
pub fn getUser(srv: *RequestServer, ctx: *http.server.Context, args: RouteArgs) !void {
const id_str = args.get("id") orelse return error.NotFound;
const id = Uuid.parse(id_str) catch return utils.respondJson(ctx, .bad_request, .{ .@"error" = "Invalid UUID" }, srv.alloc);
const user = (try srv.api.getUser(id, srv.alloc)) orelse return utils.respondJson(ctx, .not_found, .{ .@"error" = "Note not found" }, srv.alloc);
defer api.free(srv.alloc, user);
try utils.respondJson(ctx, .ok, user, srv.alloc);
}
pub fn healthcheck(srv: *RequestServer, ctx: *http.server.Context, _: RouteArgs) !void {
try utils.respondJson(ctx, .ok, .{ .status = "ok" }, srv.alloc);
}

View file

@ -91,27 +91,30 @@ fn fieldsExcept(comptime T: type, comptime to_ignore: []const String) []const St
pub const Database = struct {
db: sql.Sqlite,
const init_sql_stmts = [_][]const u8{
\\CREATE TABLE IF NOT EXISTS
\\note(
\\ id TEXT PRIMARY KEY,
\\ content TEXT NOT NULL
\\) STRICT;
,
\\CREATE TABLE IF NOT EXISTS
\\user(
\\ id TEXT PRIMARY KEY,
\\ handle TEXT NOT NULL
\\) STRICT;
};
pub fn init() !Database {
var db = try sql.Sqlite.open("./test.db");
errdefer db.close();
var stmt = try db.prepare(
\\CREATE TABLE IF NOT EXISTS
\\note(
\\ id TEXT PRIMARY KEY,
\\ content TEXT NOT NULL
\\) STRICT;
\\
\\CREATE TABLE IF NOT EXISTS
\\user(
\\ id TEXT PRIMARY KEY,
\\ handle TEXT NOT NULL
\\) STRICT;
\\
);
defer stmt.finalize();
for (init_sql_stmts) |stmt_sql| {
var stmt = try db.prepare(stmt_sql);
defer stmt.finalize();
while (try stmt.step()) |_| {}
while (try stmt.step()) |_| {}
}
return Database{ .db = db };
}

View file

@ -15,8 +15,10 @@ const RouteArgs = http.RouteArgs;
const router = Router{
.routes = &[_]Route{
Route.new(.GET, "/healthcheck", c.healthcheck),
Route.new(.GET, "/notes/:id", c.getNote),
Route.new(.POST, "/notes", c.createNote),
Route.new(.GET, "/users/:id", c.getUser),
Route.new(.POST, "/users", c.createUser),
},
};

View file

@ -23,7 +23,11 @@ pub const Sqlite = struct {
pub fn prepare(self: *Sqlite, sql: []const u8) !PreparedStmt {
var stmt: ?*c.sqlite3_stmt = undefined;
const err = c.sqlite3_prepare_v2(self.db, sql.ptr, @intCast(c_int, sql.len), &stmt, null);
if (err != c.SQLITE_OK) return error.UnknownError;
if (err != c.SQLITE_OK) {
std.debug.print("sql error {}\n", .{err});
std.debug.print("{s}\n", .{c.sqlite3_errmsg(self.db)});
return error.UnknownError;
}
return PreparedStmt{ .stmt = stmt.?, .db = self.db };
}