Add ParameterDescription message to pg-protocol (#2464)

This commit is contained in:
Sven Over 2021-04-06 15:01:04 +01:00 committed by GitHub
parent 3dc79b605c
commit 6121bd3bb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 0 deletions

View File

@ -144,6 +144,35 @@ var expectedTwoRowMessage = {
],
}
var emptyParameterDescriptionBuffer = new BufferList()
.addInt16(0) // number of parameters
.join(true, 't')
var oneParameterDescBuf = buffers.parameterDescription([1111])
var twoParameterDescBuf = buffers.parameterDescription([2222, 3333])
var expectedEmptyParameterDescriptionMessage = {
name: 'parameterDescription',
length: 6,
parameterCount: 0,
dataTypeIDs: [],
}
var expectedOneParameterMessage = {
name: 'parameterDescription',
length: 10,
parameterCount: 1,
dataTypeIDs: [1111],
}
var expectedTwoParameterMessage = {
name: 'parameterDescription',
length: 14,
parameterCount: 2,
dataTypeIDs: [2222, 3333],
}
var testForMessage = function (buffer: Buffer, expectedMessage: any) {
it('recieves and parses ' + expectedMessage.name, async () => {
const messages = await parseBuffers([buffer])
@ -245,6 +274,12 @@ describe('PgPacketStream', function () {
testForMessage(twoRowBuf, expectedTwoRowMessage)
})
describe('parameterDescription messages', function () {
testForMessage(emptyParameterDescriptionBuffer, expectedEmptyParameterDescriptionMessage)
testForMessage(oneParameterDescBuf, expectedOneParameterMessage)
testForMessage(twoParameterDescBuf, expectedTwoParameterMessage)
})
describe('parsing rows', function () {
describe('parsing empty row', function () {
testForMessage(emptyRowFieldBuf, {

View File

@ -11,6 +11,7 @@ export type MessageName =
| 'copyDone'
| 'copyData'
| 'rowDescription'
| 'parameterDescription'
| 'parameterStatus'
| 'backendKeyData'
| 'notification'
@ -152,6 +153,14 @@ export class RowDescriptionMessage {
}
}
export class ParameterDescriptionMessage {
public readonly name: MessageName = 'parameterDescription'
public readonly dataTypeIDs: number[]
constructor(public readonly length: number, public readonly parameterCount: number) {
this.dataTypeIDs = new Array(this.parameterCount)
}
}
export class ParameterStatusMessage {
public readonly name: MessageName = 'parameterStatus'
constructor(

View File

@ -15,6 +15,7 @@ import {
CopyResponse,
NotificationResponseMessage,
RowDescriptionMessage,
ParameterDescriptionMessage,
Field,
DataRowMessage,
ParameterStatusMessage,
@ -62,6 +63,7 @@ const enum MessageCodes {
ErrorMessage = 0x45, // E
NoticeMessage = 0x4e, // N
RowDescriptionMessage = 0x54, // T
ParameterDescriptionMessage = 0x74, // t
PortalSuspended = 0x73, // s
ReplicationStart = 0x57, // W
EmptyQuery = 0x49, // I
@ -188,6 +190,8 @@ export class Parser {
return this.parseErrorMessage(offset, length, bytes, 'notice')
case MessageCodes.RowDescriptionMessage:
return this.parseRowDescriptionMessage(offset, length, bytes)
case MessageCodes.ParameterDescriptionMessage:
return this.parseParameterDescriptionMessage(offset, length, bytes)
case MessageCodes.CopyIn:
return this.parseCopyInMessage(offset, length, bytes)
case MessageCodes.CopyOut:
@ -264,6 +268,16 @@ export class Parser {
return new Field(name, tableID, columnID, dataTypeID, dataTypeSize, dataTypeModifier, mode)
}
private parseParameterDescriptionMessage(offset: number, length: number, bytes: Buffer) {
this.reader.setBuffer(offset, bytes)
const parameterCount = this.reader.int16()
const message = new ParameterDescriptionMessage(length, parameterCount)
for (let i = 0; i < parameterCount; i++) {
message.dataTypeIDs[i] = this.reader.int32()
}
return message
}
private parseDataRowMessage(offset: number, length: number, bytes: Buffer) {
this.reader.setBuffer(offset, bytes)
const fieldCount = this.reader.int16()

View File

@ -62,6 +62,16 @@ const buffers = {
return buf.join(true, 'T')
},
parameterDescription: function (dataTypeIDs: number[]) {
dataTypeIDs = dataTypeIDs || []
var buf = new BufferList()
buf.addInt16(dataTypeIDs.length)
dataTypeIDs.forEach(function (dataTypeID) {
buf.addInt32(dataTypeID)
})
return buf.join(true, 't')
},
dataRow: function (columns: any[]) {
columns = columns || []
var buf = new BufferList()