Skip to content

Commit 876018e

Browse files
rpedelabrianc
rpedela
authored andcommitted
Add support for PQescapeLiteral and PQescapeIdentifier. Also add JS versions of the functions.
1 parent a1816ed commit 876018e

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

lib/client.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,52 @@ Client.prototype.cancel = function(client, query) {
213213
}
214214
};
215215

216+
// Ported from PostgreSQL 9.2.4 source code in src/interfaces/libpq/fe-exec.c
217+
Client.prototype.escapeIdentifier = function(str) {
218+
219+
var escaped = '"';
220+
221+
for(var i = 0; i < str.length; i++) {
222+
var c = str[i];
223+
if(c === '"') {
224+
escaped += c + c;
225+
} else {
226+
escaped += c;
227+
}
228+
}
229+
230+
escaped += '"';
231+
232+
return escaped;
233+
}
234+
235+
// Ported from PostgreSQL 9.2.4 source code in src/interfaces/libpq/fe-exec.c
236+
Client.prototype.escapeLiteral = function(str) {
237+
238+
var hasBackslash = false;
239+
var escaped = '\'';
240+
241+
for(var i = 0; i < str.length; i++) {
242+
var c = str[i];
243+
if(c === '\'') {
244+
escaped += c + c;
245+
} else if (c === '\\') {
246+
escaped += c + c;
247+
hasBackslash = true;
248+
} else {
249+
escaped += c;
250+
}
251+
}
252+
253+
escaped += '\'';
254+
255+
if(hasBackslash === true) {
256+
escaped = ' E' + escaped;
257+
}
258+
259+
return escaped;
260+
}
261+
216262
Client.prototype._pulseQueryQueue = function() {
217263
if(this.readyForQuery===true) {
218264
this.activeQuery = this.queryQueue.shift();

src/binding.cc

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class Connection : public ObjectWrap {
6767
command_symbol = NODE_PSYMBOL("command");
6868

6969
NODE_SET_PROTOTYPE_METHOD(t, "connect", Connect);
70+
NODE_SET_PROTOTYPE_METHOD(t, "escapeIdentifier", EscapeIdentifier);
71+
NODE_SET_PROTOTYPE_METHOD(t, "escapeLiteral", EscapeLiteral);
7072
NODE_SET_PROTOTYPE_METHOD(t, "_sendQuery", SendQuery);
7173
NODE_SET_PROTOTYPE_METHOD(t, "_sendQueryWithParams", SendQueryWithParams);
7274
NODE_SET_PROTOTYPE_METHOD(t, "_sendPrepare", SendPrepare);
@@ -130,6 +132,48 @@ class Connection : public ObjectWrap {
130132
return Undefined();
131133
}
132134

135+
//v8 entry point into Connection#escapeIdentifier
136+
static Handle<Value>
137+
EscapeIdentifier(const Arguments& args)
138+
{
139+
HandleScope scope;
140+
Connection *self = ObjectWrap::Unwrap<Connection>(args.This());
141+
142+
char* inputStr = MallocCString(args[0]);
143+
char* escapedStr = self->EscapeIdentifier(inputStr);
144+
free(inputStr);
145+
146+
if(escapedStr == NULL) {
147+
THROW(self->GetLastError());
148+
}
149+
150+
Local<Value> jsStr = String::New(escapedStr, strlen(escapedStr));
151+
PQfreemem(escapedStr);
152+
153+
return scope.Close(jsStr);
154+
}
155+
156+
//v8 entry point into Connection#escapeLiteral
157+
static Handle<Value>
158+
EscapeLiteral(const Arguments& args)
159+
{
160+
HandleScope scope;
161+
Connection *self = ObjectWrap::Unwrap<Connection>(args.This());
162+
163+
char* inputStr = MallocCString(args[0]);
164+
char* escapedStr = self->EscapeLiteral(inputStr);
165+
free(inputStr);
166+
167+
if(escapedStr == NULL) {
168+
THROW(self->GetLastError());
169+
}
170+
171+
Local<Value> jsStr = String::New(escapedStr, strlen(escapedStr));
172+
PQfreemem(escapedStr);
173+
174+
return scope.Close(jsStr);
175+
}
176+
133177
//v8 entry point into Connection#_sendQuery
134178
static Handle<Value>
135179
SendQuery(const Arguments& args)
@@ -307,6 +351,18 @@ class Connection : public ObjectWrap {
307351
return args.This();
308352
}
309353

354+
char * EscapeIdentifier(const char *str)
355+
{
356+
TRACE("js::EscapeIdentifier")
357+
return PQescapeIdentifier(connection_, str, strlen(str));
358+
}
359+
360+
char * EscapeLiteral(const char *str)
361+
{
362+
TRACE("js::EscapeLiteral")
363+
return PQescapeLiteral(connection_, str, strlen(str));
364+
}
365+
310366
int Send(const char *queryText)
311367
{
312368
TRACE("js::Send")

0 commit comments

Comments
 (0)