Move api to package
This commit is contained in:
parent
1aec8031e6
commit
581159963f
14 changed files with 43 additions and 74 deletions
|
@ -17,10 +17,16 @@ const sql_pkg = std.build.Pkg{
|
|||
.dependencies = &.{util_pkg},
|
||||
};
|
||||
|
||||
const api_pkg = std.build.Pkg{
|
||||
.name = "api",
|
||||
.source = std.build.FileSource.relative("src/api/lib.zig"),
|
||||
.dependencies = &.{ util_pkg, sql_pkg },
|
||||
};
|
||||
|
||||
const main_pkg = std.build.Pkg{
|
||||
.name = "main",
|
||||
.source = std.build.FileSource.relative("src/main/main.zig"),
|
||||
.dependencies = &.{ util_pkg, http_pkg, sql_pkg },
|
||||
.dependencies = &.{ util_pkg, http_pkg, sql_pkg, api_pkg },
|
||||
};
|
||||
|
||||
pub fn build(b: *std.build.Builder) void {
|
||||
|
@ -41,6 +47,7 @@ pub fn build(b: *std.build.Builder) void {
|
|||
exe.addPackage(sql_pkg);
|
||||
exe.addPackage(util_pkg);
|
||||
exe.addPackage(http_pkg);
|
||||
exe.addPackage(api_pkg);
|
||||
|
||||
exe.linkSystemLibrary("sqlite3");
|
||||
exe.linkSystemLibrary("pq");
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
const std = @import("std");
|
||||
const util = @import("util");
|
||||
const builtin = @import("builtin");
|
||||
const sql = @import("sql");
|
||||
|
||||
const DateTime = util.DateTime;
|
||||
const Uuid = util.Uuid;
|
||||
const Config = @import("./main.zig").Config;
|
||||
|
||||
const services = struct {
|
||||
const communities = @import("./api/communities.zig");
|
||||
const users = @import("./api/users.zig");
|
||||
const auth = @import("./api/auth.zig");
|
||||
const invites = @import("./api/invites.zig");
|
||||
const notes = @import("./api/notes.zig");
|
||||
const communities = @import("./services/communities.zig");
|
||||
const users = @import("./services/users.zig");
|
||||
const auth = @import("./services/auth.zig");
|
||||
const invites = @import("./services/invites.zig");
|
||||
const notes = @import("./services/notes.zig");
|
||||
};
|
||||
|
||||
pub const RegistrationRequest = struct {
|
||||
|
@ -59,38 +57,6 @@ pub const NoteResponse = struct {
|
|||
|
||||
pub const CommunityQueryArgs = services.communities.QueryArgs;
|
||||
|
||||
// Frees an api struct and its fields allocated from alloc
|
||||
pub fn free(alloc: std.mem.Allocator, val: anytype) void {
|
||||
switch (@typeInfo(@TypeOf(val))) {
|
||||
.Pointer => |ptr_info| switch (ptr_info.size) {
|
||||
.One => {
|
||||
free(alloc, val.*);
|
||||
alloc.destroy(val);
|
||||
},
|
||||
.Slice => {
|
||||
for (val) |elem| free(alloc, elem);
|
||||
alloc.free(val);
|
||||
},
|
||||
else => unreachable,
|
||||
},
|
||||
.Struct => inline for (std.meta.fields(@TypeOf(val))) |f| free(alloc, @field(val, f.name)),
|
||||
.Array => for (val) |elem| free(alloc, elem),
|
||||
.Optional => if (val) |opt| free(alloc, opt),
|
||||
.Bool, .Int, .Float, .Enum => {},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
threadlocal var prng: std.rand.DefaultPrng = undefined;
|
||||
|
||||
pub fn initThreadPrng(seed: u64) void {
|
||||
prng = std.rand.DefaultPrng.init(seed +% std.Thread.getCurrentId());
|
||||
}
|
||||
|
||||
pub fn getRandom() std.rand.Random {
|
||||
return prng.random();
|
||||
}
|
||||
|
||||
pub fn isAdminSetup(db: sql.Db) !bool {
|
||||
_ = services.communities.adminCommunityId(db) catch |err| switch (err) {
|
||||
error.NotFound => return false,
|
||||
|
@ -129,16 +95,14 @@ pub fn setupAdmin(db: sql.Db, origin: []const u8, username: []const u8, password
|
|||
|
||||
pub const ApiSource = struct {
|
||||
db_conn: *sql.Conn,
|
||||
config: Config,
|
||||
|
||||
pub const Conn = ApiConn(sql.Db);
|
||||
|
||||
const root_username = "root";
|
||||
|
||||
pub fn init(cfg: Config, db_conn: *sql.Conn) !ApiSource {
|
||||
pub fn init(db_conn: *sql.Conn) !ApiSource {
|
||||
return ApiSource{
|
||||
.db_conn = db_conn,
|
||||
.config = cfg,
|
||||
};
|
||||
}
|
||||
|
|
@ -3,8 +3,6 @@ const builtin = @import("builtin");
|
|||
const util = @import("util");
|
||||
const sql = @import("sql");
|
||||
|
||||
const getRandom = @import("../api.zig").getRandom;
|
||||
|
||||
const Uuid = util.Uuid;
|
||||
const DateTime = util.DateTime;
|
||||
|
||||
|
@ -70,7 +68,7 @@ pub fn create(db: anytype, origin: []const u8, options: CreateOptions, alloc: st
|
|||
// Require TLS on production builds
|
||||
if (scheme != .https and builtin.mode != .Debug) return error.UnsupportedScheme;
|
||||
|
||||
const id = Uuid.randV4(getRandom());
|
||||
const id = Uuid.randV4(util.getThreadPrng());
|
||||
|
||||
// TODO: wrap this in TX
|
||||
if (db.queryRow(
|
|
@ -1,7 +1,6 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const util = @import("util");
|
||||
const getRandom = @import("../api.zig").getRandom;
|
||||
|
||||
const Uuid = util.Uuid;
|
||||
const DateTime = util.DateTime;
|
||||
|
@ -47,10 +46,10 @@ pub const InviteOptions = struct {
|
|||
};
|
||||
|
||||
pub fn create(db: anytype, created_by: Uuid, community_id: ?Uuid, options: InviteOptions, alloc: std.mem.Allocator) !Uuid {
|
||||
const id = Uuid.randV4(getRandom());
|
||||
const id = Uuid.randV4(util.getThreadPrng());
|
||||
|
||||
var code_bytes: [rand_len]u8 = undefined;
|
||||
getRandom().bytes(&code_bytes);
|
||||
util.getThreadPrng().bytes(&code_bytes);
|
||||
|
||||
const code = try alloc.alloc(u8, code_len);
|
||||
defer alloc.free(code);
|
|
@ -4,7 +4,6 @@ const sql = @import("sql");
|
|||
|
||||
const Uuid = util.Uuid;
|
||||
const DateTime = util.DateTime;
|
||||
const getRandom = @import("../api.zig").getRandom;
|
||||
|
||||
pub const Note = struct {
|
||||
id: Uuid,
|
||||
|
@ -23,7 +22,7 @@ pub fn create(
|
|||
content: []const u8,
|
||||
alloc: std.mem.Allocator,
|
||||
) CreateError!Uuid {
|
||||
const id = Uuid.randV4(getRandom());
|
||||
const id = Uuid.randV4(util.getThreadPrng());
|
||||
|
||||
db.insert("note", .{
|
||||
.id = id,
|
|
@ -4,7 +4,6 @@ const auth = @import("./auth.zig");
|
|||
|
||||
const Uuid = util.Uuid;
|
||||
const DateTime = util.DateTime;
|
||||
const getRandom = @import("../api.zig").getRandom;
|
||||
|
||||
pub const CreateError = error{
|
||||
UsernameTaken,
|
||||
|
@ -81,7 +80,7 @@ pub fn create(
|
|||
kind: Kind,
|
||||
alloc: std.mem.Allocator,
|
||||
) CreateError!Uuid {
|
||||
const id = Uuid.randV4(getRandom());
|
||||
const id = Uuid.randV4(util.getThreadPrng());
|
||||
|
||||
try validateUsername(username);
|
||||
|
|
@ -2,9 +2,8 @@ const std = @import("std");
|
|||
const root = @import("root");
|
||||
const builtin = @import("builtin");
|
||||
const http = @import("http");
|
||||
const api = @import("./api.zig");
|
||||
const api = @import("api");
|
||||
const util = @import("util");
|
||||
const Uuid = util.Uuid;
|
||||
|
||||
pub const auth = @import("./controllers/auth.zig");
|
||||
pub const communities = @import("./controllers/communities.zig");
|
||||
|
|
|
@ -4,7 +4,6 @@ const builtin = @import("builtin");
|
|||
const http = @import("http");
|
||||
const Uuid = @import("util").Uuid;
|
||||
|
||||
const RegistrationInfo = @import("../api.zig").RegistrationInfo;
|
||||
const utils = @import("../controllers.zig").utils;
|
||||
|
||||
const RequestServer = root.RequestServer;
|
||||
|
@ -20,7 +19,6 @@ pub const login = struct {
|
|||
var api = try utils.getApiConn(srv, ctx);
|
||||
defer api.close();
|
||||
|
||||
std.log.debug("connected to api", .{});
|
||||
const token = try api.login(credentials.username, credentials.password);
|
||||
|
||||
try utils.respondJson(ctx, .ok, token);
|
||||
|
|
|
@ -15,7 +15,7 @@ pub const create = struct {
|
|||
// TODO: get rid of this temporary struct, find json library that lets me extend
|
||||
// it to parse UUIDs/etc in place
|
||||
const InviteRequest = struct {
|
||||
const Kind = @import("../api.zig").InviteRequest.Kind;
|
||||
const Kind = @import("api").InviteRequest.Kind;
|
||||
|
||||
name: ?[]const u8 = null,
|
||||
|
||||
|
|
|
@ -3,13 +3,11 @@ const http = @import("http");
|
|||
const Uuid = @import("util").Uuid;
|
||||
|
||||
const utils = @import("../controllers.zig").utils;
|
||||
const NoteCreateInfo = @import("../api.zig").NoteCreateInfo;
|
||||
const NoteCreateInfo = @import("api").NoteCreateInfo;
|
||||
|
||||
const RequestServer = root.RequestServer;
|
||||
const RouteArgs = http.RouteArgs;
|
||||
|
||||
//pub const reacts = @import("./notes/reacts.zig");
|
||||
|
||||
pub const create = struct {
|
||||
pub const method = .POST;
|
||||
pub const path = "/notes";
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
const std = @import("std");
|
||||
const root = @import("root");
|
||||
const builtin = @import("builtin");
|
||||
const http = @import("http");
|
||||
const Uuid = @import("util").Uuid;
|
||||
|
||||
const RegistrationRequest = @import("../api.zig").RegistrationRequest;
|
||||
const RegistrationRequest = @import("api").RegistrationRequest;
|
||||
const utils = @import("../controllers.zig").utils;
|
||||
|
||||
const RequestServer = root.RequestServer;
|
||||
|
|
|
@ -4,8 +4,8 @@ const sql = @import("sql");
|
|||
const http = @import("http");
|
||||
const util = @import("util");
|
||||
|
||||
pub const api = @import("./api.zig");
|
||||
pub const migrations = @import("./migrations.zig");
|
||||
const api = @import("api");
|
||||
const migrations = @import("./migrations.zig");
|
||||
const Uuid = util.Uuid;
|
||||
const c = @import("./controllers.zig");
|
||||
|
||||
|
@ -112,7 +112,6 @@ fn runAdminSetup(db: sql.Db, alloc: std.mem.Allocator) !void {
|
|||
|
||||
fn prepareDb(db: sql.Db, alloc: std.mem.Allocator) !void {
|
||||
try migrations.up(db);
|
||||
api.initThreadPrng(@bitCast(u64, std.time.milliTimestamp()));
|
||||
|
||||
if (!try api.isAdminSetup(db)) {
|
||||
std.log.info("Performing first-time admin creation...", .{});
|
||||
|
@ -136,14 +135,14 @@ fn prepareDb(db: sql.Db, alloc: std.mem.Allocator) !void {
|
|||
}
|
||||
|
||||
pub fn main() !void {
|
||||
try util.seedThreadPrng();
|
||||
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
var cfg = try loadConfig(gpa.allocator());
|
||||
var db_conn = try sql.Conn.open(cfg.db);
|
||||
try prepareDb(try db_conn.acquire(), gpa.allocator());
|
||||
//try migrations.up(&db_conn);
|
||||
//try api.setupAdmin(&db_conn, "http://localhost:8080", "root", "password", gpa.allocator());
|
||||
|
||||
var api_src = try api.ApiSource.init(cfg, &db_conn);
|
||||
var api_src = try api.ApiSource.init(&db_conn);
|
||||
var srv = try RequestServer.init(gpa.allocator(), &api_src, cfg);
|
||||
return srv.listenAndRun(std.net.Address.parseIp("0.0.0.0", 8080) catch unreachable);
|
||||
}
|
||||
|
|
|
@ -169,9 +169,19 @@ pub fn deepClone(alloc: std.mem.Allocator, val: anytype) !@TypeOf(val) {
|
|||
return result;
|
||||
}
|
||||
|
||||
test {
|
||||
_ = ciutf8;
|
||||
_ = Uuid;
|
||||
_ = PathIter;
|
||||
_ = DateTime;
|
||||
threadlocal var prng: ?std.rand.DefaultPrng = null;
|
||||
|
||||
pub fn getThreadPrng() std.rand.Random {
|
||||
if (prng) |*p| return p.random();
|
||||
|
||||
@panic("Thread PRNG not seeded");
|
||||
}
|
||||
|
||||
pub fn seedThreadPrng() !void {
|
||||
@setCold(true);
|
||||
|
||||
var buf: [8]u8 = undefined;
|
||||
try std.os.getrandom(&buf);
|
||||
|
||||
prng = std.rand.DefaultPrng.init(@bitCast(u64, buf));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue