Parsing filter can now parse sub filter, waiting to be use with the parsing to find relationship

This commit is contained in:
Adrien Bouvais 2024-11-14 20:39:04 +01:00
parent 6e7d1d150c
commit ef84200b34
4 changed files with 80 additions and 13 deletions

View File

@ -329,6 +329,9 @@ pub const FileEngine = struct {
/// Take a filter, parse all file and if one struct if validate by the filter, write it in a JSON format to the writer
/// filter can be null. This will return all of them
/// TODO: For relationship, if they are in additional_data and I need to return it with the other members, I will need to parse the file
/// This is difficult, because that mean I need to parse file while parsing files ? I dont like that because it may be the same struct
/// And because of multi thread, I can read the same file at the same time...
pub fn parseEntities(
self: *FileEngine,
struct_name: []const u8,
@ -475,7 +478,14 @@ pub const FileEngine = struct {
.Float => |v| try writer.print("{d}", .{v}),
.Int => |v| try writer.print("{d}", .{v}),
.Str => |v| try writer.print("\"{s}\"", .{v}),
.UUID => |v| try writer.print("\"{s}\"", .{UUID.format_bytes(v)}),
.UUID => |v| {
const uuid = try UUID.parse("00000000-0000-0000-0000-000000000000"); // Maybe pass that comptime to prevent parsing it everytime
if (!std.meta.eql(v, uuid.bytes)) {
try writer.print("\"{s}\"", .{UUID.format_bytes(v)});
} else {
try writer.print("{{}}", .{});
}
},
.Bool => |v| try writer.print("{any}", .{v}),
.Unix => |v| {
const datetime = DateTime.initUnix(v);

View File

@ -49,6 +49,10 @@ pub const DBEngine = struct {
pub fn init(allocator: std.mem.Allocator, potential_main_path: ?[]const u8, potential_schema_path: ?[]const u8) DBEngine {
var self = DBEngine{ .allocator = allocator };
const potential_main_path_or_environment_variable = potential_main_path orelse utils.getEnvVariable(allocator, "ZIPPONDB_PATH");
defer {
log.debug("{s} {any}\n", .{ potential_main_path_or_environment_variable.?, potential_schema_path });
if (potential_main_path_or_environment_variable != null and potential_main_path == null) allocator.free(potential_main_path_or_environment_variable.?);
}
if (potential_main_path_or_environment_variable) |main_path| {
log_path = std.fmt.bufPrint(&log_buff, "{s}/LOG/log", .{main_path}) catch "";
@ -100,6 +104,7 @@ pub const DBEngine = struct {
log.info("Database don't have any schema yet, trying to add one.", .{});
const potential_schema_path_or_environment_variable = potential_schema_path orelse utils.getEnvVariable(allocator, "ZIPPONDB_SCHEMA");
if (potential_schema_path_or_environment_variable != null and potential_schema_path == null) allocator.free(potential_main_path_or_environment_variable.?);
if (potential_schema_path_or_environment_variable) |schema_path| {
log.info("Found schema path {s}.", .{schema_path});
self.schema_engine = SchemaEngine.init(self.allocator, schema_path) catch |err| {

View File

@ -59,12 +59,13 @@ pub const ConditionValue = union(enum) {
bool_: bool,
self: UUID,
unix: u64,
link: UUID,
int_array: std.ArrayList(i32),
str_array: std.ArrayList([]const u8),
float_array: std.ArrayList(f64),
bool_array: std.ArrayList(bool),
unix_array: std.ArrayList(u64),
link: *std.AutoHashMap([16]u8, void),
link_array: *std.AutoHashMap([16]u8, void),
pub fn deinit(self: ConditionValue) void {
switch (self) {
@ -73,6 +74,7 @@ pub const ConditionValue = union(enum) {
.float_array => self.float_array.deinit(),
.bool_array => self.bool_array.deinit(),
.unix_array => self.unix_array.deinit(),
.link_array => self.link_array.deinit(),
else => {},
}
}
@ -109,6 +111,14 @@ pub const ConditionValue = union(enum) {
return ConditionValue{ .unix = s2t.parseDatetime(value).toUnix() };
}
pub fn initLink(value: []const u8) ConditionValue {
const uuid = UUID.parse(value) catch {
std.debug.print("Error: {s}", .{value});
@panic("WFT ?");
};
return ConditionValue{ .link = uuid };
}
// Array
pub fn initArrayInt(allocator: std.mem.Allocator, value: []const u8) ConditionValue {
return ConditionValue{ .int_array = s2t.parseArrayInt(allocator, value) };
@ -138,8 +148,8 @@ pub const ConditionValue = union(enum) {
return ConditionValue{ .unix_array = s2t.parseArrayDatetimeUnix(allocator, value) };
}
pub fn initLink(value: *std.AutoHashMap([16]u8, void)) ConditionValue {
return ConditionValue{ .link = value };
pub fn initLinkArray(value: *std.AutoHashMap([16]u8, void)) ConditionValue {
return ConditionValue{ .link_array = value };
}
};
@ -386,12 +396,12 @@ test "ConditionValue: link" {
try hash_map.put(uuid2.bytes, {});
// Create a ConditionValue with the link
var value = ConditionValue.initLink(&hash_map);
var value = ConditionValue.initLinkArray(&hash_map);
// Check that the hash map contains the correct number of UUIDs
try std.testing.expectEqual(@as(usize, 2), value.link.count());
try std.testing.expectEqual(@as(usize, 2), value.link_array.count());
// Check that specific UUIDs are in the hash map
try std.testing.expect(value.link.contains(uuid1.bytes));
try std.testing.expect(value.link.contains(uuid2.bytes));
try std.testing.expect(value.link_array.contains(uuid1.bytes));
try std.testing.expect(value.link_array.contains(uuid2.bytes));
}

View File

@ -564,7 +564,9 @@ pub const Parser = struct {
};
var filter: ?Filter = null;
defer if (filter != null) filter.?.deinit();
var additional_data = AdditionalData.init(self.allocator);
defer additional_data.deinit();
if (expected_tag) |tag| {
if (condition.data_type.is_array()) {
@ -607,6 +609,33 @@ pub const Parser = struct {
}
} else if (condition.data_type == .link) {
switch (token.tag) {
.l_bracket => {
try self.parseAdditionalData(
&additional_data,
struct_name,
);
},
.uuid_literal => {},
else => {},
}
additional_data.entity_count_to_find = 1;
switch (token.tag) {
.l_brace => {
filter = try self.parseFilter(struct_name, false);
},
.uuid_literal => {},
else => return printError(
"Error: Expected new filter or UUID",
ZiQlParserError.SynthaxError,
self.toker.buffer,
token.loc.start,
token.loc.end,
),
}
} else if (condition.data_type == .link_array) {
switch (token.tag) { // TODO: Also be able to do an array of UUID like [00000-00000-00000 000000-000000-0000001]
.l_bracket => {
try self.parseAdditionalData(
&additional_data,
@ -639,7 +668,7 @@ pub const Parser = struct {
.time => condition.value = ConditionValue.initTime(self.toker.buffer[start_index..token.loc.end]),
.datetime => condition.value = ConditionValue.initDateTime(self.toker.buffer[start_index..token.loc.end]),
.bool => condition.value = ConditionValue.initBool(self.toker.buffer[start_index..token.loc.end]),
.link => {
.link_array => {
var map = std.AutoHashMap([16]u8, void).init(self.allocator);
try self.file_engine.populateUUIDMap(
struct_name,
@ -647,7 +676,20 @@ pub const Parser = struct {
&map,
&additional_data,
);
condition.value = ConditionValue.initLink(&map);
condition.value = ConditionValue.initLinkArray(&map);
},
.link => switch (token.tag) {
.l_brace, .l_bracket => {}, // Get the first entity using a filter
.uuid_literal => {
condition.value = ConditionValue.initLink(self.toker.buffer[start_index..token.loc.end]);
},
else => return printError(
"Error: Expected filter or UUID",
ZiQlParserError.SynthaxError,
self.toker.buffer,
token.loc.start,
token.loc.end,
),
},
else => unreachable, // TODO: Make for link and array =/
}
@ -1108,9 +1150,9 @@ test "Specific query" {
try testParsing("GRAB User [1]");
}
//test "Relationship" {
// try testParsing("GRAB User {best_friend IN {name = 'Bob'}}");
//}
test "Relationship" {
try testParsing("GRAB User {best_friend IN {name = 'Bob'}}");
}
test "DELETE" {
try testParsing("DELETE User {name='Bob'}");