@worker-tools/deno-kv-storage
Version:
An implementation of the StorageArea (1,2,3) interface for Deno with an extensible system for supporting various database backends.
155 lines • 5.1 kB
JavaScript
import { Column } from "../query/decode.js";
import { PacketReader } from "./packet.js";
import { RowDescription } from "../query/query.js";
export class Message {
constructor(type, byteCount, body) {
Object.defineProperty(this, "type", {
enumerable: true,
configurable: true,
writable: true,
value: type
});
Object.defineProperty(this, "byteCount", {
enumerable: true,
configurable: true,
writable: true,
value: byteCount
});
Object.defineProperty(this, "body", {
enumerable: true,
configurable: true,
writable: true,
value: body
});
Object.defineProperty(this, "reader", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.reader = new PacketReader(body);
}
}
export function parseBackendKeyMessage(message) {
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) {
return message.reader.readString(message.byteCount);
}
/**
* https://www.postgresql.org/docs/14/protocol-error-fields.html
*/
export function parseNoticeMessage(message) {
// deno-lint-ignore no-explicit-any
const error_fields = {};
let byte;
let field_code;
let field_value;
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-any
export function parseRowDataMessage(message) {
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) {
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());
columns.push(column);
}
return new RowDescription(column_count, columns);
}
//# sourceMappingURL=message.js.map