Bring test back Removed useless arena, making like 40% perf improv Removed shared Loc
153 lines
5.9 KiB
Zig
153 lines
5.9 KiB
Zig
const std = @import("std");
|
|
const config = @import("config");
|
|
const Allocator = std.mem.Allocator;
|
|
|
|
const FileEngine = @import("../file/core.zig");
|
|
const SchemaEngine = @import("../schema/core.zig");
|
|
const ThreadEngine = @import("../thread/engine.zig");
|
|
const ziqlParser = @import("../ziql/parser.zig");
|
|
const setLogPath = @import("../main.zig").setLogPath;
|
|
const log = std.log.scoped(.cli);
|
|
|
|
const DBEngineState = enum { MissingFileEngine, MissingSchemaEngine, MissingAllocator, MissingThreadEngine, Ok, Init };
|
|
|
|
pub const Self = @This();
|
|
|
|
var path_buffer: [1024]u8 = undefined;
|
|
var line_buffer: [config.BUFFER_SIZE]u8 = undefined;
|
|
var in_buffer: [config.BUFFER_SIZE]u8 = undefined;
|
|
var value_buffer: [1024]u8 = undefined;
|
|
|
|
usingnamespace @import("parser.zig");
|
|
|
|
allocator: Allocator = undefined,
|
|
state: DBEngineState = .Init,
|
|
file_engine: FileEngine = undefined,
|
|
schema_engine: SchemaEngine = undefined,
|
|
thread_engine: ThreadEngine = undefined,
|
|
|
|
pub fn init(allocator: Allocator, potential_main_path: ?[]const u8, potential_schema_path: ?[]const u8) Self {
|
|
var self = Self{ .allocator = allocator };
|
|
|
|
self.thread_engine = ThreadEngine.init(self.allocator) catch {
|
|
log.err("Error initializing thread engine", .{});
|
|
self.state = .MissingThreadEngine;
|
|
return self;
|
|
};
|
|
|
|
const potential_main_path_or_environment_variable = potential_main_path orelse getEnvVariable(self.allocator, "ZIPPONDB_PATH");
|
|
if (potential_main_path_or_environment_variable) |main_path| {
|
|
setLogPath(main_path);
|
|
|
|
log.info("Found ZIPPONDB_PATH: {s}.", .{main_path});
|
|
self.file_engine = FileEngine.init(self.allocator, main_path, self.thread_engine.thread_pool) catch {
|
|
log.err("Error when init FileEngine", .{});
|
|
self.state = .MissingFileEngine;
|
|
return self;
|
|
};
|
|
self.file_engine.createMainDirectories() catch {
|
|
log.err("Error when creating main directories", .{});
|
|
self.state = .MissingFileEngine;
|
|
return self;
|
|
};
|
|
|
|
self.state = .MissingSchemaEngine;
|
|
} else {
|
|
log.info("No ZIPPONDB_PATH found.", .{});
|
|
self.state = .MissingFileEngine;
|
|
return self;
|
|
}
|
|
|
|
if (self.file_engine.isSchemaFileInDir() and potential_schema_path == null) {
|
|
const schema_path = std.fmt.bufPrint(&path_buffer, "{s}/schema", .{self.file_engine.path_to_ZipponDB_dir}) catch {
|
|
self.state = .MissingSchemaEngine;
|
|
return self;
|
|
};
|
|
|
|
log.info("Schema founded in the database directory.", .{});
|
|
self.schema_engine = SchemaEngine.init(self.allocator, schema_path, &self.file_engine) catch |err| {
|
|
log.err("Error when init SchemaEngine: {any}", .{err});
|
|
self.state = .MissingSchemaEngine;
|
|
return self;
|
|
};
|
|
self.file_engine.createStructDirectories(self.schema_engine.struct_array) catch |err| {
|
|
log.err("Error when creating struct directories: {any}", .{err});
|
|
self.state = .MissingSchemaEngine;
|
|
return self;
|
|
};
|
|
|
|
log.debug("SchemaEngine created in DBEngine with {d} struct", .{self.schema_engine.struct_array.len});
|
|
|
|
self.file_engine.schema_engine = self.schema_engine;
|
|
self.state = .Ok;
|
|
return self;
|
|
}
|
|
|
|
log.info("Database don't have any schema yet, trying to add one.", .{});
|
|
const potential_schema_path_or_environment_variable = potential_schema_path orelse getEnvVariable(self.allocator, "ZIPPONDB_SCHEMA");
|
|
if (potential_schema_path_or_environment_variable) |schema_path| {
|
|
log.info("Found schema path {s}.", .{schema_path});
|
|
self.schema_engine = SchemaEngine.init(self.allocator, schema_path, &self.file_engine) catch |err| {
|
|
log.err("Error when init SchemaEngine: {any}", .{err});
|
|
self.state = .MissingSchemaEngine;
|
|
return self;
|
|
};
|
|
self.file_engine.createStructDirectories(self.schema_engine.struct_array) catch |err| {
|
|
log.err("Error when creating struct directories: {any}", .{err});
|
|
self.state = .MissingSchemaEngine;
|
|
return self;
|
|
};
|
|
self.file_engine.schema_engine = self.schema_engine;
|
|
self.file_engine.writeSchemaFile(self.schema_engine.null_terminated) catch |err| {
|
|
log.err("Error saving schema file: {any}", .{err});
|
|
self.state = .MissingSchemaEngine;
|
|
return self;
|
|
};
|
|
|
|
self.state = .Ok;
|
|
} else {
|
|
log.info(config.HELP_MESSAGE.no_schema, .{self.file_engine.path_to_ZipponDB_dir});
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
pub fn start(self: *Self) !void {
|
|
while (true) {
|
|
std.debug.print("> ", .{}); // TODO: Find something better than just std.debug.print
|
|
const line = std.io.getStdIn().reader().readUntilDelimiterOrEof(&in_buffer, '\n') catch {
|
|
log.debug("Command too long for buffer", .{});
|
|
continue;
|
|
};
|
|
|
|
if (line) |line_str| {
|
|
log.debug("Query received: {s}", .{line_str});
|
|
|
|
const null_term_line_str = try std.fmt.bufPrintZ(&line_buffer, "{s}", .{line_str});
|
|
if (try self.parse(null_term_line_str)) break;
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn getEnvVariable(allocator: Allocator, variable: []const u8) ?[]const u8 {
|
|
var env_map = std.process.getEnvMap(allocator) catch return null;
|
|
|
|
var iter = env_map.iterator();
|
|
while (iter.next()) |entry| {
|
|
if (std.mem.eql(u8, entry.key_ptr.*, variable)) return std.fmt.bufPrint(&value_buffer, "{s}", .{entry.value_ptr.*}) catch return null;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
pub fn runQuery(self: *Self, null_term_query_str: [:0]const u8) void {
|
|
var parser = ziqlParser.init(&self.file_engine, &self.schema_engine);
|
|
parser.parse(self.allocator, null_term_query_str) catch |err| log.err("Error parsing: {any}", .{err});
|
|
}
|
|
|
|
pub fn deinit(self: *Self) void {
|
|
self.thread_engine.deinit();
|
|
self.schema_engine.deinit();
|
|
self.file_engine.deinit();
|
|
}
|