Moved the custom types to a library

This commit is contained in:
2024-10-27 12:59:28 +01:00
parent 4df151ea85
commit debc646738
9 changed files with 31 additions and 23 deletions
+10 -8
View File
@@ -1,22 +1,25 @@
const std = @import("std");
const utils = @import("stuffs/utils.zig");
const s2t = @import("types/stringToType.zig");
const dtype = @import("dtype");
const s2t = dtype.s2t;
const zid = @import("ZipponData");
const Allocator = std.mem.Allocator;
// TODO: Clean that
const UUID = @import("types/uuid.zig").UUID;
const DateTime = @import("types/date.zig").DateTime;
const DataType = @import("types/dataType.zig").DataType;
const UUID = dtype.UUID;
const DateTime = dtype.DateTime;
const DataType = dtype.DataType;
const FileTokenizer = @import("tokenizers/file.zig").Tokenizer;
const FileToken = @import("tokenizers/file.zig").Token;
const SchemaStruct = @import("schemaParser.zig").Parser.SchemaStruct;
const SchemaParser = @import("schemaParser.zig").Parser;
const SchemaTokenizer = @import("tokenizers/schema.zig").Tokenizer;
const SchemaToken = @import("tokenizers/schema.zig").Token;
const AdditionalData = @import("stuffs/additionalData.zig").AdditionalData;
const Loc = @import("tokenizers/shared/loc.zig").Loc;
// TODO: Move that to another struct, not in the file engine
const SchemaStruct = @import("schemaParser.zig").Parser.SchemaStruct;
const SchemaParser = @import("schemaParser.zig").Parser;
const FileEngineError = @import("stuffs/errors.zig").FileEngineError;
const BUFFER_SIZE = @import("config.zig").BUFFER_SIZE;
@@ -33,7 +36,6 @@ pub const FileEngine = struct {
null_terminated_schema_buff: [:0]u8,
struct_array: std.ArrayList(SchemaStruct),
// TODO: Check is all DATA folder are ok. Meaning there is all struct dir, at least one zippon file and all file are 0.zippondata or csv later
pub fn init(allocator: Allocator, path: []const u8) FileEngine {
const path_to_ZipponDB_dir = path;
+5 -5
View File
@@ -1,16 +1,16 @@
const std = @import("std");
const utils = @import("stuffs/utils.zig");
const send = utils.send;
const Allocator = std.mem.Allocator;
// TODO: Clean that
const DateTime = @import("types/date.zig").DateTime;
const FileEngine = @import("fileEngine.zig").FileEngine;
const cliTokenizer = @import("tokenizers/cli.zig").Tokenizer;
const cliToken = @import("tokenizers/cli.zig").Token;
const ziqlTokenizer = @import("tokenizers/ziql.zig").Tokenizer;
const ziqlToken = @import("tokenizers/ziql.zig").Token;
const ziqlParser = @import("ziqlParser.zig").Parser;
const utils = @import("stuffs/utils.zig");
const send = @import("stuffs/utils.zig").send;
const BUFFER_SIZE = @import("config.zig").BUFFER_SIZE;
const HELP_MESSAGE = @import("config.zig").HELP_MESSAGE;
@@ -47,7 +47,7 @@ pub fn myLog(
const potential_file: ?std.fs.File = std.fs.cwd().openFile(log_path, .{ .mode = .write_only }) catch null;
const now = DateTime.now();
const now = @import("dtype").DateTime.now();
var date_format_buffer = std.ArrayList(u8).init(log_allocator);
defer date_format_buffer.deinit();
now.format("YYYY/MM/DD-HH:mm:ss.SSSS", date_format_buffer.writer()) catch return;
+1 -1
View File
@@ -1,6 +1,6 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const DataType = @import("types/dataType.zig").DataType;
const DataType = @import("dtype").DataType;
const Toker = @import("tokenizers/schema.zig").Tokenizer;
const Token = @import("tokenizers/schema.zig").Token;
const Loc = @import("tokenizers/shared/loc.zig").Loc;
-5
View File
@@ -1,5 +0,0 @@
pub const Node = struct {
prev: ?*Node = null,
next: ?*Node = null,
query: []const u8,
};
-27
View File
@@ -1,27 +0,0 @@
/// Suported dataType for the DB
/// Maybe start using a unionenum
pub const DataType = enum {
int,
float,
str,
bool,
link,
date,
time,
datetime,
int_array,
float_array,
str_array,
bool_array,
link_array,
date_array,
time_array,
datetime_array,
pub fn is_array(self: DataType) bool {
return switch (self) {
.int_array, .float_array, .link_array, .str_array, .bool_array, .date_array, .time_array, .datetime_array => true,
else => false,
};
}
};
-465
View File
@@ -1,465 +0,0 @@
// Thanks to: https://github.com/nektro/zig-time/blob/master/time.zig
const std = @import("std");
const string = []const u8;
const time = @This();
pub const DateTime = struct {
ms: u16,
seconds: u8,
minutes: u8,
hours: u8,
days: u8,
months: u8,
years: u16,
const Self = @This(); // Pas mal ca
pub fn initUnixMs(unix: u64) Self {
return epoch_unix.addMs(unix);
}
pub fn initUnix(unix: u64) Self {
return epoch_unix.addSecs(unix);
}
pub fn now() Self {
return epoch_unix.addYears(1970).addMs(@as(u64, @intCast(std.time.milliTimestamp())));
}
/// Caller asserts that this is > epoch
pub fn init(year: u16, month: u16, day: u16, hr: u16, min: u16, sec: u16, ms: u16) Self {
return epoch_unix
.addYears(year - epoch_unix.years)
.addMonths(month)
.addDays(day)
.addHours(hr)
.addMins(min)
.addSecs(sec)
.addMs(ms);
}
pub const epoch_unix = Self{
.ms = 0,
.seconds = 0,
.minutes = 0,
.hours = 0,
.days = 0,
.months = 0,
.years = 0,
};
pub fn eql(self: Self, other: Self) bool {
return self.ms == other.ms and
self.seconds == other.seconds and
self.minutes == other.minutes and
self.hours == other.hours and
self.days == other.days and
self.months == other.months and
self.years == other.years;
}
pub fn compareDate(self: Self, other: Self) bool {
return self.days == other.days and
self.months == other.months and
self.years == other.years;
}
pub fn compareTime(self: Self, other: Self) bool {
return self.ms == other.ms and
self.seconds == other.seconds and
self.minutes == other.minutes and
self.hours == other.hours;
}
pub fn compareDatetime(self: Self, other: Self) bool {
return self.ms == other.ms and
self.seconds == other.seconds and
self.minutes == other.minutes and
self.hours == other.hours and
self.days == other.days and
self.months == other.months and
self.years == other.years;
}
// So as long as the count / unit, it continue adding the next unit, smart
pub fn addMs(self: Self, count: u64) Self {
if (count == 0) return self;
var result = self;
result.ms += @intCast(count % 1000);
return result.addSecs(count / 1000);
}
pub fn addSecs(self: Self, count: u64) Self {
if (count == 0) return self;
var result = self;
result.seconds += @intCast(count % 60);
return result.addMins(count / 60);
}
pub fn addMins(self: Self, count: u64) Self {
if (count == 0) return self;
var result = self;
result.minutes += @intCast(count % 60);
return result.addHours(count / 60);
}
pub fn addHours(self: Self, count: u64) Self {
if (count == 0) return self;
var result = self;
result.hours += @intCast(count % 24);
return result.addDays(count / 24);
}
pub fn addDays(self: Self, count: u64) Self {
if (count == 0) return self;
var result = self;
var input = count;
while (true) {
const year_len = result.daysThisYear();
if (input >= year_len) {
result.years += 1;
input -= year_len;
continue;
}
break;
}
while (true) {
const month_len = result.daysThisMonth();
if (input >= month_len) {
result.months += 1;
input -= month_len;
if (result.months == 12) {
result.years += 1;
result.months = 0;
}
continue;
}
break;
}
{
const month_len = result.daysThisMonth();
if (result.days + input > month_len) {
const left = month_len - result.days;
input -= left;
result.months += 1;
result.days = 0;
}
result.days += @intCast(input);
if (result.days == result.daysThisMonth()) {
result.months += 1;
result.days = 0;
}
if (result.months == 12) {
result.years += 1;
result.months = 0;
}
}
std.debug.assert(result.ms < 1000);
std.debug.assert(result.seconds < 60);
std.debug.assert(result.minutes < 60);
std.debug.assert(result.hours < 24);
std.debug.assert(result.days < result.daysThisMonth());
std.debug.assert(result.months < 12);
return result;
}
pub fn addMonths(self: Self, count: u64) Self {
if (count == 0) return self;
var result = self;
var input = count;
while (input > 0) {
const new = result.addDays(result.daysThisMonth());
result = new;
input -= 1;
}
return result;
}
pub fn addYears(self: Self, count: u64) Self {
var result = self;
for (0..count) |_| {
result = result.addDays(result.daysThisYear());
}
return result;
}
pub fn isLeapYear(self: Self) bool {
return time.isLeapYear(self.years);
}
pub fn daysThisYear(self: Self) u16 {
return time.daysInYear(self.years);
}
pub fn daysThisMonth(self: Self) u16 {
return self.daysInMonth(self.months);
}
fn daysInMonth(self: Self, month: u16) u16 {
return time.daysInMonth(self.years, month);
}
pub fn dayOfThisYear(self: Self) u16 {
var ret: u16 = 0;
for (0..self.months) |item| {
ret += self.daysInMonth(@intCast(item));
}
ret += self.days;
return ret;
}
pub fn toUnix(self: Self) u64 {
const x = self.toUnixMilli();
return x / 1000;
}
pub fn toUnixMilli(self: Self) u64 {
var res: u64 = 0;
res += self.ms;
res += @as(u64, self.seconds) * std.time.ms_per_s;
res += @as(u64, self.minutes) * std.time.ms_per_min;
res += @as(u64, self.hours) * std.time.ms_per_hour;
res += self.daysSinceEpoch() * std.time.ms_per_day;
return res;
}
fn daysSinceEpoch(self: Self) u64 {
var res: u64 = 0;
res += self.days;
for (0..self.years - epoch_unix.years) |i| res += time.daysInYear(@intCast(i));
for (0..self.months) |i| res += self.daysInMonth(@intCast(i));
return res;
}
/// fmt is based on https://momentjs.com/docs/#/displaying/format/
pub fn format(self: Self, comptime fmt: string, writer: anytype) !void {
if (fmt.len == 0) @compileError("DateTime: format string can't be empty");
@setEvalBranchQuota(100000);
comptime var s = 0;
comptime var e = 0;
comptime var next: ?FormatSeq = null;
inline for (fmt, 0..) |c, i| {
e = i + 1;
if (comptime std.meta.stringToEnum(FormatSeq, fmt[s..e])) |tag| {
next = tag;
if (i < fmt.len - 1) continue;
}
if (next) |tag| {
switch (tag) {
.MM => try writer.print("{:0>2}", .{self.months + 1}),
.M => try writer.print("{}", .{self.months + 1}),
.Mo => try printOrdinal(writer, self.months + 1),
.MMM => try printLongName(writer, self.months, &[_]string{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }),
.MMMM => try printLongName(writer, self.months, &[_]string{ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }),
.Q => try writer.print("{}", .{self.months / 3 + 1}),
.Qo => try printOrdinal(writer, self.months / 3 + 1),
.D => try writer.print("{}", .{self.days + 1}),
.Do => try printOrdinal(writer, self.days + 1),
.DD => try writer.print("{:0>2}", .{self.days + 1}),
.DDD => try writer.print("{}", .{self.dayOfThisYear() + 1}),
.DDDo => try printOrdinal(writer, self.dayOfThisYear() + 1),
.DDDD => try writer.print("{:0>3}", .{self.dayOfThisYear() + 1}),
.d => try writer.print("{}", .{@intFromEnum(self.weekday())}),
.do => try printOrdinal(writer, @intFromEnum(self.weekday())),
.dd => try writer.writeAll(@tagName(self.weekday())[0..2]),
.ddd => try writer.writeAll(@tagName(self.weekday())),
.dddd => try printLongName(writer, @intFromEnum(self.weekday()), &[_]string{ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }),
.e => try writer.print("{}", .{@intFromEnum(self.weekday())}),
.E => try writer.print("{}", .{@intFromEnum(self.weekday()) + 1}),
.w => try writer.print("{}", .{self.dayOfThisYear() / 7 + 1}),
.wo => try printOrdinal(writer, self.dayOfThisYear() / 7 + 1),
.ww => try writer.print("{:0>2}", .{self.dayOfThisYear() / 7 + 1}),
.Y => try writer.print("{}", .{self.years + 10000}),
.YY => try writer.print("{:0>2}", .{self.years % 100}),
.YYY => try writer.print("{}", .{self.years}),
.YYYY => try writer.print("{:0>4}", .{self.years}),
.N => try writer.writeAll(@tagName(self.era())),
.NN => try writer.writeAll("Anno Domini"),
.A => try printLongName(writer, self.hours / 12, &[_]string{ "AM", "PM" }),
.a => try printLongName(writer, self.hours / 12, &[_]string{ "am", "pm" }),
.H => try writer.print("{}", .{self.hours}),
.HH => try writer.print("{:0>2}", .{self.hours}),
.h => try writer.print("{}", .{wrap(self.hours, 12)}),
.hh => try writer.print("{:0>2}", .{wrap(self.hours, 12)}),
.k => try writer.print("{}", .{wrap(self.hours, 24)}),
.kk => try writer.print("{:0>2}", .{wrap(self.hours, 24)}),
.m => try writer.print("{}", .{self.minutes}),
.mm => try writer.print("{:0>2}", .{self.minutes}),
.s => try writer.print("{}", .{self.seconds}),
.ss => try writer.print("{:0>2}", .{self.seconds}),
.S => try writer.print("{}", .{self.ms / 100}),
.SS => try writer.print("{:0>2}", .{self.ms / 10}),
.SSS => try writer.print("{:0>3}", .{self.ms}),
.z => try writer.writeAll(@tagName(self.timezone)),
.Z => try writer.writeAll("+00:00"),
.ZZ => try writer.writeAll("+0000"),
.x => try writer.print("{}", .{self.toUnixMilli()}),
.X => try writer.print("{}", .{self.toUnix()}),
}
next = null;
s = i;
}
switch (c) {
',',
' ',
':',
'-',
'.',
'T',
'W',
'/',
=> {
try writer.writeAll(&.{c});
s = i + 1;
continue;
},
else => {},
}
}
}
pub fn formatAlloc(self: Self, alloc: std.mem.Allocator, comptime fmt: string) !string {
var list = std.ArrayList(u8).init(alloc);
defer list.deinit();
try self.format(fmt, .{}, list.writer());
return list.toOwnedSlice();
}
const FormatSeq = enum {
M, // 1 2 ... 11 12
Mo, // 1st 2nd ... 11th 12th
MM, // 01 02 ... 11 12
MMM, // Jan Feb ... Nov Dec
MMMM, // January February ... November December
Q, // 1 2 3 4
Qo, // 1st 2nd 3rd 4th
D, // 1 2 ... 30 31
Do, // 1st 2nd ... 30th 31st
DD, // 01 02 ... 30 31
DDD, // 1 2 ... 364 365
DDDo, // 1st 2nd ... 364th 365th
DDDD, // 001 002 ... 364 365
d, // 0 1 ... 5 6
do, // 0th 1st ... 5th 6th
dd, // Su Mo ... Fr Sa
ddd, // Sun Mon ... Fri Sat
dddd, // Sunday Monday ... Friday Saturday
e, // 0 1 ... 5 6 (locale)
E, // 1 2 ... 6 7 (ISO)
w, // 1 2 ... 52 53
wo, // 1st 2nd ... 52nd 53rd
ww, // 01 02 ... 52 53
Y, // 11970 11971 ... 19999 20000 20001 (Holocene calendar)
YY, // 70 71 ... 29 30
YYY, // 1 2 ... 1970 1971 ... 2029 2030
YYYY, // 0001 0002 ... 1970 1971 ... 2029 2030
N, // BC AD
NN, // Before Christ ... Anno Domini
A, // AM PM
a, // am pm
H, // 0 1 ... 22 23
HH, // 00 01 ... 22 23
h, // 1 2 ... 11 12
hh, // 01 02 ... 11 12
k, // 1 2 ... 23 24
kk, // 01 02 ... 23 24
m, // 0 1 ... 58 59
mm, // 00 01 ... 58 59
s, // 0 1 ... 58 59
ss, // 00 01 ... 58 59
S, // 0 1 ... 8 9 (second fraction)
SS, // 00 01 ... 98 99
SSS, // 000 001 ... 998 999
z, // EST CST ... MST PST
Z, // -07:00 -06:00 ... +06:00 +07:00
ZZ, // -0700 -0600 ... +0600 +0700
x, // unix milli
X, // unix
};
pub fn since(self: Self, other_in_the_past: Self) Duration {
return Duration{
.ms = self.toUnixMilli() - other_in_the_past.toUnixMilli(),
};
}
};
pub const format = struct {
pub const LT = "h:mm A";
pub const LTS = "h:mm:ss A";
pub const L = "MM/DD/YYYY";
pub const l = "M/D/YYY";
pub const LL = "MMMM D, YYYY";
pub const ll = "MMM D, YYY";
pub const LLL = LL ++ " " ++ LT;
pub const lll = ll ++ " " ++ LT;
pub const LLLL = "dddd, " ++ LLL;
pub const llll = "ddd, " ++ lll;
};
pub fn isLeapYear(year: u16) bool {
var ret = false;
if (year % 4 == 0) ret = true;
if (year % 100 == 0) ret = false;
if (year % 400 == 0) ret = true;
return ret;
}
pub fn daysInYear(year: u16) u16 {
return if (isLeapYear(year)) 366 else 365;
}
fn daysInMonth(year: u16, month: u16) u16 {
const norm = [12]u16{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
const leap = [12]u16{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
const month_days = if (!isLeapYear(year)) norm else leap;
return month_days[month];
}
fn printOrdinal(writer: anytype, num: u16) !void {
try writer.print("{}", .{num});
try writer.writeAll(switch (num) {
1 => "st",
2 => "nd",
3 => "rd",
else => "th",
});
}
fn printLongName(writer: anytype, index: u16, names: []const string) !void {
try writer.writeAll(names[index]);
}
fn wrap(val: u16, at: u16) u16 {
const tmp = val % at;
return if (tmp == 0) at else tmp;
}
pub const Duration = struct {
ms: u64,
};
-298
View File
@@ -1,298 +0,0 @@
const std = @import("std");
const UUID = @import("uuid.zig").UUID;
const DateTime = @import("date.zig").DateTime;
// TODO: Put those functions somewhere else
pub fn parseInt(value_str: []const u8) i64 {
return std.fmt.parseInt(i64, value_str, 10) catch return 0;
}
pub fn parseArrayInt(allocator: std.mem.Allocator, array_str: []const u8) std.ArrayList(i64) {
var array = std.ArrayList(i64).init(allocator);
var it = std.mem.splitAny(u8, array_str[1 .. array_str.len - 1], " ");
while (it.next()) |x| {
array.append(parseInt(x)) catch {};
}
return array;
}
pub fn parseFloat(value_str: []const u8) f64 {
return std.fmt.parseFloat(f64, value_str) catch return 0;
}
pub fn parseArrayFloat(allocator: std.mem.Allocator, array_str: []const u8) std.ArrayList(f64) {
var array = std.ArrayList(f64).init(allocator);
var it = std.mem.splitAny(u8, array_str[1 .. array_str.len - 1], " ");
while (it.next()) |x| {
array.append(parseFloat(x)) catch {};
}
return array;
}
pub fn parseBool(value_str: []const u8) bool {
return (value_str[0] != '0');
}
// TODO: Optimize all date parsing
pub fn parseDate(value_str: []const u8) DateTime {
const year: u16 = std.fmt.parseInt(u16, value_str[0..4], 10) catch 0;
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);
}
pub fn parseArrayDate(allocator: std.mem.Allocator, array_str: []const u8) std.ArrayList(DateTime) {
var array = std.ArrayList(DateTime).init(allocator);
var it = std.mem.splitAny(u8, array_str[1 .. array_str.len - 1], " ");
while (it.next()) |x| {
array.append(parseDate(x)) catch {};
}
return array;
}
pub fn parseTime(value_str: []const u8) DateTime {
const hours: u16 = std.fmt.parseInt(u16, value_str[0..2], 10) catch 0;
const minutes: u16 = std.fmt.parseInt(u16, value_str[3..5], 10) catch 0;
const seconds: u16 = if (value_str.len > 6) std.fmt.parseInt(u16, value_str[6..8], 10) catch 0 else 0;
const milliseconds: u16 = if (value_str.len > 9) std.fmt.parseInt(u16, value_str[9..13], 10) catch 0 else 0;
return DateTime.init(0, 0, 0, hours, minutes, seconds, milliseconds);
}
pub fn parseArrayTime(allocator: std.mem.Allocator, array_str: []const u8) std.ArrayList(DateTime) {
var array = std.ArrayList(DateTime).init(allocator);
var it = std.mem.splitAny(u8, array_str[1 .. array_str.len - 1], " ");
while (it.next()) |x| {
array.append(parseTime(x)) catch {};
}
return array;
}
pub fn parseDatetime(value_str: []const u8) DateTime {
const year: u16 = std.fmt.parseInt(u16, value_str[0..4], 10) catch 0;
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;
const hours: u16 = std.fmt.parseInt(u16, value_str[11..13], 10) catch 0;
const minutes: u16 = std.fmt.parseInt(u16, value_str[14..16], 10) catch 0;
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);
}
pub fn parseArrayDatetime(allocator: std.mem.Allocator, array_str: []const u8) std.ArrayList(DateTime) {
var array = std.ArrayList(DateTime).init(allocator);
var it = std.mem.splitAny(u8, array_str[1 .. array_str.len - 1], " ");
while (it.next()) |x| {
array.append(parseDatetime(x)) catch {};
}
return array;
}
pub fn parseArrayBool(allocator: std.mem.Allocator, array_str: []const u8) std.ArrayList(bool) {
var array = std.ArrayList(bool).init(allocator);
var it = std.mem.splitAny(u8, array_str[1 .. array_str.len - 1], " ");
while (it.next()) |x| {
array.append(parseBool(x)) catch {};
}
return array;
}
pub fn parseArrayUUID(allocator: std.mem.Allocator, array_str: []const u8) std.ArrayList(UUID) {
var array = std.ArrayList(UUID).init(allocator);
var it = std.mem.splitAny(u8, array_str[1 .. array_str.len - 1], " ");
while (it.next()) |x| {
const uuid = UUID.parse(x) catch continue;
array.append(uuid) catch continue;
}
return array;
}
// FIXME: I think it will not work if there is a ' inside the string, even \', need to fix that
pub fn parseArrayStr(allocator: std.mem.Allocator, array_str: []const u8) std.ArrayList([]const u8) {
var array = std.ArrayList([]const u8).init(allocator);
var it = std.mem.splitAny(u8, array_str[1 .. array_str.len - 1], "'");
_ = it.next(); // SSkip first token that is empty
while (it.next()) |x| {
if (std.mem.eql(u8, " ", x)) continue;
const x_copy = std.fmt.allocPrint(allocator, "'{s}'", .{x}) catch @panic("=(");
array.append(x_copy) catch {};
}
allocator.free(array.pop()); // Remove the last because empty like the first one
return array;
}
test "Value parsing: Int" {
const allocator = std.testing.allocator;
// Int
const values: [3][]const u8 = .{ "1", "42", "Hello" };
const expected_values: [3]i64 = .{ 1, 42, 0 };
for (values, 0..) |value, i| {
try std.testing.expect(parseInt(value) == expected_values[i]);
}
// Int array
const array_str = "[1 14 44 42 hello]";
const array = parseArrayInt(allocator, array_str);
defer array.deinit();
const expected_array: [5]i64 = .{ 1, 14, 44, 42, 0 };
try std.testing.expect(std.mem.eql(i64, array.items, &expected_array));
}
test "Value parsing: Float" {
const allocator = std.testing.allocator;
// Float
const values: [3][]const u8 = .{ "1.3", "65.991", "Hello" };
const expected_values: [3]f64 = .{ 1.3, 65.991, 0 };
for (values, 0..) |value, i| {
try std.testing.expect(parseFloat(value) == expected_values[i]);
}
// Float array
const array_str = "[1.5 14.3 44.9999 42 hello]";
const array = parseArrayFloat(allocator, array_str);
defer array.deinit();
const expected_array: [5]f64 = .{ 1.5, 14.3, 44.9999, 42, 0 };
try std.testing.expect(std.mem.eql(f64, array.items, &expected_array));
}
test "Value parsing: String" {
// Note that I dont parse string because I dont need to, a string is a string
const allocator = std.testing.allocator;
// string array
const array_str = "['Hello' 'How are you doing ?' '']";
const array = parseArrayStr(allocator, array_str);
defer {
for (array.items) |parsed| {
allocator.free(parsed);
}
array.deinit();
}
const expected_array: [3][]const u8 = .{ "'Hello'", "'How are you doing ?'", "''" };
for (array.items, expected_array) |parsed, expected| {
try std.testing.expect(std.mem.eql(u8, parsed, expected));
}
}
test "Value parsing: Bool array" {
const allocator = std.testing.allocator;
const values: [3][]const u8 = .{ "1", "Hello", "0" };
const expected_values: [3]bool = .{ true, true, false };
for (values, 0..) |value, i| {
try std.testing.expect(parseBool(value) == expected_values[i]);
}
// Bool array
const array_str = "[1 0 0 1 1]";
const array = parseArrayBool(allocator, array_str);
defer array.deinit();
const expected_array: [5]bool = .{ true, false, false, true, true };
try std.testing.expect(std.mem.eql(bool, array.items, &expected_array));
}
test "Value parsing: Date" {
const allocator = std.testing.allocator;
// 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),
};
for (values, 0..) |value, i| {
try std.testing.expect(expected_values[i].compareDate(parseDate(value)));
}
// Date array
const array_str = "[1920/01/01 1998/01/21 2024/12/31]";
const array = parseArrayDate(allocator, array_str);
defer array.deinit();
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),
};
for (array.items, expected_array) |parsed, expected| {
try std.testing.expect(expected.compareDate(parsed));
}
}
test "Value parsing: Time" {
const allocator = std.testing.allocator;
const values: [4][]const u8 = .{ "12:45:00.0000", "18:12:53.7491", "02:30:10", "12:30" };
const expected_values: [4]DateTime = .{
DateTime.init(0, 0, 0, 12, 45, 0, 0),
DateTime.init(0, 0, 0, 18, 12, 53, 7491),
DateTime.init(0, 0, 0, 2, 30, 10, 0),
DateTime.init(0, 0, 0, 12, 30, 0, 0),
};
for (values, 0..) |value, i| {
try std.testing.expect(expected_values[i].compareTime(parseTime(value)));
}
// Time array
const array_str = "[12:45:00.0000 18:12:53.7491 02:30:10 12:30]";
const array = parseArrayTime(allocator, array_str);
defer array.deinit();
const expected_array: [4]DateTime = .{
DateTime.init(0, 0, 0, 12, 45, 0, 0),
DateTime.init(0, 0, 0, 18, 12, 53, 7491),
DateTime.init(0, 0, 0, 2, 30, 10, 0),
DateTime.init(0, 0, 0, 12, 30, 0, 0),
};
for (array.items, expected_array) |parsed, expected| {
try std.testing.expect(expected.compareTime(parsed));
}
}
test "Value parsing: Datetime" {
const allocator = std.testing.allocator;
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),
};
for (values, 0..) |value, i| {
try std.testing.expect(expected_values[i].compareDatetime(parseDatetime(value)));
}
// Time array
const array_str = "[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 array = parseArrayDatetime(allocator, array_str);
defer array.deinit();
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),
};
for (array.items, expected_array) |parsed, expected| {
try std.testing.expect(expected.compareDatetime(parsed));
}
}
-262
View File
@@ -1,262 +0,0 @@
// Fast allocation-free v4 UUIDs.
// Inspired by the Go implementation at github.com/skeeto/uuid
const std = @import("std");
const crypto = std.crypto;
const fmt = std.fmt;
const testing = std.testing;
pub const Error = error{InvalidUUID};
pub const UUID = struct {
bytes: [16]u8,
pub fn init() UUID {
var uuid = UUID{ .bytes = undefined };
crypto.random.bytes(&uuid.bytes);
// Version 4
uuid.bytes[6] = (uuid.bytes[6] & 0x0f) | 0x40;
// Variant 1
uuid.bytes[8] = (uuid.bytes[8] & 0x3f) | 0x80;
return uuid;
}
pub fn compare(self: UUID, other: UUID) bool {
return std.meta.eql(self.bytes, other.bytes);
}
fn to_string(self: UUID, slice: []u8) void {
var string: [36]u8 = format_uuid(self);
std.mem.copyForwards(u8, slice, &string);
}
pub fn format_uuid(self: UUID) [36]u8 {
var buf: [36]u8 = undefined;
buf[8] = '-';
buf[13] = '-';
buf[18] = '-';
buf[23] = '-';
inline for (encoded_pos, 0..) |i, j| {
buf[i + 0] = hex[self.bytes[j] >> 4];
buf[i + 1] = hex[self.bytes[j] & 0x0f];
}
return buf;
}
// Indices in the UUID string representation for each byte.
const encoded_pos = [16]u8{ 0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34 };
// Hex
const hex = "0123456789abcdef";
// Hex to nibble mapping.
const hex_to_nibble = [256]u8{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
pub fn format(
self: UUID,
comptime layout: []const u8,
options: fmt.FormatOptions,
writer: anytype,
) !void {
_ = options; // currently unused
if (layout.len != 0 and layout[0] != 's')
@compileError("Unsupported format specifier for UUID type: '" ++ layout ++ "'.");
const buf = format_uuid(self);
try fmt.format(writer, "{s}", .{buf});
}
pub fn parse(buf: []const u8) Error!UUID {
var uuid = UUID{ .bytes = undefined };
if (buf.len != 36 or buf[8] != '-' or buf[13] != '-' or buf[18] != '-' or buf[23] != '-')
return Error.InvalidUUID;
inline for (encoded_pos, 0..) |i, j| {
const hi = hex_to_nibble[buf[i + 0]];
const lo = hex_to_nibble[buf[i + 1]];
if (hi == 0xff or lo == 0xff) {
return Error.InvalidUUID;
}
uuid.bytes[j] = hi << 4 | lo;
}
return uuid;
}
};
// Zero UUID
pub const zero: UUID = .{ .bytes = .{0} ** 16 };
// TODO: Optimize both
pub fn OR(arr1: *std.ArrayList(UUID), arr2: *std.ArrayList(UUID)) !void {
for (0..arr2.items.len) |i| {
if (!containUUID(arr1.*, arr2.items[i])) {
try arr1.append(arr2.items[i]);
}
}
}
pub fn AND(arr1: *std.ArrayList(UUID), arr2: *std.ArrayList(UUID)) !void {
var i: usize = 0;
for (0..arr1.items.len) |_| {
if (!containUUID(arr2.*, arr1.items[i])) {
_ = arr1.orderedRemove(i);
} else {
i += 1;
}
}
}
test "OR & AND" {
const allocator = std.testing.allocator;
var right_arr = std.ArrayList(UUID).init(allocator);
defer right_arr.deinit();
try right_arr.append(try UUID.parse("00000000-0000-0000-0000-000000000000"));
try right_arr.append(try UUID.parse("00000000-0000-0000-0000-000000000001"));
try right_arr.append(try UUID.parse("00000000-0000-0000-0000-000000000005"));
try right_arr.append(try UUID.parse("00000000-0000-0000-0000-000000000006"));
try right_arr.append(try UUID.parse("00000000-0000-0000-0000-000000000007"));
var left_arr1 = std.ArrayList(UUID).init(allocator);
defer left_arr1.deinit();
try left_arr1.append(try UUID.parse("00000000-0000-0000-0000-000000000000"));
try left_arr1.append(try UUID.parse("00000000-0000-0000-0000-000000000001"));
try left_arr1.append(try UUID.parse("00000000-0000-0000-0000-000000000002"));
try left_arr1.append(try UUID.parse("00000000-0000-0000-0000-000000000003"));
try left_arr1.append(try UUID.parse("00000000-0000-0000-0000-000000000004"));
var expected_arr1 = std.ArrayList(UUID).init(allocator);
defer expected_arr1.deinit();
try expected_arr1.append(try UUID.parse("00000000-0000-0000-0000-000000000000"));
try expected_arr1.append(try UUID.parse("00000000-0000-0000-0000-000000000001"));
try AND(&left_arr1, &right_arr);
try std.testing.expect(compareUUIDArray(left_arr1, expected_arr1));
var left_arr2 = std.ArrayList(UUID).init(allocator);
defer left_arr2.deinit();
try left_arr2.append(try UUID.parse("00000000-0000-0000-0000-000000000000"));
try left_arr2.append(try UUID.parse("00000000-0000-0000-0000-000000000001"));
try left_arr2.append(try UUID.parse("00000000-0000-0000-0000-000000000002"));
try left_arr2.append(try UUID.parse("00000000-0000-0000-0000-000000000003"));
try left_arr2.append(try UUID.parse("00000000-0000-0000-0000-000000000004"));
var expected_arr2 = std.ArrayList(UUID).init(allocator);
defer expected_arr2.deinit();
try expected_arr2.append(try UUID.parse("00000000-0000-0000-0000-000000000000"));
try expected_arr2.append(try UUID.parse("00000000-0000-0000-0000-000000000001"));
try expected_arr2.append(try UUID.parse("00000000-0000-0000-0000-000000000002"));
try expected_arr2.append(try UUID.parse("00000000-0000-0000-0000-000000000003"));
try expected_arr2.append(try UUID.parse("00000000-0000-0000-0000-000000000004"));
try expected_arr2.append(try UUID.parse("00000000-0000-0000-0000-000000000005"));
try expected_arr2.append(try UUID.parse("00000000-0000-0000-0000-000000000006"));
try expected_arr2.append(try UUID.parse("00000000-0000-0000-0000-000000000007"));
try OR(&left_arr2, &right_arr);
try std.testing.expect(compareUUIDArray(left_arr2, expected_arr2));
}
fn containUUID(arr: std.ArrayList(UUID), value: UUID) bool {
return for (arr.items) |elem| {
if (value.compare(elem)) break true;
} else false;
}
fn compareUUIDArray(arr1: std.ArrayList(UUID), arr2: std.ArrayList(UUID)) bool {
if (arr1.items.len != arr2.items.len) {
std.debug.print("Not same array len when comparing UUID. arr1: {d} arr2: {d}\n", .{ arr1.items.len, arr2.items.len });
return false;
}
for (0..arr1.items.len) |i| {
if (!containUUID(arr2, arr1.items[i])) return false;
}
return true;
}
test "parse and format" {
const uuids = [_][]const u8{
"d0cd8041-0504-40cb-ac8e-d05960d205ec",
"3df6f0e4-f9b1-4e34-ad70-33206069b995",
"f982cf56-c4ab-4229-b23c-d17377d000be",
"6b9f53be-cf46-40e8-8627-6b60dc33def8",
"c282ec76-ac18-4d4a-8a29-3b94f5c74813",
"00000000-0000-0000-0000-000000000000",
};
for (uuids) |uuid| {
try testing.expectFmt(uuid, "{}", .{try UUID.parse(uuid)});
}
}
test "invalid UUID" {
const uuids = [_][]const u8{
"3df6f0e4-f9b1-4e34-ad70-33206069b99", // too short
"3df6f0e4-f9b1-4e34-ad70-33206069b9912", // too long
"3df6f0e4-f9b1-4e34-ad70_33206069b9912", // missing or invalid group separator
"zdf6f0e4-f9b1-4e34-ad70-33206069b995", // invalid character
};
for (uuids) |uuid| {
try testing.expectError(Error.InvalidUUID, UUID.parse(uuid));
}
}
test "check to_string works" {
const uuid1 = UUID.init();
var string1: [36]u8 = undefined;
var string2: [36]u8 = undefined;
uuid1.to_string(&string1);
uuid1.to_string(&string2);
try testing.expectEqual(string1, string2);
}
test "compare" {
const uuid1 = UUID.init();
const uuid2 = UUID.init();
try testing.expect(uuid1.compare(uuid1));
try testing.expect(!uuid1.compare(uuid2));
}
+7 -4
View File
@@ -4,10 +4,13 @@ const FileEngine = @import("fileEngine.zig").FileEngine;
const Condition = @import("fileEngine.zig").FileEngine.Condition;
const Tokenizer = @import("tokenizers/ziql.zig").Tokenizer;
const Token = @import("tokenizers/ziql.zig").Token;
const UUID = @import("types/uuid.zig").UUID;
const AND = @import("types/uuid.zig").AND;
const OR = @import("types/uuid.zig").OR;
const DataType = @import("types/dataType.zig").DataType;
const dtype = @import("dtype");
const UUID = dtype.UUID;
const AND = dtype.AND;
const OR = dtype.OR;
const DataType = dtype.DataType;
const AdditionalData = @import("stuffs/additionalData.zig").AdditionalData;
const AdditionalDataMember = @import("stuffs/additionalData.zig").AdditionalDataMember;
const send = @import("stuffs/utils.zig").send;