Add community actors

This commit is contained in:
jaina heartles 2022-12-05 02:38:31 -08:00
parent af7c77babf
commit 3c8ac8d7d4

View file

@ -3,6 +3,7 @@ const builtin = @import("builtin");
const util = @import("util"); const util = @import("util");
const sql = @import("sql"); const sql = @import("sql");
const common = @import("./common.zig"); const common = @import("./common.zig");
const actors = @import("./actors.zig");
const Uuid = util.Uuid; const Uuid = util.Uuid;
const DateTime = util.DateTime; const DateTime = util.DateTime;
@ -38,11 +39,10 @@ pub const CreateOptions = struct {
}; };
pub const CreateError = error{ pub const CreateError = error{
DatabaseFailure,
UnsupportedScheme, UnsupportedScheme,
InvalidOrigin, InvalidOrigin,
CommunityExists, CommunityExists,
}; } || sql.DatabaseError;
pub fn create(db: anytype, origin: []const u8, options: CreateOptions, alloc: std.mem.Allocator) CreateError!Uuid { pub fn create(db: anytype, origin: []const u8, options: CreateOptions, alloc: std.mem.Allocator) CreateError!Uuid {
const scheme_len = std.mem.indexOfScalar(u8, origin, ':') orelse return error.InvalidOrigin; const scheme_len = std.mem.indexOfScalar(u8, origin, ':') orelse return error.InvalidOrigin;
@ -71,7 +71,9 @@ pub fn create(db: anytype, origin: []const u8, options: CreateOptions, alloc: st
const id = Uuid.randV4(util.getThreadPrng()); const id = Uuid.randV4(util.getThreadPrng());
// TODO: wrap this in TX // TODO: wrap this in TX
if (db.queryRow( var tx = try db.beginOrSavepoint();
errdefer tx.rollback();
if (tx.queryRow(
std.meta.Tuple(&.{Uuid}), std.meta.Tuple(&.{Uuid}),
"SELECT id FROM community WHERE host = $1", "SELECT id FROM community WHERE host = $1",
.{host}, .{host},
@ -80,11 +82,11 @@ pub fn create(db: anytype, origin: []const u8, options: CreateOptions, alloc: st
return error.CommunityExists; return error.CommunityExists;
} else |err| switch (err) { } else |err| switch (err) {
error.NoRows => {}, error.NoRows => {},
else => return error.DatabaseFailure, else => |e| return e,
} }
const name = options.name orelse host; const name = options.name orelse host;
db.insert("community", .{ try tx.insert("community", .{
.id = id, .id = id,
.owner_id = null, .owner_id = null,
.host = host, .host = host,
@ -92,8 +94,26 @@ pub fn create(db: anytype, origin: []const u8, options: CreateOptions, alloc: st
.scheme = scheme, .scheme = scheme,
.kind = options.kind, .kind = options.kind,
.created_at = DateTime.now(), .created_at = DateTime.now(),
}, alloc) catch return error.DatabaseFailure; }, alloc);
if (options.kind == .local) {
const actor_id = actors.create(tx, "community.actor", id, alloc) catch |err| switch (err) {
error.UsernameContainsInvalidChar,
error.UsernameTooLong,
error.UsernameEmpty,
error.UsernameTaken,
=> unreachable,
else => @panic("TODO"),
};
try tx.exec(
\\UPDATE community
\\SET community_actor_id = $1
\\WHERE id = $2
\\LIMIT 1
, .{ actor_id, id }, alloc);
}
try tx.commitOrRelease();
return id; return id;
} }