Added ADD in batch

This commit is contained in:
Adrien Bouvais 2024-12-30 15:31:16 +01:00
parent a535ce5283
commit 4f421f7977
2 changed files with 107 additions and 36 deletions

View File

@ -693,7 +693,7 @@ pub const FileEngine = struct {
defer arena.deinit();
const allocator = arena.allocator();
const file_index = try self.getFirstUsableIndexFile(struct_name);
const file_index = try self.getFirstUsableIndexFile(struct_name); // TODO: Speed up this
const path = std.fmt.bufPrint(&path_buffer, "{s}/DATA/{s}/{d}.zid", .{ self.path_to_ZipponDB_dir, struct_name, file_index }) catch return FileEngineError.MemoryError;
const data = try self.orderedNewData(allocator, struct_name, map);
@ -704,7 +704,7 @@ pub const FileEngine = struct {
for (0..n) |_| data_writer.write(data) catch return FileEngineError.ZipponDataError;
data_writer.flush() catch return FileEngineError.ZipponDataError;
writer.print("[\"{s}\"]", .{UUID.format_bytes(data[0].UUID)}) catch return FileEngineError.WriteError;
writer.print("\"{s}\", ", .{UUID.format_bytes(data[0].UUID)}) catch return FileEngineError.WriteError;
}
pub fn updateEntities(

View File

@ -59,6 +59,7 @@ const State = enum {
expect_right_uuid_array,
// For the new data
expect_member_OR_value,
expect_equal,
expect_new_value,
expect_comma_OR_end,
@ -228,7 +229,7 @@ pub const Parser = struct {
var data_map = std.StringHashMap(ConditionValue).init(allocator);
defer data_map.deinit();
try self.parseNewData(allocator, &data_map, struct_name);
try self.parseNewData(allocator, &data_map, struct_name, null, null);
var buff = std.ArrayList(u8).init(allocator);
defer buff.deinit();
@ -249,7 +250,7 @@ pub const Parser = struct {
var data_map = std.StringHashMap(ConditionValue).init(allocator);
defer data_map.deinit();
try self.parseNewData(allocator, &data_map, struct_name);
try self.parseNewData(allocator, &data_map, struct_name, null, null);
var buff = std.ArrayList(u8).init(allocator);
defer buff.deinit();
@ -310,39 +311,49 @@ pub const Parser = struct {
),
},
// TODO: Be able to do it in batch
.parse_new_data_and_add_data => {
var data_map = std.StringHashMap(ConditionValue).init(allocator);
defer data_map.deinit();
try self.parseNewData(allocator, &data_map, struct_name);
var order = std.ArrayList([]const u8).init(allocator);
defer order.deinit();
var ordered = false;
var error_message_buffer = std.ArrayList(u8).init(allocator);
defer error_message_buffer.deinit();
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 {
return ZiQlParserError.StructNotFound;
})) {
_ = error_message_buffer.pop();
_ = error_message_buffer.pop();
return printError(
error_message_buffer.items,
ZiQlParserError.MemberMissing,
self.toker.buffer,
token.loc.start,
token.loc.end,
);
}
var buff = std.ArrayList(u8).init(allocator);
defer buff.deinit();
buff.writer().writeAll("[") catch return ZipponError.WriteError;
token = self.toker.last_token;
if (token.tag == .identifier and std.mem.eql(u8, self.toker.getTokenSlice(token), "TESTDATASET")) {
for (0..100) |_| self.file_engine.addEntity(struct_name, data_map, &buff.writer(), 10_000) catch return ZipponError.CantWriteEntity;
} else {
while (true) {
var data_map = std.StringHashMap(ConditionValue).init(allocator);
defer data_map.deinit();
try self.parseNewData(allocator, &data_map, struct_name, &order, ordered);
ordered = true;
var error_message_buffer = std.ArrayList(u8).init(allocator);
defer error_message_buffer.deinit();
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 {
return ZiQlParserError.StructNotFound;
})) {
_ = error_message_buffer.pop();
_ = error_message_buffer.pop();
return printError(
error_message_buffer.items,
ZiQlParserError.MemberMissing,
self.toker.buffer,
token.loc.start,
token.loc.end,
);
}
token = self.toker.last_token;
self.file_engine.addEntity(struct_name, data_map, &buff.writer(), 1) catch return ZipponError.CantWriteEntity;
if (token.tag == .l_paren) continue;
break;
}
buff.writer().writeAll("]") catch return ZipponError.WriteError;
send("{s}", .{buff.items});
state = .end;
},
@ -540,7 +551,11 @@ pub const Parser = struct {
}
/// Will check if what is compared is ok, like comparing if a string is superior to another string is not for example.
fn checkConditionValidity(self: Parser, condition: Condition, token: Token) ZipponError!void {
fn checkConditionValidity(
self: Parser,
condition: Condition,
token: Token,
) ZipponError!void {
switch (condition.operation) {
.equal => switch (condition.data_type) {
.int, .float, .str, .bool, .date, .time, .datetime => {},
@ -634,7 +649,12 @@ pub const Parser = struct {
/// When this function is call, next token should be [
/// Check if an int is here -> check if ; is here -> check if member is here -> check if [ is here -> loop
fn parseAdditionalData(self: Parser, allocator: Allocator, additional_data: *AdditionalData, struct_name: []const u8) ZipponError!void {
fn parseAdditionalData(
self: Parser,
allocator: Allocator,
additional_data: *AdditionalData,
struct_name: []const u8,
) ZipponError!void {
var token = self.toker.next();
var keep_next = false;
var state: State = .expect_limit;
@ -751,18 +771,26 @@ pub const Parser = struct {
/// Take the tokenizer and return a map of the ADD action.
/// Keys are the member name and value are the string of the value in the query. E.g. 'Adrien' or '10'
/// Entry token need to be (
fn parseNewData(self: Parser, allocator: Allocator, map: *std.StringHashMap(ConditionValue), struct_name: []const u8) !void {
fn parseNewData(
self: Parser,
allocator: Allocator,
map: *std.StringHashMap(ConditionValue),
struct_name: []const u8,
order: ?*std.ArrayList([]const u8),
order_full: ?bool,
) !void {
var token = self.toker.next();
var keep_next = false;
var member_name: []const u8 = undefined; // Maybe use allocator.alloc
var state: State = .expect_member;
var state: State = .expect_member_OR_value;
var i: usize = 0;
while (state != .end) : ({
token = if (!keep_next) self.toker.next() else token;
keep_next = false;
if (PRINT_STATE) std.debug.print("parseNewData: {any}\n", .{state});
}) switch (state) {
.expect_member => switch (token.tag) {
.expect_member_OR_value => switch (token.tag) {
.identifier => {
member_name = self.toker.getTokenSlice(token);
if (!(self.schema_engine.isMemberNameInStruct(struct_name, member_name) catch {
@ -774,8 +802,43 @@ pub const Parser = struct {
token.loc.start,
token.loc.end,
);
if (order_full) |o| if (!o) order.?.*.append(allocator.dupe(u8, member_name) catch return ZipponError.MemoryError) catch return ZipponError.MemoryError;
state = .expect_equal;
},
.string_literal,
.int_literal,
.float_literal,
.date_literal,
.time_literal,
.datetime_literal,
.bool_literal_true,
.bool_literal_false,
.uuid_literal,
.l_bracket,
.l_brace,
.keyword_none,
=> if (order_full) |o| {
if (!o) return printError(
"Expected member name.",
ZiQlParserError.MemberMissing,
self.toker.buffer,
token.loc.start,
token.loc.end,
);
member_name = order.?.items[i];
i += 1;
keep_next = true;
state = .expect_new_value;
} else {
return printError(
"Expected member name.",
ZiQlParserError.MemberMissing,
self.toker.buffer,
token.loc.start,
token.loc.end,
);
},
else => return printError(
"Error: Expected member name.",
ZiQlParserError.SynthaxError,
@ -809,7 +872,7 @@ pub const Parser = struct {
.expect_comma_OR_end => switch (token.tag) {
.r_paren => state = .end,
.comma => state = .expect_member,
.comma => state = .expect_member_OR_value,
else => return printError(
"Error: Expect , or )",
ZiQlParserError.SynthaxError,
@ -1087,6 +1150,14 @@ test "ADD" {
try testParsing("GRAB User {}");
}
test "ADD batch" {
try testParsing("ADD User (name = 'ewq', email='ewq@email.com', age=22, scores=[ ], best_friend=none, friends=none, bday=2000/01/01, a_time=12:04, last_order=2000/01/01-12:45) (name = 'Roger', email='roger@email.com', age=10, scores=[ 1 11 111 123 562345 123451234 34623465234 12341234 ], best_friend=none, friends=none, bday=2000/01/01, a_time=12:04, last_order=2000/01/01-12:45)");
try testParsing("ADD User (name = 'qwe', email='qwe@email.com', age=57, scores=[ ], best_friend=none, friends=none, bday=2000/01/01, a_time=12:04, last_order=2000/01/01-12:45) ('Rodrigo', 'bob@email.com', 55, [ 1 ], {name = 'qwe'}, none, 2000/01/01, 12:04, 2000/01/01-12:45)");
try testParsing("GRAB User [name, best_friend] {name = 'Rodrigo'}");
try testParsing("GRAB User {}");
}
test "GRAB filter with string" {
try testParsing("GRAB User {name = 'Bob'}");
try testParsing("GRAB User {name != 'Brittany Rogers'}");