summaryrefslogtreecommitdiff
path: root/query.zig
diff options
context:
space:
mode:
authorGravatar Vincent Rischmann2020-11-11 14:13:31 +0100
committerGravatar Vincent Rischmann2020-11-11 14:13:31 +0100
commit0d766361474ae47a2f21464913e348702705cf4e (patch)
treec9444ab595c27cecc2bf8ee718437fc2055c0858 /query.zig
parentrefactor readBytes (diff)
downloadzig-sqlite-0d766361474ae47a2f21464913e348702705cf4e.tar.gz
zig-sqlite-0d766361474ae47a2f21464913e348702705cf4e.tar.xz
zig-sqlite-0d766361474ae47a2f21464913e348702705cf4e.zip
allow untyped bind markers
Diffstat (limited to 'query.zig')
-rw-r--r--query.zig40
1 files changed, 31 insertions, 9 deletions
diff --git a/query.zig b/query.zig
index a2a5c5c..81f7333 100644
--- a/query.zig
+++ b/query.zig
@@ -10,8 +10,8 @@ pub const Blob = struct { data: []const u8 };
10pub const Text = struct { data: []const u8 }; 10pub const Text = struct { data: []const u8 };
11 11
12const BindMarker = union(enum) { 12const BindMarker = union(enum) {
13 Type: type, 13 Typed: type,
14 None: void, 14 Untyped: void,
15}; 15};
16 16
17pub const ParsedQuery = struct { 17pub const ParsedQuery = struct {
@@ -59,7 +59,14 @@ pub const ParsedQuery = struct {
59 current_bind_marker_type_pos = 0; 59 current_bind_marker_type_pos = 0;
60 }, 60 },
61 else => { 61 else => {
62 @compileError("a bind marker start (the character ?) must be followed by a bind marker type, eg {integer}"); 62 // This is a bind marker without a type.
63 state = .Start;
64
65 parsed_query.bind_markers[parsed_query.nb_bind_markers] = BindMarker{ .Untyped = {} };
66 parsed_query.nb_bind_markers += 1;
67
68 buf[pos] = c;
69 pos += 1;
63 }, 70 },
64 }, 71 },
65 .BindMarkerType => switch (c) { 72 .BindMarkerType => switch (c) {
@@ -68,7 +75,7 @@ pub const ParsedQuery = struct {
68 75
69 const typ = parsed_query.parseType(current_bind_marker_type[0..current_bind_marker_type_pos]); 76 const typ = parsed_query.parseType(current_bind_marker_type[0..current_bind_marker_type_pos]);
70 77
71 parsed_query.bind_markers[parsed_query.nb_bind_markers] = BindMarker{ .Type = typ }; 78 parsed_query.bind_markers[parsed_query.nb_bind_markers] = BindMarker{ .Typed = typ };
72 parsed_query.nb_bind_markers += 1; 79 parsed_query.nb_bind_markers += 1;
73 }, 80 },
74 else => { 81 else => {
@@ -81,9 +88,13 @@ pub const ParsedQuery = struct {
81 }, 88 },
82 } 89 }
83 } 90 }
91
92 // The last character was ? so this must be an untyped bind marker.
84 if (state == .BindMarker) { 93 if (state == .BindMarker) {
85 @compileError("invalid final state " ++ @tagName(state) ++ ", this means you wrote a ? in last position without a bind marker type"); 94 parsed_query.bind_markers[parsed_query.nb_bind_markers] = BindMarker{ .Untyped = {} };
95 parsed_query.nb_bind_markers += 1;
86 } 96 }
97
87 if (state == .BindMarkerType) { 98 if (state == .BindMarkerType) {
88 @compileError("invalid final state " ++ @tagName(state) ++ ", this means you wrote an incomplete bind marker type"); 99 @compileError("invalid final state " ++ @tagName(state) ++ ", this means you wrote an incomplete bind marker type");
89 } 100 }
@@ -148,6 +159,10 @@ test "parsed query: query" {
148 .query = "SELECT id, name, age FROM user WHER age > ?{u32} AND age < ?{u32}", 159 .query = "SELECT id, name, age FROM user WHER age > ?{u32} AND age < ?{u32}",
149 .expected_query = "SELECT id, name, age FROM user WHER age > ? AND age < ?", 160 .expected_query = "SELECT id, name, age FROM user WHER age > ? AND age < ?",
150 }, 161 },
162 .{
163 .query = "SELECT id, name, age FROM user WHER age > ? AND age < ?",
164 .expected_query = "SELECT id, name, age FROM user WHER age > ? AND age < ?",
165 },
151 }; 166 };
152 167
153 inline for (testCases) |tc| { 168 inline for (testCases) |tc| {
@@ -166,15 +181,19 @@ test "parsed query: bind markers types" {
166 const testCases = &[_]testCase{ 181 const testCases = &[_]testCase{
167 .{ 182 .{
168 .query = "foobar ?{usize}", 183 .query = "foobar ?{usize}",
169 .expected_marker = .{ .Type = usize }, 184 .expected_marker = .{ .Typed = usize },
170 }, 185 },
171 .{ 186 .{
172 .query = "foobar ?{text}", 187 .query = "foobar ?{text}",
173 .expected_marker = .{ .Type = Text }, 188 .expected_marker = .{ .Typed = Text },
174 }, 189 },
175 .{ 190 .{
176 .query = "foobar ?{blob}", 191 .query = "foobar ?{blob}",
177 .expected_marker = .{ .Type = Blob }, 192 .expected_marker = .{ .Typed = Blob },
193 },
194 .{
195 .query = "foobar ?",
196 .expected_marker = .{ .Untyped = {} },
178 }, 197 },
179 }; 198 };
180 199
@@ -185,6 +204,9 @@ test "parsed query: bind markers types" {
185 testing.expectEqual(1, parsed_query.nb_bind_markers); 204 testing.expectEqual(1, parsed_query.nb_bind_markers);
186 205
187 const bind_marker = parsed_query.bind_markers[0]; 206 const bind_marker = parsed_query.bind_markers[0];
188 testing.expectEqual(tc.expected_marker.Type, bind_marker.Type); 207 switch (tc.expected_marker) {
208 .Typed => |typ| testing.expectEqual(typ, bind_marker.Typed),
209 .Untyped => |typ| testing.expectEqual(typ, bind_marker.Untyped),
210 }
189 } 211 }
190} 212}