aboutsummaryrefslogtreecommitdiff
path: root/src/db
diff options
context:
space:
mode:
Diffstat (limited to 'src/db')
-rw-r--r--src/db/sqlite.zig95
-rw-r--r--src/db/sqlite_new.zig32
2 files changed, 62 insertions, 65 deletions
diff --git a/src/db/sqlite.zig b/src/db/sqlite.zig
index 28d6487..d1accd5 100644
--- a/src/db/sqlite.zig
+++ b/src/db/sqlite.zig
@@ -5,7 +5,7 @@ const assert = std.debug.assert;
pub fn Database(comptime T: type) type {
const tables = switch (@typeInfo(T)) {
.@"struct" => |s| s.fields,
- else => @compileError("Database schema must be of type `struct`"),
+ else => @compileError("Database schema must be of type `struct`"),
};
// NOTE: `std.math.log2_int_ceil(@TypeOf(tables.len), tables.len)` panics
@@ -13,14 +13,14 @@ pub fn Database(comptime T: type) type {
// a (useless) schema that does not define any tables.
const TagIntTables = @Int(.unsigned, @bitSizeOf(@TypeOf(tables.len)) - @clz(tables.len));
- var table_names : [tables.len][]const u8 = undefined;
- var table_types : [tables.len]type = undefined;
+ var table_names: [tables.len][]const u8 = undefined;
+ var table_types: [tables.len]type = undefined;
var table_values: [tables.len]TagIntTables = undefined;
inline for (&table_names, &table_types, &table_values, tables, 0..) |*table_name, *table_type, *table_value, table, table_index| {
const columns = switch (@typeInfo(table.type)) {
.@"struct" => |s| s.fields,
- else => @compileError("Table `" ++ table.name ++ "` must be of type `struct`"),
+ else => @compileError("Table `" ++ table.name ++ "` must be of type `struct`"),
};
// NOTE: A table must have at least one column
@@ -29,28 +29,28 @@ pub fn Database(comptime T: type) type {
const TagIntColumns = @Int(.unsigned, std.math.log2_int_ceil(@TypeOf(columns.len), columns.len));
- var column_names : [columns.len][]const u8 = undefined;
- var column_types : [columns.len]type = undefined;
+ var column_names: [columns.len][]const u8 = undefined;
+ var column_types: [columns.len]type = undefined;
var column_values: [columns.len]TagIntColumns = undefined;
inline for (&column_names, &column_types, &column_values, columns, 0..) |*column_name, *column_type, *column_value, column, column_index| {
// TODO: check column.type (of type `Type`)
- column_name.* = column.name;
- column_type.* = column.type;
+ column_name.* = column.name;
+ column_type.* = column.type;
column_value.* = column_index;
}
const TagColumns = @Enum(TagIntColumns, .exhaustive, &column_names, &column_values);
- const Columns = @Union(.auto, TagColumns, &column_names, &column_types, &@splat(.{}));
+ const Columns = @Union(.auto, TagColumns, &column_names, &column_types, &@splat(.{}));
- table_name.* = table.name;
- table_type.* = Columns;
+ table_name.* = table.name;
+ table_type.* = Columns;
table_value.* = table_index;
}
const TagTables = @Enum(TagIntTables, .exhaustive, &table_names, &table_values);
- const Tables = @Union(.auto, TagTables, &table_names, &table_types, &@splat(.{}));
+ const Tables = @Union(.auto, TagTables, &table_names, &table_types, &@splat(.{}));
return struct {
inner: Inner,
@@ -80,7 +80,7 @@ pub fn Database(comptime T: type) type {
};
const Schema = Tables;
- const Self = @This();
+ const Self = @This();
const Inner = struct {
handle: *sqlite.sqlite3,
@@ -89,14 +89,14 @@ pub fn Database(comptime T: type) type {
pub fn init(kind: Kind) Error!Self {
const name = switch (kind) {
.temp_in_memory => ":memory:",
- .temp_on_disk => "",
- .path => |path| path,
+ .temp_on_disk => "",
+ .path => |path| path,
};
var handle: ?*sqlite.sqlite3 = null;
const result: Result = .from(sqlite.sqlite3_open(name.ptr, &handle));
const primary = result.asPrimary();
-
+
return if (primary == .ok) .{ .handle = handle.? } else result.toError(Error, handle);
}
@@ -132,8 +132,6 @@ fn Select(comptime Db: type, comptime table: std.meta.Tag(Db.Schema), comptime c
};
}
-
-
// pub const Type = struct {
// string: String.Static,
// type: type,
@@ -266,7 +264,6 @@ const String = struct {
// }
// };
-
/// SQLite result codes.
///
/// Primary result codes define a broad category of results, whereas extended
@@ -445,14 +442,14 @@ test {
const Contacts = struct {
contact_id: usize, // CHANGEME: to `Type`
- const all = &.{ .contact_id };
+ const all = &.{.contact_id};
};
};
- var db: Database(Schema) = try .init(.temp_in_memory);
+ var db: Database(Schema) = try .init(.temp_in_memory);
defer assert(db.deinit() == .ok);
- _ = db.select(.contacts, &.{ .contact_id }, .all);
+ _ = db.select(.contacts, &.{.contact_id}, .all);
var ty = db.select(.contacts, Schema.Contacts.all, .all);
ty.table = .foo;
@@ -462,7 +459,7 @@ test {
// db.select(.distinct(...)).from(...)...
//
// // If the simple SELECT is a SELECT ALL, then the entire set of result rows are returned by the SELECT. If neither ALL or DISTINCT are present, then the behavior is as if ALL were specified.
- // db.select(enum { all, distinct },
+ // db.select(enum { all, distinct },
// * == .all(),
// table-name.* == .table(.table_name),
//
@@ -470,30 +467,30 @@ test {
}
// test {
- // NOTE: we don't use `union(enum)` here as if a column has a default value,
- // an integer tag type is needed explicitely, which, from a usability
- // standpoint, is not great; we can calulate this value in `Schema.from`.
- //
- // CREATE TABLE contacts (
- // contact_id INTEGER PRIMARY KEY,
- // first_name TEXT NOT NULL DEFAULT "Hans",
- // last_name TEXT NOT NULL DEFAULT "Mustermann",
- // nickname TEXT,
- // email TEXT NOT NULL UNIQUE,
- // phone TEXT NOT NULL UNIQUE
- // );
- // const S = struct {
- // contacts: struct {
- // contact_id: PrimaryKey(Integer, .{}),
- // first_name: VarChar(255, .{}) = "Hans",
- // last_name: VarChar(255, .{}) = "Mustermann",
- // nickname: ?VarChar(255, .{}),
- // email: VarChar(255, .{.unique}),
- // phone: VarChar(255, .{.unique}),
- // },
- // };
- //
- // // NOTE: init connects to DB and creates tables if not already present
- // var db: Database(Schema(S)) = try .init(.temp_in_memory);
- // db.deinit();
+// NOTE: we don't use `union(enum)` here as if a column has a default value,
+// an integer tag type is needed explicitely, which, from a usability
+// standpoint, is not great; we can calulate this value in `Schema.from`.
+//
+// CREATE TABLE contacts (
+// contact_id INTEGER PRIMARY KEY,
+// first_name TEXT NOT NULL DEFAULT "Hans",
+// last_name TEXT NOT NULL DEFAULT "Mustermann",
+// nickname TEXT,
+// email TEXT NOT NULL UNIQUE,
+// phone TEXT NOT NULL UNIQUE
+// );
+// const S = struct {
+// contacts: struct {
+// contact_id: PrimaryKey(Integer, .{}),
+// first_name: VarChar(255, .{}) = "Hans",
+// last_name: VarChar(255, .{}) = "Mustermann",
+// nickname: ?VarChar(255, .{}),
+// email: VarChar(255, .{.unique}),
+// phone: VarChar(255, .{.unique}),
+// },
+// };
+//
+// // NOTE: init connects to DB and creates tables if not already present
+// var db: Database(Schema(S)) = try .init(.temp_in_memory);
+// db.deinit();
// }
diff --git a/src/db/sqlite_new.zig b/src/db/sqlite_new.zig
index 46706b8..36eaf61 100644
--- a/src/db/sqlite_new.zig
+++ b/src/db/sqlite_new.zig
@@ -25,7 +25,7 @@ pub fn Database(comptime T: type) type {
// TODO: make functions out of `table` and `columns`: Table(Schema), []const Column(Schema, table) for readability?
pub fn select(self: *Self, comptime table: std.meta.Tag(Schema), comptime columns: []const std.meta.Tag(@FieldType(Schema, @tagName(table)))) Select(Schema, table, columns) {
_ = self;
- std.debug.print("{any}\n", .{ columns });
+ std.debug.print("{any}\n", .{columns});
return .{
// .handle = self.handle,
};
@@ -152,17 +152,17 @@ fn Unique(comptime T: type) type {
const Type = T.Type;
// TODO: `contains(expected, str)` function
const string = if (std.mem.count(u8, T.string, "UNIQUE") > 0)
- @compileError(std.fmt.comptimePrint("Type `{s}` is already unique", .{ @typeName(T) }))
+ @compileError(std.fmt.comptimePrint("Type `{s}` is already unique", .{@typeName(T)}))
else
- std.fmt.comptimePrint("UNIQUE {s}", .{ T.string });
+ std.fmt.comptimePrint("UNIQUE {s}", .{T.string});
};
}
fn Default(comptime T: type, comptime value: T.Type) type {
return struct {
const Type = T.type;
- const string = if(std.mem.count(u8, T.string, "DEFAULT") > 0)
- @compileError(std.fmt.comptimePrint("Type `{s}` already has a default value", .{ @typeName(T) }))
+ const string = if (std.mem.count(u8, T.string, "DEFAULT") > 0)
+ @compileError(std.fmt.comptimePrint("Type `{s}` already has a default value", .{@typeName(T)}))
else
std.fmt.comptimePrint("{s} DEFAULT {}", .{ T.string, value });
};
@@ -202,12 +202,12 @@ fn Test(comptime Schema: type, comptime table: std.meta.Tag(Schema), comptime co
fn Eql(comptime column: std.meta.Tag(ColumnUnion), value: @FieldType(ColumnUnion, @tagName(column))) type {
return struct {
- const fmt: []const u8 = std.fmt.comptimePrint("{s} = ", .{ @tagName(column) });
- const args: @Tuple(&.{ @TypeOf(value) }) = .{ value };
+ const fmt: []const u8 = std.fmt.comptimePrint("{s} = ", .{@tagName(column)});
+ const args: @Tuple(&.{@TypeOf(value)}) = .{value};
};
}
// fn And() type {
- // todo: concat fmt slices and args tuples
+ // todo: concat fmt slices and args tuples
// }
string: Node,
@@ -236,10 +236,10 @@ test "schema" {
const Schema = struct {
contacts: Contacts,
// contacts: struct {
- // contact_id: Integer = .constrain(.primary_key),
- // age: Integer = .unconstrained,
- // contact_id: Integer(usize) = .constrain(.{ .primary_key = true }),
- // first_name: Default(VarChar(255), "Hans"),
+ // contact_id: Integer = .constrain(.primary_key),
+ // age: Integer = .unconstrained,
+ // contact_id: Integer(usize) = .constrain(.{ .primary_key = true }),
+ // first_name: Default(VarChar(255), "Hans"),
// },
};
@@ -254,10 +254,10 @@ test "schema" {
const t: Test(@TypeOf(db).Schema, .contacts, &.{ .id, .first_name }) = .eql(.id, 42);
// const t: Test(@TypeOf(db).Schema, .contacts, &.{ .id, .first_name }) = .op_and(.eql(.id, 42), .eql(.first_name, "name"));
- std.debug.print("test output: {s}{}\n", switch (t.string) { .eql => |eq| .{ eq.fmt, eq.args } });
+ std.debug.print("test output: {s}{}\n", switch (t.string) {
+ .eql => |eq| .{ eq.fmt, eq.args },
+ });
const Int = Default(Unique(Integer(usize)), 42);
- std.debug.print("default unique integer with default 42: {s}\n", .{ Int.string });
-
-
+ std.debug.print("default unique integer with default 42: {s}\n", .{Int.string});
}