Extremely Popular
Latest
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198import { Column } from "../query/decode.ts";import { PacketReader } from "./packet.ts";import { RowDescription } from "../query/query.ts";
export class Message { public reader: PacketReader;
constructor( public type: string, public byteCount: number, public body: Uint8Array, ) { this.reader = new PacketReader(body); }}
/** * The notice interface defining the fields of a notice message */export interface Notice { /** The notice severity level */ severity: string; /** The notice code */ code: string; /** The notice message */ message: string; /** The additional notice detail */ detail?: string; /** The notice hint descrip=bing possible ways to fix this notice */ hint?: string; /** The position of code that triggered the notice */ position?: string; /** The internal position of code that triggered the notice */ internalPosition?: string; /** The internal query that triggered the notice */ internalQuery?: string; /** The where metadata */ where?: string; /** The database schema */ schema?: string; /** The table name */ table?: string; /** The column name */ column?: string; /** The data type name */ dataType?: string; /** The constraint name */ constraint?: string; /** The file name */ file?: string; /** The line number */ line?: string; /** The routine name */ routine?: string;}
export function parseBackendKeyMessage(message: Message): { pid: number; secret_key: number;} { return { pid: message.reader.readInt32(), secret_key: message.reader.readInt32(), };}
/** * This function returns the command result tag from the command message */export function parseCommandCompleteMessage(message: Message): string { return message.reader.readString(message.byteCount);}
/** * https://www.postgresql.org/docs/14/protocol-error-fields.html */export function parseNoticeMessage(message: Message): Notice { // deno-lint-ignore no-explicit-any const error_fields: any = {};
let byte: number; let field_code: string; let field_value: string;
while ((byte = message.reader.readByte())) { field_code = String.fromCharCode(byte); field_value = message.reader.readCString();
switch (field_code) { case "S": error_fields.severity = field_value; break; case "C": error_fields.code = field_value; break; case "M": error_fields.message = field_value; break; case "D": error_fields.detail = field_value; break; case "H": error_fields.hint = field_value; break; case "P": error_fields.position = field_value; break; case "p": error_fields.internalPosition = field_value; break; case "q": error_fields.internalQuery = field_value; break; case "W": error_fields.where = field_value; break; case "s": error_fields.schema = field_value; break; case "t": error_fields.table = field_value; break; case "c": error_fields.column = field_value; break; case "d": error_fields.dataTypeName = field_value; break; case "n": error_fields.constraint = field_value; break; case "F": error_fields.file = field_value; break; case "L": error_fields.line = field_value; break; case "R": error_fields.routine = field_value; break; default: // from Postgres docs // > Since more field types might be added in future, // > frontends should silently ignore fields of unrecognized type. break; } }
return error_fields;}
/** * Parses a row data message into an array of bytes ready to be processed as column values */// TODO// Research corner cases where parseRowData can return null values// deno-lint-ignore no-explicit-anyexport function parseRowDataMessage(message: Message): any[] { const field_count = message.reader.readInt16(); const row = [];
for (let i = 0; i < field_count; i++) { const col_length = message.reader.readInt32();
if (col_length == -1) { row.push(null); continue; }
// reading raw bytes here, they will be properly parsed later row.push(message.reader.readBytes(col_length)); }
return row;}
export function parseRowDescriptionMessage(message: Message): RowDescription { const column_count = message.reader.readInt16(); const columns = [];
for (let i = 0; i < column_count; i++) { // TODO: if one of columns has 'format' == 'binary', // all of them will be in same format? const column = new Column( message.reader.readCString(), // name message.reader.readInt32(), // tableOid message.reader.readInt16(), // index message.reader.readInt32(), // dataTypeOid message.reader.readInt16(), // column message.reader.readInt32(), // typeModifier message.reader.readInt16(), // format ); columns.push(column); }
return new RowDescription(column_count, columns);}