import postgresRange from 'postgres-range' import { parseArray } from './array' import { parseBigint, parseString, parseTimestamp, parseTimestampTz } from './basic' import type { PGParser } from '../parsers' import type { PGSerializable, PGSerialize } from '../serializers' import type { PGArray } from './array' /* ========================================================================== * * PGRANGE TYPE * * ========================================================================== */ /** A parsed PostgreSQL `range` */ export interface PGRange { readonly lower: T | null readonly upper: T | null readonly mask: number hasMask(flags: number): boolean isBounded(): boolean isEmpty(): boolean isLowerBoundClosed(): boolean isUpperBoundClosed(): boolean hasLowerBound(): boolean hasUpperBound(): boolean containsPoint(point: T): boolean containsRange(range: PGRange): boolean toPostgres(serialize: PGSerialize): string } /** Constructor (with static constants) for {@link PGRange} */ export interface PGRangeConstructor { new (lower: T | null, upper: T | null, flags: number): PGRange readonly RANGE_EMPTY: number readonly RANGE_LB_INC: number readonly RANGE_UB_INC: number readonly RANGE_LB_INF: number readonly RANGE_UB_INF: number } /** A parsed PostgreSQL `range` */ export const PGRange: PGRangeConstructor = class PGRangeImpl extends postgresRange.Range implements PGRange, PGSerializable { readonly mask: number constructor(lower: T | null, upper: T | null, flags: number) { super(lower, upper, flags) this.mask = flags } toPostgres(serialize: PGSerialize): string { return postgresRange.serialize(this, serialize) } static readonly RANGE_EMPTY = postgresRange.RANGE_EMPTY static readonly RANGE_LB_INC = postgresRange.RANGE_LB_INC static readonly RANGE_UB_INC = postgresRange.RANGE_UB_INC static readonly RANGE_LB_INF = postgresRange.RANGE_LB_INF static readonly RANGE_UB_INF = postgresRange.RANGE_UB_INF } /* ========================================================================== * * PARSERS * * ========================================================================== */ /** Parse a PostgreSQL `range` */ export function parseRange(value: string): PGRange /** Parse a PostgreSQL `range` */ export function parseRange(value: string, parser: PGParser): PGRange /* Overloaded implementation */ export function parseRange( value: string, parser: PGParser = parseString, ): PGRange { const range = postgresRange.parse(value, parser) return new PGRange(range.lower, range.upper, (range as any).mask) } /* ===== SPECIALIZED TYPES ================================================== */ /** Parse a PostgreSQL `range` of _integers_ */ export const parseIntRange: PGParser> = (value: string) => parseRange(value, parseInt) /** Parse a PostgreSQL `range` of _floats_ */ export const parseFloatRange: PGParser> = (value: string) => parseRange(value, parseFloat) /** Parse a PostgreSQL `range` of _big integers_ */ export const parseBigintRange: PGParser> = (value: string) => parseRange(value, parseBigint) /** Parse a PostgreSQL `range` of _timestamps_ */ export const parseTimestampRange: PGParser> = (value: string) => parseRange(value, parseTimestamp) /** Parse a PostgreSQL `range` of _timestamps with time zone_ */ export const parseTimestampTzRange: PGParser> = (value: string) => parseRange(value, parseTimestampTz) /* ===== ARRAYS OF RANGES =================================================== */ /** Parse an array of PostgreSQL `range` of _strings_ */ export const parseRangeArray: PGParser>> = (value: string) => parseArray>(value, parseRange) /** Parse an array of PostgreSQL `range` of _integers_ */ export const parseIntRangeArray: PGParser>> = (value: string) => parseArray(value, parseIntRange) /** Parse an array of PostgreSQL `range` of _floats_ */ export const parseFloatRangeArray: PGParser>> = (value: string) => parseArray(value, parseFloatRange) /** Parse an array of PostgreSQL `range` of _big integers_ */ export const parseBigintRangeArray: PGParser>> = (value: string) => parseArray(value, parseBigintRange) /** Parse an array of PostgreSQL `range` of _timestamps_ */ export const parseTimestampRangeArray: PGParser>> = (value: string) => parseArray(value, parseTimestampRange) /** Parse an array of PostgreSQL `range` of _timestamps with time zone_ */ export const parseTimestampTzRangeArray: PGParser>> = (value: string) => parseArray(value, parseTimestampTzRange)