Fix distinct type row mapping
This commit is contained in:
@@ -289,6 +289,10 @@ Nim Type Postgres Type SQLite Type
|
||||
`JsonNode`_ `jsonb`_
|
||||
=============== ====================== =================
|
||||
|
||||
Distinct types backed by a supported type are parsed through their backing
|
||||
type and then converted to the distinct type. This also applies when the
|
||||
distinct type is nested in an `Option`_ or `seq`.
|
||||
|
||||
.. [#f1] Note that this implies that all `NULL`-able fields should be typed
|
||||
as optional using `Option[fieldType]`. Conversely, any fields with
|
||||
non-optional types should also be constrained to be `NOT NULL` in
|
||||
|
||||
@@ -18,6 +18,7 @@ requires "namespaced_logging >= 2.0.2"
|
||||
|
||||
task unittest, "Runs the unit test suite.":
|
||||
exec "nim c -r --path:src tests/test_datetime"
|
||||
exec "nim c -r --path:src tests/test_distinct"
|
||||
|
||||
task integrationtest, "Runs the PostgreSQL integration test suite.":
|
||||
exec "nim c -r --path:src tests/test_datetime_postgres"
|
||||
|
||||
@@ -266,10 +266,9 @@ func createParseStmt*(t, value: NimNode): NimNode =
|
||||
else: error "Cannot parse column with unknown generic instance type: " & $t.getTypeInst
|
||||
|
||||
elif t.typeKind == ntyDistinct:
|
||||
result = quote do:
|
||||
block:
|
||||
let tmp: `t` = `value`
|
||||
tmp
|
||||
let baseType = t.getTypeImpl[0]
|
||||
let parseStmt = createParseStmt(baseType, value)
|
||||
result = quote do: `t`(`parseStmt`)
|
||||
|
||||
elif t.typeKind == ntyRef:
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
import std/[options, times, unittest]
|
||||
|
||||
import uuids
|
||||
|
||||
import fiber_orm/util
|
||||
|
||||
|
||||
type
|
||||
StringId = distinct string
|
||||
NestedStringId = distinct StringId
|
||||
UuidId = distinct UUID
|
||||
Count = distinct int
|
||||
Ratio = distinct float
|
||||
Enabled = distinct bool
|
||||
|
||||
State = enum
|
||||
pending
|
||||
complete
|
||||
|
||||
DistinctState = distinct State
|
||||
|
||||
DistinctModel = object
|
||||
id: StringId
|
||||
nestedId: NestedStringId
|
||||
userId: UuidId
|
||||
count: Count
|
||||
ratio: Ratio
|
||||
enabled: Enabled
|
||||
state: DistinctState
|
||||
optionalId: Option[StringId]
|
||||
absentId: Option[StringId]
|
||||
relatedIds: seq[StringId]
|
||||
occurredAt: DateTime
|
||||
|
||||
|
||||
suite "distinct type row mapping":
|
||||
|
||||
test "parses each distinct type through its backing type":
|
||||
let model = rowToModel(DistinctModel, @[
|
||||
"item_123",
|
||||
"nested_123",
|
||||
"07e268ed-a3c1-4952-bc45-778b3000b76c",
|
||||
"42",
|
||||
"1.25",
|
||||
"true",
|
||||
"complete",
|
||||
"optional_123",
|
||||
"",
|
||||
"{related_1,related_2}",
|
||||
"2026-08-26 14:32:10.123457+00",
|
||||
])
|
||||
|
||||
check:
|
||||
string(model.id) == "item_123"
|
||||
string(StringId(model.nestedId)) == "nested_123"
|
||||
UUID(model.userId) ==
|
||||
parseUUID("07e268ed-a3c1-4952-bc45-778b3000b76c")
|
||||
int(model.count) == 42
|
||||
float(model.ratio) == 1.25
|
||||
bool(model.enabled)
|
||||
State(model.state) == complete
|
||||
model.optionalId.isSome
|
||||
string(model.optionalId.get) == "optional_123"
|
||||
model.absentId.isNone
|
||||
model.relatedIds.len == 2
|
||||
string(model.relatedIds[0]) == "related_1"
|
||||
string(model.relatedIds[1]) == "related_2"
|
||||
model.occurredAt.nanosecond == 123_457_000
|
||||
|
||||
test "preserves backing-type parse failures":
|
||||
expect ValueError:
|
||||
discard rowToModel(DistinctModel, @[
|
||||
"item_123",
|
||||
"nested_123",
|
||||
"not-a-uuid",
|
||||
"42",
|
||||
"1.25",
|
||||
"true",
|
||||
"complete",
|
||||
"",
|
||||
"",
|
||||
"{}",
|
||||
"2026-08-26 14:32:10+00",
|
||||
])
|
||||
Reference in New Issue
Block a user