1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
const std = @import("std");
const c = @cImport({
@cInclude("duckdb.h");
});
const Result = @import("Result.zig").Result;
_q : c.duckdb_prepared_statement,
_current_binding: usize,
const Self = @This();
pub fn init(stmt: c.duckdb_prepared_statement) !Self{
return .{
._q = stmt,
._current_binding = 1,
};
}
pub fn bindInt(self: *Self, param: anytype) !void{
const state = switch(@TypeOf(param)) {
u8 => c.duckdb_bind_uint8 (self._q, self._current_binding, param),
u16 => c.duckdb_bind_uint16(self._q, self._current_binding, param),
u32 => c.duckdb_bind_uint32(self._q, self._current_binding, param),
u64 => c.duckdb_bind_uint64(self._q, self._current_binding, param),
i8 => c.duckdb_bind_int8 (self._q, self._current_binding, param),
i16 => c.duckdb_bind_int16(self._q, self._current_binding, param),
i32 => c.duckdb_bind_int32(self._q, self._current_binding, param),
i64 => c.duckdb_bind_int64(self._q, self._current_binding, param),
else => @compileError("Invalid int type for binding: "
++ @typeName(@TypeOf(param))),
};
if ( state == c.DuckDBError ) {
return error.DuckDbBindError;
}
self._current_binding += 1;
}
pub fn bindFloat(self: *Self, param: anytype) !void{
const state = switch(@TypeOf(param)) {
f32 => c.duckdb_bind_float (self._q, self._current_binding, param),
f64 => c.duckdb_bind_double(self._q, self._current_binding, param),
else => @compileError("Invalid float type for binding: "
++ @typeName(@TypeOf(param))),
};
if ( state == c.DuckDBError ) {
return error.DuckDbBindError;
}
self._current_binding += 1;
}
pub fn bindBool(self: *Self, param: bool) !void{
const state = c.duckdb_bind_bool(self._q, self._current_binding, param);
if ( state == c.DuckDBError ) {
return error.DuckDbBindError;
}
self._current_binding += 1;
}
pub fn bindNull(self: *Self) !void{
const state = c.duckdb_bind_bool(self._q, self._current_binding);
if ( state == c.DuckDBError ) {
return error.DuckDbBindError;
}
self._current_binding += 1;
}
pub fn bindString(self: *Self, param: []const u8) !void{
const state = c.duckdb_bind_varchar_length(self._q, self._current_binding,
param.ptr, param.len);
if ( state == c.DuckDBError ) {
return error.DuckDbBindError;
}
self._current_binding += 1;
}
pub fn bind(self: *Self, param: anytype) !void {
switch (@typeInfo(@TypeOf(param))) {
.Null => return try self.bindNull(),
.Bool => return try self.bindBool(param),
.Int => return try self.bindInt(param),
.Float => return try self.bindFloat(param),
.Array => |arr| {
if (arr.child == u8){
return try self.bindString(param);
} else {
return error.UnbindableType;
}
},
.Pointer => |ptr| {
if (ptr.size == .Slice and ptr.child == u8){
return try self.bindString(param);
} else {
return error.UnbindableType;
}
},
else => @compileError("Invalid type for binding: "
++ @typeName(@TypeOf(param))),
}
}
pub fn bindAll(self: *Self, params: anytype) !void{
const param_count: usize = c.duckdb_nparams(self._q);
switch (@typeInfo(@TypeOf(params))) {
.Array => |arr| {
if (arr.len == param_count){
inline for (params) |p|{
try self.bind(p);
}
return;
} else {
return error.BindingLengthsDoNotMatch;
}
},
.Struct => |str|{
const x = str.fields;
if (x.len == param_count){
inline for (x) |field|{
try self.bind(@field(params, field.name));
}
return;
} else {
return error.BindingLengthsDoNotMatch;
}
},
else => @compileError("Invalid type for binding: "
++ @typeName(@TypeOf(params))),
}
}
pub fn exec(self: *Self, comptime T: type) !Result(T){
var result: c.duckdb_result = undefined;
const state = c.duckdb_execute_prepared(self._q, &result);
if ( state == c.DuckDBError ){
return error.DuckDbExecError;
}
return try Result(T).init(result);
}
pub fn clear(self: *Self) void {
c.duckdb_clear_bindings(self._q);
}
pub fn deinit(self: *Self) void{
c.duckdb_destroy_prepare(&self._q);
}
|