diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 31 |
1 files changed, 30 insertions, 1 deletions
| @@ -33,10 +33,11 @@ If you use this library, expect to have to make changes when you update the code | |||
| 33 | * [Non allocating](#non-allocating-1) | 33 | * [Non allocating](#non-allocating-1) |
| 34 | * [Allocating](#allocating-1) | 34 | * [Allocating](#allocating-1) |
| 35 | * [Bind parameters and resultset rows](#bind-parameters-and-resultset-rows) | 35 | * [Bind parameters and resultset rows](#bind-parameters-and-resultset-rows) |
| 36 | * [Custom type binding and reading](#custom-type-binding-and-reading) | ||
| 36 | * [Comptime checks](#comptime-checks) | 37 | * [Comptime checks](#comptime-checks) |
| 37 | * [Check the number of bind parameters.](#check-the-number-of-bind-parameters) | 38 | * [Check the number of bind parameters.](#check-the-number-of-bind-parameters) |
| 38 | * [Assign types to bind markers and check them.](#assign-types-to-bind-markers-and-check-them) | 39 | * [Assign types to bind markers and check them.](#assign-types-to-bind-markers-and-check-them) |
| 39 | * [User defined functions](#user-defined-functions) | 40 | * [User defined SQL functions](#user-defined-sql-functions) |
| 40 | * [Scalar functions](#scalar-functions) | 41 | * [Scalar functions](#scalar-functions) |
| 41 | * [Aggregate functions](#aggregate-functions) | 42 | * [Aggregate functions](#aggregate-functions) |
| 42 | 43 | ||
| @@ -422,6 +423,34 @@ Here are the rules for resultset rows: | |||
| 422 | 423 | ||
| 423 | Note that arrays must have a sentinel because we need a way to communicate where the data actually stops in the array, so for example use `[200:0]u8` for a `TEXT` field. | 424 | Note that arrays must have a sentinel because we need a way to communicate where the data actually stops in the array, so for example use `[200:0]u8` for a `TEXT` field. |
| 424 | 425 | ||
| 426 | ## Custom type binding and reading | ||
| 427 | |||
| 428 | Sometimes the default field binding or reading logic is not what you want, for example if you want to store an enum using its tag name instead of its integer value or | ||
| 429 | if you want to store a byte slice as an hex string. | ||
| 430 | |||
| 431 | To accomplish this you must first define a wrapper struct for your type. For example if your type is a `[4]u8` and you want to treat it as an integer: | ||
| 432 | ```zig | ||
| 433 | pub const MyArray = struct { | ||
| 434 | data: [4]u8, | ||
| 435 | |||
| 436 | pub const BaseType = u32; | ||
| 437 | |||
| 438 | pub fn bindField(self: MyArray, _: std.mem.Allocator) !BaseType { | ||
| 439 | return std.mem.readIntNative(BaseType, &self.data); | ||
| 440 | } | ||
| 441 | |||
| 442 | pub fn readField(_: std.mem.Allocator, value: BaseType) !MyArray { | ||
| 443 | var arr: MyArray = undefined; | ||
| 444 | std.mem.writeIntNative(BaseType, &arr.data, value); | ||
| 445 | return arr; | ||
| 446 | } | ||
| 447 | }; | ||
| 448 | ``` | ||
| 449 | |||
| 450 | Now when you bind a value of type `MyArray` the value returned by `bindField` will be used for binding instead. | ||
| 451 | |||
| 452 | Same for reading, when you select _into_ a `MyArray` row or field the value returned by `readField` will be used instead. | ||
| 453 | |||
| 425 | # Comptime checks | 454 | # Comptime checks |
| 426 | 455 | ||
| 427 | Prepared statements contain _comptime_ metadata which is used to validate every call to `exec`, `one` and `all` _at compile time_. | 456 | Prepared statements contain _comptime_ metadata which is used to validate every call to `exec`, `one` and `all` _at compile time_. |