aboutsummaryrefslogtreecommitdiff
path: root/src/db/sqlite.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/db/sqlite.zig')
-rw-r--r--src/db/sqlite.zig95
1 files changed, 46 insertions, 49 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();
// }