deno.land / x / pg_mem@2.8.1 / datatypes / t-jsonb.ts
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121import { DataType, nil, _IType } from '../interfaces-private.ts';import { TypeBase } from './datatype-base.ts';import { Evaluator } from '../evaluator.ts';import { deepCompare, deepEqual, errorMessage } from '../utils.ts';import { Types } from './datatypes.ts';import { JSON_NIL } from '../execution/clean-results.ts';import { QueryError } from '../interfaces.ts';import { jsonStringify as stringify} from 'https://deno.land/x/stable_stringify@v0.2.1/jsonStringify.ts';
export class JSONBType extends TypeBase<any> {
constructor(readonly primary: DataType) { super(); }
doCanCast(_to: _IType): boolean | nil { switch (_to.primary) { case DataType.text: case DataType.json: case DataType.jsonb: case DataType.float: case DataType.bool: case DataType.integer: return true; } return null; }
doCast(a: Evaluator, to: _IType): Evaluator { switch (to.primary) { case DataType.text: return a .setType(Types.text()) .setConversion(json => stringify(this.toResult(json)) , toJsonB => ({ toJsonB })) .cast(to) as Evaluator; // <== might need truncation case DataType.jsonb: case DataType.json: return a.setType(to); case DataType.float: case DataType.integer: const isInt = to.primary === DataType.integer; return a .setType(to) .setConversion(json => { if (json === JSON_NIL) { throw new QueryError('cannot cast jsonb null to type ' + (isInt ? 'integer' : 'double precision'), '22023'); } if (typeof json !== 'number') { throw new QueryError('cannot cast jsonb string to type ' + (isInt ? 'integer' : 'double precision'), '22023'); } return isInt ? Math.round(json) : json; }, toFloat => ({ toFloat })); case DataType.bool: return a .setType(to) .setConversion(json => { if (typeof json !== 'boolean') { throw new QueryError('cannot cast jsonb string to type boolean', '22023'); } return json; }, toFloat => ({ toFloat })); default: return a.setType(to); }
}
doCanBuildFrom(from: _IType) { switch (from.primary) { case DataType.text: return true; } return false; }
doBuildFrom(value: Evaluator, from: _IType): Evaluator<Date> | nil { switch (from.primary) { case DataType.text: return value .setConversion(raw => { try { return JSON.parse(raw, (_, x) => x ?? JSON_NIL) ?? JSON_NIL } catch (e) { throw new QueryError({ error: `invalid input syntax for type json`, details: errorMessage(e), code: '22P02', }); } } , toJsonb => ({ toJsonb })); } return null; }
doEquals(a: any, b: any): boolean { return deepEqual(this.toResult(a), this.toResult(b), false); }
doGt(a: any, b: any): boolean { return deepCompare(this.toResult(a), this.toResult(b)) > 0; }
doLt(a: any, b: any): boolean { return deepCompare(this.toResult(a), this.toResult(b)) < 0; }
toResult(result: any): any { return result === JSON_NIL ? null : result; }
}
Version Info