named queries working & all tests passing

This commit is contained in:
brianc 2011-03-06 22:27:35 -06:00
parent 1fd718bd74
commit cabca209c7
3 changed files with 49 additions and 13 deletions

View File

@ -11,7 +11,7 @@ params := -u $(user) --password $(password) -p $(port) -d $(database) -h $(host)
node-command := xargs -n 1 -I file node file $(params) node-command := xargs -n 1 -I file node file $(params)
.PHONY : test test-connection test-integration bench test-native .PHONY : test test-connection test-integration bench test-native build/default/binding.node
test: test-unit test: test-unit
test-all: test-unit test-integration test-native test-all: test-unit test-integration test-native
@ -19,7 +19,7 @@ test-all: test-unit test-integration test-native
bench: bench:
@find benchmark -name "*-bench.js" | $(node-command) @find benchmark -name "*-bench.js" | $(node-command)
build/default/binding.node: src/binding.cc build/default/binding.node:
@node-waf configure build @node-waf configure build
test-unit: test-unit:

View File

@ -66,9 +66,14 @@ p._pulseQueryQueue = function() {
} }
this._activeQuery = query; this._activeQuery = query;
if(query.name) { if(query.name) {
if(this._namedQueries[query.name]) {
this._sendQueryPrepared(query.name, query.values||[]);
} else {
this._namedQuery = true; this._namedQuery = true;
this._namedQueries[query.name] = true;
this._sendPrepare(query.name, query.text, (query.values||[]).length); this._sendPrepare(query.name, query.text, (query.values||[]).length);
} }
}
else if(query.values) { else if(query.values) {
//call native function //call native function
this._sendQueryWithParams(query.text, query.values) this._sendQueryWithParams(query.text, query.values)
@ -82,6 +87,7 @@ var ctor = function(config) {
config = config || {}; config = config || {};
var connection = new Connection(); var connection = new Connection();
connection._queryQueue = []; connection._queryQueue = [];
connection._namedQueries = {};
connection._activeQuery = null; connection._activeQuery = null;
connection._config = utils.normalizeConnectionInfo(config); connection._config = utils.normalizeConnectionInfo(config);
connection.on('connect', function() { connection.on('connect', function() {
@ -103,10 +109,11 @@ var ctor = function(config) {
} }
}) })
connection.on('_readyForQuery', function() { connection.on('_readyForQuery', function() {
var q = this._activeQuery;
//a named query finished being prepared //a named query finished being prepared
if(this._namedQuery) { if(this._namedQuery) {
this._namedQuery = false; this._namedQuery = false;
connection. this._sendQueryPrepared(q.name, q.values||[]);
} else { } else {
connection._activeQuery.handleReadyForQuery(); connection._activeQuery.handleReadyForQuery();
connection._activeQuery = null; connection._activeQuery = null;

View File

@ -145,10 +145,6 @@ public:
Handle<Value> params = args[1]; Handle<Value> params = args[1];
if(!params->IsArray()) {
return ThrowException(Exception::Error(String::New("Values must be array")));
}
char* queryText = MallocCString(args[0]); char* queryText = MallocCString(args[0]);
Local<Array> jsParams = Local<Array>::Cast(args[1]); Local<Array> jsParams = Local<Array>::Cast(args[1]);
char** paramValues = ArgToCStringArray(jsParams); char** paramValues = ArgToCStringArray(jsParams);
@ -214,21 +210,22 @@ public:
return cString; return cString;
} }
//v8 entry point into Connection#_sendPrepare //v8 entry point into Connection#_sendPrepare(string queryName, string queryText, int nParams)
static Handle<Value> static Handle<Value>
SendPrepare(const Arguments& args) SendPrepare(const Arguments& args)
{ {
HandleScope scope; HandleScope scope;
return ThrowException(Exception::Error(String::New("Prepared named queries not implemented")));
Connection *self = ObjectWrap::Unwrap<Connection>(args.This()); Connection *self = ObjectWrap::Unwrap<Connection>(args.This());
String::Utf8Value queryName(args[0]); String::Utf8Value queryName(args[0]);
String::Utf8Value queryText(args[1]); String::Utf8Value queryText(args[1]);
int length = args[2]->Int32Value();
self->SendPrepare(*queryName, *queryText, 0); self->SendPrepare(*queryName, *queryText, length);
return Undefined(); return Undefined();
} }
//v8 entry point into Connection#_sendQueryPrepared(string queryName, string[] paramValues)
static Handle<Value> static Handle<Value>
SendQueryPrepared(const Arguments& args) SendQueryPrepared(const Arguments& args)
{ {
@ -236,6 +233,33 @@ public:
Connection *self = ObjectWrap::Unwrap<Connection>(args.This()); Connection *self = ObjectWrap::Unwrap<Connection>(args.This());
String::Utf8Value queryName(args[0]); String::Utf8Value queryName(args[0]);
//TODO this is much copy/pasta code
if(!args[0]->IsString()) {
return ThrowException(Exception::Error(String::New("First parameter must be a string query")));
}
if(!args[1]->IsArray()) {
return ThrowException(Exception::Error(String::New("Values must be array")));
}
Handle<Value> params = args[1];
char* queryText = MallocCString(args[0]);
Local<Array> jsParams = Local<Array>::Cast(args[1]);
char** paramValues = ArgToCStringArray(jsParams);
if(!paramValues) {
return ThrowException(Exception::Error(String::New("Something bad happened when allocating parameter array")));
}
int len = jsParams->Length();
int result = self->SendPreparedQuery(queryText, len, paramValues);
free(queryText);
Free(paramValues, len);
if(result == 1) {
return Undefined();
}
return ThrowException(Exception::Error(String::New("Could not dispatch parameterized query")));
return Undefined(); return Undefined();
} }
@ -300,6 +324,11 @@ protected:
return PQsendPrepare(connection_, name, command, nParams, NULL); return PQsendPrepare(connection_, name, command, nParams, NULL);
} }
int SendPreparedQuery(const char *name, int nParams, const char * const *paramValues)
{
return PQsendQueryPrepared(connection_, name, nParams, paramValues, NULL, NULL, 0);
}
//flushes socket //flushes socket
void Flush() void Flush()
{ {