Same for schemaEngine
This commit is contained in:
parent
d5f7309869
commit
90edb94f7a
@ -84,200 +84,200 @@ pub const SchemaStruct = struct {
|
|||||||
/// Manage everything that is relate to the schema
|
/// Manage everything that is relate to the schema
|
||||||
/// This include keeping in memory the schema and schema file, and some functions to get like all members of a specific struct.
|
/// This include keeping in memory the schema and schema file, and some functions to get like all members of a specific struct.
|
||||||
/// For now it is a bit empty. But this is where I will manage migration
|
/// For now it is a bit empty. But this is where I will manage migration
|
||||||
pub const SchemaEngine = struct {
|
pub const SchemaEngine = @This();
|
||||||
struct_array: []SchemaStruct,
|
|
||||||
null_terminated: [:0]u8,
|
|
||||||
|
|
||||||
// The path is the path to the schema file
|
struct_array: []SchemaStruct,
|
||||||
pub fn init(path: []const u8, file_engine: *FileEngine) ZipponError!SchemaEngine {
|
null_terminated: [:0]u8,
|
||||||
arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
|
||||||
allocator = arena.allocator();
|
|
||||||
|
|
||||||
var buffer: [BUFFER_SIZE]u8 = undefined;
|
// The path is the path to the schema file
|
||||||
|
pub fn init(path: []const u8, file_engine: *FileEngine) ZipponError!SchemaEngine {
|
||||||
|
arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
|
allocator = arena.allocator();
|
||||||
|
|
||||||
log.debug("Trying to init a SchemaEngine with path {s}", .{path});
|
var buffer: [BUFFER_SIZE]u8 = undefined;
|
||||||
const len: usize = try FileEngine.readSchemaFile(path, &buffer);
|
|
||||||
const null_terminated = std.fmt.bufPrintZ(&schema_buffer, "{s}", .{buffer[0..len]}) catch return ZipponError.MemoryError;
|
|
||||||
|
|
||||||
var toker = Tokenizer.init(null_terminated);
|
log.debug("Trying to init a SchemaEngine with path {s}", .{path});
|
||||||
var parser = Parser.init(&toker, allocator);
|
const len: usize = try FileEngine.readSchemaFile(path, &buffer);
|
||||||
|
const null_terminated = std.fmt.bufPrintZ(&schema_buffer, "{s}", .{buffer[0..len]}) catch return ZipponError.MemoryError;
|
||||||
|
|
||||||
var struct_array = std.ArrayList(SchemaStruct).init(allocator);
|
var toker = Tokenizer.init(null_terminated);
|
||||||
errdefer struct_array.deinit();
|
var parser = Parser.init(&toker, allocator);
|
||||||
parser.parse(&struct_array) catch return ZipponError.SchemaNotConform;
|
|
||||||
|
|
||||||
log.debug("SchemaEngine init with {d} SchemaStruct.", .{struct_array.items.len});
|
var struct_array = std.ArrayList(SchemaStruct).init(allocator);
|
||||||
|
errdefer struct_array.deinit();
|
||||||
|
parser.parse(&struct_array) catch return ZipponError.SchemaNotConform;
|
||||||
|
|
||||||
for (struct_array.items) |sstruct| {
|
log.debug("SchemaEngine init with {d} SchemaStruct.", .{struct_array.items.len});
|
||||||
file_engine.populateFileIndexUUIDMap(sstruct, sstruct.uuid_file_index) catch |err| {
|
|
||||||
log.err("Error populate file index UUID map {any}", .{err});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return SchemaEngine{
|
for (struct_array.items) |sstruct| {
|
||||||
.struct_array = struct_array.toOwnedSlice() catch return ZipponError.MemoryError,
|
file_engine.populateFileIndexUUIDMap(sstruct, sstruct.uuid_file_index) catch |err| {
|
||||||
.null_terminated = null_terminated,
|
log.err("Error populate file index UUID map {any}", .{err});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(_: SchemaEngine) void {
|
return SchemaEngine{
|
||||||
arena.deinit();
|
.struct_array = struct_array.toOwnedSlice() catch return ZipponError.MemoryError,
|
||||||
|
.null_terminated = null_terminated,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(_: SchemaEngine) void {
|
||||||
|
arena.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the type of the member
|
||||||
|
pub fn memberName2DataType(self: *SchemaEngine, 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];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the type of the member
|
return ZipponError.MemberNotFound;
|
||||||
pub fn memberName2DataType(self: *SchemaEngine, 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);
|
pub fn memberName2DataIndex(self: *SchemaEngine, struct_name: []const u8, member_name: []const u8) ZipponError!usize {
|
||||||
if (std.mem.eql(u8, mn, member_name)) return dtypes[i];
|
for (try self.structName2structMembers(struct_name), 0..) |mn, i| {
|
||||||
|
if (std.mem.eql(u8, mn, member_name)) return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZipponError.MemberNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the list of all member name for a struct name
|
||||||
|
pub fn structName2structMembers(self: SchemaEngine, struct_name: []const u8) ZipponError![][]const u8 {
|
||||||
|
var i: usize = 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) {
|
||||||
|
return ZipponError.StructNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.struct_array[i].members;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn structName2SchemaStruct(self: SchemaEngine, struct_name: []const u8) ZipponError!SchemaStruct {
|
||||||
|
var i: usize = 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) {
|
||||||
|
return ZipponError.StructNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.struct_array[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn structName2DataType(self: SchemaEngine, 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: SchemaEngine, struct_name: []const u8) bool {
|
||||||
|
var i: u16 = 0;
|
||||||
|
while (i < self.struct_array.len) : (i += 1) if (std.mem.eql(u8, self.struct_array[i].name, struct_name)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if a struct have the member name
|
||||||
|
pub fn isMemberNameInStruct(self: SchemaEngine, struct_name: []const u8, member_name: []const u8) ZipponError!bool {
|
||||||
|
for (try self.structName2structMembers(struct_name)) |mn| {
|
||||||
|
if (std.mem.eql(u8, mn, member_name)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the SchemaStruct of the struct that the member is linked. So if it is not a link, it is itself, if it is a link, it the the sstruct of the link
|
||||||
|
pub fn linkedStructName(self: SchemaEngine, struct_name: []const u8, member_name: []const u8) ZipponError!SchemaStruct {
|
||||||
|
const sstruct = try self.structName2SchemaStruct(struct_name);
|
||||||
|
if (sstruct.links.get(member_name)) |struct_link_name| {
|
||||||
|
return try self.structName2SchemaStruct(struct_link_name);
|
||||||
|
}
|
||||||
|
return sstruct;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if the map have all the member name as key and not more
|
||||||
|
pub fn checkIfAllMemberInMap(
|
||||||
|
self: SchemaEngine,
|
||||||
|
struct_name: []const u8,
|
||||||
|
map: *std.StringHashMap(ConditionValue),
|
||||||
|
error_message_buffer: *std.ArrayList(u8),
|
||||||
|
) ZipponError!bool {
|
||||||
|
const all_struct_member = try self.structName2structMembers(struct_name);
|
||||||
|
var count: u16 = 0;
|
||||||
|
|
||||||
|
const writer = error_message_buffer.writer();
|
||||||
|
|
||||||
|
for (all_struct_member) |mn| {
|
||||||
|
if (std.mem.eql(u8, mn, "id")) continue;
|
||||||
|
if (map.contains(mn)) count += 1 else writer.print(" {s},", .{mn}) catch return ZipponError.WriteError;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((count == all_struct_member.len - 1) and (count == map.count()));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn isUUIDExist(self: SchemaEngine, struct_name: []const u8, uuid: UUID) bool {
|
||||||
|
const sstruct = self.structName2SchemaStruct(struct_name) catch return false;
|
||||||
|
return sstruct.uuid_file_index.contains(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create an array of empty RelationMap based on the additionalData
|
||||||
|
pub fn relationMapArrayInit(
|
||||||
|
self: SchemaEngine,
|
||||||
|
alloc: Allocator,
|
||||||
|
struct_name: []const u8,
|
||||||
|
additional_data: AdditionalData,
|
||||||
|
) ZipponError![]RelationMap {
|
||||||
|
// So here I should have relationship if children are relations
|
||||||
|
var array = std.ArrayList(RelationMap).init(alloc);
|
||||||
|
const sstruct = try self.structName2SchemaStruct(struct_name);
|
||||||
|
for (additional_data.childrens.items) |child| if (sstruct.links.contains(child.name)) {
|
||||||
|
const map = alloc.create(std.AutoHashMap([16]u8, JsonString)) catch return ZipponError.MemoryError;
|
||||||
|
map.* = std.AutoHashMap([16]u8, JsonString).init(alloc);
|
||||||
|
array.append(RelationMap{
|
||||||
|
.struct_name = sstruct.links.get(child.name).?,
|
||||||
|
.member_name = child.name,
|
||||||
|
.additional_data = child.additional_data, // Maybe I need to check if it exist, im not sure it always exist
|
||||||
|
.map = map,
|
||||||
|
}) catch return ZipponError.MemoryError;
|
||||||
|
};
|
||||||
|
return array.toOwnedSlice() catch return ZipponError.MemoryError;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fileListToParse(
|
||||||
|
self: SchemaEngine,
|
||||||
|
alloc: Allocator,
|
||||||
|
struct_name: []const u8,
|
||||||
|
map: std.AutoHashMap([16]u8, JsonString),
|
||||||
|
) ZipponError![]usize {
|
||||||
|
const sstruct = try self.structName2SchemaStruct(struct_name);
|
||||||
|
var unique_indices = std.AutoHashMap(usize, void).init(alloc);
|
||||||
|
defer unique_indices.deinit();
|
||||||
|
|
||||||
|
var iter = map.keyIterator();
|
||||||
|
while (iter.next()) |uuid| {
|
||||||
|
if (sstruct.uuid_file_index.get(UUID{ .bytes = uuid.* })) |file_index| {
|
||||||
|
unique_indices.put(file_index, {}) catch return ZipponError.MemoryError;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ZipponError.MemberNotFound;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn memberName2DataIndex(self: *SchemaEngine, struct_name: []const u8, member_name: []const u8) ZipponError!usize {
|
var result = alloc.alloc(usize, unique_indices.count()) catch return ZipponError.MemoryError;
|
||||||
for (try self.structName2structMembers(struct_name), 0..) |mn, i| {
|
var i: usize = 0;
|
||||||
if (std.mem.eql(u8, mn, member_name)) return i;
|
var index_iter = unique_indices.keyIterator();
|
||||||
}
|
while (index_iter.next()) |index| {
|
||||||
|
result[i] = index.*;
|
||||||
return ZipponError.MemberNotFound;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the list of all member name for a struct name
|
return result;
|
||||||
pub fn structName2structMembers(self: SchemaEngine, struct_name: []const u8) ZipponError![][]const u8 {
|
}
|
||||||
var i: usize = 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) {
|
|
||||||
return ZipponError.StructNotFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.struct_array[i].members;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn structName2SchemaStruct(self: SchemaEngine, struct_name: []const u8) ZipponError!SchemaStruct {
|
|
||||||
var i: usize = 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) {
|
|
||||||
return ZipponError.StructNotFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.struct_array[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn structName2DataType(self: SchemaEngine, 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: SchemaEngine, struct_name: []const u8) bool {
|
|
||||||
var i: u16 = 0;
|
|
||||||
while (i < self.struct_array.len) : (i += 1) if (std.mem.eql(u8, self.struct_array[i].name, struct_name)) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if a struct have the member name
|
|
||||||
pub fn isMemberNameInStruct(self: SchemaEngine, struct_name: []const u8, member_name: []const u8) ZipponError!bool {
|
|
||||||
for (try self.structName2structMembers(struct_name)) |mn| {
|
|
||||||
if (std.mem.eql(u8, mn, member_name)) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the SchemaStruct of the struct that the member is linked. So if it is not a link, it is itself, if it is a link, it the the sstruct of the link
|
|
||||||
pub fn linkedStructName(self: SchemaEngine, struct_name: []const u8, member_name: []const u8) ZipponError!SchemaStruct {
|
|
||||||
const sstruct = try self.structName2SchemaStruct(struct_name);
|
|
||||||
if (sstruct.links.get(member_name)) |struct_link_name| {
|
|
||||||
return try self.structName2SchemaStruct(struct_link_name);
|
|
||||||
}
|
|
||||||
return sstruct;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return true if the map have all the member name as key and not more
|
|
||||||
pub fn checkIfAllMemberInMap(
|
|
||||||
self: SchemaEngine,
|
|
||||||
struct_name: []const u8,
|
|
||||||
map: *std.StringHashMap(ConditionValue),
|
|
||||||
error_message_buffer: *std.ArrayList(u8),
|
|
||||||
) ZipponError!bool {
|
|
||||||
const all_struct_member = try self.structName2structMembers(struct_name);
|
|
||||||
var count: u16 = 0;
|
|
||||||
|
|
||||||
const writer = error_message_buffer.writer();
|
|
||||||
|
|
||||||
for (all_struct_member) |mn| {
|
|
||||||
if (std.mem.eql(u8, mn, "id")) continue;
|
|
||||||
if (map.contains(mn)) count += 1 else writer.print(" {s},", .{mn}) catch return ZipponError.WriteError;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((count == all_struct_member.len - 1) and (count == map.count()));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn isUUIDExist(self: SchemaEngine, struct_name: []const u8, uuid: UUID) bool {
|
|
||||||
const sstruct = self.structName2SchemaStruct(struct_name) catch return false;
|
|
||||||
return sstruct.uuid_file_index.contains(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create an array of empty RelationMap based on the additionalData
|
|
||||||
pub fn relationMapArrayInit(
|
|
||||||
self: SchemaEngine,
|
|
||||||
alloc: Allocator,
|
|
||||||
struct_name: []const u8,
|
|
||||||
additional_data: AdditionalData,
|
|
||||||
) ZipponError![]RelationMap {
|
|
||||||
// So here I should have relationship if children are relations
|
|
||||||
var array = std.ArrayList(RelationMap).init(alloc);
|
|
||||||
const sstruct = try self.structName2SchemaStruct(struct_name);
|
|
||||||
for (additional_data.childrens.items) |child| if (sstruct.links.contains(child.name)) {
|
|
||||||
const map = alloc.create(std.AutoHashMap([16]u8, JsonString)) catch return ZipponError.MemoryError;
|
|
||||||
map.* = std.AutoHashMap([16]u8, JsonString).init(alloc);
|
|
||||||
array.append(RelationMap{
|
|
||||||
.struct_name = sstruct.links.get(child.name).?,
|
|
||||||
.member_name = child.name,
|
|
||||||
.additional_data = child.additional_data, // Maybe I need to check if it exist, im not sure it always exist
|
|
||||||
.map = map,
|
|
||||||
}) catch return ZipponError.MemoryError;
|
|
||||||
};
|
|
||||||
return array.toOwnedSlice() catch return ZipponError.MemoryError;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fileListToParse(
|
|
||||||
self: SchemaEngine,
|
|
||||||
alloc: Allocator,
|
|
||||||
struct_name: []const u8,
|
|
||||||
map: std.AutoHashMap([16]u8, JsonString),
|
|
||||||
) ZipponError![]usize {
|
|
||||||
const sstruct = try self.structName2SchemaStruct(struct_name);
|
|
||||||
var unique_indices = std.AutoHashMap(usize, void).init(alloc);
|
|
||||||
defer unique_indices.deinit();
|
|
||||||
|
|
||||||
var iter = map.keyIterator();
|
|
||||||
while (iter.next()) |uuid| {
|
|
||||||
if (sstruct.uuid_file_index.get(UUID{ .bytes = uuid.* })) |file_index| {
|
|
||||||
unique_indices.put(file_index, {}) catch return ZipponError.MemoryError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = alloc.alloc(usize, unique_indices.count()) catch return ZipponError.MemoryError;
|
|
||||||
var i: usize = 0;
|
|
||||||
var index_iter = unique_indices.keyIterator();
|
|
||||||
while (index_iter.next()) |index| {
|
|
||||||
result[i] = index.*;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user