summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEkaitz Zarraga <ekaitz@elenq.tech>2024-08-01 15:46:56 +0200
committerEkaitz Zarraga <ekaitz@elenq.tech>2024-08-01 15:46:56 +0200
commitb5316c4dc3ba84a4257b996f9d1505f95fe95ab4 (patch)
tree4b30760788b20d5860f4764479fd96e731fcc60b /src
parent9a2ed3ddf6ebbcc46d0aea394ca92b76f65e16e7 (diff)
Separate database Result and start generics
Diffstat (limited to 'src')
-rw-r--r--src/db.zig118
-rw-r--r--src/duckdb/Result.zig71
-rw-r--r--src/duckdb/db.zig76
-rw-r--r--src/main.zig2
4 files changed, 148 insertions, 119 deletions
diff --git a/src/db.zig b/src/db.zig
deleted file mode 100644
index b0aa63a..0000000
--- a/src/db.zig
+++ /dev/null
@@ -1,118 +0,0 @@
-const std = @import("std");
-const assert = std.debug.assert;
-const c = @cImport({
- @cInclude("duckdb.h");
-});
-
-
-const Result = struct {
- _res: c.duckdb_result,
- _chunk: c.duckdb_data_chunk,
-
- pub fn init() Result {
- return .{
- ._res = undefined,
- ._chunk = null
- };
- }
- pub fn deinit(self: *Result) void {
- c.duckdb_destroy_result(&self._res);
- c.duckdb_destroy_data_chunk(&self._chunk);
- }
-
- /// There's not way to know how many total elements we have, but we can
- /// know how many we have in the current chunk.
- fn getCurrentChunkSize(self: Result) usize {
- if (self._chunk != null) {
- return 0;
- }
- return c.duckdb_data_chunk_get_size(self._chunk);
- }
-
- pub fn getColumnCount(self: Result) usize {
- return c.duckdb_data_chunk_get_column_count(self._chunk);
- }
-
- /// This needs to be called repeatedly to obtain the next blocks of
- /// data. There's no way to know how many elements we'll obtain from
- /// it.
- pub fn fetchDataChunk(self: *Result) void{
- if (self._chunk != null){
- c.duckdb_destroy_data_chunk(&self._chunk);
- }
- self._chunk = c.duckdb_fetch_chunk(self._res);
- }
-
- pub fn exausted(self: Result) bool{
- return self._chunk != null;
- }
-};
-
-
-const Connection = struct {
- _conn: c.duckdb_connection,
-
- pub fn init(db: Self) !Connection {
- var conn: Connection = undefined;
- if( c.duckdb_connect(db._db, &conn._conn) == c.DuckDBError ){
- return error.DuckDBError;
- }
- return conn;
- }
-
- pub fn deinit(self: *Connection) void {
- c.duckdb_disconnect(&self._conn);
- }
-
- pub fn query(self: *Connection, q: [*c]const u8) !Result{
- var result = Result.init();
- const state = c.duckdb_query(self._conn, q, &result._res);
- if ( state == c.DuckDBError){
- return error.DuckDBError;
- }
- result.fetchDataChunk();
- return result;
- }
-};
-
-
-pub const Self = @This();
-
-_db: c.duckdb_database,
-
-pub fn init(file: [*c]const u8) !Self{
- var db : Self = undefined;
- if (c.duckdb_open(file, &db._db) == c.DuckDBError) {
- return error.DuckDBError;
- }
- return db;
-}
-
-pub fn deinit(self: *Self) void{
- c.duckdb_close(&self._db);
-}
-
-pub fn connect(self: Self) !Connection {
- return Connection.init(self);
-}
-
-test "Open and connect" {
- var database = try Self.init(":memory:");
- defer database.deinit();
- var connection = try database.connect();
- defer connection.deinit();
-}
-
-test "Query size" {
- var database = try Self.init(":memory:");
- defer database.deinit();
- var connection = try database.connect();
- defer connection.deinit();
-
- _ = try connection.query("CREATE TABLE integers (i INTEGER, j INTEGER);");
- _ = try connection.query("INSERT INTO integers VALUES (3, 4), (5, 6), (7, NULL);");
- var result = try connection.query("SELECT * FROM integers;");
- defer result.deinit();
-
- try std.testing.expect(2 == result.getColumnCount());
-}
diff --git a/src/duckdb/Result.zig b/src/duckdb/Result.zig
new file mode 100644
index 0000000..b49f704
--- /dev/null
+++ b/src/duckdb/Result.zig
@@ -0,0 +1,71 @@
+const std = @import("std");
+const c = @cImport({
+ @cInclude("duckdb.h");
+});
+
+
+pub fn Result(comptime T: type) type{
+
+ return struct {
+ _res: c.duckdb_result,
+ _chunk: c.duckdb_data_chunk,
+
+ const Self = @This();
+
+ pub fn init(conn : c.duckdb_connection, query: [:0]const u8) !Self {
+ var self : Self = .{
+ ._res = undefined,
+ ._chunk = null
+ };
+ const state = c.duckdb_query(conn, query, &self._res);
+ if ( state == c.DuckDBError){
+ return error.DuckDBError;
+ }
+ self.fetchDataChunk();
+ return self;
+ }
+ pub fn deinit(self: *Self) void {
+ c.duckdb_destroy_result(&self._res);
+ c.duckdb_destroy_data_chunk(&self._chunk);
+ }
+
+ /// There's not way to know how many total elements we have, but we can
+ /// know how many we have in the current chunk.
+ fn getCurrentChunkSize(self: Self) usize {
+ if (self._chunk != null) {
+ return 0;
+ }
+ return c.duckdb_data_chunk_get_size(self._chunk);
+ }
+
+ pub fn getColumnCount(self: Self) usize {
+ return c.duckdb_data_chunk_get_column_count(self._chunk);
+ }
+
+ /// This needs to be called repeatedly to obtain the next blocks of
+ /// data. There's no way to know how many elements we'll obtain from
+ /// it.
+ fn fetchDataChunk(self: *Self) void{
+ if (self._chunk != null){
+ c.duckdb_destroy_data_chunk(&self._chunk);
+ }
+ self._chunk = c.duckdb_fetch_chunk(self._res);
+ }
+
+ pub fn exausted(self: Self) bool{
+ return self._chunk != null;
+ }
+
+ /// We need some comptime magic to create the output structures from
+ /// the T.
+ pub fn next(self: *Self) T{
+ _ = self;
+ const result: T = undefined;
+ switch (@typeInfo(T)) {
+ .Struct => std.debug.print("GOOOD: ", .{}),
+ else => null,
+ }
+ return result;
+ }
+ };
+}
diff --git a/src/duckdb/db.zig b/src/duckdb/db.zig
new file mode 100644
index 0000000..134a1f4
--- /dev/null
+++ b/src/duckdb/db.zig
@@ -0,0 +1,76 @@
+const std = @import("std");
+const assert = std.debug.assert;
+const c = @cImport({
+ @cInclude("duckdb.h");
+});
+const Result = @import("Result.zig").Result;
+
+
+const Connection = struct {
+ _conn: c.duckdb_connection,
+
+ pub fn init(db: Database) !Connection {
+ var conn: Connection = undefined;
+ if( c.duckdb_connect(db._db, &conn._conn) == c.DuckDBError ){
+ return error.DuckDBError;
+ }
+ return conn;
+ }
+
+ pub fn deinit(self: *Connection) void {
+ c.duckdb_disconnect(&self._conn);
+ }
+
+ pub fn query(self: *Connection, q: [:0]const u8, comptime res_type: type)
+ !Result(res_type) {
+ return try Result(res_type).init(self._conn, q);
+ }
+};
+
+
+pub const Database = @This();
+
+_db: c.duckdb_database,
+
+pub fn init(file: [*c]const u8) !Database{
+ var db : Database = undefined;
+ if (c.duckdb_open(file, &db._db) == c.DuckDBError) {
+ return error.DuckDBError;
+ }
+ return db;
+}
+
+pub fn deinit(self: *Database) void{
+ c.duckdb_close(&self._db);
+}
+
+pub fn connect(self: Database) !Connection {
+ return Connection.init(self);
+}
+
+test "Open and connect" {
+ var database = try Database.init(":memory:");
+ defer database.deinit();
+ var connection = try database.connect();
+ defer connection.deinit();
+}
+
+test "Query size" {
+ var database = try Database.init(":memory:");
+ defer database.deinit();
+ var connection = try database.connect();
+ defer connection.deinit();
+
+ const s : type = comptime struct {
+ primer: u8,
+ segund: u8
+ };
+
+ _ = try connection.query("CREATE TABLE integers (i INTEGER, j INTEGER);", void);
+ _ = try connection.query("INSERT INTO integers VALUES (3, 4), (5, 6), (7, NULL);", void);
+ var result = try connection.query("SELECT * FROM integers;", s);
+ _ = result.next();
+ defer result.deinit();
+
+ try std.testing.expect(2 == result.getColumnCount());
+}
diff --git a/src/main.zig b/src/main.zig
index 14e1810..d970b68 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-pub const Db = @import("./db.zig");
+pub const Db = @import("./duckdb/db.zig");
pub fn main() !void {
var database = try Db.init(":memory:");