1 /*
2 * Copyright (c) 2009 - 2020, Micro Systems Marc Balmer, CH-5073 Gipf-Oberfrick
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Micro Systems Marc Balmer nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 /* PostgreSQL extension module (using Lua) */
29
30 #ifdef __APPLE__
31 #include <libkern/OSByteOrder.h>
32 #define htobe64(x) OSSwapHostToBigInt64(x)
33 #elif __FreeBSD__
34 #include <sys/endian.h>
35 #elif __linux__
36 #include <endian.h>
37 #endif
38 #include <stdlib.h>
39 #include <stdint.h>
40 #include <string.h>
41
42 #include <libpq-fe.h>
43 #include <libpq/libpq-fs.h>
44 #include <pg_config.h>
45
46 #include <lua.h>
47 #include <lauxlib.h>
48 #include <lualib.h>
49
50 #include "luapgsql.h"
51
52 #if LUA_VERSION_NUM < 502
53 #define lua_setuservalue lua_setfenv
54 #define lua_getuservalue lua_getfenv
55
56 static void
luaL_setmetatable(lua_State * L,const char * tname)57 luaL_setmetatable(lua_State *L, const char *tname)
58 {
59 luaL_getmetatable(L, tname);
60 lua_setmetatable(L, -2);
61 }
62 #endif
63
64 /*
65 * Garbage collected memory
66 */
67 static void *
gcmalloc(lua_State * L,size_t size)68 gcmalloc(lua_State *L, size_t size)
69 {
70 void **p;
71
72 p = lua_newuserdata(L, size);
73 *p = NULL;
74 luaL_setmetatable(L, GCMEM_METATABLE);
75 return p;
76 }
77
78 /* Memory can be free'ed immediately or left to the garbage collector */
79 static void
gcfree(void * p)80 gcfree(void *p)
81 {
82 void **mem = (void **)p;
83 PQfreemem(*mem);
84 *mem = NULL;
85 }
86
87 static int
gcmem_clear(lua_State * L)88 gcmem_clear(lua_State *L)
89 {
90 void **p = luaL_checkudata(L, 1, GCMEM_METATABLE);
91 PQfreemem(*p);
92 *p = NULL;
93 return 0;
94 }
95
96 /*
97 * Create a new connection object with a uservalue table
98 */
99 static PGconn **
pgsql_conn_new(lua_State * L)100 pgsql_conn_new(lua_State *L) {
101 PGconn **data;
102
103 data = lua_newuserdata(L, sizeof(PGconn *));
104 *data = NULL;
105 lua_newtable(L);
106 lua_setuservalue(L, -2);
107 luaL_setmetatable(L, CONN_METATABLE);
108 return data;
109 }
110
111 /*
112 * Database Connection Control Functions
113 */
114 static int
pgsql_connectdb(lua_State * L)115 pgsql_connectdb(lua_State *L)
116 {
117 PGconn **data;
118 const char *cstr;
119
120 cstr = luaL_checkstring(L, 1);
121 data = pgsql_conn_new(L);
122
123 *data = PQconnectdb(cstr);
124 if (*data == NULL)
125 lua_pushnil(L);
126 return 1;
127 }
128
129 static int
pgsql_connectStart(lua_State * L)130 pgsql_connectStart(lua_State *L)
131 {
132 PGconn **data;
133 const char *cstr;
134
135 cstr = luaL_checkstring(L, 1);
136 data = pgsql_conn_new(L);
137 *data = PQconnectStart(cstr);
138
139 if (*data == NULL)
140 lua_pushnil(L);
141 return 1;
142 }
143
144 static PGconn *
pgsql_conn(lua_State * L,int n)145 pgsql_conn(lua_State *L, int n)
146 {
147 PGconn **data;
148
149 data = luaL_checkudata(L, n, CONN_METATABLE);
150 luaL_argcheck(L, *data != NULL, n, "database connection is finished");
151 return *data;
152 }
153
154 static int
pgsql_connectPoll(lua_State * L)155 pgsql_connectPoll(lua_State *L)
156 {
157 lua_pushinteger(L, PQconnectPoll(pgsql_conn(L, 1)));
158 return 1;
159 }
160
161 static int
pgsql_libVersion(lua_State * L)162 pgsql_libVersion(lua_State *L)
163 {
164 lua_pushinteger(L, PQlibVersion());
165 return 1;
166 }
167
168 #if PG_VERSION_NUM >= 90100
169 static int
pgsql_ping(lua_State * L)170 pgsql_ping(lua_State *L)
171 {
172 lua_pushinteger(L, PQping(luaL_checkstring(L, 1)));
173 return 1;
174 }
175 #endif
176
177 static int
pgsql_encryptPassword(lua_State * L)178 pgsql_encryptPassword(lua_State *L)
179 {
180 char const **pw;
181 const char *passwd, *user;
182
183 passwd = luaL_checkstring(L, 1);
184 user = luaL_checkstring(L, 2);
185 pw = gcmalloc(L, sizeof(char *));
186 *pw = PQencryptPassword(passwd, user);
187 lua_pushstring(L, *pw);
188 gcfree(pw);
189 return 1;
190 }
191
192 static int
pgsql_unescapeBytea(lua_State * L)193 pgsql_unescapeBytea(lua_State *L)
194 {
195 unsigned char **p;
196 size_t len;
197 const char *bytea;
198
199 bytea = luaL_checkstring(L, 1);
200 p = gcmalloc(L, sizeof(char *));
201 *p = PQunescapeBytea((const unsigned char *)bytea, &len);
202 if (*p == NULL)
203 lua_pushnil(L);
204 else {
205 lua_pushlstring(L, (const char *)*p, len);
206 gcfree(p);
207 }
208 return 1;
209 }
210
211 static int
pgsql_initOpenSSL(lua_State * L)212 pgsql_initOpenSSL(lua_State *L)
213 {
214 PQinitOpenSSL(lua_toboolean(L, 1), lua_toboolean(L, 2));
215 return 0;
216 }
217
218 static int
conn_finish(lua_State * L)219 conn_finish(lua_State *L)
220 {
221 PGconn **conn;
222
223 conn = luaL_checkudata(L, 1, CONN_METATABLE);
224 if (*conn) {
225 /*
226 * Check in the registry if a value has been stored at
227 * index '*conn'; if a value is found, don't close the
228 * connection.
229 * This mechanism can be used when the PostgreSQL connection
230 * object is provided to Lua from a C program that wants to
231 * ensure the connections stays open, even when the Lua
232 * program has terminated.
233 * To prevent the closing of the connection, use the following
234 * code to set a value in the registry at index '*conn' just
235 * before handing the connection object to Lua:
236 *
237 * PGconn *conn, **data;
238 *
239 * conn = PQconnectdb(...);
240 * data = lua_newuserdata(L, sizeof(PGconn *));
241 * *data = conn;
242 * lua_pushlightuserdata(L, *data);
243 * lua_pushboolean(L, 1);
244 * lua_settable(L, LUA_REGISTRYINDEX);
245 */
246 lua_pushlightuserdata(L, *conn);
247 lua_gettable(L, LUA_REGISTRYINDEX);
248 if (lua_isnil(L, -1)) {
249 PQfinish(*conn);
250 *conn = NULL;
251 /* clean out now invalidated keys from uservalue */
252 lua_getuservalue(L, 1);
253 lua_pushnil(L);
254 lua_setfield(L, -2, "trace_file");
255 }
256 }
257 return 0;
258 }
259
260 static int
conn_reset(lua_State * L)261 conn_reset(lua_State *L)
262 {
263 PQreset(pgsql_conn(L, 1));
264 return 0;
265 }
266
267 static int
conn_resetStart(lua_State * L)268 conn_resetStart(lua_State *L)
269 {
270 lua_pushboolean(L, PQresetStart(pgsql_conn(L, 1)));
271 return 1;
272 }
273
274 static int
conn_resetPoll(lua_State * L)275 conn_resetPoll(lua_State *L)
276 {
277 lua_pushinteger(L, PQresetPoll(pgsql_conn(L, 1)));
278 return 1;
279 }
280
281 /*
282 * Connection status functions
283 */
284 static int
conn_db(lua_State * L)285 conn_db(lua_State *L)
286 {
287 lua_pushstring(L, PQdb(pgsql_conn(L, 1)));
288 return 1;
289 }
290
291 static int
conn_user(lua_State * L)292 conn_user(lua_State *L)
293 {
294 lua_pushstring(L, PQuser(pgsql_conn(L, 1)));
295 return 1;
296 }
297
298 static int
conn_pass(lua_State * L)299 conn_pass(lua_State *L)
300 {
301 lua_pushstring(L, PQpass(pgsql_conn(L, 1)));
302 return 1;
303 }
304
305 static int
conn_host(lua_State * L)306 conn_host(lua_State *L)
307 {
308 lua_pushstring(L, PQhost(pgsql_conn(L, 1)));
309 return 1;
310 }
311
312 static int
conn_port(lua_State * L)313 conn_port(lua_State *L)
314 {
315 lua_pushstring(L, PQport(pgsql_conn(L, 1)));
316 return 1;
317 }
318
319 static int
conn_tty(lua_State * L)320 conn_tty(lua_State *L)
321 {
322 lua_pushstring(L, PQtty(pgsql_conn(L, 1)));
323 return 1;
324 }
325
326 static int
conn_options(lua_State * L)327 conn_options(lua_State *L)
328 {
329 lua_pushstring(L, PQoptions(pgsql_conn(L, 1)));
330 return 1;
331 }
332
333 static int
conn_status(lua_State * L)334 conn_status(lua_State *L)
335 {
336 PGconn **conn;
337
338 conn = luaL_checkudata(L, 1, CONN_METATABLE);
339 lua_pushinteger(L, PQstatus(*conn));
340 return 1;
341 }
342
343 static int
conn_transactionStatus(lua_State * L)344 conn_transactionStatus(lua_State *L)
345 {
346 lua_pushinteger(L, PQtransactionStatus(pgsql_conn(L, 1)));
347 return 1;
348 }
349
350 static int
conn_parameterStatus(lua_State * L)351 conn_parameterStatus(lua_State *L)
352 {
353 const char *status;
354
355 status = PQparameterStatus(pgsql_conn(L, 1), luaL_checkstring(L, 2));
356 if (status == NULL)
357 lua_pushnil(L);
358 else
359 lua_pushstring(L, status);
360 return 1;
361 }
362
363 static int
conn_protocolVersion(lua_State * L)364 conn_protocolVersion(lua_State *L)
365 {
366 lua_pushinteger(L, PQprotocolVersion(pgsql_conn(L, 1)));
367 return 1;
368 }
369
370 static int
conn_serverVersion(lua_State * L)371 conn_serverVersion(lua_State *L)
372 {
373 lua_pushinteger(L, PQserverVersion(pgsql_conn(L, 1)));
374 return 1;
375 }
376
377 static int
conn_errorMessage(lua_State * L)378 conn_errorMessage(lua_State *L)
379 {
380 lua_pushstring(L, PQerrorMessage(pgsql_conn(L, 1)));
381 return 1;
382 }
383
384 static int
conn_socket(lua_State * L)385 conn_socket(lua_State *L)
386 {
387 int fd;
388
389 fd = PQsocket(pgsql_conn(L, 1));
390 if (fd >= 0)
391 lua_pushinteger(L, fd);
392 else
393 lua_pushnil(L);
394 return 1;
395 }
396
397 static int
conn_backendPID(lua_State * L)398 conn_backendPID(lua_State *L)
399 {
400 lua_pushinteger(L, PQbackendPID(pgsql_conn(L, 1)));
401 return 1;
402 }
403
404 static int
conn_connectionNeedsPassword(lua_State * L)405 conn_connectionNeedsPassword(lua_State *L)
406 {
407 lua_pushboolean(L, PQconnectionNeedsPassword(pgsql_conn(L, 1)));
408 return 1;
409 }
410
411 static int
conn_connectionUsedPassword(lua_State * L)412 conn_connectionUsedPassword(lua_State *L)
413 {
414 lua_pushboolean(L, PQconnectionUsedPassword(pgsql_conn(L, 1)));
415 return 1;
416 }
417
418 #if PG_VERSION_NUM >= 90500
419 static int
conn_sslInUse(lua_State * L)420 conn_sslInUse(lua_State *L)
421 {
422 lua_pushboolean(L, PQsslInUse(pgsql_conn(L, 1)));
423 return 1;
424 }
425
426 static int
conn_sslAttribute(lua_State * L)427 conn_sslAttribute(lua_State *L)
428 {
429 lua_pushstring(L,
430 PQsslAttribute(pgsql_conn(L, 1), luaL_checkstring(L, 2)));
431 return 1;
432 }
433
434 static int
conn_sslAttributeNames(lua_State * L)435 conn_sslAttributeNames(lua_State *L)
436 {
437 const char * const *attribNames;
438 int k;
439
440 attribNames = PQsslAttributeNames(pgsql_conn(L, 1));
441 lua_newtable(L);
442 for (k = 1; *attribNames; k++, attribNames++) {
443 lua_pushinteger(L, k);
444 lua_pushstring(L, *attribNames);
445 lua_settable(L, -3);
446 }
447 return 1;
448 }
449 #endif
450
451 /*
452 * Command Execution Functions
453 */
454 static int
conn_exec(lua_State * L)455 conn_exec(lua_State *L)
456 {
457 PGconn *conn;
458 PGresult **res;
459 const char *command;
460
461 conn = pgsql_conn(L, 1);
462 command = luaL_checkstring(L, 2);
463
464 res = lua_newuserdata(L, sizeof(PGresult *));
465 *res = PQexec(conn, command);
466 if (*res == NULL)
467 lua_pushnil(L);
468 else
469 luaL_setmetatable(L, RES_METATABLE);
470 return 1;
471 }
472
473 static void
get_param(lua_State * L,int t,int n,Oid * paramTypes,char ** paramValues,int * paramLengths,int * paramFormats)474 get_param(lua_State *L, int t, int n, Oid *paramTypes, char **paramValues,
475 int *paramLengths, int *paramFormats)
476 {
477 switch (lua_type(L, t)) {
478 case LUA_TBOOLEAN:
479 if (paramTypes != NULL)
480 paramTypes[n] = BOOLOID;
481 if (paramValues != NULL) {
482 paramValues[n] = lua_newuserdata(L, sizeof(char));
483 *(char *)paramValues[n] = lua_toboolean(L, t);
484 paramLengths[n] = 1;
485 }
486 if (paramFormats != NULL)
487 paramFormats[n] = 1;
488 break;
489 case LUA_TNUMBER:
490 if (paramTypes != NULL) {
491 #if LUA_VERSION_NUM >= 503
492 if (lua_isinteger(L, t))
493 paramTypes[n] = INT8OID;
494 else
495 #endif
496 paramTypes[n] = FLOAT8OID;
497 }
498 if (paramValues != NULL) {
499 union {
500 double v;
501 uint64_t i;
502 } swap;
503
504 #if LUA_VERSION_NUM >= 503
505 if (lua_isinteger(L, t))
506 swap.i = lua_tointeger(L, t);
507 else
508 #endif
509 swap.v = lua_tonumber(L, t);
510 paramValues[n] = lua_newuserdata(L, sizeof(uint64_t));
511 *(uint64_t *)paramValues[n] = htobe64(swap.i);
512 paramLengths[n] = sizeof(uint64_t);
513 }
514 if (paramFormats != NULL)
515 paramFormats[n] = 1;
516 break;
517 case LUA_TSTRING:
518 if (paramTypes != NULL)
519 paramTypes[n] = TEXTOID;
520 if (paramValues != NULL) {
521 const char *s;
522 size_t len;
523
524 s = lua_tolstring(L, t, &len);
525 paramValues[n] = lua_newuserdata(L, len + 1);
526 /*
527 * lua_tolstring returns a string with '\0' after
528 * the last character.
529 */
530 memcpy(paramValues[n], s, len + 1);
531 }
532 if (paramFormats != NULL)
533 paramFormats[n] = 0;
534 break;
535 case LUA_TNIL:
536 if (paramTypes != NULL)
537 paramTypes[n] = 0;
538 if (paramValues != NULL)
539 paramValues[n] = NULL;
540 if (paramFormats != NULL)
541 paramFormats[n] = 0;
542 break;
543 default:
544 luaL_error(L, "unsupported PostgreSQL parameter type %s ("
545 "use table.unpack() for table types)", luaL_typename(L, t));
546 /* NOTREACHED */
547 }
548 }
549
550 static int
conn_execParams(lua_State * L)551 conn_execParams(lua_State *L)
552 {
553 PGconn *conn;
554 PGresult **res;
555 Oid *paramTypes;
556 char **paramValues;
557 const char *command;
558 int n, nParams, *paramLengths, *paramFormats;
559
560 conn = pgsql_conn(L, 1);
561 command = luaL_checkstring(L, 2);
562
563 nParams = lua_gettop(L) - 2; /* subtract connection and command */
564
565 if (nParams > 65535)
566 luaL_error(L, "number of parameters must not exceed 65535");
567
568 if (nParams) {
569 luaL_checkstack(L, 4 + nParams, "out of stack space");
570
571 paramTypes = lua_newuserdata(L, nParams * sizeof(Oid));
572 paramValues = lua_newuserdata(L, nParams * sizeof(char *));
573 paramLengths = lua_newuserdata(L, nParams * sizeof(int));
574 paramFormats = lua_newuserdata(L, nParams * sizeof(int));
575
576 for (n = 0; n < nParams; n++)
577 get_param(L, 3 + n, n, paramTypes, paramValues,
578 paramLengths, paramFormats);
579 } else {
580 paramTypes = NULL;
581 paramValues = NULL;
582 paramLengths = NULL;
583 paramFormats = NULL;
584 }
585 luaL_checkstack(L, 2, "out of stack space");
586 res = lua_newuserdata(L, sizeof(PGresult *));
587 *res = PQexecParams(conn, command, nParams, paramTypes,
588 (const char * const*)paramValues, paramLengths, paramFormats, 0);
589 if (*res == NULL)
590 lua_pushnil(L);
591 else
592 luaL_setmetatable(L, RES_METATABLE);
593 return 1;
594 }
595
596 static int
conn_prepare(lua_State * L)597 conn_prepare(lua_State *L)
598 {
599 PGconn *conn;
600 PGresult **res;
601 Oid *paramTypes;
602 const char *command, *name;
603 int n, nParams;
604
605 conn = pgsql_conn(L, 1);
606 command = luaL_checkstring(L, 2);
607 name = luaL_checkstring(L, 3);
608
609 nParams = lua_gettop(L) - 3; /* subtract connection, name, command */
610
611 if (nParams > 65535)
612 luaL_error(L, "number of parameters must not exceed 65535");
613
614 if (nParams) {
615 paramTypes = lua_newuserdata(L, nParams * sizeof(Oid));
616
617 for (n = 0; n < nParams; n++)
618 get_param(L, 4 + n, n, paramTypes, NULL, NULL, NULL);
619 } else
620 paramTypes = NULL;
621
622 res = lua_newuserdata(L, sizeof(PGresult *));
623 *res = PQprepare(conn, command, name, nParams, paramTypes);
624 if (*res == NULL)
625 lua_pushnil(L);
626 else
627 luaL_setmetatable(L, RES_METATABLE);
628 return 1;
629 }
630
631 static int
conn_execPrepared(lua_State * L)632 conn_execPrepared(lua_State *L)
633 {
634 PGconn *conn;
635 PGresult **res;
636 char **paramValues;
637 const char *command;
638 int n, nParams, *paramLengths, *paramFormats;
639
640 conn = pgsql_conn(L, 1);
641 command = luaL_checkstring(L, 2);
642
643 nParams = lua_gettop(L) - 2; /* subtract connection and name */
644
645 if (nParams > 65535)
646 luaL_error(L, "number of parameters must not exceed 65535");
647
648 if (nParams) {
649 luaL_checkstack(L, 3 + nParams, "out of stack space");
650
651 paramValues = lua_newuserdata(L, nParams * sizeof(char *));
652 paramLengths = lua_newuserdata(L, nParams * sizeof(int));
653 paramFormats = lua_newuserdata(L, nParams * sizeof(int));
654
655 for (n = 0; n < nParams; n++)
656 get_param(L, 3 + n, n, NULL, paramValues, paramLengths,
657 paramFormats);
658 } else {
659 paramValues = NULL;
660 paramLengths = NULL;
661 paramFormats = NULL;
662 }
663 luaL_checkstack(L, 2, "out of stack space");
664
665 res = lua_newuserdata(L, sizeof(PGresult *));
666 *res = PQexecPrepared(conn, command, nParams,
667 (const char * const*)paramValues, paramLengths, paramFormats, 0);
668 if (*res == NULL)
669 lua_pushnil(L);
670 else
671 luaL_setmetatable(L, RES_METATABLE);
672 return 1;
673 }
674
675 static int
conn_describePrepared(lua_State * L)676 conn_describePrepared(lua_State *L)
677 {
678 PGconn *conn;
679 PGresult **res;
680 const char *name;
681
682 conn = pgsql_conn(L, 1);
683 name = luaL_checkstring(L, 2);
684
685 res = lua_newuserdata(L, sizeof(PGresult *));
686 *res = PQdescribePrepared(conn, name);
687 if (*res == NULL)
688 lua_pushnil(L);
689 else
690 luaL_setmetatable(L, RES_METATABLE);
691 return 1;
692 }
693
694 static int
conn_describePortal(lua_State * L)695 conn_describePortal(lua_State *L)
696 {
697 PGconn *conn;
698 PGresult **res;
699 const char *name;
700
701 conn = pgsql_conn(L, 1);
702 name = luaL_checkstring(L, 2);
703
704 res = lua_newuserdata(L, sizeof(PGresult *));
705 *res = PQdescribePortal(conn, name);
706 if (*res == NULL)
707 lua_pushnil(L);
708 else
709 luaL_setmetatable(L, RES_METATABLE);
710 return 1;
711 }
712
713 static int
conn_escapeString(lua_State * L)714 conn_escapeString(lua_State *L)
715 {
716 PGconn *d;
717 size_t len;
718 char *buf;
719 const char *str;
720 int error;
721
722 d = pgsql_conn(L, 1);
723
724 str = lua_tolstring(L, 2, &len);
725 if (str == NULL) {
726 lua_pushnil(L);
727 return 1;
728 }
729 buf = lua_newuserdata(L, 2 * (len + 1));
730
731 PQescapeStringConn(d, buf, str, len, &error);
732 if (!error)
733 lua_pushstring(L, buf);
734 else
735 lua_pushnil(L);
736 return 1;
737 }
738
739 static int
conn_escapeLiteral(lua_State * L)740 conn_escapeLiteral(lua_State *L)
741 {
742 const char *s;
743 char **p;
744 PGconn *d;
745 size_t len;
746
747 d = pgsql_conn(L, 1);
748 s = luaL_checklstring(L, 2, &len);
749 p = gcmalloc(L, sizeof(char *));
750 *p = PQescapeLiteral(d, s, len);
751 lua_pushstring(L, *p);
752 gcfree(p);
753 return 1;
754 }
755
756 static int
conn_escapeIdentifier(lua_State * L)757 conn_escapeIdentifier(lua_State *L)
758 {
759 const char *s;
760 char **p;
761 PGconn *d;
762 size_t len;
763
764 d = pgsql_conn(L, 1);
765 s = luaL_checklstring(L, 2, &len);
766 p = gcmalloc(L, sizeof(char *));
767 *p = PQescapeIdentifier(d, s, len);
768 lua_pushstring(L, *p);
769 gcfree(p);
770 return 1;
771 }
772
773 static int
conn_escapeBytea(lua_State * L)774 conn_escapeBytea(lua_State *L)
775 {
776 unsigned char **p;
777 const unsigned char *s;
778 PGconn *d;
779 size_t from_length, to_length;
780
781 d = pgsql_conn(L, 1);
782 s = (const unsigned char *)luaL_checklstring(L, 2, &from_length);
783 p = gcmalloc(L, sizeof(char *));
784 *p = PQescapeByteaConn(d, s, from_length, &to_length);
785 if (*p) {
786 lua_pushlstring(L, (const char *)*p, to_length - 1);
787 gcfree(p);
788 } else
789 lua_pushnil(L);
790 return 1;
791 }
792
793 /*
794 * Asynchronous Command Execution Functions
795 */
796 static int
conn_sendQuery(lua_State * L)797 conn_sendQuery(lua_State *L)
798 {
799 lua_pushboolean(L, PQsendQuery(pgsql_conn(L, 1),
800 luaL_checkstring(L, 2)));
801 return 1;
802 }
803
804 static int
conn_sendQueryParams(lua_State * L)805 conn_sendQueryParams(lua_State *L)
806 {
807 PGconn *conn;
808 Oid *paramTypes;
809 char **paramValues;
810 const char *command;
811 int n, nParams, *paramLengths, *paramFormats;
812
813 conn = pgsql_conn(L, 1);
814 command = luaL_checkstring(L, 2);
815
816 nParams = lua_gettop(L) - 2; /* subtract connection and command */
817
818 if (nParams) {
819 luaL_checkstack(L, 4 + nParams, "out of stack space");
820
821 paramTypes = lua_newuserdata(L, nParams * sizeof(Oid));
822 paramValues = lua_newuserdata(L, nParams * sizeof(char *));
823 paramLengths = lua_newuserdata(L, nParams * sizeof(int));
824 paramFormats = lua_newuserdata(L, nParams * sizeof(int));
825
826 for (n = 0; n < nParams; n++)
827 get_param(L, 3 + n, n, paramTypes, paramValues,
828 paramLengths, paramFormats);
829 } else {
830 paramTypes = NULL;
831 paramValues = NULL;
832 paramLengths = NULL;
833 paramFormats = NULL;
834 }
835 lua_pushboolean(L,
836 PQsendQueryParams(conn, command, nParams, paramTypes,
837 (const char * const*)paramValues, paramLengths, paramFormats, 0));
838 return 1;
839 }
840
841 static int
conn_sendPrepare(lua_State * L)842 conn_sendPrepare(lua_State *L)
843 {
844 PGconn *conn;
845 Oid *paramTypes;
846 const char *command, *name;
847 int n, nParams;
848
849 conn = pgsql_conn(L, 1);
850 command = luaL_checkstring(L, 2);
851 name = luaL_checkstring(L, 3);
852
853 nParams = lua_gettop(L) - 3; /* subtract connection, name, command */
854
855 if (nParams) {
856 paramTypes = lua_newuserdata(L, nParams * sizeof(Oid));
857
858 for (n = 0; n < nParams; n++)
859 get_param(L, 4 + n, n, paramTypes, NULL, NULL, NULL);
860 } else
861 paramTypes = NULL;
862 lua_pushboolean(L,
863 PQsendPrepare(conn, command, name, nParams, paramTypes));
864 return 1;
865 }
866
867 static int
conn_sendQueryPrepared(lua_State * L)868 conn_sendQueryPrepared(lua_State *L)
869 {
870 PGconn *conn;
871 char **paramValues;
872 const char *name;
873 int n, nParams, *paramLengths, *paramFormats;
874
875 conn = pgsql_conn(L, 1);
876 name = luaL_checkstring(L, 2);
877
878 nParams = lua_gettop(L) - 2; /* subtract connection and name */
879
880 if (nParams) {
881 luaL_checkstack(L, 3 + nParams, "out of stack space");
882
883 paramValues = lua_newuserdata(L, nParams * sizeof(char *));
884 paramLengths = lua_newuserdata(L, nParams * sizeof(int));
885 paramFormats = lua_newuserdata(L, nParams * sizeof(int));
886
887 for (n = 0; n < nParams; n++)
888 get_param(L, 3 + n, n, NULL, paramValues, paramLengths,
889 paramFormats);
890 } else {
891 paramValues = NULL;
892 paramLengths = NULL;
893 paramFormats = NULL;
894 }
895 lua_pushboolean(L,
896 PQsendQueryPrepared(conn, name, nParams,
897 (const char * const*)paramValues, paramLengths, paramFormats, 0));
898 return 1;
899 }
900
901 static int
conn_sendDescribePrepared(lua_State * L)902 conn_sendDescribePrepared(lua_State *L)
903 {
904 lua_pushboolean(L,
905 PQsendDescribePrepared(pgsql_conn(L, 1), luaL_checkstring(L, 2)));
906 return 1;
907 }
908
909 static int
conn_sendDescribePortal(lua_State * L)910 conn_sendDescribePortal(lua_State *L)
911 {
912 lua_pushboolean(L,
913 PQsendDescribePortal(pgsql_conn(L, 1), luaL_checkstring(L, 2)));
914 return 1;
915 }
916
917 static int
conn_getResult(lua_State * L)918 conn_getResult(lua_State *L)
919 {
920 PGresult *r, **res;
921
922 r = PQgetResult(pgsql_conn(L, 1));
923 if (r == NULL)
924 lua_pushnil(L);
925 else {
926 res = lua_newuserdata(L, sizeof(PGresult *));
927 *res = r;
928 luaL_setmetatable(L, RES_METATABLE);
929 }
930 return 1;
931 }
932
933 static int
conn_cancel(lua_State * L)934 conn_cancel(lua_State *L)
935 {
936 PGconn *d;
937 PGcancel *cancel;
938 char errbuf[256];
939 int res = 1;
940
941 d = pgsql_conn(L, 1);
942 cancel = PQgetCancel(d);
943 if (cancel != NULL) {
944 res = PQcancel(cancel, errbuf, sizeof errbuf);
945 if (!res) {
946 lua_pushboolean(L, 0);
947 lua_pushstring(L, errbuf);
948 } else
949 lua_pushboolean(L, 1);
950 PQfreeCancel(cancel);
951 } else
952 lua_pushboolean(L, 0);
953 return res == 1 ? 1 : 2;
954 }
955
956 #if PG_VERSION_NUM >= 90200
957 static int
conn_setSingleRowMode(lua_State * L)958 conn_setSingleRowMode(lua_State *L)
959 {
960 lua_pushboolean(L, PQsetSingleRowMode(pgsql_conn(L, 1)));
961 return 1;
962 }
963 #endif
964
965 /*
966 * Asynchronous Notification Functions
967 */
968 static int
conn_notifies(lua_State * L)969 conn_notifies(lua_State *L)
970 {
971 PGnotify **notify, *n;
972
973 n = PQnotifies(pgsql_conn(L, 1));
974 if (n == NULL)
975 lua_pushnil(L);
976 else {
977 notify = lua_newuserdata(L, sizeof(PGnotify *));
978 *notify = n;
979 luaL_setmetatable(L, NOTIFY_METATABLE);
980 }
981 return 1;
982 }
983
984 /*
985 * Commands associated with the COPY command
986 */
987 static int
conn_putCopyData(lua_State * L)988 conn_putCopyData(lua_State *L)
989 {
990 const char *data;
991 size_t len;
992 int r;
993
994 data = luaL_checklstring(L, 2, &len);
995 r = PQputCopyData(pgsql_conn(L, 1), data, len);
996
997 if (r != -1)
998 lua_pushboolean(L, r);
999 else
1000 lua_pushnil(L);
1001 return 1;
1002 }
1003
1004 static int
conn_putCopyEnd(lua_State * L)1005 conn_putCopyEnd(lua_State *L)
1006 {
1007 PGconn *conn;
1008 int r;
1009
1010 conn = pgsql_conn(L, 1);
1011 r = PQputCopyEnd(conn, luaL_optstring(L, 2, NULL));
1012
1013 if (r != -1)
1014 lua_pushboolean(L, r);
1015 else
1016 lua_pushnil(L);
1017 return 1;
1018 }
1019
1020 static int
conn_getCopyData(lua_State * L)1021 conn_getCopyData(lua_State *L)
1022 {
1023 PGconn *conn;
1024 int async, len;
1025 char **data;
1026
1027 conn = pgsql_conn(L, 1);
1028 async = lua_toboolean(L, 2);
1029 data = gcmalloc(L, sizeof(char *));
1030 len = PQgetCopyData(conn, data, async);
1031 if (len > 0)
1032 lua_pushlstring(L, *data, len);
1033 else if (len == 0) /* no data yet */
1034 lua_pushboolean(L, 0);
1035 else if (len == -1) /* copy done */
1036 lua_pushboolean(L, 1);
1037 else /* an error occurred */
1038 lua_pushnil(L);
1039 gcfree(data);
1040 return 1;
1041 }
1042
1043 /*
1044 * Control functions
1045 */
1046 static int
conn_clientEncoding(lua_State * L)1047 conn_clientEncoding(lua_State *L)
1048 {
1049 lua_pushstring(L,
1050 pg_encoding_to_char(PQclientEncoding(pgsql_conn(L, 1))));
1051 return 1;
1052 }
1053
1054 static int
conn_setClientEncoding(lua_State * L)1055 conn_setClientEncoding(lua_State *L)
1056 {
1057 if (PQsetClientEncoding(pgsql_conn(L, 1), luaL_checkstring(L, 2)))
1058 lua_pushboolean(L, 0);
1059 else
1060 lua_pushboolean(L, 1);
1061 return 1;
1062 }
1063
1064 static int
conn_setErrorVerbosity(lua_State * L)1065 conn_setErrorVerbosity(lua_State *L)
1066 {
1067 lua_pushinteger(L,
1068 PQsetErrorVerbosity(pgsql_conn(L, 1), luaL_checkinteger(L, 2)));
1069 return 1;
1070 }
1071
1072 static int
closef_untrace(lua_State * L)1073 closef_untrace(lua_State *L)
1074 {
1075 PGconn *conn;
1076 lua_CFunction cf;
1077
1078 luaL_checkudata(L, 1, LUA_FILEHANDLE);
1079
1080 /* untrace so libpq doesn't segfault */
1081 lua_getuservalue(L, 1);
1082 lua_getfield(L, -1, "PGconn");
1083 conn = pgsql_conn(L, -1);
1084 lua_getfield(L, -2, "old_uservalue");
1085 #if LUA_VERSION_NUM >= 502
1086 lua_getfield(L, -3, "old_closef");
1087 #else
1088 lua_getfield(L, -1, "__close");
1089 #endif
1090 cf = lua_tocfunction(L, -1);
1091 lua_pop(L, 1);
1092 lua_setuservalue(L, 1);
1093
1094 PQuntrace(conn);
1095
1096 /* let go of PGconn's reference to file handle */
1097 lua_getuservalue(L, -1);
1098 lua_pushnil(L);
1099 lua_setfield(L, -2, "trace_file");
1100
1101 /* pop stream uservalue, PGconn, PGconn uservalue */
1102 lua_pop(L, 3);
1103
1104 /* call original close function */
1105 return (*cf)(L);
1106 }
1107
1108 static int
conn_trace(lua_State * L)1109 conn_trace(lua_State *L)
1110 {
1111 PGconn *conn;
1112 #if LUA_VERSION_NUM >= 502
1113 luaL_Stream *stream;
1114
1115 conn = pgsql_conn(L, 1);
1116 stream = luaL_checkudata(L, 2, LUA_FILEHANDLE);
1117 luaL_argcheck(L, stream->f != NULL, 2, "invalid file handle");
1118
1119 /*
1120 * Keep a reference to the file object in uservalue of connection
1121 * so it doesn't get garbage collected.
1122 */
1123 lua_getuservalue(L, 1);
1124 lua_pushvalue(L, 2);
1125 lua_setfield(L, -2, "trace_file");
1126
1127 /*
1128 * Swap out closef luaL_Stream member for our wrapper that will
1129 * untrace.
1130 */
1131 lua_createtable(L, 0, 3);
1132 lua_getuservalue(L, 2);
1133 lua_setfield(L, -2, "old_uservalue");
1134 lua_pushcfunction(L, stream->closef);
1135 lua_setfield(L, -2, "old_closef");
1136 lua_pushvalue(L, 1);
1137 lua_setfield(L, -2, "PGconn");
1138 lua_setuservalue(L, 2);
1139 stream->closef = closef_untrace;
1140
1141 PQtrace(conn, stream->f);
1142 #else
1143 FILE **fp;
1144
1145 conn = pgsql_conn(L, 1);
1146 fp = luaL_checkudata(L, 2, LUA_FILEHANDLE);
1147 luaL_argcheck(L, *fp != NULL, 2, "invalid file handle");
1148
1149 /*
1150 * Keep a reference to the file object in uservalue of connection
1151 * so it doesn't get garbage collected.
1152 */
1153 lua_getuservalue(L, 1);
1154 lua_pushvalue(L, 2);
1155 lua_setfield(L, -2, "trace_file");
1156
1157 /*
1158 * Swap __close field in file environment for our wrapper that will
1159 * untrace keep the old closef under the key of the PGconn.
1160 */
1161 lua_createtable(L, 0, 3);
1162 lua_pushcfunction(L, closef_untrace);
1163 lua_setfield(L, -2, "__close");
1164 lua_getuservalue(L, 2);
1165 lua_setfield(L, -2, "old_uservalue");
1166 lua_pushvalue(L, 1);
1167 lua_setfield(L, -2, "PGconn");
1168 lua_setuservalue(L, 2);
1169
1170 PQtrace(conn, *fp);
1171 #endif
1172 return 0;
1173 }
1174
1175 static int
conn_untrace(lua_State * L)1176 conn_untrace(lua_State *L)
1177 {
1178 PQuntrace(pgsql_conn(L, 1));
1179
1180 /* Let go of PGconn's reference to file handle. */
1181 lua_getuservalue(L, 1);
1182 lua_pushnil(L);
1183 lua_setfield(L, -2, "trace_file");
1184
1185 return 0;
1186 }
1187
1188 /*
1189 * Miscellaneous Functions
1190 */
1191 static int
conn_consumeInput(lua_State * L)1192 conn_consumeInput(lua_State *L)
1193 {
1194 lua_pushboolean(L, PQconsumeInput(pgsql_conn(L, 1)));
1195 return 1;
1196 }
1197
1198 static int
conn_isBusy(lua_State * L)1199 conn_isBusy(lua_State *L)
1200 {
1201 lua_pushboolean(L, PQisBusy(pgsql_conn(L, 1)));
1202 return 1;
1203 }
1204
1205 static int
conn_setnonblocking(lua_State * L)1206 conn_setnonblocking(lua_State *L)
1207 {
1208 int r;
1209
1210 r = PQsetnonblocking(pgsql_conn(L, 1), lua_toboolean(L, 2));
1211 lua_pushboolean(L, !r);
1212 return 1;
1213 }
1214
1215 static int
conn_isnonblocking(lua_State * L)1216 conn_isnonblocking(lua_State *L)
1217 {
1218 lua_pushboolean(L, PQisnonblocking(pgsql_conn(L, 1)));
1219 return 1;
1220 }
1221
1222 static int
conn_flush(lua_State * L)1223 conn_flush(lua_State *L)
1224 {
1225 int r;
1226
1227 r = PQflush(pgsql_conn(L, 1));
1228
1229 if (r >= 0)
1230 lua_pushboolean(L, r == 0);
1231 else
1232 lua_pushnil(L);
1233 return 1;
1234 }
1235
1236 #if PG_VERSION_NUM >= 100000
1237 static int
conn_encryptPassword(lua_State * L)1238 conn_encryptPassword(lua_State *L)
1239 {
1240 const char *algorithm = NULL;
1241 char **pw;
1242
1243 if (lua_isstring(L, 4))
1244 algorithm = lua_tostring(L, 4);
1245
1246 pw = gcmalloc(L, sizeof(char *));
1247 *pw = PQencryptPasswordConn(pgsql_conn(L, 1), luaL_checkstring(L, 2),
1248 luaL_checkstring(L, 3), algorithm);
1249 if (*pw) {
1250 lua_pushstring(L, *pw);
1251 gcfree(pw);
1252 } else
1253 lua_pushnil(L);
1254 return 1;
1255 }
1256 #endif
1257
1258 /* Notice processing */
1259 static void
noticeReceiver(void * arg,const PGresult * r)1260 noticeReceiver(void *arg, const PGresult *r)
1261 {
1262 notice *n = arg;
1263 PGresult **res;
1264
1265 lua_rawgeti(n->L, LUA_REGISTRYINDEX, n->f);
1266 res = lua_newuserdata(n->L, sizeof(PGresult *));
1267
1268 *res = (PGresult *)r;
1269 luaL_setmetatable(n->L, RES_METATABLE);
1270
1271 if (lua_pcall(n->L, 1, 0, 0))
1272 luaL_error(n->L, "%s", lua_tostring(n->L, -1));
1273 *res = NULL; /* avoid double free */
1274 }
1275
1276 static void
noticeProcessor(void * arg,const char * message)1277 noticeProcessor(void *arg, const char *message)
1278 {
1279 notice *n = arg;
1280
1281 lua_rawgeti(n->L, LUA_REGISTRYINDEX, n->f);
1282 lua_pushstring(n->L, message);
1283 if (lua_pcall(n->L, 1, 0, 0))
1284 luaL_error(n->L, "%s", lua_tostring(n->L, -1));
1285 }
1286
1287 static int
conn_setNoticeReceiver(lua_State * L)1288 conn_setNoticeReceiver(lua_State *L)
1289 {
1290 notice **n;
1291 PGconn *conn;
1292 int f;
1293
1294 if (!lua_isfunction(L, -1))
1295 return luaL_argerror(L, -1, "function expected");
1296
1297 f = luaL_ref(L, LUA_REGISTRYINDEX);
1298 conn = pgsql_conn(L, 1);
1299
1300 n = gcmalloc(L, sizeof(notice *));
1301 *n = malloc(sizeof(notice));
1302 if (*n != NULL) {
1303 (*n)->L = L;
1304 (*n)->f = f;
1305 PQsetNoticeReceiver(conn, noticeReceiver, *n);
1306 } else
1307 return luaL_error(L, "out of memory");
1308 return 0;
1309 }
1310
1311 static int
conn_setNoticeProcessor(lua_State * L)1312 conn_setNoticeProcessor(lua_State *L)
1313 {
1314 notice **n;
1315 PGconn *conn;
1316 int f;
1317
1318 if (!lua_isfunction(L, -1))
1319 return luaL_argerror(L, -1, "function expected");
1320
1321 f = luaL_ref(L, LUA_REGISTRYINDEX);
1322 conn = pgsql_conn(L, 1);
1323
1324 n = gcmalloc(L, sizeof(notice *));
1325 *n = malloc(sizeof(notice));
1326 if (*n != NULL) {
1327 (*n)->L = L;
1328 (*n)->f = f;
1329 PQsetNoticeProcessor(conn, noticeProcessor, *n);
1330 } else
1331 return luaL_error(L, "out of memory");
1332 return 0;
1333 }
1334
1335 /* Large objects */
1336 static int
conn_lo_create(lua_State * L)1337 conn_lo_create(lua_State *L)
1338 {
1339 Oid oid;
1340
1341 if (lua_gettop(L) == 2)
1342 oid = luaL_checkinteger(L, 2);
1343 else
1344 oid = 0;
1345 lua_pushinteger(L, lo_create(pgsql_conn(L, 1), oid));
1346 return 1;
1347 }
1348
1349 static int
conn_lo_import(lua_State * L)1350 conn_lo_import(lua_State *L)
1351 {
1352 lua_pushinteger(L, lo_import(pgsql_conn(L, 1), luaL_checkstring(L, 2)));
1353 return 1;
1354 }
1355
1356 static int
conn_lo_import_with_oid(lua_State * L)1357 conn_lo_import_with_oid(lua_State *L)
1358 {
1359 lua_pushinteger(L,
1360 lo_import_with_oid(pgsql_conn(L, 1), luaL_checkstring(L, 2),
1361 luaL_checkinteger(L, 3)));
1362 return 1;
1363 }
1364
1365 static int
conn_lo_export(lua_State * L)1366 conn_lo_export(lua_State *L)
1367 {
1368 int r;
1369
1370 r = lo_export(pgsql_conn(L, 1), luaL_checkinteger(L, 2),
1371 luaL_checkstring(L, 3));
1372
1373 lua_pushboolean(L, r == 1);
1374 return 1;
1375 }
1376
1377 static int
conn_lo_open(lua_State * L)1378 conn_lo_open(lua_State *L)
1379 {
1380 int fd;
1381
1382 fd = lo_open(pgsql_conn(L, 1), luaL_checkinteger(L, 2),
1383 luaL_checkinteger(L, 3));
1384 if (fd == -1)
1385 lua_pushnil(L);
1386 else
1387 lua_pushinteger(L, fd);
1388 return 1;
1389 }
1390
1391 static int
conn_lo_write(lua_State * L)1392 conn_lo_write(lua_State *L)
1393 {
1394 const char *s;
1395 size_t len;
1396
1397 s = lua_tolstring(L, 3, &len);
1398 lua_pushinteger(L, lo_write(pgsql_conn(L, 1), luaL_checkinteger(L, 2),
1399 s, len));
1400 return 1;
1401 }
1402
1403 static int
conn_lo_read(lua_State * L)1404 conn_lo_read(lua_State *L)
1405 {
1406 char *buf;
1407 size_t len;
1408
1409 len = luaL_checkinteger(L, 3);
1410 buf = lua_newuserdata(L, len);
1411 len = lo_read(pgsql_conn(L, 1), luaL_checkinteger(L, 2), buf, len);
1412 lua_pushlstring(L, buf, len);
1413 lua_pushinteger(L, len);
1414 return 2;
1415 }
1416
1417 static int
conn_lo_lseek(lua_State * L)1418 conn_lo_lseek(lua_State *L)
1419 {
1420 lua_pushinteger(L, lo_lseek(pgsql_conn(L, 1), luaL_checkinteger(L, 2),
1421 luaL_checkinteger(L, 3), luaL_checkinteger(L, 4)));
1422 return 1;
1423 }
1424
1425 static int
conn_lo_tell(lua_State * L)1426 conn_lo_tell(lua_State *L)
1427 {
1428 lua_pushinteger(L, lo_tell(pgsql_conn(L, 1), luaL_checkinteger(L, 2)));
1429 return 1;
1430 }
1431
1432 static int
conn_lo_truncate(lua_State * L)1433 conn_lo_truncate(lua_State *L)
1434 {
1435 lua_pushinteger(L, lo_truncate(pgsql_conn(L, 1),
1436 luaL_checkinteger(L, 2), luaL_checkinteger(L, 3)));
1437 return 1;
1438 }
1439
1440 static int
conn_lo_close(lua_State * L)1441 conn_lo_close(lua_State *L)
1442 {
1443 lua_pushboolean(L,
1444 lo_close(pgsql_conn(L, 1), luaL_checkinteger(L, 2)) == 0);
1445 return 1;
1446 }
1447
1448 static int
conn_lo_unlink(lua_State * L)1449 conn_lo_unlink(lua_State *L)
1450 {
1451 lua_pushboolean(L,
1452 lo_unlink(pgsql_conn(L, 1), luaL_checkinteger(L, 2)) == 1);
1453 return 1;
1454 }
1455
1456 #if PG_VERSION_NUM >= 90300
1457 static int
conn_lo_lseek64(lua_State * L)1458 conn_lo_lseek64(lua_State *L)
1459 {
1460 lua_pushinteger(L, lo_lseek64(pgsql_conn(L, 1), luaL_checkinteger(L, 2),
1461 luaL_checkinteger(L, 3), luaL_checkinteger(L, 4)));
1462 return 1;
1463 }
1464
1465 static int
conn_lo_tell64(lua_State * L)1466 conn_lo_tell64(lua_State *L)
1467 {
1468 lua_pushinteger(L,
1469 lo_tell64(pgsql_conn(L, 1), luaL_checkinteger(L, 2)));
1470 return 1;
1471 }
1472
1473 static int
conn_lo_truncate64(lua_State * L)1474 conn_lo_truncate64(lua_State *L)
1475 {
1476 lua_pushinteger(L, lo_truncate64(pgsql_conn(L, 1),
1477 luaL_checkinteger(L, 2), luaL_checkinteger(L, 3)));
1478 return 1;
1479 }
1480 #endif
1481
1482 /*
1483 * Result set functions
1484 */
1485 static int
res_status(lua_State * L)1486 res_status(lua_State *L)
1487 {
1488 lua_pushinteger(L,
1489 PQresultStatus(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE)));
1490 return 1;
1491 }
1492
1493 static int
res_resStatus(lua_State * L)1494 res_resStatus(lua_State *L)
1495 {
1496 lua_pushstring(L, PQresStatus(luaL_checkinteger(L, 2)));
1497 return 1;
1498 }
1499
1500 static int
res_errorMessage(lua_State * L)1501 res_errorMessage(lua_State *L)
1502 {
1503 lua_pushstring(L,
1504 PQresultErrorMessage(*(PGresult **)luaL_checkudata(L, 1,
1505 RES_METATABLE)));
1506 return 1;
1507 }
1508
1509 static int
res_errorField(lua_State * L)1510 res_errorField(lua_State *L)
1511 {
1512 char *field;
1513
1514 field = PQresultErrorField(
1515 *(PGresult **)luaL_checkudata(L, 1, RES_METATABLE),
1516 lua_tointeger(L, 2));
1517 if (field == NULL)
1518 lua_pushnil(L);
1519 else
1520 lua_pushstring(L, field);
1521 return 1;
1522 }
1523
1524 static int
res_nfields(lua_State * L)1525 res_nfields(lua_State *L)
1526 {
1527 lua_pushinteger(L,
1528 PQnfields(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE)));
1529 return 1;
1530 }
1531
1532 static int
res_ntuples(lua_State * L)1533 res_ntuples(lua_State *L)
1534 {
1535 lua_pushinteger(L,
1536 PQntuples(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE)));
1537 return 1;
1538 }
1539
1540 static int
res_fname(lua_State * L)1541 res_fname(lua_State *L)
1542 {
1543 lua_pushstring(L,
1544 PQfname(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE),
1545 luaL_checkinteger(L, 2) - 1));
1546 return 1;
1547 }
1548
1549 static int
res_fnumber(lua_State * L)1550 res_fnumber(lua_State *L)
1551 {
1552 lua_pushinteger(L,
1553 PQfnumber(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE),
1554 luaL_checkstring(L, 2)) + 1);
1555 return 1;
1556 }
1557
1558 static int
res_ftable(lua_State * L)1559 res_ftable(lua_State *L)
1560 {
1561 lua_pushinteger(L,
1562 PQftable(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE),
1563 luaL_checkinteger(L, 2) - 1));
1564 return 1;
1565 }
1566
1567 static int
res_ftablecol(lua_State * L)1568 res_ftablecol(lua_State *L)
1569 {
1570 lua_pushinteger(L,
1571 PQftablecol(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE),
1572 luaL_checkinteger(L, 2) - 1));
1573 return 1;
1574 }
1575
1576 static int
res_fformat(lua_State * L)1577 res_fformat(lua_State *L)
1578 {
1579 lua_pushinteger(L,
1580 PQfformat(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE),
1581 luaL_checkinteger(L, 2) - 1));
1582 return 1;
1583 }
1584
1585 static int
res_ftype(lua_State * L)1586 res_ftype(lua_State *L)
1587 {
1588 lua_pushinteger(L,
1589 PQftype(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE),
1590 luaL_checkinteger(L, 2) - 1));
1591 return 1;
1592 }
1593
1594 static int
res_fmod(lua_State * L)1595 res_fmod(lua_State *L)
1596 {
1597 lua_pushinteger(L,
1598 PQfmod(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE),
1599 luaL_checkinteger(L, 2) - 1));
1600 return 1;
1601 }
1602
1603 static int
res_fsize(lua_State * L)1604 res_fsize(lua_State *L)
1605 {
1606 lua_pushinteger(L,
1607 PQfsize(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE),
1608 luaL_checkinteger(L, 2) - 1));
1609 return 1;
1610 }
1611
1612 static int
res_binaryTuples(lua_State * L)1613 res_binaryTuples(lua_State *L)
1614 {
1615 lua_pushboolean(L,
1616 PQbinaryTuples(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE)));
1617 return 1;
1618 }
1619
1620 static int
res_getvalue(lua_State * L)1621 res_getvalue(lua_State *L)
1622 {
1623 lua_pushstring(L,
1624 PQgetvalue(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE),
1625 luaL_checkinteger(L, 2) - 1, luaL_checkinteger(L, 3) - 1));
1626 return 1;
1627 }
1628
1629 static int
res_getisnull(lua_State * L)1630 res_getisnull(lua_State *L)
1631 {
1632 lua_pushboolean(L,
1633 PQgetisnull(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE),
1634 luaL_checkinteger(L, 2) - 1, luaL_checkinteger(L, 3) - 1));
1635 return 1;
1636 }
1637
1638 static int
res_getlength(lua_State * L)1639 res_getlength(lua_State *L)
1640 {
1641 lua_pushinteger(L,
1642 PQgetlength(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE),
1643 luaL_checkinteger(L, 2) - 1, luaL_checkinteger(L, 3) - 1));
1644 return 1;
1645 }
1646
1647 static int
res_nparams(lua_State * L)1648 res_nparams(lua_State *L)
1649 {
1650 lua_pushinteger(L,
1651 PQnparams(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE)));
1652 return 1;
1653 }
1654
1655 static int
res_paramtype(lua_State * L)1656 res_paramtype(lua_State *L)
1657 {
1658 lua_pushinteger(L,
1659 PQparamtype(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE),
1660 luaL_checkinteger(L, 2)) - 1);
1661 return 1;
1662 }
1663
1664 static int
res_cmdStatus(lua_State * L)1665 res_cmdStatus(lua_State *L)
1666 {
1667 lua_pushstring(L,
1668 PQcmdStatus(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE)));
1669 return 1;
1670 }
1671
1672 static int
res_cmdTuples(lua_State * L)1673 res_cmdTuples(lua_State *L)
1674 {
1675 lua_pushstring(L,
1676 PQcmdTuples(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE)));
1677 return 1;
1678 }
1679
1680 static int
res_oidValue(lua_State * L)1681 res_oidValue(lua_State *L)
1682 {
1683 lua_pushinteger(L,
1684 PQoidValue(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE)));
1685 return 1;
1686 }
1687
1688 static int
res_oidStatus(lua_State * L)1689 res_oidStatus(lua_State *L)
1690 {
1691 lua_pushstring(L,
1692 PQoidStatus(*(PGresult **)luaL_checkudata(L, 1, RES_METATABLE)));
1693 return 1;
1694 }
1695
1696 /* Lua specific functions */
1697 static int
res_copy(lua_State * L)1698 res_copy(lua_State *L)
1699 {
1700 PGresult *res = *(PGresult **)luaL_checkudata(L, 1, RES_METATABLE);
1701 int row, col, convert;
1702
1703 convert = 0; /* Do not convert numeric types */
1704
1705 if (lua_gettop(L) == 2)
1706 convert = lua_toboolean(L, 2);
1707
1708 lua_newtable(L);
1709 for (row = 0; row < PQntuples(res); row++) {
1710 lua_pushinteger(L, row + 1);
1711 lua_newtable(L);
1712 for (col = 0; col < PQnfields(res); col++) {
1713 if (convert)
1714 switch (PQftype(res, col)) {
1715 case BOOLOID:
1716 lua_pushboolean(L,
1717 strcmp(PQgetvalue(res, row, col),
1718 "f"));
1719 break;
1720 case INT2OID:
1721 case INT4OID:
1722 case INT8OID:
1723 lua_pushinteger(L,
1724 atol(PQgetvalue(res, row, col)));
1725 break;
1726 case FLOAT4OID:
1727 case FLOAT8OID:
1728 case NUMERICOID:
1729 lua_pushnumber(L,
1730 atof(PQgetvalue(res, row, col)));
1731 break;
1732 default:
1733 lua_pushstring(L,
1734 PQgetvalue(res, row, col));
1735 }
1736 else
1737 lua_pushstring(L, PQgetvalue(res, row, col));
1738 lua_setfield(L, -2, PQfname(res, col));
1739 }
1740 lua_settable(L, -3);
1741 }
1742 return 1;
1743 }
1744
1745 static int
res_fields_iterator(lua_State * L)1746 res_fields_iterator(lua_State *L)
1747 {
1748 tuple *t = luaL_checkudata(L, 1, TUPLE_METATABLE);
1749 int n;
1750
1751 t->row++;
1752
1753 luaL_checkstack(L, PQnfields(t->res), "out of stack space");
1754 if (t->row == PQntuples(t->res))
1755 for (n = 0; n < PQnfields(t->res); n++)
1756 lua_pushnil(L);
1757 else
1758 for (n = 0; n < PQnfields(t->res); n++)
1759 lua_pushstring(L, PQgetvalue(t->res, t->row, n));
1760 return PQnfields(t->res);
1761 }
1762
1763 static int
res_fields(lua_State * L)1764 res_fields(lua_State *L)
1765 {
1766 tuple *t;
1767
1768 lua_pushcfunction(L, res_fields_iterator);
1769 t = lua_newuserdata(L, sizeof(tuple));
1770 luaL_setmetatable(L, TUPLE_METATABLE);
1771 t->res = *(PGresult **)luaL_checkudata(L, 1, RES_METATABLE);
1772 t->row = -1;
1773 return 2;
1774 }
1775
1776 static int
res_tuples_iterator(lua_State * L)1777 res_tuples_iterator(lua_State *L)
1778 {
1779 tuple *t = luaL_checkudata(L, 1, TUPLE_METATABLE);
1780
1781 t->row++;
1782
1783 if (t->row == PQntuples(t->res)) {
1784 lua_pushnil(L);
1785 lua_pushnil(L);
1786 } else {
1787 lua_pushvalue(L, 1);
1788 lua_pushinteger(L, t->row + 1);
1789 }
1790 return 2;
1791 }
1792
1793 static int
res_tuples(lua_State * L)1794 res_tuples(lua_State *L)
1795 {
1796 PGresult **res;
1797 tuple *t;
1798
1799 res = (PGresult **)luaL_checkudata(L, 1, RES_METATABLE);
1800
1801 lua_pushcfunction(L, res_tuples_iterator);
1802 t = lua_newuserdata(L, sizeof(tuple));
1803 luaL_setmetatable(L, TUPLE_METATABLE);
1804 t->res = *res;
1805 t->row = -1;
1806 return 2;
1807 }
1808
1809 static int
res_index(lua_State * L)1810 res_index(lua_State *L)
1811 {
1812 if (lua_type(L, -1) == LUA_TNUMBER) {
1813 tuple *t;
1814 PGresult *res;
1815 int row;
1816
1817 res = *(PGresult **)luaL_checkudata(L, 1, RES_METATABLE);
1818 row = luaL_checkinteger(L, 2) - 1;
1819
1820 if (row < 0 || row >= PQntuples(res))
1821 lua_pushnil(L);
1822 else {
1823 t = lua_newuserdata(L, sizeof(tuple));
1824 t->res = res;
1825 t->row = row;
1826 luaL_setmetatable(L, TUPLE_METATABLE);
1827 }
1828 } else {
1829 const char *nam;
1830
1831 nam = lua_tostring(L, -1);
1832 if (lua_getmetatable(L, -2)) {
1833 lua_pushstring(L, nam);
1834 lua_rawget(L, -2);
1835 } else
1836 lua_pushnil(L);
1837 }
1838 return 1;
1839 }
1840
1841 static int
res_clear(lua_State * L)1842 res_clear(lua_State *L)
1843 {
1844 PGresult **r;
1845
1846 r = luaL_checkudata(L, 1, RES_METATABLE);
1847 if (*r) {
1848 PQclear(*r);
1849 *r = NULL;
1850 }
1851 return 0;
1852 }
1853
1854 /*
1855 * Notifies methods (objects returned by conn:notifies())
1856 */
1857 static int
notify_relname(lua_State * L)1858 notify_relname(lua_State *L)
1859 {
1860 PGnotify **n;
1861
1862 n = luaL_checkudata(L, 1, NOTIFY_METATABLE);
1863 lua_pushstring(L, (*n)->relname);
1864 return 1;
1865 }
1866
1867 static int
notify_pid(lua_State * L)1868 notify_pid(lua_State *L)
1869 {
1870 PGnotify **n;
1871
1872 n = luaL_checkudata(L, 1, NOTIFY_METATABLE);
1873 lua_pushinteger(L, (*n)->be_pid);
1874 return 1;
1875 }
1876
1877 static int
notify_extra(lua_State * L)1878 notify_extra(lua_State *L)
1879 {
1880 PGnotify **n;
1881
1882 n = luaL_checkudata(L, 1, NOTIFY_METATABLE);
1883 lua_pushstring(L, (*n)->extra);
1884 return 1;
1885 }
1886
1887 static int
notify_clear(lua_State * L)1888 notify_clear(lua_State *L)
1889 {
1890 PGnotify **n;
1891
1892 n = luaL_checkudata(L, 1, NOTIFY_METATABLE);
1893 if (*n) {
1894 PQfreemem(*n);
1895 *n = NULL;
1896 }
1897 return 0;
1898 }
1899
1900 /*
1901 * Tuple and value functions
1902 */
1903 static int
tuple_copy(lua_State * L)1904 tuple_copy(lua_State *L)
1905 {
1906 tuple *t = luaL_checkudata(L, 1, TUPLE_METATABLE);
1907 int col;
1908
1909 lua_newtable(L);
1910 for (col = 0; col < PQnfields(t->res); col++) {
1911 lua_pushstring(L, PQgetvalue(t->res, t->row, col));
1912 lua_setfield(L, -2, PQfname(t->res, col));
1913 }
1914 return 1;
1915 }
1916
1917 static int
field_iterator(lua_State * L)1918 field_iterator(lua_State *L)
1919 {
1920 field *f = luaL_checkudata(L, 1, FIELD_METATABLE);
1921
1922 f->col++;
1923
1924 if (f->col == PQnfields(f->tuple->res)) {
1925 lua_pushnil(L);
1926 lua_pushnil(L);
1927 } else {
1928 lua_pushstring(L, PQfname(f->tuple->res, f->col));
1929 lua_pushstring(L,
1930 PQgetvalue(f->tuple->res, f->tuple->row, f->col));
1931 }
1932 return 2;
1933 }
1934
1935 static int
tuple_getfields(lua_State * L)1936 tuple_getfields(lua_State *L)
1937 {
1938 tuple *t = luaL_checkudata(L, 1, TUPLE_METATABLE);
1939 field *f;
1940
1941 lua_pushcfunction(L, field_iterator);
1942 f = lua_newuserdata(L, sizeof(field));
1943 f->tuple = t;
1944 f->col = -1;
1945 luaL_setmetatable(L, FIELD_METATABLE);
1946 return 2;
1947 }
1948
1949 static int
tuple_getisnull(lua_State * L)1950 tuple_getisnull(lua_State *L)
1951 {
1952 tuple *t = luaL_checkudata(L, 1, TUPLE_METATABLE);
1953 const char *fnam;
1954 int fnumber;
1955
1956 switch (lua_type(L, 2)) {
1957 case LUA_TNUMBER:
1958 fnumber = lua_tointeger(L, 2) - 1;
1959 if (fnumber < 0 || fnumber >= PQnfields(t->res))
1960 lua_pushnil(L);
1961 else
1962 lua_pushboolean(L, PQgetisnull(t->res, t->row,
1963 lua_tointeger(L, 2) - 1));
1964 break;
1965 case LUA_TSTRING:
1966 fnam = lua_tostring(L, 2);
1967 fnumber = PQfnumber(t->res, fnam);
1968
1969 if (fnumber == -1)
1970 lua_pushnil(L);
1971 else
1972 lua_pushboolean(L, PQgetisnull(t->res, t->row,
1973 PQfnumber(t->res, lua_tostring(L, 2))));
1974 break;
1975 default:
1976 lua_pushnil(L);
1977 }
1978 return 1;
1979 }
1980
1981 static int
tuple_getlength(lua_State * L)1982 tuple_getlength(lua_State *L)
1983 {
1984 tuple *t = luaL_checkudata(L, 1, TUPLE_METATABLE);
1985 const char *fnam;
1986 int fnumber;
1987
1988 switch (lua_type(L, 2)) {
1989 case LUA_TNUMBER:
1990 fnumber = lua_tointeger(L, 2) - 1;
1991 if (fnumber < 0 || fnumber >= PQnfields(t->res))
1992 lua_pushnil(L);
1993 else
1994 lua_pushinteger(L, PQgetlength(t->res, t->row,
1995 lua_tointeger(L, 2) - 1));
1996 break;
1997 case LUA_TSTRING:
1998 fnam = lua_tostring(L, 2);
1999 fnumber = PQfnumber(t->res, fnam);
2000
2001 if (fnumber == -1)
2002 lua_pushnil(L);
2003 else
2004 lua_pushinteger(L, PQgetlength(t->res, t->row,
2005 PQfnumber(t->res, lua_tostring(L, 2))));
2006 break;
2007 default:
2008 lua_pushnil(L);
2009 }
2010 return 1;
2011 }
2012
2013 static int
tuple_index(lua_State * L)2014 tuple_index(lua_State *L)
2015 {
2016 tuple *t = luaL_checkudata(L, 1, TUPLE_METATABLE);
2017 const char *fnam;
2018 int fnumber;
2019
2020 switch (lua_type(L, 2)) {
2021 case LUA_TNUMBER:
2022 fnumber = lua_tointeger(L, 2) - 1;
2023 if (fnumber < 0 || fnumber >= PQnfields(t->res))
2024 lua_pushnil(L);
2025 else
2026 lua_pushstring(L, PQgetvalue(t->res, t->row, fnumber));
2027 break;
2028 case LUA_TSTRING:
2029 fnam = lua_tostring(L, 2);
2030 fnumber = PQfnumber(t->res, fnam);
2031
2032 if (fnumber == -1) {
2033 if (!strcmp(fnam, "copy"))
2034 lua_pushcfunction(L, tuple_copy);
2035 else if (!strcmp(fnam, "getfields"))
2036 lua_pushcfunction(L, tuple_getfields);
2037 else if (!strcmp(fnam, "getisnull"))
2038 lua_pushcfunction(L, tuple_getisnull);
2039 else if (!strcmp(fnam, "getlength"))
2040 lua_pushcfunction(L, tuple_getlength);
2041 else
2042 lua_pushnil(L);
2043 } else
2044 lua_pushstring(L, PQgetvalue(t->res, t->row,
2045 PQfnumber(t->res, fnam)));
2046 break;
2047 default:
2048 lua_pushnil(L);
2049 }
2050 return 1;
2051 }
2052
2053 static int
tuple_length(lua_State * L)2054 tuple_length(lua_State *L)
2055 {
2056 tuple *t = luaL_checkudata(L, 1, TUPLE_METATABLE);
2057
2058 lua_pushinteger(L, PQnfields(t->res));
2059 return 1;
2060 }
2061
2062 /*
2063 * Module definitions, constants etc.
2064 */
2065 struct constant {
2066 char *name;
2067 int value;
2068 };
2069
2070 static struct constant pgsql_constant[] = {
2071 /* Connection status */
2072 { "CONNECTION_STARTED", CONNECTION_STARTED },
2073 { "CONNECTION_MADE", CONNECTION_MADE },
2074 { "CONNECTION_AWAITING_RESPONSE", CONNECTION_AWAITING_RESPONSE },
2075 { "CONNECTION_AUTH_OK", CONNECTION_AUTH_OK },
2076 { "CONNECTION_OK", CONNECTION_OK },
2077 { "CONNECTION_SSL_STARTUP", CONNECTION_SSL_STARTUP },
2078 { "CONNECTION_SETENV", CONNECTION_SETENV },
2079 { "CONNECTION_BAD", CONNECTION_BAD },
2080 #if PG_VERSION_NUM >= 100000
2081 { "CONNECTION_CONSUME", CONNECTION_CONSUME },
2082 #endif
2083
2084 /* Resultset status codes */
2085 { "PGRES_EMPTY_QUERY", PGRES_EMPTY_QUERY },
2086 { "PGRES_COMMAND_OK", PGRES_COMMAND_OK },
2087 { "PGRES_TUPLES_OK", PGRES_TUPLES_OK },
2088 #if PG_VERSION_NUM >= 90200
2089 { "PGRES_SINGLE_TUPLE", PGRES_SINGLE_TUPLE },
2090 #endif
2091 { "PGRES_COPY_OUT", PGRES_COPY_OUT },
2092 { "PGRES_COPY_IN", PGRES_COPY_IN },
2093 #if PG_VERSION_NUM >= 90100
2094 { "PGRES_COPY_BOTH", PGRES_COPY_BOTH },
2095 { "PGRES_SINGLE_TUPLE", PGRES_SINGLE_TUPLE },
2096 #endif
2097 { "PGRES_BAD_RESPONSE", PGRES_BAD_RESPONSE },
2098 { "PGRES_NONFATAL_ERROR", PGRES_NONFATAL_ERROR },
2099 { "PGRES_FATAL_ERROR", PGRES_FATAL_ERROR },
2100
2101 /* Polling status */
2102 { "PGRES_POLLING_FAILED", PGRES_POLLING_FAILED },
2103 { "PGRES_POLLING_READING", PGRES_POLLING_READING },
2104 { "PGRES_POLLING_WRITING", PGRES_POLLING_WRITING },
2105 { "PGRES_POLLING_OK", PGRES_POLLING_OK },
2106
2107 /* Transaction status */
2108 { "PQTRANS_IDLE", PQTRANS_IDLE },
2109 { "PQTRANS_ACTIVE", PQTRANS_ACTIVE },
2110 { "PQTRANS_INTRANS", PQTRANS_INTRANS },
2111 { "PQTRANS_INERROR", PQTRANS_INERROR },
2112 { "PQTRANS_UNKNOWN", PQTRANS_UNKNOWN },
2113
2114 /* Diagnostic codes */
2115 { "PG_DIAG_SEVERITY", PG_DIAG_SEVERITY },
2116 { "PG_DIAG_SQLSTATE", PG_DIAG_SQLSTATE },
2117 { "PG_DIAG_MESSAGE_PRIMARY", PG_DIAG_MESSAGE_PRIMARY },
2118 { "PG_DIAG_MESSAGE_DETAIL", PG_DIAG_MESSAGE_DETAIL },
2119 { "PG_DIAG_MESSAGE_HINT", PG_DIAG_MESSAGE_HINT },
2120 { "PG_DIAG_STATEMENT_POSITION", PG_DIAG_STATEMENT_POSITION },
2121 { "PG_DIAG_INTERNAL_POSITION", PG_DIAG_INTERNAL_POSITION },
2122 { "PG_DIAG_INTERNAL_QUERY", PG_DIAG_INTERNAL_QUERY },
2123 { "PG_DIAG_CONTEXT", PG_DIAG_CONTEXT },
2124 { "PG_DIAG_SOURCE_FILE", PG_DIAG_SOURCE_FILE },
2125 { "PG_DIAG_SOURCE_LINE", PG_DIAG_SOURCE_LINE },
2126 { "PG_DIAG_SOURCE_FUNCTION", PG_DIAG_SOURCE_FUNCTION },
2127
2128 /* Error verbosity */
2129 { "PQERRORS_TERSE", PQERRORS_TERSE },
2130 { "PQERRORS_DEFAULT", PQERRORS_DEFAULT },
2131 { "PQERRORS_VERBOSE", PQERRORS_VERBOSE },
2132
2133 #if PG_VERSION_NUM >= 90100
2134 /* PQping codes */
2135 { "PQPING_OK", PQPING_OK },
2136 { "PQPING_REJECT", PQPING_REJECT },
2137 { "PQPING_NO_RESPONSE", PQPING_NO_RESPONSE },
2138 { "PQPING_NO_ATTEMPT", PQPING_NO_ATTEMPT },
2139 #endif
2140
2141 /* Large objects */
2142 { "INV_READ", INV_READ },
2143 { "INV_WRITE", INV_WRITE },
2144 { "SEEK_CUR", SEEK_CUR },
2145 { "SEEK_END", SEEK_END },
2146 { "SEEK_SET", SEEK_SET },
2147
2148 /* Miscellaneous values */
2149 { "InvalidOid", InvalidOid },
2150
2151 { NULL, 0 }
2152 };
2153
2154 static void
pgsql_set_info(lua_State * L)2155 pgsql_set_info(lua_State *L)
2156 {
2157 lua_pushliteral(L, "_COPYRIGHT");
2158 lua_pushliteral(L, "Copyright (C) 2009 - 2020 by "
2159 "micro systems marc balmer");
2160 lua_settable(L, -3);
2161 lua_pushliteral(L, "_DESCRIPTION");
2162 lua_pushliteral(L, "PostgreSQL binding for Lua");
2163 lua_settable(L, -3);
2164 lua_pushliteral(L, "_VERSION");
2165 lua_pushliteral(L, "pgsql 1.6.8");
2166 lua_settable(L, -3);
2167 }
2168
2169 int
luaopen_pgsql(lua_State * L)2170 luaopen_pgsql(lua_State *L)
2171 {
2172 int n;
2173 struct luaL_Reg luapgsql[] = {
2174 /* Database Connection Control Functions */
2175 { "connectdb", pgsql_connectdb },
2176 { "connectStart", pgsql_connectStart },
2177 { "libVersion", pgsql_libVersion },
2178 #if PG_VERSION_NUM >= 90100
2179 { "ping", pgsql_ping },
2180 #endif
2181 { "encryptPassword", pgsql_encryptPassword },
2182 { "unescapeBytea", pgsql_unescapeBytea },
2183
2184 /* SSL support */
2185 { "initOpenSSL", pgsql_initOpenSSL },
2186 { NULL, NULL }
2187 };
2188
2189 struct luaL_Reg conn_methods[] = {
2190 /* Database Connection Control Functions */
2191 { "connectPoll", pgsql_connectPoll },
2192 { "finish", conn_finish },
2193 { "reset", conn_reset },
2194 { "resetStart", conn_resetStart },
2195 { "resetPoll", conn_resetPoll },
2196
2197 /* Connection Status Functions */
2198 { "db", conn_db },
2199 { "user", conn_user },
2200 { "pass", conn_pass },
2201 { "host", conn_host },
2202 { "port", conn_port },
2203 { "tty", conn_tty },
2204 { "options", conn_options },
2205 { "status", conn_status },
2206 { "transactionStatus", conn_transactionStatus },
2207 { "parameterStatus", conn_parameterStatus },
2208 { "protocolVersion", conn_protocolVersion },
2209 { "serverVersion", conn_serverVersion },
2210 { "errorMessage", conn_errorMessage },
2211 { "socket", conn_socket },
2212 { "backendPID", conn_backendPID },
2213 { "connectionNeedsPassword", conn_connectionNeedsPassword },
2214 { "connectionUsedPassword", conn_connectionUsedPassword },
2215 #if PG_VERSION_NUM >= 90500
2216 { "sslInUse", conn_sslInUse },
2217 { "sslAttribute", conn_sslAttribute },
2218 { "sslAttributeNames", conn_sslAttributeNames },
2219 #endif
2220
2221 /* Command Execution Functions */
2222 { "escapeString", conn_escapeString },
2223 { "escapeLiteral", conn_escapeLiteral },
2224 { "escapeIdentifier", conn_escapeIdentifier },
2225 { "escapeBytea", conn_escapeBytea },
2226 { "exec", conn_exec },
2227 { "execParams", conn_execParams },
2228 { "prepare", conn_prepare },
2229 { "execPrepared", conn_execPrepared },
2230 { "describePrepared", conn_describePrepared },
2231 { "describePortal", conn_describePortal },
2232
2233 /* Asynchronous command processing */
2234 { "sendQuery", conn_sendQuery },
2235 { "sendQueryParams", conn_sendQueryParams },
2236 { "sendPrepare", conn_sendPrepare },
2237 { "sendQueryPrepared", conn_sendQueryPrepared },
2238 { "sendDescribePrepared", conn_sendDescribePrepared },
2239 { "sendDescribePortal", conn_sendDescribePortal },
2240 { "getResult", conn_getResult },
2241 { "cancel", conn_cancel },
2242
2243 #if PG_VERSION_NUM >= 90200
2244 /* Retrieving query results row-by-row */
2245 { "setSingleRowMode", conn_setSingleRowMode },
2246 #endif
2247
2248 /* Asynchronous Notifications Functions */
2249 { "notifies", conn_notifies },
2250
2251 /* Function associated with the COPY command */
2252 { "putCopyData", conn_putCopyData },
2253 { "putCopyEnd", conn_putCopyEnd },
2254 { "getCopyData", conn_getCopyData },
2255
2256 /* Control Functions */
2257 { "clientEncoding", conn_clientEncoding },
2258 { "setClientEncoding", conn_setClientEncoding },
2259 { "setErrorVerbosity", conn_setErrorVerbosity },
2260 { "trace", conn_trace },
2261 { "untrace", conn_untrace },
2262
2263 /* Miscellaneous Functions */
2264 { "consumeInput", conn_consumeInput },
2265 { "isBusy", conn_isBusy },
2266 { "setnonblocking", conn_setnonblocking },
2267 { "isnonblocking", conn_isnonblocking },
2268 { "flush", conn_flush },
2269 #if PG_VERSION_NUM >= 100000
2270 { "encryptPassword", conn_encryptPassword },
2271 #endif
2272 /* Notice processing */
2273 { "setNoticeReceiver", conn_setNoticeReceiver },
2274 { "setNoticeProcessor", conn_setNoticeProcessor },
2275
2276 /* Large Objects */
2277 { "lo_create", conn_lo_create },
2278 { "lo_import", conn_lo_import },
2279 { "lo_import_with_oid", conn_lo_import_with_oid },
2280 { "lo_export", conn_lo_export },
2281 { "lo_open", conn_lo_open },
2282 { "lo_write", conn_lo_write },
2283 { "lo_read", conn_lo_read },
2284 { "lo_lseek", conn_lo_lseek },
2285 { "lo_tell", conn_lo_tell },
2286 { "lo_truncate", conn_lo_truncate },
2287 { "lo_close", conn_lo_close },
2288 { "lo_unlink", conn_lo_unlink },
2289 #if PG_VERSION_NUM >= 90300
2290 { "lo_lseek64", conn_lo_lseek64 },
2291 { "lo_tell64", conn_lo_tell64 },
2292 { "lo_truncate64", conn_lo_truncate64 },
2293 #endif
2294 { NULL, NULL }
2295 };
2296 struct luaL_Reg res_methods[] = {
2297 /* Main functions */
2298 { "status", res_status },
2299 { "resStatus", res_resStatus },
2300 { "errorMessage", res_errorMessage },
2301 { "errorField", res_errorField },
2302
2303 /* Retrieving query result information */
2304 { "ntuples", res_ntuples },
2305 { "nfields", res_nfields },
2306 { "fname", res_fname },
2307 { "fnumber", res_fnumber },
2308 { "ftable", res_ftable },
2309 { "ftablecol", res_ftablecol },
2310 { "fformat", res_fformat },
2311 { "ftype", res_ftype },
2312 { "fmod", res_fmod },
2313 { "fsize", res_fsize },
2314 { "binaryTuples", res_binaryTuples },
2315 { "getvalue", res_getvalue },
2316 { "getisnull", res_getisnull },
2317 { "getlength", res_getlength },
2318 { "nparams", res_nparams },
2319 { "paramtype", res_paramtype },
2320
2321 /* Other result information */
2322 { "cmdStatus", res_cmdStatus },
2323 { "cmdTuples", res_cmdTuples },
2324 { "oidValue", res_oidValue },
2325 { "oidStatus", res_oidStatus },
2326
2327 /* Lua specific extension */
2328 { "copy", res_copy },
2329 { "fields", res_fields },
2330 { "tuples", res_tuples },
2331 { "clear", res_clear },
2332 { NULL, NULL }
2333 };
2334 struct luaL_Reg notify_methods[] = {
2335 { "relname", notify_relname },
2336 { "pid", notify_pid },
2337 { "extra", notify_extra },
2338 { NULL, NULL }
2339 };
2340 if (luaL_newmetatable(L, CONN_METATABLE)) {
2341 #if LUA_VERSION_NUM >= 502
2342 luaL_setfuncs(L, conn_methods, 0);
2343 #else
2344 luaL_register(L, NULL, conn_methods);
2345 #endif
2346 lua_pushliteral(L, "__gc");
2347 lua_pushcfunction(L, conn_finish);
2348 lua_settable(L, -3);
2349
2350 lua_pushliteral(L, "__index");
2351 lua_pushvalue(L, -2);
2352 lua_settable(L, -3);
2353
2354 lua_pushliteral(L, "__metatable");
2355 lua_pushliteral(L, "must not access this metatable");
2356 lua_settable(L, -3);
2357 }
2358 lua_pop(L, 1);
2359
2360 if (luaL_newmetatable(L, RES_METATABLE)) {
2361 #if LUA_VERSION_NUM >= 502
2362 luaL_setfuncs(L, res_methods, 0);
2363 #else
2364 luaL_register(L, NULL, res_methods);
2365 #endif
2366 lua_pushliteral(L, "__gc");
2367 lua_pushcfunction(L, res_clear);
2368 lua_settable(L, -3);
2369
2370 lua_pushliteral(L, "__index");
2371 lua_pushcfunction(L, res_index);
2372 lua_settable(L, -3);
2373
2374 lua_pushliteral(L, "__len");
2375 lua_pushcfunction(L, res_ntuples);
2376 lua_settable(L, -3);
2377
2378 lua_pushliteral(L, "__metatable");
2379 lua_pushliteral(L, "must not access this metatable");
2380 lua_settable(L, -3);
2381 }
2382 lua_pop(L, 1);
2383
2384 if (luaL_newmetatable(L, NOTIFY_METATABLE)) {
2385 #if LUA_VERSION_NUM >= 502
2386 luaL_setfuncs(L, notify_methods, 0);
2387 #else
2388 luaL_register(L, NULL, notify_methods);
2389 #endif
2390 lua_pushliteral(L, "__gc");
2391 lua_pushcfunction(L, notify_clear);
2392 lua_settable(L, -3);
2393
2394 lua_pushliteral(L, "__index");
2395 lua_pushvalue(L, -2);
2396 lua_settable(L, -3);
2397
2398 lua_pushliteral(L, "__metatable");
2399 lua_pushliteral(L, "must not access this metatable");
2400 lua_settable(L, -3);
2401 }
2402 lua_pop(L, 1);
2403
2404 if (luaL_newmetatable(L, TUPLE_METATABLE)) {
2405 lua_pushliteral(L, "__index");
2406 lua_pushcfunction(L, tuple_index);
2407 lua_settable(L, -3);
2408
2409 lua_pushliteral(L, "__len");
2410 lua_pushcfunction(L, tuple_length);
2411 lua_settable(L, -3);
2412
2413 lua_pushliteral(L, "__metatable");
2414 lua_pushliteral(L, "must not access this metatable");
2415 lua_settable(L, -3);
2416 }
2417 lua_pop(L, 1);
2418
2419 if (luaL_newmetatable(L, FIELD_METATABLE)) {
2420 lua_pushliteral(L, "__metatable");
2421 lua_pushliteral(L, "must not access this metatable");
2422 lua_settable(L, -3);
2423 }
2424 lua_pop(L, 1);
2425
2426 if (luaL_newmetatable(L, GCMEM_METATABLE)) {
2427 lua_pushliteral(L, "__gc");
2428 lua_pushcfunction(L, gcmem_clear);
2429 lua_settable(L, -3);
2430 }
2431 lua_pop(L, 1);
2432
2433 #if LUA_VERSION_NUM >= 502
2434 luaL_newlib(L, luapgsql);
2435 #else
2436 luaL_register(L, "pgsql", luapgsql);
2437 #endif
2438 pgsql_set_info(L);
2439 for (n = 0; pgsql_constant[n].name != NULL; n++) {
2440 lua_pushinteger(L, pgsql_constant[n].value);
2441 lua_setfield(L, -2, pgsql_constant[n].name);
2442 };
2443
2444 return 1;
2445 }
2446