49
49
#undef PACKAGE_VERSION
50
50
#include <module.h>
51
51
52
+ struct dec_opt {
53
+ char cast ;
54
+ int dnew_index ;
55
+ };
56
+ typedef struct dec_opt dec_opt_t ;
57
+
52
58
/**
53
59
* Infinity timeout from tarantool_ev.c. I mean, this should be in
54
60
* a module.h file.
@@ -97,7 +103,7 @@ lua_push_error(struct lua_State *L)
97
103
* Parse pg values to lua
98
104
*/
99
105
static int
100
- parse_pg_value (struct lua_State * L , char dec_cast , PGresult * res , int row , int col )
106
+ parse_pg_value (struct lua_State * L , dec_opt_t * dopt , PGresult * res , int row , int col )
101
107
{
102
108
if (PQgetisnull (res , row , col ))
103
109
return false;
@@ -108,9 +114,18 @@ parse_pg_value(struct lua_State *L, char dec_cast, PGresult *res, int row, int c
108
114
109
115
switch (PQftype (res , col )) {
110
116
case NUMERICOID : {
111
- if (dec_cast == 's' )
112
- {
117
+ if (dopt -> cast == 's' ) {
118
+ lua_pushlstring (L , val , len );
119
+ break ;
120
+ }
121
+ else if (dopt -> cast == 'd' && dopt -> dnew_index != -1 ) {
122
+ lua_rawgeti (L , LUA_REGISTRYINDEX , dopt -> dnew_index );
113
123
lua_pushlstring (L , val , len );
124
+ int fail = lua_pcall (L , 1 , 1 , 0 );
125
+ if (fail ) {
126
+ lua_pop (L , 2 );
127
+ return false;
128
+ }
114
129
break ;
115
130
}
116
131
// else fallthrough
@@ -148,15 +163,15 @@ static int
148
163
safe_pg_parsetuples (struct lua_State * L )
149
164
{
150
165
PGresult * res = (PGresult * )lua_topointer (L , 1 );
151
- const char dec_cast = (char ) lua_tointeger (L , 2 );
166
+ dec_opt_t * dopt = (dec_opt_t * ) lua_topointer (L , 2 );
152
167
int row , rows = PQntuples (res );
153
168
int col , cols = PQnfields (res );
154
169
lua_newtable (L );
155
170
for (row = 0 ; row < rows ; ++ row ) {
156
171
lua_pushnumber (L , row + 1 );
157
172
lua_newtable (L );
158
173
for (col = 0 ; col < cols ; ++ col )
159
- parse_pg_value (L , dec_cast , res , row , col );
174
+ parse_pg_value (L , dopt , res , row , col );
160
175
lua_settable (L , -3 );
161
176
}
162
177
return 1 ;
@@ -213,7 +228,7 @@ pg_wait_for_result(PGconn *conn)
213
228
* Appends result fom postgres to lua table
214
229
*/
215
230
static int
216
- pg_resultget (struct lua_State * L , const char dec_cast , PGconn * conn , int * res_no , int status_ok )
231
+ pg_resultget (struct lua_State * L , dec_opt_t * dopt , PGconn * conn , int * res_no , int status_ok )
217
232
{
218
233
int wait_res = pg_wait_for_result (conn );
219
234
if (wait_res != 1 )
@@ -243,7 +258,7 @@ pg_resultget(struct lua_State *L, const char dec_cast, PGconn *conn, int *res_no
243
258
lua_pushinteger (L , (* res_no )++ );
244
259
lua_pushcfunction (L , safe_pg_parsetuples );
245
260
lua_pushlightuserdata (L , pg_res );
246
- lua_pushinteger (L , dec_cast );
261
+ lua_pushlightuserdata (L , dopt );
247
262
fail = lua_pcall (L , 2 , 1 , 0 );
248
263
if (!fail )
249
264
lua_settable (L , -3 );
@@ -338,19 +353,25 @@ lua_pg_execute(struct lua_State *L)
338
353
{
339
354
PGconn * conn = lua_check_pgconn (L , 1 );
340
355
341
- char dec_cast = 'n' ;
356
+ dec_opt_t dopt = { 'n' , -1 } ;
342
357
if (lua_isstring (L , 2 )) {
343
358
const char * tmp = lua_tostring (L , 2 );
344
- if (* tmp == 'n' || * tmp == 's' ) // TODO 'd' - decimal
345
- dec_cast = * tmp ;
359
+ if (* tmp == 'n' || * tmp == 's' || * tmp == 'd' )
360
+ dopt . cast = * tmp ;
346
361
}
347
362
348
- if (!lua_isstring (L , 3 )) {
363
+ if (!lua_isstring (L , 4 )) {
349
364
safe_pushstring (L , "Second param should be a sql command" );
350
365
return lua_push_error (L );
351
366
}
352
- const char * sql = lua_tostring (L , 3 );
353
- int paramCount = lua_gettop (L ) - 3 ;
367
+
368
+ if (lua_isfunction (L , 3 )) {
369
+ lua_pushvalue (L , 3 );
370
+ dopt .dnew_index = luaL_ref (L , LUA_REGISTRYINDEX );
371
+ }
372
+
373
+ const char * sql = lua_tostring (L , 4 );
374
+ int paramCount = lua_gettop (L ) - 4 ;
354
375
355
376
const char * * paramValues = NULL ;
356
377
int * paramLengths = NULL ;
@@ -371,7 +392,7 @@ lua_pg_execute(struct lua_State *L)
371
392
372
393
int idx ;
373
394
for (idx = 0 ; idx < paramCount ; ++ idx ) {
374
- lua_parse_param (L , idx + 4 , paramValues + idx ,
395
+ lua_parse_param (L , idx + 5 , paramValues + idx ,
375
396
paramLengths + idx , paramTypes + idx );
376
397
}
377
398
res = PQsendQueryParams (conn , sql , paramCount , paramTypes ,
@@ -383,14 +404,19 @@ lua_pg_execute(struct lua_State *L)
383
404
if (res == -1 ) {
384
405
lua_pushinteger (L , PQstatus (conn ) == CONNECTION_BAD ? -1 : 0 );
385
406
lua_pushstring (L , PQerrorMessage (conn ));
407
+ if (dopt .dnew_index != -1 )
408
+ luaL_unref (L , LUA_REGISTRYINDEX , dopt .dnew_index );
386
409
return 2 ;
387
410
}
388
411
lua_pushinteger (L , 0 );
389
412
lua_newtable (L );
390
413
391
414
int res_no = 1 ;
392
415
int status_ok = 1 ;
393
- while ((status_ok = pg_resultget (L , dec_cast , conn , & res_no , status_ok )));
416
+ while ((status_ok = pg_resultget (L , & dopt , conn , & res_no , status_ok )));
417
+
418
+ if (dopt .dnew_index != -1 )
419
+ luaL_unref (L , LUA_REGISTRYINDEX , dopt .dnew_index );
394
420
395
421
return 2 ;
396
422
}
0 commit comments