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 {
|
pub fn init(alloc: std.mem.Allocator) !ApiServer {
|
||||||
return ApiServer{
|
return ApiServer{
|
||||||
.memdb = try memdb.Database.init(alloc),
|
.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(),
|
.db = try db.Database.init(),
|
||||||
};
|
};
|
||||||
|
@ -63,36 +63,34 @@ pub const ApiServer = struct {
|
||||||
// TODO: check for dupes
|
// TODO: check for dupes
|
||||||
|
|
||||||
const note = reify(models.Note, id, info);
|
const note = reify(models.Note, id, info);
|
||||||
try self.db.insertNote(note);
|
try self.db.insert(models.Note, note);
|
||||||
//try self.memdb.notes.put(note);
|
|
||||||
|
|
||||||
return note;
|
return note;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn createUser(self: *ApiServer, info: CreateInfo(models.User)) !models.User {
|
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());
|
const id = Uuid.randV4(self.prng.random());
|
||||||
|
|
||||||
// check for handle dupes
|
// check for handle dupes
|
||||||
var iter = self.memdb.users.data.iterator();
|
//var iter = self.memdb.users.data.iterator();
|
||||||
while (iter.next()) |it| {
|
//while (iter.next()) |it| {
|
||||||
if (std.mem.eql(u8, it.value_ptr.handle, info.handle)) {
|
//if (std.mem.eql(u8, it.value_ptr.handle, info.handle)) {
|
||||||
return error.DuplicateHandle;
|
//return error.DuplicateHandle;
|
||||||
}
|
//}
|
||||||
}
|
//}
|
||||||
// TODO: check for id dupes
|
// TODO: check for id dupes
|
||||||
|
|
||||||
const user = reify(models.User, id, info);
|
const user = reify(models.User, id, info);
|
||||||
try self.memdb.users.put(user);
|
try self.db.insert(models.User, user);
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getNote(self: *ApiServer, id: Uuid, alloc: std.mem.Allocator) !?models.Note {
|
pub fn getNote(self: *ApiServer, id: Uuid, alloc: std.mem.Allocator) !?models.Note {
|
||||||
return self.db.getNoteById(id, alloc);
|
return self.db.getById(models.Note, id, alloc);
|
||||||
//return self.memdb.notes.get(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);
|
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 {
|
pub fn healthcheck(srv: *RequestServer, ctx: *http.server.Context, _: RouteArgs) !void {
|
||||||
try utils.respondJson(ctx, .ok, .{ .status = "ok" }, srv.alloc);
|
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 {
|
pub const Database = struct {
|
||||||
db: sql.Sqlite,
|
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 {
|
pub fn init() !Database {
|
||||||
var db = try sql.Sqlite.open("./test.db");
|
var db = try sql.Sqlite.open("./test.db");
|
||||||
errdefer db.close();
|
errdefer db.close();
|
||||||
|
|
||||||
var stmt = try db.prepare(
|
for (init_sql_stmts) |stmt_sql| {
|
||||||
\\CREATE TABLE IF NOT EXISTS
|
var stmt = try db.prepare(stmt_sql);
|
||||||
\\note(
|
defer stmt.finalize();
|
||||||
\\ 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();
|
|
||||||
|
|
||||||
while (try stmt.step()) |_| {}
|
while (try stmt.step()) |_| {}
|
||||||
|
}
|
||||||
|
|
||||||
return Database{ .db = db };
|
return Database{ .db = db };
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,10 @@ const RouteArgs = http.RouteArgs;
|
||||||
const router = Router{
|
const router = Router{
|
||||||
.routes = &[_]Route{
|
.routes = &[_]Route{
|
||||||
Route.new(.GET, "/healthcheck", c.healthcheck),
|
Route.new(.GET, "/healthcheck", c.healthcheck),
|
||||||
|
|
||||||
Route.new(.GET, "/notes/:id", c.getNote),
|
Route.new(.GET, "/notes/:id", c.getNote),
|
||||||
Route.new(.POST, "/notes", c.createNote),
|
Route.new(.POST, "/notes", c.createNote),
|
||||||
|
Route.new(.GET, "/users/:id", c.getUser),
|
||||||
Route.new(.POST, "/users", c.createUser),
|
Route.new(.POST, "/users", c.createUser),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,7 +23,11 @@ pub const Sqlite = struct {
|
||||||
pub fn prepare(self: *Sqlite, sql: []const u8) !PreparedStmt {
|
pub fn prepare(self: *Sqlite, sql: []const u8) !PreparedStmt {
|
||||||
var stmt: ?*c.sqlite3_stmt = undefined;
|
var stmt: ?*c.sqlite3_stmt = undefined;
|
||||||
const err = c.sqlite3_prepare_v2(self.db, sql.ptr, @intCast(c_int, sql.len), &stmt, null);
|
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 };
|
return PreparedStmt{ .stmt = stmt.?, .db = self.db };
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue