Skip to content

Commit

Permalink
Add bindings for PQdescribePrepared, PQnparams and PQparamtype (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
akheron authored Jun 19, 2024
1 parent 14d7c03 commit 0d5d339
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 0 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ __sync__ sends a command to the server to execute a previously prepared statemen
- `statementName` is a required string of the name of the prepared statement.
- `parameters` are the parameters to pass to the prepared statement.

##### `pq.describePrepared(statementName:string)`
__sync__ sends a command to the server to describe a previously prepared statement. blocks until the results are returned. Use `pq.nparams` and `pq.paramtype` to obtain information about the parameters and `pq.nfields`, `pq.fname` and `pq.ftype` about the result columns of the prepared statement.

### Async Command Execution Functions

In libpq the async command execution functions _only_ dispatch a request to the backend to run a query. They do not start result fetching on their own. Because libpq is a C api there is a somewhat complicated "dance" to retrieve the result information in a non-blocking way. node-libpq attempts to do as little as possible to abstract over this; therefore, the following functions are only part of the story. For a complete tutorial on how to dispatch & retrieve results from libpq in an async way you can [view the complete approach here](https://github.com/brianc/node-pg-native/blob/master/index.js#L105)
Expand Down Expand Up @@ -190,6 +193,14 @@ Retrieve the text value at a given tuple (row) and field (column) offset. Both o

Returns `true` if the value at the given offsets is actually `null`. Otherwise returns `false`. This is because `pq.getvalue()` returns an empty string for both an actual empty string and for a `null` value. Weird, huh?

##### `pq.nparams():int`

Returns the number of parameters a prepared statement expects.

##### `pq.paramtype(paramNumber:int):int`

Returns the `Oid` of the prepared statement's parameter at the given offset.

##### `pq.cmdStatus():string`

Returns the status string associated with a result. Something akin to `INSERT 3 0` if you inserted 3 rows.
Expand Down
20 changes: 20 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@ PQ.prototype.execPrepared = function (statementName, parameters) {
this.$execPrepared(statementName, parameters);
};

//SYNC describes a named, prepared query and stores the result
//immediately stores the results within the PQ object for consumption with
//nparams, paramtype, nfields, etc...
PQ.prototype.describePrepared = function(statementName) {
if(!statementName) {
statementName = '';
}
this.$describePrepared(statementName);
};

//send a command to begin executing a query in async mode
//returns true if sent, or false if there was a send failure
PQ.prototype.sendQuery = function (commandText) {
Expand Down Expand Up @@ -257,6 +267,16 @@ PQ.prototype.getisnull = function (row, col) {
return this.$getisnull(row, col);
};

//returns the number of parameters of a prepared statement
PQ.prototype.nparams = function() {
return this.$nparams();
};

//returns the data type of the indicated statement parameter (starting from 0)
PQ.prototype.paramtype = function(n) {
return this.$paramtype(n);
};

//returns the status of the command
PQ.prototype.cmdStatus = function () {
return this.$cmdStatus();
Expand Down
3 changes: 3 additions & 0 deletions src/addon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ NAN_MODULE_INIT(InitAddon) {
Nan::SetPrototypeMethod(tpl, "$execParams", Connection::ExecParams);
Nan::SetPrototypeMethod(tpl, "$prepare", Connection::Prepare);
Nan::SetPrototypeMethod(tpl, "$execPrepared", Connection::ExecPrepared);
Nan::SetPrototypeMethod(tpl, "$describePrepared", Connection::DescribePrepared);

//async query functions
Nan::SetPrototypeMethod(tpl, "$sendQuery", Connection::SendQuery);
Expand Down Expand Up @@ -49,6 +50,8 @@ NAN_MODULE_INIT(InitAddon) {
Nan::SetPrototypeMethod(tpl, "$ftype", Connection::Ftype);
Nan::SetPrototypeMethod(tpl, "$getvalue", Connection::Getvalue);
Nan::SetPrototypeMethod(tpl, "$getisnull", Connection::Getisnull);
Nan::SetPrototypeMethod(tpl, "$nparams", Connection::Nparams);
Nan::SetPrototypeMethod(tpl, "$paramtype", Connection::Paramtype);
Nan::SetPrototypeMethod(tpl, "$cmdStatus", Connection::CmdStatus);
Nan::SetPrototypeMethod(tpl, "$cmdTuples", Connection::CmdTuples);
Nan::SetPrototypeMethod(tpl, "$resultStatus", Connection::ResultStatus);
Expand Down
37 changes: 37 additions & 0 deletions src/connection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,21 @@ NAN_METHOD(Connection::ExecPrepared) {
self->SetLastResult(result);
}

NAN_METHOD(Connection::DescribePrepared) {
Connection *self = NODE_THIS();

Nan::Utf8String statementName(info[0]);

TRACEF("Connection::DescribePrepared: %s\n", *statementName);

PGresult* result = PQdescribePrepared(
self->pq,
*statementName
);

self->SetLastResult(result);
}


NAN_METHOD(Connection::Clear) {
TRACE("Connection::Clear");
Expand Down Expand Up @@ -282,6 +297,28 @@ NAN_METHOD(Connection::Getisnull) {
info.GetReturnValue().Set(rowValue == 1);
}

NAN_METHOD(Connection::Nparams) {
TRACE("Connection::Nparams");
Connection *self = NODE_THIS();

PGresult* res = self->lastResult;

int nparams = PQnparams(res);

info.GetReturnValue().Set(nparams);
}

NAN_METHOD(Connection::Paramtype) {
TRACE("Connection::Paramtype");
Connection *self = NODE_THIS();

PGresult* res = self->lastResult;

int paramType = PQparamtype(res, Nan::To<int32_t>(info[0]).FromJust());

info.GetReturnValue().Set(paramType);
}

NAN_METHOD(Connection::CmdStatus) {
TRACE("Connection::CmdStatus");
Connection *self = NODE_THIS();
Expand Down
3 changes: 3 additions & 0 deletions src/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Connection : public Nan::ObjectWrap {
static NAN_METHOD(ExecParams);
static NAN_METHOD(Prepare);
static NAN_METHOD(ExecPrepared);
static NAN_METHOD(DescribePrepared);
static NAN_METHOD(Clear);
static NAN_METHOD(Ntuples);
static NAN_METHOD(Nfields);
Expand All @@ -26,6 +27,8 @@ class Connection : public Nan::ObjectWrap {
static NAN_METHOD(Ftype);
static NAN_METHOD(Getvalue);
static NAN_METHOD(Getisnull);
static NAN_METHOD(Nparams);
static NAN_METHOD(Paramtype);
static NAN_METHOD(CmdStatus);
static NAN_METHOD(CmdTuples);
static NAN_METHOD(ResultStatus);
Expand Down
11 changes: 11 additions & 0 deletions test/sync-prepare.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,15 @@ describe('prepare and execPrepared', function () {
);
});
});

describe('describing a prepared statement', function() {
it('works properly', function() {
this.pq.describePrepared(statementName);
assert.strictEqual(this.pq.nparams(), 1)
assert.strictEqual(this.pq.paramtype(0), 25)
assert.strictEqual(this.pq.nfields(), 1);
assert.strictEqual(this.pq.fname(0), 'name');
assert.strictEqual(this.pq.ftype(0), 25);
});
});
});

0 comments on commit 0d5d339

Please sign in to comment.