diff --git a/src/lib.zig b/src/lib.zig index 5af2dbc9efde548b598933071aba84a119e4f7c6..41ef5e4037e5eacce716ff87f5039846453734fa 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -1,15 +1,91 @@ const std = @import("std"); -const EngineType = enum { +pub const DriverType = enum { sqlite3, }; -pub fn engine(comptime etype: EngineType) type { +pub fn Driver(comptime etype: DriverType) type { return switch (etype) { .sqlite3 => @import("./sqlite3.zig"), }; } +pub fn connect(_type: DriverType, allocator: std.mem.Allocator, connection: [:0]const u8) !Engine { + return switch (_type) { + .sqlite3 => .{ .sqlite3 = try .connect(allocator, connection) }, + }; +} + +pub const Engine = union(DriverType) { + sqlite3: Driver(.sqlite3), + + pub fn close(engine: *Engine) void { + return switch (engine.*) { + inline else => |*e| e.close(), + }; + } + + pub fn lock(engine: *Engine) void { + return switch (engine.*) { + inline else => |*e| e.lock(), + }; + } + + pub fn unlock(engine: *Engine) void { + return switch (engine.*) { + inline else => |*e| e.unlock(), + }; + } + + pub fn exec(engine: *Engine, alloc: std.mem.Allocator, comptime query: []const u8, args: anytype) !void { + return switch (engine.*) { + inline else => |*e| e.exec(alloc, query, args), + }; + } + + pub fn first(engine: *Engine, alloc: std.mem.Allocator, comptime T: type, comptime query: []const u8, args: anytype) !?T { + return switch (engine.*) { + inline else => |*e| e.first(alloc, T, query, args), + }; + } + + pub fn collect(engine: *Engine, alloc: std.mem.Allocator, comptime T: type, comptime query: []const u8, args: anytype) ![]T { + return switch (engine.*) { + inline else => |*e| e.collect(alloc, T, query, args), + }; + } + + pub fn collectDyn(engine: *Engine, alloc: std.mem.Allocator, comptime T: type, query: []const u8, args: anytype) ![]T { + return switch (engine.*) { + inline else => |*e| { + var stmt = try e.prepareDynamic(query); + defer stmt.deinit(); + var iter = try stmt.iteratorAlloc(T, alloc, args); + var list = std.ArrayList(T).init(alloc); + errdefer list.deinit(); + while (try iter.nextAlloc(alloc, .{})) |row| { + try list.append(row); + } + return list.toOwnedSlice(); + }, + }; + } + + // + + pub fn doesTableExist(engine: *Engine, alloc: std.mem.Allocator, name: []const u8) !bool { + return switch (engine.*) { + inline else => |*e| e.doesTableExist(alloc, name), + }; + } + + pub fn hasColumnWithName(engine: *Engine, alloc: std.mem.Allocator, comptime table: []const u8, comptime column: []const u8) !bool { + return switch (engine.*) { + inline else => |*e| e.hasColumnWithName(alloc, table, column), + }; + } +}; + pub const backer = struct { pub const sqlite = @import("sqlite"); }; diff --git a/src/sqlite3.zig b/src/sqlite3.zig index 392c3e9b7187b01e1303ecdef70575a0a41ea3db..9030ed8a93f1d5e52f882f1bd0a06680c67dae7b 100644 --- a/src/sqlite3.zig +++ b/src/sqlite3.zig @@ -27,6 +27,14 @@ pub fn close(self: *Self) void { self.db.deinit(); } +pub fn lock(self: *Self) void { + self.mutex.lock(); +} + +pub fn unlock(self: *Self) void { + self.mutex.unlock(); +} + fn prepare(self: *Self, comptime query: string) !sqlite.StatementType(.{}, query) { return self.db.prepare(query) catch |err| switch (err) { error.SQLiteError => std.debug.panic("{s}", .{self.db.getDetailedError()}),