const std = @import("std"); const Allocator = std.mem.Allocator; const backend = @import("backend.zig"); const log = @import("../logging.zig"); pub const FlowRow = struct { id: []const u8, created: []const u8, updated: []const u8, name: []const u8, tags: []const u8, }; pub fn getByName(alloc: Allocator, name: []const u8) !?FlowRow { var rows = backend.db.query( "SELECT id, created, updated, name, tags FROM flow WHERE name = ?", .{name}, ) catch return null; defer rows.deinit(); if (rows.next()) |row| { return rowToFlow(alloc, row); } return null; } pub fn getById(alloc: Allocator, id: []const u8) !?FlowRow { var rows = backend.db.query( "SELECT id, created, updated, name, tags FROM flow WHERE id = ?", .{id}, ) catch return null; defer rows.deinit(); if (rows.next()) |row| { return rowToFlow(alloc, row); } return null; } pub fn insert(id: []const u8, name: []const u8) !void { backend.db.exec( "INSERT INTO flow (id, name) VALUES (?, ?)", .{ id, name }, ) catch |err| { log.err("database", "insert flow error: {}", .{err}); return err; }; } pub fn list(alloc: Allocator, limit: usize) ![]FlowRow { var results = std.ArrayListUnmanaged(FlowRow){}; errdefer results.deinit(alloc); var rows = backend.db.query( "SELECT id, created, updated, name, tags FROM flow ORDER BY created DESC LIMIT ?", .{@as(i64, @intCast(limit))}, ) catch |err| { log.err("database", "list flows error: {}", .{err}); return err; }; defer rows.deinit(); while (rows.next()) |row| { try results.append(alloc, rowToFlow(alloc, row)); } return results.toOwnedSlice(alloc); } pub fn update(id: []const u8, tags: ?[]const u8) !bool { // check if flow exists var rows = backend.db.query( "SELECT id FROM flow WHERE id = ?", .{id}, ) catch return false; defer rows.deinit(); if (rows.next() == null) { return false; } if (tags) |t| { backend.db.exec( "UPDATE flow SET tags = ?, updated = CURRENT_TIMESTAMP WHERE id = ?", .{ t, id }, ) catch |err| { log.err("database", "update flow error: {}", .{err}); return false; }; } return true; } pub fn delete(id: []const u8) !bool { // check if flow exists var rows = backend.db.query( "SELECT id FROM flow WHERE id = ?", .{id}, ) catch return false; defer rows.deinit(); if (rows.next() == null) { return false; } backend.db.exec( "DELETE FROM flow WHERE id = ?", .{id}, ) catch |err| { log.err("database", "delete flow error: {}", .{err}); return false; }; return true; } fn rowToFlow(alloc: Allocator, row: anytype) FlowRow { return .{ .id = alloc.dupe(u8, row.text(0)) catch "", .created = alloc.dupe(u8, row.text(1)) catch "", .updated = alloc.dupe(u8, row.text(2)) catch "", .name = alloc.dupe(u8, row.text(3)) catch "", .tags = alloc.dupe(u8, row.text(4)) catch "[]", }; }