import { Oid, OidType, OidTypes, OidValue } from "./oid.ts";import { bold, yellow } from "../deps.ts";import { decodeBigint, decodeBigintArray, decodeBoolean, decodeBooleanArray, decodeBox, decodeBoxArray, decodeBytea, decodeByteaArray, decodeCircle, decodeCircleArray, decodeDate, decodeDateArray, decodeDatetime, decodeDatetimeArray, decodeFloat, decodeFloatArray, decodeInt, decodeIntArray, decodeJson, decodeJsonArray, decodeLine, decodeLineArray, decodeLineSegment, decodeLineSegmentArray, decodePath, decodePathArray, decodePoint, decodePointArray, decodePolygon, decodePolygonArray, decodeStringArray, decodeTid, decodeTidArray,} from "./decoders.ts";import { ClientControls } from "../connection/connection_params.ts";import { parseArray } from "./array_parser.ts";
export class Column { constructor( public name: string, public tableOid: number, public index: number, public typeOid: number, public columnLength: number, public typeModifier: number, public format: Format, ) {}}
enum Format { TEXT = 0, BINARY = 1,}
const decoder = new TextDecoder();
function decodeBinary() { throw new Error("Decoding binary data is not implemented!");}
function decodeText(value: string, typeOid: number) { try { switch (typeOid) { case Oid.bpchar: case Oid.char: case Oid.cidr: case Oid.float8: case Oid.inet: case Oid.macaddr: case Oid.name: case Oid.numeric: case Oid.oid: case Oid.regclass: case Oid.regconfig: case Oid.regdictionary: case Oid.regnamespace: case Oid.regoper: case Oid.regoperator: case Oid.regproc: case Oid.regprocedure: case Oid.regrole: case Oid.regtype: case Oid.text: case Oid.time: case Oid.timetz: case Oid.uuid: case Oid.varchar: case Oid.void: return value; case Oid.bpchar_array: case Oid.char_array: case Oid.cidr_array: case Oid.float8_array: case Oid.inet_array: case Oid.macaddr_array: case Oid.name_array: case Oid.numeric_array: case Oid.oid_array: case Oid.regclass_array: case Oid.regconfig_array: case Oid.regdictionary_array: case Oid.regnamespace_array: case Oid.regoper_array: case Oid.regoperator_array: case Oid.regproc_array: case Oid.regprocedure_array: case Oid.regrole_array: case Oid.regtype_array: case Oid.text_array: case Oid.time_array: case Oid.timetz_array: case Oid.uuid_array: case Oid.varchar_array: return decodeStringArray(value); case Oid.float4: return decodeFloat(value); case Oid.float4_array: return decodeFloatArray(value); case Oid.int2: case Oid.int4: case Oid.xid: return decodeInt(value); case Oid.int2_array: case Oid.int4_array: case Oid.xid_array: return decodeIntArray(value); case Oid.bool: return decodeBoolean(value); case Oid.bool_array: return decodeBooleanArray(value); case Oid.box: return decodeBox(value); case Oid.box_array: return decodeBoxArray(value); case Oid.circle: return decodeCircle(value); case Oid.circle_array: return decodeCircleArray(value); case Oid.bytea: return decodeBytea(value); case Oid.byte_array: return decodeByteaArray(value); case Oid.date: return decodeDate(value); case Oid.date_array: return decodeDateArray(value); case Oid.int8: return decodeBigint(value); case Oid.int8_array: return decodeBigintArray(value); case Oid.json: case Oid.jsonb: return decodeJson(value); case Oid.json_array: case Oid.jsonb_array: return decodeJsonArray(value); case Oid.line: return decodeLine(value); case Oid.line_array: return decodeLineArray(value); case Oid.lseg: return decodeLineSegment(value); case Oid.lseg_array: return decodeLineSegmentArray(value); case Oid.path: return decodePath(value); case Oid.path_array: return decodePathArray(value); case Oid.point: return decodePoint(value); case Oid.point_array: return decodePointArray(value); case Oid.polygon: return decodePolygon(value); case Oid.polygon_array: return decodePolygonArray(value); case Oid.tid: return decodeTid(value); case Oid.tid_array: return decodeTidArray(value); case Oid.timestamp: case Oid.timestamptz: return decodeDatetime(value); case Oid.timestamp_array: case Oid.timestamptz_array: return decodeDatetimeArray(value); default: return value; } } catch (_e) { console.error( bold(yellow(`Error decoding type Oid ${typeOid} value`)) + _e.message + "\n" + bold("Defaulting to null."), ); return null; }}
export function decode( value: Uint8Array, column: Column, controls?: ClientControls,) { const strValue = decoder.decode(value);
if (controls?.decoders) { const oidType = OidTypes[column.typeOid as OidValue]; const decoderFunc = controls.decoders?.[column.typeOid] || controls.decoders?.[oidType];
if (decoderFunc) { return decoderFunc(strValue, column.typeOid, parseArray); } else if (oidType?.includes("_array")) { const baseOidType = oidType.replace("_array", "") as OidType; if (baseOidType in Oid) { const decoderFunc = controls.decoders?.[Oid[baseOidType]] || controls.decoders?.[baseOidType]; if (decoderFunc) { return parseArray( strValue, (value: string) => decoderFunc(value, column.typeOid, parseArray), ); } } } }
if (controls?.decodeStrategy === "string") { return strValue; }
if (column.format === Format.BINARY) { return decodeBinary(); } else if (column.format === Format.TEXT) { return decodeText(strValue, column.typeOid); } else { throw new Error(`Unknown column format: ${column.format}`); }}