From db065e3e4482048f7dd2e45ca1025766ee187961 Mon Sep 17 00:00:00 2001 From: Nicolas Guerrero Date: Sun, 31 Jan 2021 05:47:09 -0500 Subject: [PATCH 1/3] Add Circle type --- query/types.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/query/types.ts b/query/types.ts index a0fc1bbf..1e8466a9 100644 --- a/query/types.ts +++ b/query/types.ts @@ -6,6 +6,14 @@ export interface Box { b: Point; } +/** + * https://www.postgresql.org/docs/13/datatype-geometric.html#DATATYPE-CIRCLE + */ +export interface Circle { + point: Point, + radius: Float8, +} + /** * Decimal-like string. Uses dot to split the decimal * From cb4bdc89c4f5ef68c0cd9ddc1949b56f510dbd95 Mon Sep 17 00:00:00 2001 From: Nicolas Guerrero Date: Sun, 31 Jan 2021 05:55:12 -0500 Subject: [PATCH 2/3] Add parser support --- decode.ts | 6 ++++++ oid.ts | 5 ++--- query/decoders.ts | 16 ++++++++++++++++ query/types.ts | 4 ++-- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/decode.ts b/decode.ts index 2cee0619..27520447 100644 --- a/decode.ts +++ b/decode.ts @@ -9,6 +9,8 @@ import { decodeBoxArray, decodeBytea, decodeByteaArray, + decodeCircle, + decodeCircleArray, decodeDate, decodeDateArray, decodeDatetime, @@ -112,6 +114,10 @@ function decodeText(value: Uint8Array, typeOid: number): any { return decodeBox(strValue); case Oid.box_array: return decodeBoxArray(strValue); + case Oid.circle: + return decodeCircle(strValue); + case Oid.circle_array: + return decodeCircleArray(strValue); case Oid.bytea: return decodeBytea(strValue); case Oid.byte_array: diff --git a/oid.ts b/oid.ts index 10916bbc..06b6b657 100644 --- a/oid.ts +++ b/oid.ts @@ -61,10 +61,9 @@ export const Oid = { // deno-lint-ignore camelcase _tinterval_0: 704, _unknown: 705, + circle: 718, // deno-lint-ignore camelcase - _circle_0: 718, - // deno-lint-ignore camelcase - _circle_1: 719, + circle_array: 719, // deno-lint-ignore camelcase _money_0: 790, // deno-lint-ignore camelcase diff --git a/query/decoders.ts b/query/decoders.ts index 51edbc03..40273ff2 100644 --- a/query/decoders.ts +++ b/query/decoders.ts @@ -1,6 +1,7 @@ import { parseArray } from "./array_parser.ts"; import { Box, + Circle, Float8, Line, LineSegment, @@ -102,6 +103,21 @@ function decodeByteaHex(byteaStr: string): Uint8Array { return bytes; } +export function decodeCircle(value: string): Circle { + const [point, radius] = value.substring(1, value.length - 1).split( + /,(?![^(]*\))/, + ); + + return { + point: decodePoint(point), + radius: radius as Float8, + }; +} + +export function decodeCircleArray(value: string) { + return parseArray(value, decodeCircle); +} + export function decodeDate(dateStr: string): Date | number { // there are special `infinity` and `-infinity` // cases representing out-of-range dates diff --git a/query/types.ts b/query/types.ts index 1e8466a9..fbd22288 100644 --- a/query/types.ts +++ b/query/types.ts @@ -10,8 +10,8 @@ export interface Box { * https://www.postgresql.org/docs/13/datatype-geometric.html#DATATYPE-CIRCLE */ export interface Circle { - point: Point, - radius: Float8, + point: Point; + radius: Float8; } /** From 4d2e47728a49e40ee2f4cb7a137ea4c647bbfcf0 Mon Sep 17 00:00:00 2001 From: Nicolas Guerrero Date: Sun, 31 Jan 2021 06:01:04 -0500 Subject: [PATCH 3/3] Add tests --- tests/data_types.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/data_types.ts b/tests/data_types.ts index f481a164..efa936a4 100644 --- a/tests/data_types.ts +++ b/tests/data_types.ts @@ -10,6 +10,7 @@ import TEST_CONNECTION_PARAMS from "./config.ts"; import { getTestClient } from "./helpers.ts"; import { Box, + Circle, Float4, Float8, Line, @@ -867,3 +868,25 @@ testClient(async function polygonArray() { assertEquals(selectRes.rows[0][0][0], points); }); + +testClient(async function circle() { + const point = generateRandomPoint(); + const radius = String(generateRandomNumber(100)); + + const { rows } = await CLIENT.queryArray<[Circle]>( + `SELECT '<(${point.x},${point.y}), ${radius}>'::CIRCLE`, + ); + + assertEquals(rows[0][0], { point, radius }); +}); + +testClient(async function circleArray() { + const point = generateRandomPoint(); + const radius = String(generateRandomNumber(100)); + + const { rows } = await CLIENT.queryArray<[[Circle]]>( + `SELECT ARRAY['<(${point.x},${point.y}), ${radius}>'::CIRCLE]`, + ); + + assertEquals(rows[0][0][0], { point, radius }); +});