Skip to content

Commit

Permalink
Add ParameterDescription message to pg-protocol (#2464)
Browse files Browse the repository at this point in the history
  • Loading branch information
spacedentist authored Apr 6, 2021
1 parent 3dc79b6 commit 6121bd3
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 0 deletions.
35 changes: 35 additions & 0 deletions packages/pg-protocol/src/inbound-parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down Expand Up @@ -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, {
Expand Down
9 changes: 9 additions & 0 deletions packages/pg-protocol/src/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type MessageName =
| 'copyDone'
| 'copyData'
| 'rowDescription'
| 'parameterDescription'
| 'parameterStatus'
| 'backendKeyData'
| 'notification'
Expand Down Expand Up @@ -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(
Expand Down
14 changes: 14 additions & 0 deletions packages/pg-protocol/src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
CopyResponse,
NotificationResponseMessage,
RowDescriptionMessage,
ParameterDescriptionMessage,
Field,
DataRowMessage,
ParameterStatusMessage,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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()
Expand Down
10 changes: 10 additions & 0 deletions packages/pg-protocol/src/testing/test-buffers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit 6121bd3

Please sign in to comment.