diff --git a/src/lib.zig b/src/lib.zig index 38868f251d3890fbe96cb59f4a78f7eb3e432471..9b0ff38008a09addc80d15d309b036994d63b8b0 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -90,4 +90,16 @@ pub const Engine = union(DriverType) { inline else => |*e| e.hasColumnWithName(alloc, table, column), }; } + + pub fn createTable(engine: *Engine, alloc: std.mem.Allocator, comptime name: []const u8, comptime pk_name: []const u8, pk_type: type) !void { + return switch (engine.*) { + inline else => |*e| e.createTable(alloc, name, pk_name, pk_type), + }; + } + + pub fn addColumn(engine: *Engine, alloc: std.mem.Allocator, comptime table_name: []const u8, comptime col_name: []const u8, T: type) !void { + return switch (engine.*) { + inline else => |*e| e.addColumn(alloc, table_name, col_name, T), + }; + } }; diff --git a/src/postgresql.zig b/src/postgresql.zig index 3023afb3f77680f7105490cd48e2b9f29c427353..7f01370221d6a3e15dd2d6d0ba79df66cbacd3c4 100644 --- a/src/postgresql.zig +++ b/src/postgresql.zig @@ -281,6 +281,36 @@ pub fn hasColumnWithName(driver: *Driver, alloc: std.mem.Allocator, comptime tab @panic("TODO"); } +pub fn createTable(driver: *Driver, alloc: std.mem.Allocator, comptime name: []const u8, comptime pk_name: []const u8, pk_type: type) !void { + _ = driver; + _ = alloc; + _ = name; + _ = pk_name; + _ = pk_type; + @panic("TODO"); +} + +pub fn addColumn(driver: *Driver, alloc: std.mem.Allocator, comptime table_name: []const u8, comptime col_name: []const u8, T: type) !void { + _ = driver; + _ = alloc; + _ = table_name; + _ = col_name; + _ = T; + @panic("TODO"); +} + +pub fn nameForType(T: type) []const u8 { + if (@typeInfo(T) == .optional) { + return nameForType2(T); + } + return nameForType2(T) ++ " not null"; +} + +pub fn nameForType2(T: type) []const u8 { + _ = T; + @panic("TODO"); +} + // // CancelRequest // GSSENCRequest diff --git a/src/sqlite3.zig b/src/sqlite3.zig index c20f2cbac366ef264a5fc77c8f2bb371aa55e8ed..1a653f9ab024ad36961beef36a6ad8d8cb69e69d 100644 --- a/src/sqlite3.zig +++ b/src/sqlite3.zig @@ -2,6 +2,7 @@ const std = @import("std"); const string = []const u8; const sqlite = @import("sqlite"); const tracer = @import("tracer"); +const extras = @import("extras"); const Self = @This(); @@ -104,6 +105,48 @@ pub fn hasColumnWithName(self: *Self, alloc: std.mem.Allocator, comptime table: return false; } +pub fn createTable(self: *Self, alloc: std.mem.Allocator, comptime name: []const u8, comptime pk_name: []const u8, pk_type: type) !void { + const t = tracer.trace(@src(), " {s} ({s})", .{ name, pk_name }); + defer t.end(); + try self.exec(alloc, comptime std.fmt.comptimePrint("create table {s}({s} {s} primary key not null)", .{ name, pk_name, nameForType2(pk_type) }), .{}); +} + +pub fn addColumn(self: *Self, alloc: std.mem.Allocator, comptime table_name: []const u8, comptime col_name: []const u8, T: type) !void { + const t = tracer.trace(@src(), " {s}.{s}", .{ table_name, col_name }); + defer t.end(); + try self.exec(alloc, comptime std.fmt.comptimePrint("alter table {s} add \"{s}\" {s}", .{ table_name, col_name, nameForType(T) }), .{}); +} + +pub fn nameForType(T: type) []const u8 { + if (@typeInfo(T) == .optional) { + return nameForType2(@typeInfo(T).optional.child); + } + return nameForType2(T) ++ " not null"; +} + +pub fn nameForType2(T: type) []const u8 { + const tinfo = @typeInfo(T); + + if (comptime extras.isZigString(T)) { + return "text"; + } + if (tinfo == .@"struct") { + const info = tinfo.@"struct"; + if (@hasDecl(T, "BaseType")) return nameForType2(T.BaseType); + if (info.layout == .@"packed") return nameForType2(info.backing_integer.?); + } + if (tinfo == .@"enum") { + return nameForType2(T.BaseType); + } + if (tinfo == .int or tinfo == .bool) { + return "integer"; + } + if (comptime extras.isArrayOf(u8)(T)) { + return "blob"; + } + @compileError(@typeName(T)); // TODO +} + pub const Pragma = struct { pub const TableInfo = struct { cid: u16,