diff options
| author | 2023-12-18 09:16:30 +0900 | |
|---|---|---|
| committer | 2023-12-18 09:16:30 +0900 | |
| commit | adc33e8982966e595897a1dbf87e6ee9a710ad3f (patch) | |
| tree | e24a8959b9439dd191b49263e843b60881a46dba | |
| parent | query: support [] and ` identifiers (diff) | |
| download | zig-sqlite-adc33e8982966e595897a1dbf87e6ee9a710ad3f.tar.gz zig-sqlite-adc33e8982966e595897a1dbf87e6ee9a710ad3f.tar.xz zig-sqlite-adc33e8982966e595897a1dbf87e6ee9a710ad3f.zip | |
query: parse names of bind parameters
bind parameter amount should not increase if bind parameter with same
name exists.
Diffstat (limited to '')
| -rw-r--r-- | query.zig | 20 |
1 files changed, 19 insertions, 1 deletions
| @@ -6,6 +6,8 @@ const Blob = @import("sqlite.zig").Blob; | |||
| 6 | const Text = @import("sqlite.zig").Text; | 6 | const Text = @import("sqlite.zig").Text; |
| 7 | 7 | ||
| 8 | const BindMarker = struct { | 8 | const BindMarker = struct { |
| 9 | /// Name of the bind parameter in case it's named. | ||
| 10 | name: ?[]const u8 = null, | ||
| 9 | /// Contains the expected type for a bind parameter which will be checked | 11 | /// Contains the expected type for a bind parameter which will be checked |
| 10 | /// at comptime when calling bind on a statement. | 12 | /// at comptime when calling bind on a statement. |
| 11 | /// | 13 | /// |
| @@ -17,6 +19,14 @@ fn isNamedIdentifierChar(c: u8) bool { | |||
| 17 | return std.ascii.isAlphabetic(c) or std.ascii.isDigit(c) or c == '_'; | 19 | return std.ascii.isAlphabetic(c) or std.ascii.isDigit(c) or c == '_'; |
| 18 | } | 20 | } |
| 19 | 21 | ||
| 22 | fn bindMarkerForName(comptime markers: []const BindMarker, comptime name: []const u8) ?BindMarker { | ||
| 23 | for (markers[0..]) |marker| { | ||
| 24 | if (marker.name != null and std.mem.eql(u8, marker.name.?, name)) | ||
| 25 | return marker; | ||
| 26 | } | ||
| 27 | return null; | ||
| 28 | } | ||
| 29 | |||
| 20 | pub fn ParsedQuery(comptime query: []const u8) ParsedQueryState(query.len) { | 30 | pub fn ParsedQuery(comptime query: []const u8) ParsedQueryState(query.len) { |
| 21 | // This contains the final SQL query after parsing with our | 31 | // This contains the final SQL query after parsing with our |
| 22 | // own typed bind markers removed. | 32 | // own typed bind markers removed. |
| @@ -31,6 +41,9 @@ pub fn ParsedQuery(comptime query: []const u8) ParsedQueryState(query.len) { | |||
| 31 | comptime var bind_markers: [128]BindMarker = undefined; | 41 | comptime var bind_markers: [128]BindMarker = undefined; |
| 32 | comptime var nb_bind_markers: usize = 0; | 42 | comptime var nb_bind_markers: usize = 0; |
| 33 | 43 | ||
| 44 | // used for capturing slices, such as bind parameter name | ||
| 45 | comptime var hold_pos = 0; | ||
| 46 | |||
| 34 | inline for (query) |c| { | 47 | inline for (query) |c| { |
| 35 | switch (state) { | 48 | switch (state) { |
| 36 | .start => switch (c) { | 49 | .start => switch (c) { |
| @@ -71,6 +84,7 @@ pub fn ParsedQuery(comptime query: []const u8) ParsedQueryState(query.len) { | |||
| 71 | if (isNamedIdentifierChar(c)) { | 84 | if (isNamedIdentifierChar(c)) { |
| 72 | // This is the start of a named bind marker. | 85 | // This is the start of a named bind marker. |
| 73 | state = .bind_marker_identifier; | 86 | state = .bind_marker_identifier; |
| 87 | hold_pos = pos + 1; | ||
| 74 | } else { | 88 | } else { |
| 75 | // This is a unnamed, untyped bind marker. | 89 | // This is a unnamed, untyped bind marker. |
| 76 | state = .start; | 90 | state = .start; |
| @@ -92,7 +106,11 @@ pub fn ParsedQuery(comptime query: []const u8) ParsedQueryState(query.len) { | |||
| 92 | if (!isNamedIdentifierChar(c)) { | 106 | if (!isNamedIdentifierChar(c)) { |
| 93 | // This marks the end of the named bind marker. | 107 | // This marks the end of the named bind marker. |
| 94 | state = .start; | 108 | state = .start; |
| 95 | nb_bind_markers += 1; | 109 | const name = buf[hold_pos..pos - 1]; |
| 110 | if (bindMarkerForName(bind_markers[0..nb_bind_markers], name) == null) { | ||
| 111 | bind_markers[nb_bind_markers].name = name; | ||
| 112 | nb_bind_markers += 1; | ||
| 113 | } | ||
| 96 | } | 114 | } |
| 97 | buf[pos] = c; | 115 | buf[pos] = c; |
| 98 | pos += 1; | 116 | pos += 1; |