| ... | @@ -2,6 +2,7 @@ const std = @import("std"); | ... | @@ -2,6 +2,7 @@ const std = @import("std"); |
| 2 | const string = []const u8; | 2 | const string = []const u8; |
| 3 | const sqlite = @import("sqlite"); | 3 | const sqlite = @import("sqlite"); |
| 4 | const tracer = @import("tracer"); | 4 | const tracer = @import("tracer"); |
| | 5 | const extras = @import("extras"); |
| 5 | | 6 | |
| 6 | const Self = @This(); | 7 | const Self = @This(); |
| 7 | | 8 | |
| ... | @@ -104,6 +105,48 @@ pub fn hasColumnWithName(self: *Self, alloc: std.mem.Allocator, comptime table: | ... | @@ -104,6 +105,48 @@ pub fn hasColumnWithName(self: *Self, alloc: std.mem.Allocator, comptime table: |
| 104 | return false; | 105 | return false; |
| 105 | } | 106 | } |
| 106 | | 107 | |
| | 108 | pub fn createTable(self: *Self, alloc: std.mem.Allocator, comptime name: []const u8, comptime pk_name: []const u8, pk_type: type) !void { |
| | 109 | const t = tracer.trace(@src(), " {s} ({s})", .{ name, pk_name }); |
| | 110 | defer t.end(); |
| | 111 | try self.exec(alloc, comptime std.fmt.comptimePrint("create table {s}({s} {s} primary key not null)", .{ name, pk_name, nameForType2(pk_type) }), .{}); |
| | 112 | } |
| | 113 | |
| | 114 | pub fn addColumn(self: *Self, alloc: std.mem.Allocator, comptime table_name: []const u8, comptime col_name: []const u8, T: type) !void { |
| | 115 | const t = tracer.trace(@src(), " {s}.{s}", .{ table_name, col_name }); |
| | 116 | defer t.end(); |
| | 117 | try self.exec(alloc, comptime std.fmt.comptimePrint("alter table {s} add \"{s}\" {s}", .{ table_name, col_name, nameForType(T) }), .{}); |
| | 118 | } |
| | 119 | |
| | 120 | pub fn nameForType(T: type) []const u8 { |
| | 121 | if (@typeInfo(T) == .optional) { |
| | 122 | return nameForType2(@typeInfo(T).optional.child); |
| | 123 | } |
| | 124 | return nameForType2(T) ++ " not null"; |
| | 125 | } |
| | 126 | |
| | 127 | pub fn nameForType2(T: type) []const u8 { |
| | 128 | const tinfo = @typeInfo(T); |
| | 129 | |
| | 130 | if (comptime extras.isZigString(T)) { |
| | 131 | return "text"; |
| | 132 | } |
| | 133 | if (tinfo == .@"struct") { |
| | 134 | const info = tinfo.@"struct"; |
| | 135 | if (@hasDecl(T, "BaseType")) return nameForType2(T.BaseType); |
| | 136 | if (info.layout == .@"packed") return nameForType2(info.backing_integer.?); |
| | 137 | } |
| | 138 | if (tinfo == .@"enum") { |
| | 139 | return nameForType2(T.BaseType); |
| | 140 | } |
| | 141 | if (tinfo == .int or tinfo == .bool) { |
| | 142 | return "integer"; |
| | 143 | } |
| | 144 | if (comptime extras.isArrayOf(u8)(T)) { |
| | 145 | return "blob"; |
| | 146 | } |
| | 147 | @compileError(@typeName(T)); // TODO |
| | 148 | } |
| | 149 | |
| 107 | pub const Pragma = struct { | 150 | pub const Pragma = struct { |
| 108 | pub const TableInfo = struct { | 151 | pub const TableInfo = struct { |
| 109 | cid: u16, | 152 | cid: u16, |