summaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
authorGravatar Vincent Rischmann2020-12-21 21:41:58 +0100
committerGravatar Vincent Rischmann2020-12-21 21:44:18 +0100
commit5d24758af869360e296d53e161e5f81669ff082c (patch)
tree55db43fc53cf9ec9808a57cff212fd0eee8f3c8d /README.md
parentMerge branch 'improve-readme' (diff)
downloadzig-sqlite-5d24758af869360e296d53e161e5f81669ff082c.tar.gz
zig-sqlite-5d24758af869360e296d53e161e5f81669ff082c.tar.xz
zig-sqlite-5d24758af869360e296d53e161e5f81669ff082c.zip
document the iterator
Diffstat (limited to '')
-rw-r--r--README.md56
1 files changed, 55 insertions, 1 deletions
diff --git a/README.md b/README.md
index d059a24..6d4bc26 100644
--- a/README.md
+++ b/README.md
@@ -114,7 +114,7 @@ for (rows) |row| {
114} 114}
115``` 115```
116 116
117The `all` method takes a type and an optional tuple. 117The `all` method takes a type and an options tuple.
118 118
119The type represents a "row", it can be: 119The type represents a "row", it can be:
120* a struct where each field maps to the corresponding column in the resultset (so field 0 must map to field 1 and so on). 120* a struct where each field maps to the corresponding column in the resultset (so field 0 must map to field 1 and so on).
@@ -122,6 +122,9 @@ The type represents a "row", it can be:
122 122
123Not all types are allowed, see the section "Bind parameters and resultset rows" for more information on the types mapping rules. 123Not all types are allowed, see the section "Bind parameters and resultset rows" for more information on the types mapping rules.
124 124
125The options tuple is used to pass additional state required for some queries, usually it will be an allocator.
126Not all queries require an allocator, hence why it's not required for every call.
127
125The `one` method on a statement works the same way except it returns the first row of the result set: 128The `one` method on a statement works the same way except it returns the first row of the result set:
126 129
127```zig 130```zig
@@ -151,6 +154,57 @@ if (row) |age| {
151} 154}
152``` 155```
153 156
157### Iterating
158
159Another way to get the data returned by a query is to use the `sqlite.Iterator` type.
160
161You can only get one by calling the `iterator` method on a statement:
162
163```zig
164var stmt = try db.prepare("SELECT name FROM user WHERE age < ?");
165defer stmt.deinit();
166
167var iter = try stmt.iterator([]const u8, .{
168 .age = 20,
169});
170
171var names = std.ArrayList([]const u8).init(allocator);
172while (true) {
173 const row = (try iter.next(.{ .allocator = allocator })) orelse break;
174 try rows.append(row);
175}
176```
177
178The `iterator` method takes a type which is the same as with `all` or `one`: every row retrieved by calling `next` will have this type.
179
180Using the iterator is straightforward: call `next` on it in a loop; it can either fail with an error or return an optional value: if that optional is null, iterating is done.
181
182The `next` method takes an options tuple which serves the same function as the one in `all` or `one`.
183
184The code example above uses the iterator but it's no different than just calling `all` used like this; the real benefit of the iterator is to be able to process each row
185sequentially without needing to store all the resultset in memory at the same time.
186
187Here's an example:
188```zig
189var stmt = try db.prepare("SELECT name FROM user WHERE age < ?");
190defer stmt.deinit();
191
192var iter = try stmt.iterator([]const u8, .{
193 .age = 20,
194});
195
196while (true) {
197 var arena = std.heap.ArenaAllocator.init(allocator);
198 defer arena.deinit();
199
200 const name = (try iter.next(.{ .allocator = &arena.allocator })) orelse break;
201
202 // do stuff with name here
203}
204```
205
206Used like this the memory required for the row is only used for one iteration. You can imagine this is especially useful if your resultset contains millions of rows.
207
154### Bind parameters and resultset rows 208### Bind parameters and resultset rows
155 209
156Since sqlite doesn't have many [types](https://www.sqlite.org/datatype3.html) only a small number of Zig types are allowed in binding parameters and in resultset mapping types. 210Since sqlite doesn't have many [types](https://www.sqlite.org/datatype3.html) only a small number of Zig types are allowed in binding parameters and in resultset mapping types.