You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+69Lines changed: 69 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -241,6 +241,75 @@ let newId = query:
241
241
242
242
```
243
243
244
+
### Typed Queries
245
+
246
+
Use `query(T):` when you want Ormin to deserialize selected columns directly into a named Nim type instead of returning the default tuple shape. This is useful at module boundaries where a named object, ref object, or scalar domain type is clearer than a tuple.
247
+
248
+
For object results, selected column names must match fields on the destination type. Use `as` aliases when the database column name differs from the Nim field name:
249
+
250
+
```nim
251
+
type
252
+
ThreadSummary = object
253
+
id: int
254
+
title: string
255
+
256
+
let threads = query(ThreadSummary):
257
+
select thread(id, name as title)
258
+
orderby id
259
+
```
260
+
261
+
Selecting one column can map directly to a scalar type:
262
+
263
+
```nim
264
+
let names = query(string):
265
+
select thread(name)
266
+
```
267
+
268
+
Queries that return a single row, such as a `limit 1` query, return one `T` instead of `seq[T]`:
269
+
270
+
```nim
271
+
let thread = query(ThreadSummary):
272
+
select thread(id, name as title)
273
+
where id == ?threadId
274
+
limit 1
275
+
```
276
+
277
+
#### `fromQueryHook` Column Hooks
278
+
279
+
Typed queries deserialize each selected column through `fromQueryHook`. You can overload this hook for your own field or scalar destination types:
280
+
281
+
```nim
282
+
import ormin/query_hooks
283
+
284
+
type
285
+
TitleLength = distinct int
286
+
287
+
ThreadTitleSize = object
288
+
id: int
289
+
title: TitleLength
290
+
291
+
proc fromQueryHook*(val: var TitleLength, value: string) =
292
+
val = TitleLength(value.len)
293
+
294
+
let rows = query(ThreadTitleSize):
295
+
select thread(id, name as title)
296
+
```
297
+
298
+
If a hook needs to handle SQL `NULL` itself, accept a `DbValue[SourceType]`:
299
+
300
+
```nim
301
+
type
302
+
NullableTitle = distinct string
303
+
304
+
proc fromQueryHook*(val: var NullableTitle, value: DbValue[string]) =
305
+
if value.isNull:
306
+
val = NullableTitle("<untitled>")
307
+
else:
308
+
val = NullableTitle(value.value)
309
+
```
310
+
311
+
These are column deserialization hooks. In object typed queries, Ormin calls `fromQueryHook` separately for each selected column that maps to a destination field; it does not currently call a hook for the entire row object. For whole-row transformations, query into an intermediate typed result and convert it in regular Nim code.
312
+
244
313
### JSON and Raw SQL
245
314
246
315
JSON values can be spliced directly using `%` expressions. The `%` prefix tells Ormin to treat the following Nim expression as a `JsonNode` without conversion:
0 commit comments