diff --git a/lib/types/stringToType.zig b/lib/types/stringToType.zig index b900bf8..b7e3e9d 100644 --- a/lib/types/stringToType.zig +++ b/lib/types/stringToType.zig @@ -44,7 +44,7 @@ pub fn parseDate(value_str: []const u8) DateTime { const month: u16 = std.fmt.parseInt(u16, value_str[5..7], 10) catch 0; const day: u16 = std.fmt.parseInt(u16, value_str[8..10], 10) catch 0; - return DateTime.init(year, month, day, 0, 0, 0, 0); + return DateTime.init(year, month - 1, day - 1, 0, 0, 0, 0); } pub fn parseArrayDate(allocator: std.mem.Allocator, array_str: []const u8) ![]const DateTime { @@ -109,7 +109,7 @@ pub fn parseDatetime(value_str: []const u8) DateTime { const seconds: u16 = if (value_str.len > 17) std.fmt.parseInt(u16, value_str[17..19], 10) catch 0 else 0; const milliseconds: u16 = if (value_str.len > 20) std.fmt.parseInt(u16, value_str[20..24], 10) catch 0 else 0; - return DateTime.init(year, month, day, hours, minutes, seconds, milliseconds); + return DateTime.init(year, month - 1, day - 1, hours, minutes, seconds, milliseconds); } pub fn parseArrayDatetime(allocator: std.mem.Allocator, array_str: []const u8) ![]const DateTime { @@ -258,9 +258,9 @@ test "Value parsing: Date" { // Date const values: [3][]const u8 = .{ "1920/01/01", "1998/01/21", "2024/12/31" }; const expected_values: [3]DateTime = .{ - DateTime.init(1920, 1, 1, 0, 0, 0, 0), - DateTime.init(1998, 1, 21, 0, 0, 0, 0), - DateTime.init(2024, 12, 31, 0, 0, 0, 0), + DateTime.init(1920, 0, 0, 0, 0, 0, 0), + DateTime.init(1998, 0, 20, 0, 0, 0, 0), + DateTime.init(2024, 11, 30, 0, 0, 0, 0), }; for (values, 0..) |value, i| { try std.testing.expect(expected_values[i].compareDate(parseDate(value))); @@ -271,9 +271,9 @@ test "Value parsing: Date" { const array = try parseArrayDate(allocator, array_str); defer allocator.free(array); const expected_array: [3]DateTime = .{ - DateTime.init(1920, 1, 1, 0, 0, 0, 0), - DateTime.init(1998, 1, 21, 0, 0, 0, 0), - DateTime.init(2024, 12, 31, 0, 0, 0, 0), + DateTime.init(1920, 0, 0, 0, 0, 0, 0), + DateTime.init(1998, 0, 20, 0, 0, 0, 0), + DateTime.init(2024, 11, 30, 0, 0, 0, 0), }; for (array, expected_array) |parsed, expected| { try std.testing.expect(expected.compareDate(parsed)); @@ -314,10 +314,10 @@ test "Value parsing: Datetime" { const values: [4][]const u8 = .{ "1920/01/01-12:45:00.0000", "1920/01/01-18:12:53.7491", "1920/01/01-02:30:10", "1920/01/01-12:30" }; const expected_values: [4]DateTime = .{ - DateTime.init(1920, 1, 1, 12, 45, 0, 0), - DateTime.init(1920, 1, 1, 18, 12, 53, 7491), - DateTime.init(1920, 1, 1, 2, 30, 10, 0), - DateTime.init(1920, 1, 1, 12, 30, 0, 0), + DateTime.init(1920, 0, 0, 12, 45, 0, 0), + DateTime.init(1920, 0, 0, 18, 12, 53, 7491), + DateTime.init(1920, 0, 0, 2, 30, 10, 0), + DateTime.init(1920, 0, 0, 12, 30, 0, 0), }; for (values, 0..) |value, i| { try std.testing.expect(expected_values[i].compareDatetime(parseDatetime(value))); @@ -328,10 +328,10 @@ test "Value parsing: Datetime" { const array = try parseArrayDatetime(allocator, array_str); defer allocator.free(array); const expected_array: [4]DateTime = .{ - DateTime.init(1920, 1, 1, 12, 45, 0, 0), - DateTime.init(1920, 1, 1, 18, 12, 53, 7491), - DateTime.init(1920, 1, 1, 2, 30, 10, 0), - DateTime.init(1920, 1, 1, 12, 30, 0, 0), + DateTime.init(1920, 0, 0, 12, 45, 0, 0), + DateTime.init(1920, 0, 0, 18, 12, 53, 7491), + DateTime.init(1920, 0, 0, 2, 30, 10, 0), + DateTime.init(1920, 0, 0, 12, 30, 0, 0), }; for (array, expected_array) |parsed, expected| { try std.testing.expect(expected.compareDatetime(parsed)); diff --git a/src/fileEngine.zig b/src/fileEngine.zig index 201513b..970cf78 100644 --- a/src/fileEngine.zig +++ b/src/fileEngine.zig @@ -437,9 +437,9 @@ pub const FileEngine = struct { } // Append all writer to each other - writer.writeByte('[') catch return FileEngineError.WriteError; + //writer.writeByte('[') catch return FileEngineError.WriteError; for (thread_writer_list) |list| writer.writeAll(list.items) catch return FileEngineError.WriteError; - writer.writeByte(']') catch return FileEngineError.WriteError; + //writer.writeByte(']') catch return FileEngineError.WriteError; } fn parseEntitiesOneFile( @@ -475,7 +475,7 @@ pub const FileEngine = struct { if (sync_context.checkStructLimit()) break; if (filter) |f| if (!f.evaluate(row)) continue; - writeEntity( + writeEntityTable( writer, row, additional_data, @@ -490,7 +490,21 @@ pub const FileEngine = struct { _ = sync_context.completeThread(); } - fn writeEntity( + fn writeEntityTable( + writer: anytype, + row: []zid.Data, + additional_data: *AdditionalData, + data_types: []const DataType, + ) !void { + try writer.writeAll("| "); + for (additional_data.member_to_find.items) |member| { + try writeValue(writer, row[member.index], data_types[member.index]); + try writer.writeAll(" \t| "); + } + try writer.writeByte('\n'); + } + + fn writeEntityJSON( writer: anytype, row: []zid.Data, additional_data: *AdditionalData, diff --git a/src/stuffs/filter.zig b/src/stuffs/filter.zig index 04f8d5c..92c6ee4 100644 --- a/src/stuffs/filter.zig +++ b/src/stuffs/filter.zig @@ -247,7 +247,7 @@ pub const Filter = struct { fn evaluateNode(self: Filter, node: *FilterNode, row: []Data) bool { return switch (node.*) { - .condition => |cond| Filter.evaluateCondition(cond, row), + .condition => |cond| Filter.evaluateCondition(cond, row[cond.data_index]), .logical => |logical| switch (logical.operator) { .AND => self.evaluateNode(logical.left, row) and self.evaluateNode(logical.right, row), .OR => self.evaluateNode(logical.left, row) or self.evaluateNode(logical.right, row), @@ -256,9 +256,7 @@ pub const Filter = struct { }; } - fn evaluateCondition(condition: Condition, row: []Data) bool { - const row_value: Data = row[condition.data_index]; - log.debug("Checking condition {any}", .{condition}); + fn evaluateCondition(condition: Condition, row_value: Data) bool { return switch (condition.operation) { .equal => switch (condition.data_type) { .int => row_value.Int == condition.value.int, diff --git a/src/stuffs/utils.zig b/src/stuffs/utils.zig index 04239bf..9a6694e 100644 --- a/src/stuffs/utils.zig +++ b/src/stuffs/utils.zig @@ -103,3 +103,39 @@ pub fn printOpenFile(comptime format: []const u8, args: anytype, options: std.fs const path = std.fmt.bufPrint(&path_buffer, format, args) catch return ZipponError.CantOpenDir; return std.fs.cwd().openFile(path, options) catch ZipponError.CantOpenFile; } + +pub fn printTable(writer: anytype, headers: []const []const u8, data: []const []const []const u8) !void { + // Calculate column widths + var col_widths = [_]usize{0} ** 10; + + // Determine max width for each column + for (headers, 0..) |header, i| { + col_widths[i] = @max(col_widths[i], header.len); + } + + for (data) |row| { + for (row, 0..) |cell, i| { + col_widths[i] = @max(col_widths[i], cell.len); + } + } + + // Print headers + for (headers, 0..) |header, i| { + try writer.print("{s:<[*]}", .{ header, col_widths[i] + 2 }); + } + try writer.print("\n", .{}); + + // Print separator + for (headers, 0..) |_, i| { + try writer.print("{s:-<[*]}", .{ "-", col_widths[i] + 2 }); + } + try writer.print("\n", .{}); + + // Print data rows + for (data) |row| { + for (row, 0..) |cell, i| { + try writer.print("{s:<[*]}", .{ cell, col_widths[i] + 2 }); + } + try writer.print("\n", .{}); + } +} diff --git a/src/ziqlParser.zig b/src/ziqlParser.zig index 5bd0255..66f5210 100644 --- a/src/ziqlParser.zig +++ b/src/ziqlParser.zig @@ -1014,12 +1014,15 @@ pub const Parser = struct { test "ADD" { try testParsing("ADD User (name = 'Bob', email='bob@email.com', age=55, scores=[ 1 ], best_friend=none, bday=2000/01/01, a_time=12:04, last_order=2000/01/01-12:45)"); - try testParsing("ADD User (name = 'Bob', email='bob@email.com', age=55, scores=[ 666 123 331 ], best_friend=none, bday=2000/01/01, a_time=12:04:54, last_order=2000/01/01-12:45)"); - try testParsing("ADD User (name = 'Bob', email='bob@email.com', age=-55, scores=[ 33 ], best_friend=none, bday=2000/01/01, a_time=12:04:54.8741, last_order=2000/01/01-12:45)"); - try testParsing("ADD User (name = 'Boba', email='boba@email.com', age=20, scores=[ ], best_friend=none, bday=2000/01/01, a_time=12:04:54.8741, last_order=2000/01/01-12:45)"); + try testParsing("ADD User (name = 'Bob', email='bob@email.com', age=55, scores=[ 666 123 331 ], best_friend=none, bday=2000/11/01, a_time=12:04:54, last_order=2000/01/01-12:45)"); + try testParsing("ADD User (name = 'Bob', email='bob@email.com', age=-55, scores=[ 33 ], best_friend=none, bday=2000/01/04, a_time=12:04:54.8741, last_order=2000/01/01-12:45)"); + try testParsing("ADD User (name = 'Boba', email='boba@email.com', age=20, scores=[ ], best_friend=none, bday=2000/06/06, a_time=04:04:54.8741, last_order=2000/01/01-12:45)"); // This need to take the first User named Bob as it is a unique link try testParsing("ADD User (name = 'Bob', email='bob@email.com', age=-55, scores=[ 1 ], best_friend={name = 'Bob'}, bday=2000/01/01, a_time=12:04:54.8741, last_order=2000/01/01-12:45)"); + try testParsing("ADD User (name = 'Bou', email='bob@email.com', age=66, scores=[ 1 ], best_friend={name = 'Boba'}, bday=2000/01/01, a_time=02:04:54.8741, last_order=2000/01/01-12:45)"); + + try testParsing("GRAB User"); } test "GRAB filter with string" { @@ -1062,15 +1065,16 @@ test "Specific query" { test "UPDATE relationship" { try testParsing("UPDATE User [1] {} TO (best_friend = {name='Boba'} )"); - try testParsing("GRAB User {best_friend IN {name = 'Boba'}}"); // Not yet working } -//test "GRAB Relationship" { -// try testParsing("GRAB User {best_friend IN {name = 'Bob'}}"); -//} +// Not yet working but dont trow an error +test "GRAB Relationship" { + try testParsing("GRAB User {best_friend IN {name = 'Bob'}}"); + try testParsing("GRAB User {best_friend IN {name = 'Boba'}}"); +} test "DELETE" { - try testParsing("DELETE User {name='Bob'}"); + try testParsing("DELETE User {}"); } test "Synthax error" {