Merge pull request #447 from eugeneware/buffer-params
Bind Buffer Variables as binary values (with Native implementation also)
This commit is contained in:
commit
aea984f7bc
@ -209,15 +209,27 @@ Connection.prototype.bind = function(config, more) {
|
||||
config.binary = config.binary || false;
|
||||
var values = config.values || [];
|
||||
var len = values.length;
|
||||
var useBinary = false;
|
||||
for (var j = 0; j < len; j++)
|
||||
useBinary |= values[j] instanceof Buffer;
|
||||
var buffer = this.writer
|
||||
.addCString(config.portal)
|
||||
.addCString(config.statement)
|
||||
.addInt16(0) //always use default text format
|
||||
.addInt16(len); //number of parameters
|
||||
.addCString(config.statement);
|
||||
if (!useBinary)
|
||||
buffer.addInt16(0);
|
||||
else {
|
||||
buffer.addInt16(len);
|
||||
for (j = 0; j < len; j++)
|
||||
buffer.addInt16(values[j] instanceof Buffer);
|
||||
}
|
||||
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);
|
||||
|
@ -46,6 +46,9 @@ function arrayString(val) {
|
||||
//note: you can override this function to provide your own conversion mechanism
|
||||
//for complex types, etc...
|
||||
var prepareValue = function(val) {
|
||||
if (val instanceof Buffer) {
|
||||
return val;
|
||||
}
|
||||
if(val instanceof Date) {
|
||||
return dateToString(val);
|
||||
}
|
||||
|
@ -922,9 +922,17 @@ private:
|
||||
paramValues[i] = cString;
|
||||
} else if(val->IsNull()) {
|
||||
paramValues[i] = NULL;
|
||||
} else if(val->IsObject() && Buffer::HasInstance(val)) {
|
||||
char *cHexString = MallocCHexString(val->ToObject());
|
||||
if(!cHexString) {
|
||||
LOG("ArgToCStringArray: OUT OF MEMORY OR SOMETHING BAD!");
|
||||
ReleaseCStringArray(paramValues, i-1);
|
||||
return 0;
|
||||
}
|
||||
paramValues[i] = cHexString;
|
||||
} else {
|
||||
//a paramter was not a string
|
||||
LOG("Parameter not a string");
|
||||
LOG("Parameter not a string or buffer");
|
||||
ReleaseCStringArray(paramValues, i-1);
|
||||
return 0;
|
||||
}
|
||||
@ -952,6 +960,27 @@ private:
|
||||
strcpy(cString, *utf8String);
|
||||
return cString;
|
||||
}
|
||||
|
||||
//helper function to Malloc a Bytea encoded Hex string from a buffer
|
||||
static char* MallocCHexString(v8::Handle<Object> buf)
|
||||
{
|
||||
char* bufferData = Buffer::Data(buf);
|
||||
size_t hexStringLen = Buffer::Length(buf)*2 + 3;
|
||||
char *cHexString = (char *) malloc(hexStringLen);
|
||||
if(!cHexString) {
|
||||
return cHexString;
|
||||
}
|
||||
strcpy(cHexString, "\\x");
|
||||
for (uint32_t i = 0, k = 2; k < hexStringLen; i += 1, k += 2) {
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
uint8_t val = static_cast<uint8_t>(bufferData[i]);
|
||||
cHexString[k + 0] = hex[val >> 4];
|
||||
cHexString[k + 1] = hex[val & 15];
|
||||
}
|
||||
cHexString[hexStringLen-1] = 0;
|
||||
return cHexString;
|
||||
}
|
||||
|
||||
void SendCopyFromChunk(Handle<Object> chunk) {
|
||||
PQputCopyData(connection_, Buffer::Data(chunk), Buffer::Length(chunk));
|
||||
}
|
||||
|
@ -116,6 +116,32 @@ test('bind messages', function() {
|
||||
});
|
||||
});
|
||||
|
||||
test('with named statement, portal, and buffer value', function() {
|
||||
con.bind({
|
||||
portal: 'bang',
|
||||
statement: 'woo',
|
||||
values: ['1', 'hi', null, new Buffer('zing', 'UTF-8')]
|
||||
});
|
||||
var expectedBuffer = new BufferList()
|
||||
.addCString('bang') //portal name
|
||||
.addCString('woo') //statement name
|
||||
.addInt16(4)//value count
|
||||
.addInt16(0)//string
|
||||
.addInt16(0)//string
|
||||
.addInt16(0)//string
|
||||
.addInt16(1)//binary
|
||||
.addInt16(4)
|
||||
.addInt32(1)
|
||||
.add(Buffer("1"))
|
||||
.addInt32(2)
|
||||
.add(Buffer("hi"))
|
||||
.addInt32(-1)
|
||||
.addInt32(4)
|
||||
.add(new Buffer('zing', 'UTF-8'))
|
||||
.addInt16(0)
|
||||
.join(true, 'B');
|
||||
assert.received(stream, expectedBuffer);
|
||||
});
|
||||
|
||||
test("sends execute message", function() {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user