pg-protocol
Advanced tools
Comparing version 1.3.0 to 1.4.0
@@ -9,3 +9,3 @@ "use strict"; | ||
this.headerPosition = 0; | ||
this.buffer = Buffer.alloc(size); | ||
this.buffer = Buffer.allocUnsafe(size); | ||
} | ||
@@ -19,3 +19,3 @@ ensure(size) { | ||
var newSize = oldBuffer.length + (oldBuffer.length >> 1) + size; | ||
this.buffer = Buffer.alloc(newSize); | ||
this.buffer = Buffer.allocUnsafe(newSize); | ||
oldBuffer.copy(this.buffer); | ||
@@ -22,0 +22,0 @@ } |
@@ -103,3 +103,7 @@ "use strict"; | ||
.addCString('woo') // statement name | ||
.addInt16(4) | ||
.addInt16(0) | ||
.addInt16(0) | ||
.addInt16(0) | ||
.addInt16(0) | ||
.addInt16(4) | ||
@@ -118,2 +122,26 @@ .addInt32(1) | ||
}); | ||
it('with custom valueMapper', function () { | ||
const actual = serializer_1.serialize.bind({ | ||
portal: 'bang', | ||
statement: 'woo', | ||
values: ['1', 'hi', null, 'zing'], | ||
valueMapper: () => null, | ||
}); | ||
var expectedBuffer = new buffer_list_1.default() | ||
.addCString('bang') // portal name | ||
.addCString('woo') // statement name | ||
.addInt16(4) | ||
.addInt16(0) | ||
.addInt16(0) | ||
.addInt16(0) | ||
.addInt16(0) | ||
.addInt16(4) | ||
.addInt32(-1) | ||
.addInt32(-1) | ||
.addInt32(-1) | ||
.addInt32(-1) | ||
.addInt16(0) | ||
.join(true, 'B'); | ||
assert_1.default.deepEqual(actual, expectedBuffer); | ||
}); | ||
it('with named statement, portal, and buffer value', function () { | ||
@@ -120,0 +148,0 @@ const actual = serializer_1.serialize.bind({ |
@@ -7,2 +7,3 @@ /// <reference types="node" /> | ||
}; | ||
declare type ValueMapper = (param: any, index: number) => any; | ||
declare type BindOpts = { | ||
@@ -13,2 +14,3 @@ portal?: string; | ||
values?: any[]; | ||
valueMapper?: ValueMapper; | ||
}; | ||
@@ -15,0 +17,0 @@ declare type ExecOpts = { |
@@ -63,2 +63,27 @@ "use strict"; | ||
}; | ||
const paramWriter = new buffer_writer_1.Writer(); | ||
const writeValues = function (values, valueMapper) { | ||
for (let i = 0; i < values.length; i++) { | ||
const mappedVal = valueMapper ? valueMapper(values[i], i) : values[i]; | ||
if (mappedVal == null) { | ||
// add the param type (string) to the writer | ||
writer.addInt16(0 /* STRING */); | ||
// write -1 to the param writer to indicate null | ||
paramWriter.addInt32(-1); | ||
} | ||
else if (mappedVal instanceof Buffer) { | ||
// add the param type (binary) to the writer | ||
writer.addInt16(1 /* BINARY */); | ||
// add the buffer to the param writer | ||
paramWriter.addInt32(mappedVal.length); | ||
paramWriter.add(mappedVal); | ||
} | ||
else { | ||
// add the param type (string) to the writer | ||
writer.addInt16(0 /* STRING */); | ||
paramWriter.addInt32(Buffer.byteLength(mappedVal)); | ||
paramWriter.addString(mappedVal); | ||
} | ||
} | ||
}; | ||
const bind = (config = {}) => { | ||
@@ -69,41 +94,11 @@ // normalize config | ||
const binary = config.binary || false; | ||
var values = config.values || emptyArray; | ||
var len = values.length; | ||
var useBinary = false; | ||
// TODO(bmc): all the loops in here aren't nice, we can do better | ||
for (var j = 0; j < len; j++) { | ||
useBinary = useBinary || values[j] instanceof Buffer; | ||
} | ||
var buffer = writer.addCString(portal).addCString(statement); | ||
if (!useBinary) { | ||
buffer.addInt16(0); | ||
} | ||
else { | ||
buffer.addInt16(len); | ||
for (j = 0; j < len; j++) { | ||
buffer.addInt16(values[j] instanceof Buffer ? 1 : 0); | ||
} | ||
} | ||
buffer.addInt16(len); | ||
for (var i = 0; i < len; i++) { | ||
var val = values[i]; | ||
if (val === null || typeof val === 'undefined') { | ||
buffer.addInt32(-1); | ||
} | ||
else if (val instanceof Buffer) { | ||
buffer.addInt32(val.length); | ||
buffer.add(val); | ||
} | ||
else { | ||
buffer.addInt32(Buffer.byteLength(val)); | ||
buffer.addString(val); | ||
} | ||
} | ||
if (binary) { | ||
buffer.addInt16(1); // format codes to use binary | ||
buffer.addInt16(1); | ||
} | ||
else { | ||
buffer.addInt16(0); // format codes to use text | ||
} | ||
const values = config.values || emptyArray; | ||
const len = values.length; | ||
writer.addCString(portal).addCString(statement); | ||
writer.addInt16(len); | ||
writeValues(values, config.valueMapper); | ||
writer.addInt16(len); | ||
writer.add(paramWriter.flush()); | ||
// format code | ||
writer.addInt16(binary ? 1 /* BINARY */ : 0 /* STRING */); | ||
return writer.flush(66 /* bind */); | ||
@@ -110,0 +105,0 @@ }; |
{ | ||
"name": "pg-protocol", | ||
"version": "1.3.0", | ||
"version": "1.4.0", | ||
"description": "The postgres client/server binary protocol, implemented in TypeScript", | ||
@@ -16,3 +16,3 @@ "main": "dist/index.js", | ||
"ts-node": "^8.5.4", | ||
"typescript": "^3.7.3" | ||
"typescript": "^4.0.3" | ||
}, | ||
@@ -26,3 +26,7 @@ "scripts": { | ||
}, | ||
"gitHead": "7ffe68eba056b9a6d0fa88f928aa85e768c28838" | ||
"files": [ | ||
"/dist/*{js,ts,map}", | ||
"/src" | ||
], | ||
"gitHead": "ec1dcab966ecb03080e75112f6d3623d1360b634" | ||
} |
@@ -8,3 +8,3 @@ //binary data writer tuned for encoding binary specific to the postgres binary protocol | ||
constructor(private size = 256) { | ||
this.buffer = Buffer.alloc(size) | ||
this.buffer = Buffer.allocUnsafe(size) | ||
} | ||
@@ -19,3 +19,3 @@ | ||
var newSize = oldBuffer.length + (oldBuffer.length >> 1) + size | ||
this.buffer = Buffer.alloc(newSize) | ||
this.buffer = Buffer.allocUnsafe(newSize) | ||
oldBuffer.copy(this.buffer) | ||
@@ -22,0 +22,0 @@ } |
@@ -113,3 +113,7 @@ import assert from 'assert' | ||
.addCString('woo') // statement name | ||
.addInt16(4) | ||
.addInt16(0) | ||
.addInt16(0) | ||
.addInt16(0) | ||
.addInt16(0) | ||
.addInt16(4) | ||
@@ -129,2 +133,27 @@ .addInt32(1) | ||
it('with custom valueMapper', function () { | ||
const actual = serialize.bind({ | ||
portal: 'bang', | ||
statement: 'woo', | ||
values: ['1', 'hi', null, 'zing'], | ||
valueMapper: () => null, | ||
}) | ||
var expectedBuffer = new BufferList() | ||
.addCString('bang') // portal name | ||
.addCString('woo') // statement name | ||
.addInt16(4) | ||
.addInt16(0) | ||
.addInt16(0) | ||
.addInt16(0) | ||
.addInt16(0) | ||
.addInt16(4) | ||
.addInt32(-1) | ||
.addInt32(-1) | ||
.addInt32(-1) | ||
.addInt32(-1) | ||
.addInt16(0) | ||
.join(true, 'B') | ||
assert.deepEqual(actual, expectedBuffer) | ||
}) | ||
it('with named statement, portal, and buffer value', function () { | ||
@@ -131,0 +160,0 @@ const actual = serialize.bind({ |
@@ -104,2 +104,4 @@ import { Writer } from './buffer-writer' | ||
type ValueMapper = (param: any, index: number) => any | ||
type BindOpts = { | ||
@@ -110,4 +112,37 @@ portal?: string | ||
values?: any[] | ||
// optional map from JS value to postgres value per parameter | ||
valueMapper?: ValueMapper | ||
} | ||
const paramWriter = new Writer() | ||
// make this a const enum so typescript will inline the value | ||
const enum ParamType { | ||
STRING = 0, | ||
BINARY = 1, | ||
} | ||
const writeValues = function (values: any[], valueMapper?: ValueMapper): void { | ||
for (let i = 0; i < values.length; i++) { | ||
const mappedVal = valueMapper ? valueMapper(values[i], i) : values[i] | ||
if (mappedVal == null) { | ||
// add the param type (string) to the writer | ||
writer.addInt16(ParamType.STRING) | ||
// write -1 to the param writer to indicate null | ||
paramWriter.addInt32(-1) | ||
} else if (mappedVal instanceof Buffer) { | ||
// add the param type (binary) to the writer | ||
writer.addInt16(ParamType.BINARY) | ||
// add the buffer to the param writer | ||
paramWriter.addInt32(mappedVal.length) | ||
paramWriter.add(mappedVal) | ||
} else { | ||
// add the param type (string) to the writer | ||
writer.addInt16(ParamType.STRING) | ||
paramWriter.addInt32(Buffer.byteLength(mappedVal)) | ||
paramWriter.addString(mappedVal) | ||
} | ||
} | ||
} | ||
const bind = (config: BindOpts = {}): Buffer => { | ||
@@ -118,40 +153,15 @@ // normalize config | ||
const binary = config.binary || false | ||
var values = config.values || emptyArray | ||
var len = values.length | ||
const values = config.values || emptyArray | ||
const len = values.length | ||
var useBinary = false | ||
// TODO(bmc): all the loops in here aren't nice, we can do better | ||
for (var j = 0; j < len; j++) { | ||
useBinary = useBinary || values[j] instanceof Buffer | ||
} | ||
writer.addCString(portal).addCString(statement) | ||
writer.addInt16(len) | ||
var buffer = writer.addCString(portal).addCString(statement) | ||
if (!useBinary) { | ||
buffer.addInt16(0) | ||
} else { | ||
buffer.addInt16(len) | ||
for (j = 0; j < len; j++) { | ||
buffer.addInt16(values[j] instanceof Buffer ? 1 : 0) | ||
} | ||
} | ||
buffer.addInt16(len) | ||
for (var i = 0; i < len; i++) { | ||
var val = values[i] | ||
if (val === null || typeof val === 'undefined') { | ||
buffer.addInt32(-1) | ||
} else if (val instanceof Buffer) { | ||
buffer.addInt32(val.length) | ||
buffer.add(val) | ||
} else { | ||
buffer.addInt32(Buffer.byteLength(val)) | ||
buffer.addString(val) | ||
} | ||
} | ||
writeValues(values, config.valueMapper) | ||
if (binary) { | ||
buffer.addInt16(1) // format codes to use binary | ||
buffer.addInt16(1) | ||
} else { | ||
buffer.addInt16(0) // format codes to use text | ||
} | ||
writer.addInt16(len) | ||
writer.add(paramWriter.flush()) | ||
// format code | ||
writer.addInt16(binary ? ParamType.BINARY : ParamType.STRING) | ||
return writer.flush(code.bind) | ||
@@ -158,0 +168,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
215788
51
4170