Add community actors

This commit is contained in:
jaina heartles 2022-12-05 02:38:31 -08:00
parent af7c77babf
commit 3c8ac8d7d4
1 changed files with 26 additions and 6 deletions

View File

@ -3,6 +3,7 @@ const builtin = @import("builtin");
const util = @import("util");
const sql = @import("sql");
const common = @import("./common.zig");
const actors = @import("./actors.zig");
const Uuid = util.Uuid;
const DateTime = util.DateTime;
@ -38,11 +39,10 @@ pub const CreateOptions = struct {
};
pub const CreateError = error{
DatabaseFailure,
UnsupportedScheme,
InvalidOrigin,
CommunityExists,
};
} || sql.DatabaseError;
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;
@ -71,7 +71,9 @@ pub fn create(db: anytype, origin: []const u8, options: CreateOptions, alloc: st
const id = Uuid.randV4(util.getThreadPrng());
// TODO: wrap this in TX
if (db.queryRow(
var tx = try db.beginOrSavepoint();
errdefer tx.rollback();
if (tx.queryRow(
std.meta.Tuple(&.{Uuid}),
"SELECT id FROM community WHERE host = $1",
.{host},
@ -80,11 +82,11 @@ pub fn create(db: anytype, origin: []const u8, options: CreateOptions, alloc: st
return error.CommunityExists;
} else |err| switch (err) {
error.NoRows => {},
else => return error.DatabaseFailure,
else => |e| return e,
}
const name = options.name orelse host;
db.insert("community", .{
try tx.insert("community", .{
.id = id,
.owner_id = null,
.host = host,
@ -92,8 +94,26 @@ pub fn create(db: anytype, origin: []const u8, options: CreateOptions, alloc: st
.scheme = scheme,
.kind = options.kind,
.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;
}