Add drive files to db
This commit is contained in:
parent
14c75e0659
commit
f457b7a0d6
2 changed files with 90 additions and 0 deletions
69
src/api/services/files.zig
Normal file
69
src/api/services/files.zig
Normal file
|
@ -0,0 +1,69 @@
|
|||
const std = @import("std");
|
||||
const util = @import("util");
|
||||
|
||||
const Uuid = util.Uuid;
|
||||
const DateTime = util.DateTime;
|
||||
|
||||
pub const FileOwner = union(enum) {
|
||||
user_id: Uuid,
|
||||
community_id: Uuid,
|
||||
};
|
||||
|
||||
pub const DriveFile = struct {
|
||||
id: Uuid,
|
||||
filename: []const u8,
|
||||
owner: FileOwner,
|
||||
size: usize,
|
||||
created_at: DateTime,
|
||||
};
|
||||
|
||||
pub const files = struct {
|
||||
pub fn create(db: anytype, owner: FileOwner, filename: []const u8, data: []const u8, alloc: std.mem.Allocator) !void {
|
||||
const id = Uuid.randV4(util.getThreadPrng());
|
||||
const now = DateTime.now();
|
||||
|
||||
// TODO: assert we're not in a transaction
|
||||
db.insert("drive_file", .{
|
||||
.id = id,
|
||||
.filename = filename,
|
||||
.owner = owner,
|
||||
.created_at = now,
|
||||
}, alloc) catch return error.DatabaseFailure;
|
||||
// Assume the previous statement succeeded and is not stuck in a transaction
|
||||
errdefer {
|
||||
db.exec("DELETE FROM drive_file WHERE ID = $1", .{id}, alloc) catch |err| {
|
||||
std.log.err("Unable to remove file record in DB: {}", .{err});
|
||||
};
|
||||
}
|
||||
|
||||
try saveFile(id, data);
|
||||
}
|
||||
|
||||
const data_root = "./files";
|
||||
fn saveFile(id: Uuid, data: []const u8) !void {
|
||||
var dir = try std.fs.cwd().openDir(data_root);
|
||||
defer dir.close();
|
||||
|
||||
var file = try dir.createFile(id.toCharArray(), .{ .exclusive = true });
|
||||
defer file.close();
|
||||
|
||||
try file.writer().writeAll(data);
|
||||
try file.sync();
|
||||
}
|
||||
|
||||
pub fn deref(alloc: std.mem.Allocator, id: Uuid) ![]const u8 {
|
||||
var dir = try std.fs.cwd().openDir(data_root);
|
||||
defer dir.close();
|
||||
|
||||
return dir.readFileAlloc(alloc, id.toCharArray(), 1 << 32);
|
||||
}
|
||||
|
||||
pub fn delete(db: anytype, alloc: std.mem.Allocator, id: Uuid) !void {
|
||||
var dir = try std.fs.cwd().openDir(data_root);
|
||||
defer dir.close();
|
||||
|
||||
try dir.deleteFile(id.toCharArray());
|
||||
|
||||
db.exec("DELETE FROM drive_file WHERE ID = $1", .{id}, alloc) catch return error.DatabaseFailure;
|
||||
}
|
||||
};
|
|
@ -205,4 +205,25 @@ const migrations: []const Migration = &.{
|
|||
,
|
||||
.down = "DROP TABLE follow",
|
||||
},
|
||||
.{
|
||||
.name = "files",
|
||||
.up =
|
||||
\\CREATE TABLE drive_file(
|
||||
\\ id UUID NOT NULL PRIMARY KEY,
|
||||
\\
|
||||
\\ filename TEXT NOT NULL,
|
||||
\\ account_owner_id UUID REFERENCES account(id),
|
||||
\\ community_owner_id UUID REFERENCES community(id),
|
||||
\\ size INTEGER NOT NULL,
|
||||
\\
|
||||
\\ created_at TIMESTAMPTZ NOT NULL,
|
||||
\\
|
||||
\\ CHECK(
|
||||
\\ (account_owner_id IS NULL AND community_owner_id IS NOT NULL)
|
||||
\\ OR (account_owner_id IS NOT NULL AND community_owner_id IS NULL)
|
||||
\\ )
|
||||
\\);
|
||||
,
|
||||
.down = "DROP TABLE drive_file",
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue