81 lines
2.1 KiB
Zig
81 lines
2.1 KiB
Zig
const std = @import("std");
|
|
const Allocator = std.mem.Allocator;
|
|
const builtin = @import("builtin");
|
|
const optimize_mode = builtin.mode;
|
|
|
|
const sqlite = @import("sqlite");
|
|
|
|
pub const schema =
|
|
\\CREATE TABLE IF NOT EXISTS tag(
|
|
\\ id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
\\ key TEXT UNIQUE NOT NULL,
|
|
\\ parent_key TEXT TEXT,
|
|
\\ FOREIGN KEY (parent_key) REFERENCES tag(key) ON DELETE RESTRICT
|
|
\\);
|
|
;
|
|
|
|
id: usize,
|
|
key: []const u8,
|
|
parent: ?*@This() = null,
|
|
children: ?[]@This() = null,
|
|
|
|
const internal = struct {
|
|
id: usize,
|
|
key: []const u8,
|
|
parent_key: ?[]const u8,
|
|
};
|
|
|
|
const ArrList = std.ArrayList(@This());
|
|
|
|
pub fn getTopLevelTags(conn: *sqlite.Db, arena: Allocator) ![]@This() {
|
|
var stmt = try conn.prepareDynamic("SELECT id, key, parent_key FROM tag WHERE parent_key IS NULL;");
|
|
defer stmt.deinit();
|
|
|
|
var list = ArrList.empty;
|
|
defer list.deinit(arena);
|
|
|
|
var iter = try stmt.iterator(internal, .{});
|
|
while (try iter.nextAlloc(arena, .{})) |row| {
|
|
var tag: @This() = .{
|
|
.id = row.id,
|
|
.key = row.key,
|
|
};
|
|
try tag.getChildren(conn, arena);
|
|
try list.append(arena, tag);
|
|
}
|
|
|
|
return list.toOwnedSlice(arena);
|
|
}
|
|
|
|
pub fn getChildren(self: *@This(), conn: *sqlite.Db, arena: Allocator) !void {
|
|
var stmt = try conn.prepareDynamic("SELECT id, key, parent_key FROM tag WHERE parent_key LIKE ?;");
|
|
defer stmt.deinit();
|
|
|
|
var list = ArrList.empty;
|
|
defer list.deinit(arena);
|
|
|
|
var iter = try stmt.iterator(internal, .{self.key});
|
|
while (try iter.nextAlloc(arena, .{})) |row| {
|
|
var tag: @This() = .{
|
|
.id = row.id,
|
|
.key = row.key,
|
|
};
|
|
tag.parent = self;
|
|
try tag.getChildren(conn, arena);
|
|
try list.append(arena, tag);
|
|
}
|
|
|
|
self.children = try list.toOwnedSlice(arena);
|
|
}
|
|
|
|
pub fn jsonStringify(v: @This(), jws: anytype) !void {
|
|
try jws.beginObject();
|
|
|
|
try jws.objectField("key");
|
|
try jws.write(v.key);
|
|
|
|
try jws.objectField("children");
|
|
try jws.write(v.children);
|
|
|
|
try jws.endObject();
|
|
}
|