From 5d07304b6277e673d2b9935b3300f83e6bbae644 Mon Sep 17 00:00:00 2001 From: fox0430 Date: Tue, 21 Apr 2026 17:57:38 +0900 Subject: [PATCH 1/2] Add generic Option[T] dispatch --- async_postgres/pg_types.nim | 9 ++++++ async_postgres/pg_types/accessors.nim | 46 +++++++++++++++++++++++++++ async_postgres/pg_types/ranges.nim | 15 +++++++++ 3 files changed, 70 insertions(+) diff --git a/async_postgres/pg_types.nim b/async_postgres/pg_types.nim index cfedb3a..0546298 100644 --- a/async_postgres/pg_types.nim +++ b/async_postgres/pg_types.nim @@ -1,5 +1,6 @@ import std/[json, options, times] +import pg_protocol import pg_types/[core, encoding, decoding, accessors, user_types, ranges] export core, encoding, decoding, accessors, user_types, ranges @@ -207,3 +208,11 @@ nameAccessor(getNumMultirangeArrayOpt, Option[seq[PgMultirange[PgNumeric]]]) nameAccessor(getTsMultirangeArrayOpt, Option[seq[PgMultirange[DateTime]]]) nameAccessor(getTsTzMultirangeArrayOpt, Option[seq[PgMultirange[DateTime]]]) nameAccessor(getDateMultirangeArrayOpt, Option[seq[PgMultirange[DateTime]]]) + +# Generic Option[T] dispatch: delegates to the bare `get(col, T)` plus a NULL +# check, so every bare type overload automatically gains an Option counterpart. +proc get*[T](row: Row, col: int, _: typedesc[Option[T]]): Option[T] = + if row.isNull(col): + none(T) + else: + some(row.get(col, T)) diff --git a/async_postgres/pg_types/accessors.nim b/async_postgres/pg_types/accessors.nim index 37a49d9..2f0a7bd 100644 --- a/async_postgres/pg_types/accessors.nim +++ b/async_postgres/pg_types/accessors.nim @@ -1807,6 +1807,12 @@ proc get*(row: Row, col: int, T: typedesc[PgXml]): PgXml = proc get*(row: Row, col: int, T: typedesc[PgBit]): PgBit = row.getBit(col) +proc get*(row: Row, col: int, T: typedesc[PgTime]): PgTime = + row.getTime(col) + +proc get*(row: Row, col: int, T: typedesc[PgTimeTz]): PgTimeTz = + row.getTimeTz(col) + proc get*(row: Row, col: int, T: typedesc[PgHstore]): PgHstore = row.getHstore(col) @@ -1857,6 +1863,9 @@ proc get*(row: Row, col: int, T: typedesc[seq[bool]]): seq[bool] = proc get*(row: Row, col: int, T: typedesc[seq[string]]): seq[string] = row.getStrArray(col) +proc get*(row: Row, col: int, T: typedesc[seq[seq[byte]]]): seq[seq[byte]] = + row.getBytesArray(col) + proc get*(row: Row, col: int, T: typedesc[seq[PgBit]]): seq[PgBit] = row.getBitArray(col) @@ -1926,6 +1935,43 @@ proc get*(row: Row, col: int, T: typedesc[seq[PgTsQuery]]): seq[PgTsQuery] = proc get*(row: Row, col: int, T: typedesc[seq[PgHstore]]): seq[PgHstore] = row.getHstoreArray(col) +# Per-element Option array types + +proc get*( + row: Row, col: int, T: typedesc[seq[Option[int16]]] +): seq[Option[int16]] = + row.getInt16ArrayElemOpt(col) + +proc get*( + row: Row, col: int, T: typedesc[seq[Option[int32]]] +): seq[Option[int32]] = + row.getIntArrayElemOpt(col) + +proc get*( + row: Row, col: int, T: typedesc[seq[Option[int64]]] +): seq[Option[int64]] = + row.getInt64ArrayElemOpt(col) + +proc get*( + row: Row, col: int, T: typedesc[seq[Option[float32]]] +): seq[Option[float32]] = + row.getFloat32ArrayElemOpt(col) + +proc get*( + row: Row, col: int, T: typedesc[seq[Option[float64]]] +): seq[Option[float64]] = + row.getFloatArrayElemOpt(col) + +proc get*( + row: Row, col: int, T: typedesc[seq[Option[bool]]] +): seq[Option[bool]] = + row.getBoolArrayElemOpt(col) + +proc get*( + row: Row, col: int, T: typedesc[seq[Option[string]]] +): seq[Option[string]] = + row.getStrArrayElemOpt(col) + proc columnIndex*(fields: seq[FieldDescription], name: string): int = ## Find the index of a column by name. Raises PgTypeError if not found. for i, f in fields: diff --git a/async_postgres/pg_types/ranges.nim b/async_postgres/pg_types/ranges.nim index 3924cc1..0fef3d8 100644 --- a/async_postgres/pg_types/ranges.nim +++ b/async_postgres/pg_types/ranges.nim @@ -1489,6 +1489,21 @@ proc get*( ): PgMultirange[PgNumeric] = row.getNumMultirange(col) +proc get*( + row: Row, col: int, T: typedesc[seq[PgRange[int32]]] +): seq[PgRange[int32]] = + row.getInt4RangeArray(col) + +proc get*( + row: Row, col: int, T: typedesc[seq[PgRange[int64]]] +): seq[PgRange[int64]] = + row.getInt8RangeArray(col) + +proc get*( + row: Row, col: int, T: typedesc[seq[PgRange[PgNumeric]]] +): seq[PgRange[PgNumeric]] = + row.getNumRangeArray(col) + proc get*( row: Row, col: int, T: typedesc[seq[PgMultirange[int32]]] ): seq[PgMultirange[int32]] = From 4bff1843f427a4732f056d990713850973639866 Mon Sep 17 00:00:00 2001 From: fox0430 Date: Tue, 21 Apr 2026 17:59:18 +0900 Subject: [PATCH 2/2] nph --- async_postgres/pg_types/accessors.nim | 28 +++++++-------------------- async_postgres/pg_types/ranges.nim | 8 ++------ 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/async_postgres/pg_types/accessors.nim b/async_postgres/pg_types/accessors.nim index 2f0a7bd..8685bac 100644 --- a/async_postgres/pg_types/accessors.nim +++ b/async_postgres/pg_types/accessors.nim @@ -1937,39 +1937,25 @@ proc get*(row: Row, col: int, T: typedesc[seq[PgHstore]]): seq[PgHstore] = # Per-element Option array types -proc get*( - row: Row, col: int, T: typedesc[seq[Option[int16]]] -): seq[Option[int16]] = +proc get*(row: Row, col: int, T: typedesc[seq[Option[int16]]]): seq[Option[int16]] = row.getInt16ArrayElemOpt(col) -proc get*( - row: Row, col: int, T: typedesc[seq[Option[int32]]] -): seq[Option[int32]] = +proc get*(row: Row, col: int, T: typedesc[seq[Option[int32]]]): seq[Option[int32]] = row.getIntArrayElemOpt(col) -proc get*( - row: Row, col: int, T: typedesc[seq[Option[int64]]] -): seq[Option[int64]] = +proc get*(row: Row, col: int, T: typedesc[seq[Option[int64]]]): seq[Option[int64]] = row.getInt64ArrayElemOpt(col) -proc get*( - row: Row, col: int, T: typedesc[seq[Option[float32]]] -): seq[Option[float32]] = +proc get*(row: Row, col: int, T: typedesc[seq[Option[float32]]]): seq[Option[float32]] = row.getFloat32ArrayElemOpt(col) -proc get*( - row: Row, col: int, T: typedesc[seq[Option[float64]]] -): seq[Option[float64]] = +proc get*(row: Row, col: int, T: typedesc[seq[Option[float64]]]): seq[Option[float64]] = row.getFloatArrayElemOpt(col) -proc get*( - row: Row, col: int, T: typedesc[seq[Option[bool]]] -): seq[Option[bool]] = +proc get*(row: Row, col: int, T: typedesc[seq[Option[bool]]]): seq[Option[bool]] = row.getBoolArrayElemOpt(col) -proc get*( - row: Row, col: int, T: typedesc[seq[Option[string]]] -): seq[Option[string]] = +proc get*(row: Row, col: int, T: typedesc[seq[Option[string]]]): seq[Option[string]] = row.getStrArrayElemOpt(col) proc columnIndex*(fields: seq[FieldDescription], name: string): int = diff --git a/async_postgres/pg_types/ranges.nim b/async_postgres/pg_types/ranges.nim index 0fef3d8..0aee3c3 100644 --- a/async_postgres/pg_types/ranges.nim +++ b/async_postgres/pg_types/ranges.nim @@ -1489,14 +1489,10 @@ proc get*( ): PgMultirange[PgNumeric] = row.getNumMultirange(col) -proc get*( - row: Row, col: int, T: typedesc[seq[PgRange[int32]]] -): seq[PgRange[int32]] = +proc get*(row: Row, col: int, T: typedesc[seq[PgRange[int32]]]): seq[PgRange[int32]] = row.getInt4RangeArray(col) -proc get*( - row: Row, col: int, T: typedesc[seq[PgRange[int64]]] -): seq[PgRange[int64]] = +proc get*(row: Row, col: int, T: typedesc[seq[PgRange[int64]]]): seq[PgRange[int64]] = row.getInt8RangeArray(col) proc get*(