ZipponDB/src/cli/core.zig
MrBounty 6fa8d6b7c6 Opti
Bring test back

Removed useless arena, making like 40% perf improv

Removed shared Loc
2025-01-23 17:31:14 +01:00

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();
}