prefect server in zig
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3
4const backend = @import("backend.zig");
5const log = @import("../logging.zig");
6
7pub const BlockTypeRow = struct {
8 id: []const u8,
9 created: []const u8,
10 updated: []const u8,
11 name: []const u8,
12 slug: []const u8,
13 logo_url: ?[]const u8,
14 documentation_url: ?[]const u8,
15 description: ?[]const u8,
16 code_example: ?[]const u8,
17 is_protected: bool,
18};
19
20pub fn insert(
21 id: []const u8,
22 name: []const u8,
23 slug: []const u8,
24 logo_url: ?[]const u8,
25 documentation_url: ?[]const u8,
26 description: ?[]const u8,
27 code_example: ?[]const u8,
28 is_protected: bool,
29) !void {
30 backend.db.exec(
31 \\INSERT INTO block_type (id, name, slug, logo_url, documentation_url, description, code_example, is_protected)
32 \\VALUES (?, ?, ?, ?, ?, ?, ?, ?)
33 , .{
34 id,
35 name,
36 slug,
37 logo_url,
38 documentation_url,
39 description,
40 code_example,
41 @as(i32, if (is_protected) 1 else 0),
42 }) catch |err| {
43 log.err("database", "insert block_type error: {}", .{err});
44 return err;
45 };
46}
47
48pub fn getBySlug(alloc: Allocator, slug: []const u8) !?BlockTypeRow {
49 var rows = backend.db.query(
50 \\SELECT id, created, updated, name, slug, logo_url, documentation_url,
51 \\ description, code_example, is_protected
52 \\FROM block_type WHERE slug = ?
53 , .{slug}) catch return null;
54 defer rows.deinit();
55
56 if (rows.next()) |row| {
57 return rowToBlockType(alloc, row);
58 }
59 return null;
60}
61
62pub fn getById(alloc: Allocator, id: []const u8) !?BlockTypeRow {
63 var rows = backend.db.query(
64 \\SELECT id, created, updated, name, slug, logo_url, documentation_url,
65 \\ description, code_example, is_protected
66 \\FROM block_type WHERE id = ?
67 , .{id}) catch return null;
68 defer rows.deinit();
69
70 if (rows.next()) |row| {
71 return rowToBlockType(alloc, row);
72 }
73 return null;
74}
75
76/// SQL for update - dialect-specific for datetime function
77const update_sql = struct {
78 const sqlite = "UPDATE block_type SET logo_url = ?, documentation_url = ?, description = ?, code_example = ?, updated = datetime('now') WHERE id = ?";
79 const postgres = "UPDATE block_type SET logo_url = ?, documentation_url = ?, description = ?, code_example = ?, updated = NOW()::TEXT WHERE id = ?";
80};
81
82pub fn update(
83 id: []const u8,
84 logo_url: ?[]const u8,
85 documentation_url: ?[]const u8,
86 description: ?[]const u8,
87 code_example: ?[]const u8,
88) !void {
89 const sql = switch (backend.db.dialect) {
90 .sqlite => update_sql.sqlite,
91 .postgres => update_sql.postgres,
92 };
93 backend.db.exec(sql, .{ logo_url, documentation_url, description, code_example, id }) catch |err| {
94 log.err("database", "update block_type error: {}", .{err});
95 return err;
96 };
97}
98
99pub fn list(alloc: Allocator, limit: usize) ![]BlockTypeRow {
100 var results = std.ArrayListUnmanaged(BlockTypeRow){};
101 errdefer results.deinit(alloc);
102
103 var rows = backend.db.query(
104 \\SELECT id, created, updated, name, slug, logo_url, documentation_url,
105 \\ description, code_example, is_protected
106 \\FROM block_type ORDER BY created DESC LIMIT ?
107 , .{@as(i64, @intCast(limit))}) catch |err| {
108 log.err("database", "list block_types error: {}", .{err});
109 return err;
110 };
111 defer rows.deinit();
112
113 while (rows.next()) |row| {
114 try results.append(alloc, rowToBlockType(alloc, row));
115 }
116
117 return results.toOwnedSlice(alloc);
118}
119
120fn rowToBlockType(alloc: Allocator, row: anytype) BlockTypeRow {
121 return .{
122 .id = alloc.dupe(u8, row.text(0)) catch "",
123 .created = alloc.dupe(u8, row.text(1)) catch "",
124 .updated = alloc.dupe(u8, row.text(2)) catch "",
125 .name = alloc.dupe(u8, row.text(3)) catch "",
126 .slug = alloc.dupe(u8, row.text(4)) catch "",
127 .logo_url = if (row.text(5).len > 0) alloc.dupe(u8, row.text(5)) catch null else null,
128 .documentation_url = if (row.text(6).len > 0) alloc.dupe(u8, row.text(6)) catch null else null,
129 .description = if (row.text(7).len > 0) alloc.dupe(u8, row.text(7)) catch null else null,
130 .code_example = if (row.text(8).len > 0) alloc.dupe(u8, row.text(8)) catch null else null,
131 .is_protected = row.int(9) != 0,
132 };
133}