Add conditions to query builder
This commit is contained in:
parent
4087345323
commit
80ded57904
1 changed files with 69 additions and 0 deletions
69
src/main/db/query_builder.zig
Normal file
69
src/main/db/query_builder.zig
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const util = @import("util");
|
||||||
|
|
||||||
|
const String = []const u8;
|
||||||
|
const comptimePrint = std.fmt.comptimePrint;
|
||||||
|
|
||||||
|
// Combines an array/tuple of strings into a single string, with a copy of
|
||||||
|
// joiner in between each one
|
||||||
|
fn join(comptime vals: []const String, comptime joiner: String) String {
|
||||||
|
if (vals.len == 0) return "";
|
||||||
|
|
||||||
|
var result: String = "";
|
||||||
|
for (vals) |v| {
|
||||||
|
result = comptimePrint("{s}{s}{s}", .{ result, joiner, v });
|
||||||
|
}
|
||||||
|
|
||||||
|
return result[joiner.len..];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn joinConditions(comptime cs: []const Condition, comptime joiner: String) String {
|
||||||
|
var strs: [cs.len]String = undefined;
|
||||||
|
for (cs) |v, i| strs[i] = v.str();
|
||||||
|
return join(&strs, joiner);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const Condition = union(enum) {
|
||||||
|
const BinaryOp = struct {
|
||||||
|
lhs: String,
|
||||||
|
rhs: String,
|
||||||
|
};
|
||||||
|
|
||||||
|
eql: BinaryOp,
|
||||||
|
is_null: String,
|
||||||
|
val: String,
|
||||||
|
not: *const Condition,
|
||||||
|
all: []const Condition,
|
||||||
|
any: []const Condition,
|
||||||
|
|
||||||
|
fn str(comptime self: Condition) String {
|
||||||
|
comptime {
|
||||||
|
return comptimePrint("({s})", .{switch (self) {
|
||||||
|
.eql => |op| comptimePrint("{s} = {s}", .{ op.lhs, op.rhs }),
|
||||||
|
.is_null => |val| comptimePrint("{s} IS NULL", .{val}),
|
||||||
|
.val => |val| val,
|
||||||
|
.not => |c| comptimePrint("NOT {s}", .{c.str()}),
|
||||||
|
.all => |cs| joinConditions(cs, " AND "),
|
||||||
|
.any => |cs| joinConditions(cs, " OR "),
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
test "Condition.str()" {
|
||||||
|
try std.testing.expectEqualStrings(
|
||||||
|
"((abc = def) AND (def = abc))",
|
||||||
|
(comptime Condition{ .all = &.{
|
||||||
|
.{ .eql = .{ .lhs = "abc", .rhs = "def" } },
|
||||||
|
.{ .eql = .{ .lhs = "def", .rhs = "abc" } },
|
||||||
|
} }).str(),
|
||||||
|
);
|
||||||
|
|
||||||
|
try std.testing.expectEqualStrings(
|
||||||
|
"((abc IS NULL) OR (NOT (def)))",
|
||||||
|
(comptime Condition{ .any = &.{
|
||||||
|
.{ .is_null = "abc" },
|
||||||
|
.{ .not = &.{ .val = "def" } },
|
||||||
|
} }).str(),
|
||||||
|
);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue