Use sql api for users
This commit is contained in:
parent
40e7037444
commit
74fb8d2574
5 changed files with 49 additions and 33 deletions
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue