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| {
|
for (members, dtypes, 0..) |member, dt, i| {
|
||||||
if (dt == .link or dt == .link_array) continue;
|
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,
|
float_array: []const f64,
|
||||||
bool_array: []const bool,
|
bool_array: []const bool,
|
||||||
unix_array: []const u64,
|
unix_array: []const u64,
|
||||||
link: *std.AutoHashMap(UUID, void),
|
link: *const std.AutoHashMap(UUID, void),
|
||||||
link_array: *std.AutoHashMap(UUID, void),
|
link_array: *const std.AutoHashMap(UUID, void),
|
||||||
|
|
||||||
pub fn init(dtype: DataType, value: []const u8) ConditionValue {
|
pub fn init(dtype: DataType, value: []const u8) ConditionValue {
|
||||||
return switch (dtype) {
|
return switch (dtype) {
|
||||||
@ -134,11 +134,11 @@ pub const ConditionValue = union(enum) {
|
|||||||
return ConditionValue{ .unix_array = value };
|
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 };
|
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 };
|
return ConditionValue{ .link_array = value };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -366,7 +366,7 @@ pub fn parseEntitiesRelationMap(
|
|||||||
dir,
|
dir,
|
||||||
sstruct.zid_schema,
|
sstruct.zid_schema,
|
||||||
relation_map.additional_data,
|
relation_map.additional_data,
|
||||||
try self.schema_engine.structName2DataType(struct_name),
|
sstruct.types,
|
||||||
&sync_context,
|
&sync_context,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -13,14 +13,27 @@ const JsonString = RelationMap.JsonString;
|
|||||||
|
|
||||||
const ZipponError = @import("error").ZipponError;
|
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 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 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
|
// 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 {
|
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 sstruct = try self.structName2SchemaStruct(struct_name);
|
||||||
const dtypes = try self.structName2DataType(struct_name);
|
|
||||||
if (std.mem.eql(u8, mn, member_name)) return dtypes[i];
|
for (sstruct.members, 0..) |mn, i| {
|
||||||
|
if (std.mem.eql(u8, mn, member_name)) return sstruct.types[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return ZipponError.MemberNotFound;
|
return ZipponError.MemberNotFound;
|
||||||
@ -47,7 +60,7 @@ pub fn structName2structMembers(self: Self, struct_name: []const u8) ZipponError
|
|||||||
return self.struct_array[i].members;
|
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 {
|
pub fn structName2SchemaStruct(self: Self, struct_name: []const u8) ZipponError!SchemaStruct {
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
|
|
||||||
@ -60,20 +73,6 @@ pub fn structName2SchemaStruct(self: Self, struct_name: []const u8) ZipponError!
|
|||||||
return self.struct_array[i];
|
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
|
/// Chech if the name of a struct is in the current schema
|
||||||
pub fn isStructNameExists(self: Self, struct_name: []const u8) bool {
|
pub fn isStructNameExists(self: Self, struct_name: []const u8) bool {
|
||||||
var i: u16 = 0;
|
var i: u16 = 0;
|
||||||
@ -98,23 +97,43 @@ pub fn linkedStructName(self: Self, struct_name: []const u8, member_name: []cons
|
|||||||
return sstruct;
|
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,
|
self: Self,
|
||||||
struct_name: []const u8,
|
struct_name: []const u8,
|
||||||
map: *std.StringHashMap(ValueOrArray),
|
map: *std.StringHashMap(ValueOrArray),
|
||||||
error_message_buffer: *std.ArrayList(u8),
|
writer: std.ArrayList(u8).Writer,
|
||||||
) ZipponError!bool {
|
) ZipponError!bool {
|
||||||
const all_struct_member = try self.structName2structMembers(struct_name);
|
const sstruct = try self.structName2SchemaStruct(struct_name);
|
||||||
var count: u16 = 0;
|
var count: u16 = 0;
|
||||||
|
|
||||||
const writer = error_message_buffer.writer();
|
for (sstruct.members, sstruct.types) |mn, dt| {
|
||||||
|
|
||||||
for (all_struct_member) |mn| {
|
|
||||||
if (std.mem.eql(u8, mn, "id")) continue;
|
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 {
|
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}");
|
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" };
|
const db = DB{ .path = "test1", .schema = "schema/test" };
|
||||||
try testParsing(db, "GRAB User");
|
try testParsing(db, "GRAB User");
|
||||||
try testParsing(db, "GRAB User {}");
|
try testParsing(db, "GRAB User {}");
|
||||||
try testParsing(db, "GRAB User [1]");
|
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
|
// Array manipulation
|
||||||
@ -188,14 +198,6 @@ test "GRAB Relationship dot" { // TODO: Make this a reality
|
|||||||
try testParsing(db, "GRAB User [1] {}");
|
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
|
// 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();
|
const error_message_buffer_writer = error_message_buffer.writer();
|
||||||
error_message_buffer_writer.writeAll("Error missing: ") catch return ZipponError.WriteError;
|
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;
|
return ZipponError.StructNotFound;
|
||||||
})) {
|
})) {
|
||||||
_ = error_message_buffer.pop();
|
_ = error_message_buffer.pop();
|
||||||
|
@ -85,6 +85,12 @@ pub fn parseAdditionalData(
|
|||||||
|
|
||||||
state = .expect_comma_OR_r_bracket_OR_l_bracket;
|
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(
|
else => return printError(
|
||||||
"Error: Expected a member name.",
|
"Error: Expected a member name.",
|
||||||
ZipponError.SynthaxError,
|
ZipponError.SynthaxError,
|
||||||
|
@ -76,6 +76,7 @@ pub const Token = struct {
|
|||||||
uuid_literal,
|
uuid_literal,
|
||||||
identifier,
|
identifier,
|
||||||
equal,
|
equal,
|
||||||
|
star, // *
|
||||||
bang, // !
|
bang, // !
|
||||||
pipe, // |
|
pipe, // |
|
||||||
l_paren, // (
|
l_paren, // (
|
||||||
@ -171,6 +172,11 @@ pub const Tokenizer = struct {
|
|||||||
'=' => {
|
'=' => {
|
||||||
state = .equal;
|
state = .equal;
|
||||||
},
|
},
|
||||||
|
'*' => {
|
||||||
|
result.tag = .star;
|
||||||
|
self.index += 1;
|
||||||
|
break;
|
||||||
|
},
|
||||||
'!' => {
|
'!' => {
|
||||||
state = .bang;
|
state = .bang;
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user