Array and link are empty by default if not in ADD action. Also can use * to return everything execpt link
The * is to be use like that GRAB User [*, friends] Because if I just do GRAB User [friends], I only get friends So I would of need to specify all of them like GRAB User [name, age, email, .., friends]
This commit is contained in:
parent
30a7a83e56
commit
b757e01b64
@ -20,10 +20,10 @@ pub fn init(allocator: Allocator) AdditionalData {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn populateWithEverythingExceptLink(self: *AdditionalData, members: [][]const u8, dtypes: []DataType) !void {
|
||||
pub fn populateWithEverythingExceptLink(self: *AdditionalData, members: [][]const u8, dtypes: []DataType) ZipponError!void {
|
||||
for (members, dtypes, 0..) |member, dt, i| {
|
||||
if (dt == .link or dt == .link_array) continue;
|
||||
try self.childrens.append(AdditionalDataMember.init(self.allocator, member, i));
|
||||
self.childrens.append(AdditionalDataMember.init(self.allocator, member, i)) catch return ZipponError.MemoryError;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,8 @@ pub const ConditionValue = union(enum) {
|
||||
float_array: []const f64,
|
||||
bool_array: []const bool,
|
||||
unix_array: []const u64,
|
||||
link: *std.AutoHashMap(UUID, void),
|
||||
link_array: *std.AutoHashMap(UUID, void),
|
||||
link: *const std.AutoHashMap(UUID, void),
|
||||
link_array: *const std.AutoHashMap(UUID, void),
|
||||
|
||||
pub fn init(dtype: DataType, value: []const u8) ConditionValue {
|
||||
return switch (dtype) {
|
||||
@ -134,11 +134,11 @@ pub const ConditionValue = union(enum) {
|
||||
return ConditionValue{ .unix_array = value };
|
||||
}
|
||||
|
||||
pub fn initLink(value: *std.AutoHashMap(UUID, void)) ConditionValue {
|
||||
pub fn initLink(value: *const std.AutoHashMap(UUID, void)) ConditionValue {
|
||||
return ConditionValue{ .link = value };
|
||||
}
|
||||
|
||||
pub fn initArrayLink(value: *std.AutoHashMap(UUID, void)) ConditionValue {
|
||||
pub fn initArrayLink(value: *const std.AutoHashMap(UUID, void)) ConditionValue {
|
||||
return ConditionValue{ .link_array = value };
|
||||
}
|
||||
};
|
||||
|
@ -366,7 +366,7 @@ pub fn parseEntitiesRelationMap(
|
||||
dir,
|
||||
sstruct.zid_schema,
|
||||
relation_map.additional_data,
|
||||
try self.schema_engine.structName2DataType(struct_name),
|
||||
sstruct.types,
|
||||
&sync_context,
|
||||
},
|
||||
);
|
||||
|
@ -13,14 +13,27 @@ const JsonString = RelationMap.JsonString;
|
||||
|
||||
const ZipponError = @import("error").ZipponError;
|
||||
|
||||
var empty_map_buf: [20]u8 = undefined;
|
||||
var fa = std.heap.FixedBufferAllocator.init(&empty_map_buf);
|
||||
const empty_map_allocator = fa.allocator();
|
||||
|
||||
const empty_int: [0]i32 = .{};
|
||||
const empty_float: [0]f64 = .{};
|
||||
const empty_unix: [0]u64 = .{};
|
||||
const empty_bool: [0]bool = .{};
|
||||
const empty_str: [0][]const u8 = .{};
|
||||
const zero_link = std.AutoHashMap(UUID, void).init(empty_map_allocator);
|
||||
const empty_link = std.AutoHashMap(UUID, void).init(empty_map_allocator);
|
||||
|
||||
// I need to redo how SchemaStruct work because it is a mess
|
||||
// I mean I use wayyyyyyyyyyyyyyyyyyyyyyy too much structName2SchemaStruct or stuff like that
|
||||
// I mean that not good to always for loop and compare when a map would work
|
||||
|
||||
pub fn memberName2DataType(self: *Self, struct_name: []const u8, member_name: []const u8) ZipponError!DataType {
|
||||
for (try self.structName2structMembers(struct_name), 0..) |mn, i| {
|
||||
const dtypes = try self.structName2DataType(struct_name);
|
||||
if (std.mem.eql(u8, mn, member_name)) return dtypes[i];
|
||||
const sstruct = try self.structName2SchemaStruct(struct_name);
|
||||
|
||||
for (sstruct.members, 0..) |mn, i| {
|
||||
if (std.mem.eql(u8, mn, member_name)) return sstruct.types[i];
|
||||
}
|
||||
|
||||
return ZipponError.MemberNotFound;
|
||||
@ -47,7 +60,7 @@ pub fn structName2structMembers(self: Self, struct_name: []const u8) ZipponError
|
||||
return self.struct_array[i].members;
|
||||
}
|
||||
|
||||
// TODO: This is the first one I want to change to use a map
|
||||
// Return the SchemaStruct based on it's name
|
||||
pub fn structName2SchemaStruct(self: Self, struct_name: []const u8) ZipponError!SchemaStruct {
|
||||
var i: usize = 0;
|
||||
|
||||
@ -60,20 +73,6 @@ pub fn structName2SchemaStruct(self: Self, struct_name: []const u8) ZipponError!
|
||||
return self.struct_array[i];
|
||||
}
|
||||
|
||||
pub fn structName2DataType(self: Self, struct_name: []const u8) ZipponError![]const DataType {
|
||||
var i: u16 = 0;
|
||||
|
||||
while (i < self.struct_array.len) : (i += 1) {
|
||||
if (std.mem.eql(u8, self.struct_array[i].name, struct_name)) break;
|
||||
}
|
||||
|
||||
if (i == self.struct_array.len and !std.mem.eql(u8, self.struct_array[i].name, struct_name)) {
|
||||
return ZipponError.StructNotFound;
|
||||
}
|
||||
|
||||
return self.struct_array[i].types;
|
||||
}
|
||||
|
||||
/// Chech if the name of a struct is in the current schema
|
||||
pub fn isStructNameExists(self: Self, struct_name: []const u8) bool {
|
||||
var i: u16 = 0;
|
||||
@ -98,23 +97,43 @@ pub fn linkedStructName(self: Self, struct_name: []const u8, member_name: []cons
|
||||
return sstruct;
|
||||
}
|
||||
|
||||
pub fn checkIfAllMemberInMap(
|
||||
/// Use with NewData to check if all member are in the map, otherwise write the missing one to be send with the error
|
||||
/// Also if array and link are missing, to make them empty instead
|
||||
pub fn checkIfAllMemberInMapAndAddEmptyMissingArray(
|
||||
self: Self,
|
||||
struct_name: []const u8,
|
||||
map: *std.StringHashMap(ValueOrArray),
|
||||
error_message_buffer: *std.ArrayList(u8),
|
||||
writer: std.ArrayList(u8).Writer,
|
||||
) ZipponError!bool {
|
||||
const all_struct_member = try self.structName2structMembers(struct_name);
|
||||
const sstruct = try self.structName2SchemaStruct(struct_name);
|
||||
var count: u16 = 0;
|
||||
|
||||
const writer = error_message_buffer.writer();
|
||||
|
||||
for (all_struct_member) |mn| {
|
||||
for (sstruct.members, sstruct.types) |mn, dt| {
|
||||
if (std.mem.eql(u8, mn, "id")) continue;
|
||||
if (map.contains(mn)) count += 1 else writer.print(" {s},", .{mn}) catch return ZipponError.WriteError;
|
||||
if (map.contains(mn)) count += 1 else {
|
||||
if (dt.is_array() or dt == .link) {
|
||||
map.put(
|
||||
mn,
|
||||
switch (dt) {
|
||||
.int_array => ValueOrArray{ .value = try ConditionValue.initArrayInt(&empty_int) },
|
||||
.float_array => ValueOrArray{ .value = try ConditionValue.initArrayFloat(&empty_float) },
|
||||
.str_array => ValueOrArray{ .value = try ConditionValue.initArrayStr(&empty_str) },
|
||||
.bool_array => ValueOrArray{ .value = try ConditionValue.initArrayBool(&empty_bool) },
|
||||
.date_array => ValueOrArray{ .value = try ConditionValue.initArrayUnix(&empty_unix) },
|
||||
.time_array => ValueOrArray{ .value = try ConditionValue.initArrayUnix(&empty_unix) },
|
||||
.datetime_array => ValueOrArray{ .value = try ConditionValue.initArrayUnix(&empty_unix) },
|
||||
.link_array => ValueOrArray{ .value = ConditionValue.initArrayLink(&empty_link) },
|
||||
.link => ValueOrArray{ .value = ConditionValue.initLink(&zero_link) },
|
||||
else => unreachable,
|
||||
},
|
||||
) catch return ZipponError.MemoryError;
|
||||
count += 1;
|
||||
}
|
||||
writer.print(" {s},", .{mn}) catch return ZipponError.WriteError;
|
||||
}
|
||||
}
|
||||
|
||||
return ((count == all_struct_member.len - 1) and (count == map.count()));
|
||||
return ((count == sstruct.members.len - 1) and (count == map.count()));
|
||||
}
|
||||
|
||||
pub fn isUUIDExist(self: Self, struct_name: []const u8, uuid: UUID) bool {
|
||||
|
20
src/test.zig
20
src/test.zig
@ -89,11 +89,21 @@ test "GRAB filter with date" { // OK
|
||||
try testParsing(db, "GRAB User {last_order > 2000/01/01-12:45}");
|
||||
}
|
||||
|
||||
test "Specific query" { // OK
|
||||
// FIXME: GRAB User [1] return nothing
|
||||
test "Specific query" { // NOT OK
|
||||
const db = DB{ .path = "test1", .schema = "schema/test" };
|
||||
try testParsing(db, "GRAB User");
|
||||
try testParsing(db, "GRAB User {}");
|
||||
try testParsing(db, "GRAB User [1]");
|
||||
try testParsing(db, "GRAB User [*, friends]");
|
||||
}
|
||||
|
||||
test "Specific query ADD" { // OK
|
||||
const db = DB{ .path = "test1", .schema = "schema/test" };
|
||||
try testParsing(db, "ADD User (name = 'Bob1', email='bob@email.com', age=55, best_friend=none, friends=none, bday=2000/01/01, a_time=12:04, last_order=2000/01/01-12:45)");
|
||||
try testParsing(db, "ADD User (name = 'Bob2', email='bob@email.com', age=55, best_friend=none, bday=2000/01/01, a_time=12:04, last_order=2000/01/01-12:45)");
|
||||
try testParsing(db, "ADD User (name = 'Bob3', email='bob@email.com', age=55, bday=2000/01/01, a_time=12:04, last_order=2000/01/01-12:45)");
|
||||
try testParsing(db, "GRAB User {name IN ['Bob1', 'Bob2', 'Bob3']}");
|
||||
}
|
||||
|
||||
// Array manipulation
|
||||
@ -188,14 +198,6 @@ test "GRAB Relationship dot" { // TODO: Make this a reality
|
||||
try testParsing(db, "GRAB User [1] {}");
|
||||
}
|
||||
|
||||
// Cleaning
|
||||
// ===============================================================
|
||||
|
||||
test "DELETE" {
|
||||
const db = DB{ .path = "test1", .schema = "schema/test" };
|
||||
try testParsing(db, "DELETE User {}");
|
||||
}
|
||||
|
||||
// 3 Struct Relationship
|
||||
// ===============================================================
|
||||
|
||||
|
@ -353,7 +353,11 @@ pub fn parse(self: *Self, parent_allocator: Allocator, buffer: [:0]const u8) Zip
|
||||
const error_message_buffer_writer = error_message_buffer.writer();
|
||||
error_message_buffer_writer.writeAll("Error missing: ") catch return ZipponError.WriteError;
|
||||
|
||||
if (!(self.schema_engine.checkIfAllMemberInMap(struct_name, &data_map, &error_message_buffer) catch {
|
||||
if (!(self.schema_engine.checkIfAllMemberInMapAndAddEmptyMissingArray(
|
||||
struct_name,
|
||||
&data_map,
|
||||
error_message_buffer.writer(),
|
||||
) catch {
|
||||
return ZipponError.StructNotFound;
|
||||
})) {
|
||||
_ = error_message_buffer.pop();
|
||||
|
@ -85,6 +85,12 @@ pub fn parseAdditionalData(
|
||||
|
||||
state = .expect_comma_OR_r_bracket_OR_l_bracket;
|
||||
},
|
||||
.star => {
|
||||
const sstruct = try self.schema_engine.structName2SchemaStruct(struct_name);
|
||||
try additional_data.populateWithEverythingExceptLink(sstruct.members, sstruct.types);
|
||||
last_member = undefined;
|
||||
state = .expect_comma_OR_r_bracket_OR_l_bracket;
|
||||
},
|
||||
else => return printError(
|
||||
"Error: Expected a member name.",
|
||||
ZipponError.SynthaxError,
|
||||
|
@ -76,6 +76,7 @@ pub const Token = struct {
|
||||
uuid_literal,
|
||||
identifier,
|
||||
equal,
|
||||
star, // *
|
||||
bang, // !
|
||||
pipe, // |
|
||||
l_paren, // (
|
||||
@ -171,6 +172,11 @@ pub const Tokenizer = struct {
|
||||
'=' => {
|
||||
state = .equal;
|
||||
},
|
||||
'*' => {
|
||||
result.tag = .star;
|
||||
self.index += 1;
|
||||
break;
|
||||
},
|
||||
'!' => {
|
||||
state = .bang;
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user