Tue, 01 Sep 2009 13:15:02 +0000
Add __tostring method to connection and statement objects.
1 | 1 | #include "dbd_postgresql.h" |
2 | ||
3 | static lua_push_type_t postgresql_to_lua_push(unsigned int postgresql_type) { | |
4 | lua_push_type_t lua_type; | |
5 | ||
6 | switch(postgresql_type) { | |
7 | case INT2OID: | |
8 | case INT4OID: | |
20
5ab0b30f8fbd
Bugfix: the type return by 'select count(...)' was being pushed as a string because of missing psql => lua type mapping.
nrich@ii.net
parents:
17
diff
changeset
|
9 | case INT8OID: |
1 | 10 | lua_type = LUA_PUSH_INTEGER; |
11 | break; | |
12 | ||
13 | case FLOAT4OID: | |
14 | case FLOAT8OID: | |
15 | lua_type = LUA_PUSH_NUMBER; | |
16 | break; | |
17 | ||
18 | case BOOLOID: | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
19 | lua_type = LUA_PUSH_BOOLEAN; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
20 | break; |
1 | 21 | |
22 | default: | |
23 | lua_type = LUA_PUSH_STRING; | |
24 | } | |
25 | ||
26 | return lua_type; | |
27 | } | |
28 | ||
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
29 | static int deallocate(statement_t *statement) { |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
30 | char command[IDLEN+11]; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
31 | |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
32 | snprintf(command, IDLEN+11, "DEALLOCATE %s", statement->name); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
33 | |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
34 | PGresult *result = PQexec(statement->postgresql, command); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
35 | ExecStatusType status; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
36 | |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
37 | if (!result) |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
38 | return 1; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
39 | |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
40 | status = PQresultStatus(result); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
41 | PQclear(result); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
42 | |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
43 | if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
44 | return 1; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
45 | |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
46 | return 0; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
47 | } |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
48 | |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
49 | |
21
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
50 | /* |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
51 | * num_affected_rows = statement:affected() |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
52 | */ |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
53 | static int statement_affected(lua_State *L) { |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
54 | statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
55 | |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
56 | if (!statement->result) { |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
57 | luaL_error(L, DBI_ERR_INVALID_STATEMENT); |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
58 | } |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
59 | |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
60 | lua_pushinteger(L, atoi(PQcmdTuples(statement->result))); |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
61 | |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
62 | return 1; |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
63 | } |
1 | 64 | |
2 | 65 | /* |
66 | * success = statement:close() | |
67 | */ | |
1 | 68 | static int statement_close(lua_State *L) { |
69 | statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); | |
70 | ||
71 | if (statement->result) { | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
72 | /* |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
73 | * Deallocate prepared statement on the |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
74 | * server side |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
75 | */ |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
76 | deallocate(statement); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
77 | |
1 | 78 | PQclear(statement->result); |
79 | statement->result = NULL; | |
80 | } | |
81 | ||
82 | return 0; | |
83 | } | |
84 | ||
2 | 85 | /* |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
86 | * column_names = statement:columns() |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
87 | */ |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
88 | static int statement_columns(lua_State *L) { |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
89 | statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
90 | |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
91 | int i; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
92 | int num_columns; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
93 | int d = 1; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
94 | |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
95 | if (!statement->result) { |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
96 | luaL_error(L, DBI_ERR_INVALID_STATEMENT); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
97 | return 0; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
98 | } |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
99 | |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
100 | num_columns = PQnfields(statement->result); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
101 | lua_newtable(L); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
102 | for (i = 0; i < num_columns; i++) { |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
103 | const char *name = PQfname(statement->result, i); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
104 | |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
105 | LUA_PUSH_ARRAY_STRING(d, name); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
106 | } |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
107 | |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
108 | return 1; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
109 | } |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
110 | |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
111 | /* |
2 | 112 | * success = statement:execute(...) |
113 | */ | |
1 | 114 | static int statement_execute(lua_State *L) { |
115 | int n = lua_gettop(L); | |
116 | statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); | |
117 | int num_bind_params = n - 1; | |
118 | ExecStatusType status; | |
119 | int p; | |
10 | 120 | const char *errstr = NULL; |
1 | 121 | |
9 | 122 | const char **params; |
1 | 123 | PGresult *result = NULL; |
124 | ||
125 | statement->tuple = 0; | |
126 | ||
127 | params = malloc(num_bind_params * sizeof(params)); | |
11
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
128 | memset(params, 0, num_bind_params * sizeof(params)); |
1 | 129 | |
2 | 130 | /* |
131 | * convert and copy parameters into a string array | |
132 | */ | |
1 | 133 | for (p = 2; p <= n; p++) { |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
134 | int i = p - 2; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
135 | int type = lua_type(L, p); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
136 | char err[64]; |
1 | 137 | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
138 | switch(type) { |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
139 | case LUA_TNIL: |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
140 | params[i] = NULL; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
141 | break; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
142 | case LUA_TBOOLEAN: |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
143 | /* |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
144 | * boolean values in postgresql can either be |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
145 | * t/f or 1/0. Pass integer values rather than |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
146 | * strings to maintain semantic compatibility |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
147 | * with other DBD drivers that pass booleans |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
148 | * as integers. |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
149 | */ |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
150 | params[i] = lua_toboolean(L, p) ? "1" : "0"; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
151 | break; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
152 | case LUA_TNUMBER: |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
153 | case LUA_TSTRING: |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
154 | params[i] = lua_tostring(L, p); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
155 | break; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
156 | default: |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
157 | snprintf(err, sizeof(err)-1, DBI_ERR_BINDING_TYPE_ERR, lua_typename(L, type)); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
158 | errstr = err; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
159 | goto cleanup; |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
160 | } |
1 | 161 | } |
162 | ||
163 | result = PQexecPrepared( | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
164 | statement->postgresql, |
1 | 165 | statement->name, |
166 | num_bind_params, | |
167 | (const char **)params, | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
168 | NULL, |
1 | 169 | NULL, |
170 | 0 | |
171 | ); | |
172 | ||
10 | 173 | cleanup: |
1 | 174 | free(params); |
175 | ||
10 | 176 | if (errstr) { |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
177 | lua_pushboolean(L, 0); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
178 | lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, errstr); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
179 | return 2; |
10 | 180 | } |
181 | ||
1 | 182 | if (!result) { |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
183 | lua_pushboolean(L, 0); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
184 | lua_pushfstring(L, DBI_ERR_ALLOC_RESULT, PQerrorMessage(statement->postgresql)); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
185 | return 2; |
1 | 186 | } |
187 | ||
188 | status = PQresultStatus(result); | |
189 | if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) { | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
190 | lua_pushboolean(L, 0); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
191 | lua_pushfstring(L, DBI_ERR_BINDING_EXEC, PQresultErrorMessage(result)); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
192 | return 2; |
1 | 193 | } |
194 | ||
195 | statement->result = result; | |
196 | ||
197 | lua_pushboolean(L, 1); | |
198 | return 1; | |
199 | } | |
200 | ||
2 | 201 | /* |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
202 | * can only be called after an execute |
2 | 203 | */ |
11
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
204 | static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) { |
1 | 205 | int tuple = statement->tuple++; |
206 | int i; | |
207 | int num_columns; | |
12
014ba3ab3903
Renamed statement:fetch() to statement:rows(), and statement:row() to statement:fetch(). The API reads better this way.
nrich@ii.net
parents:
11
diff
changeset
|
208 | int d = 1; |
1 | 209 | |
3 | 210 | if (!statement->result) { |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
211 | luaL_error(L, DBI_ERR_FETCH_INVALID); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
212 | return 0; |
3 | 213 | } |
214 | ||
1 | 215 | if (PQresultStatus(statement->result) != PGRES_TUPLES_OK) { |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
216 | lua_pushnil(L); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
217 | return 1; |
1 | 218 | } |
219 | ||
220 | if (tuple >= PQntuples(statement->result)) { | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
221 | lua_pushnil(L); /* no more results */ |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
222 | return 1; |
1 | 223 | } |
224 | ||
225 | num_columns = PQnfields(statement->result); | |
226 | lua_newtable(L); | |
227 | for (i = 0; i < num_columns; i++) { | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
228 | const char *name = PQfname(statement->result, i); |
1 | 229 | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
230 | if (PQgetisnull(statement->result, tuple, i)) { |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
231 | if (named_columns) { |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
232 | LUA_PUSH_ATTRIB_NIL(name); |
1 | 233 | } else { |
234 | LUA_PUSH_ARRAY_NIL(d); | |
235 | } | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
236 | } else { |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
237 | const char *value = PQgetvalue(statement->result, tuple, i); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
238 | lua_push_type_t lua_push = postgresql_to_lua_push(PQftype(statement->result, i)); |
1 | 239 | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
240 | /* |
2 | 241 | * data is returned as strings from PSQL |
9 | 242 | * convert them here into Lua types |
2 | 243 | */ |
244 | ||
1 | 245 | if (lua_push == LUA_PUSH_NIL) { |
246 | if (named_columns) { | |
247 | LUA_PUSH_ATTRIB_NIL(name); | |
248 | } else { | |
249 | LUA_PUSH_ARRAY_NIL(d); | |
250 | } | |
251 | } else if (lua_push == LUA_PUSH_INTEGER) { | |
252 | int val = atoi(value); | |
253 | ||
254 | if (named_columns) { | |
255 | LUA_PUSH_ATTRIB_INT(name, val); | |
256 | } else { | |
257 | LUA_PUSH_ARRAY_INT(d, val); | |
258 | } | |
259 | } else if (lua_push == LUA_PUSH_NUMBER) { | |
260 | double val = strtod(value, NULL); | |
261 | ||
262 | if (named_columns) { | |
263 | LUA_PUSH_ATTRIB_FLOAT(name, val); | |
264 | } else { | |
265 | LUA_PUSH_ARRAY_FLOAT(d, val); | |
266 | } | |
267 | } else if (lua_push == LUA_PUSH_STRING) { | |
268 | if (named_columns) { | |
269 | LUA_PUSH_ATTRIB_STRING(name, value); | |
270 | } else { | |
271 | LUA_PUSH_ARRAY_STRING(d, value); | |
272 | } | |
273 | } else if (lua_push == LUA_PUSH_BOOLEAN) { | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
274 | /* |
2 | 275 | * booleans are returned as a string |
276 | * either 't' or 'f' | |
277 | */ | |
1 | 278 | int val = value[0] == 't' ? 1 : 0; |
279 | ||
280 | if (named_columns) { | |
281 | LUA_PUSH_ATTRIB_BOOL(name, val); | |
282 | } else { | |
283 | LUA_PUSH_ARRAY_BOOL(d, val); | |
284 | } | |
285 | } else { | |
4 | 286 | luaL_error(L, DBI_ERR_UNKNOWN_PUSH); |
1 | 287 | } |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
288 | } |
1 | 289 | } |
290 | ||
291 | return 1; | |
292 | } | |
293 | ||
11
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
294 | |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
295 | static int next_iterator(lua_State *L) { |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
296 | statement_t *statement = (statement_t *)luaL_checkudata(L, lua_upvalueindex(1), DBD_POSTGRESQL_STATEMENT); |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
297 | int named_columns = lua_toboolean(L, lua_upvalueindex(2)); |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
298 | |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
299 | return statement_fetch_impl(L, statement, named_columns); |
1 | 300 | } |
301 | ||
2 | 302 | /* |
12
014ba3ab3903
Renamed statement:fetch() to statement:rows(), and statement:row() to statement:fetch(). The API reads better this way.
nrich@ii.net
parents:
11
diff
changeset
|
303 | * table = statement:fetch(named_indexes) |
2 | 304 | */ |
12
014ba3ab3903
Renamed statement:fetch() to statement:rows(), and statement:row() to statement:fetch(). The API reads better this way.
nrich@ii.net
parents:
11
diff
changeset
|
305 | static int statement_fetch(lua_State *L) { |
014ba3ab3903
Renamed statement:fetch() to statement:rows(), and statement:row() to statement:fetch(). The API reads better this way.
nrich@ii.net
parents:
11
diff
changeset
|
306 | statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); |
014ba3ab3903
Renamed statement:fetch() to statement:rows(), and statement:row() to statement:fetch(). The API reads better this way.
nrich@ii.net
parents:
11
diff
changeset
|
307 | int named_columns = lua_toboolean(L, 2); |
11
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
308 | |
12
014ba3ab3903
Renamed statement:fetch() to statement:rows(), and statement:row() to statement:fetch(). The API reads better this way.
nrich@ii.net
parents:
11
diff
changeset
|
309 | return statement_fetch_impl(L, statement, named_columns); |
014ba3ab3903
Renamed statement:fetch() to statement:rows(), and statement:row() to statement:fetch(). The API reads better this way.
nrich@ii.net
parents:
11
diff
changeset
|
310 | } |
014ba3ab3903
Renamed statement:fetch() to statement:rows(), and statement:row() to statement:fetch(). The API reads better this way.
nrich@ii.net
parents:
11
diff
changeset
|
311 | |
014ba3ab3903
Renamed statement:fetch() to statement:rows(), and statement:row() to statement:fetch(). The API reads better this way.
nrich@ii.net
parents:
11
diff
changeset
|
312 | /* |
21
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
313 | * num_rows = statement:rowcount() |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
314 | */ |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
315 | static int statement_rowcount(lua_State *L) { |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
316 | statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
317 | |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
318 | if (!statement->result) { |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
319 | luaL_error(L, DBI_ERR_INVALID_STATEMENT); |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
320 | } |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
321 | |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
322 | lua_pushinteger(L, PQntuples(statement->result)); |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
323 | |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
324 | return 1; |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
325 | } |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
326 | |
7956401a0c5e
Added the statement:affected() and statement:rowcount() methods.
nrich@ii.net
parents:
20
diff
changeset
|
327 | /* |
12
014ba3ab3903
Renamed statement:fetch() to statement:rows(), and statement:row() to statement:fetch(). The API reads better this way.
nrich@ii.net
parents:
11
diff
changeset
|
328 | * iterfunc = statement:rows(named_indexes) |
014ba3ab3903
Renamed statement:fetch() to statement:rows(), and statement:row() to statement:fetch(). The API reads better this way.
nrich@ii.net
parents:
11
diff
changeset
|
329 | */ |
014ba3ab3903
Renamed statement:fetch() to statement:rows(), and statement:row() to statement:fetch(). The API reads better this way.
nrich@ii.net
parents:
11
diff
changeset
|
330 | static int statement_rows(lua_State *L) { |
11
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
331 | if (lua_gettop(L) == 1) { |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
332 | lua_pushvalue(L, 1); |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
333 | lua_pushboolean(L, 0); |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
334 | } else { |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
335 | lua_pushvalue(L, 1); |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
336 | lua_pushboolean(L, lua_toboolean(L, 2)); |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
337 | } |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
338 | |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
339 | lua_pushcclosure(L, next_iterator, 2); |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
340 | return 1; |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
341 | } |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
342 | |
b3e05e361f46
Bugfix: PSQL array returns were not being indexed properly.
nrich@ii.net
parents:
10
diff
changeset
|
343 | /* |
2 | 344 | * __gc |
345 | */ | |
1 | 346 | static int statement_gc(lua_State *L) { |
347 | /* always free the handle */ | |
348 | statement_close(L); | |
349 | ||
350 | return 0; | |
351 | } | |
352 | ||
32
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
353 | /* |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
354 | * __tostring |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
355 | */ |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
356 | static int statement_tostring(lua_State *L) { |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
357 | statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
358 | |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
359 | lua_pushfstring(L, "%s: %p", DBD_POSTGRESQL_STATEMENT, statement); |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
360 | |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
361 | return 1; |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
362 | } |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
363 | |
1 | 364 | int dbd_postgresql_statement_create(lua_State *L, connection_t *conn, const char *sql_query) { |
365 | statement_t *statement = NULL; | |
366 | ExecStatusType status; | |
367 | PGresult *result = NULL; | |
368 | char *new_sql; | |
369 | char name[IDLEN]; | |
370 | ||
2 | 371 | /* |
372 | * convert SQL string into a PSQL API compatible SQL statement | |
373 | */ | |
17
21c4feaeafe7
Added initial Oracle driver support - functionality is complete, but may be too buggy in its current state for any serious use.
nrich@ii.net
parents:
12
diff
changeset
|
374 | new_sql = replace_placeholders(L, '$', sql_query); |
1 | 375 | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
376 | snprintf(name, IDLEN, "dbd-postgresql-%017u", ++conn->statement_id); |
1 | 377 | |
378 | result = PQprepare(conn->postgresql, name, new_sql, 0, NULL); | |
2 | 379 | |
380 | /* | |
381 | * free converted statement after use | |
382 | */ | |
1 | 383 | free(new_sql); |
384 | ||
385 | if (!result) { | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
386 | lua_pushnil(L); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
387 | lua_pushfstring(L, DBI_ERR_ALLOC_STATEMENT, PQerrorMessage(statement->postgresql)); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
388 | return 2; |
1 | 389 | } |
390 | ||
391 | status = PQresultStatus(result); | |
392 | if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) { | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
393 | const char *err_string = PQresultErrorMessage(result); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
394 | PQclear(result); |
3 | 395 | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
396 | lua_pushnil(L); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
397 | lua_pushfstring(L, DBI_ERR_PREP_STATEMENT, err_string); |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
398 | return 2; |
1 | 399 | } |
400 | ||
401 | PQclear(result); | |
402 | ||
403 | statement = (statement_t *)lua_newuserdata(L, sizeof(statement_t)); | |
404 | statement->postgresql = conn->postgresql; | |
405 | statement->result = NULL; | |
406 | statement->tuple = 0; | |
407 | strncpy(statement->name, name, IDLEN-1); | |
408 | statement->name[IDLEN-1] = '\0'; | |
409 | ||
410 | luaL_getmetatable(L, DBD_POSTGRESQL_STATEMENT); | |
411 | lua_setmetatable(L, -2); | |
412 | ||
413 | return 1; | |
414 | } | |
415 | ||
416 | int dbd_postgresql_statement(lua_State *L) { | |
2 | 417 | static const luaL_Reg statement_methods[] = { |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
418 | {"affected", statement_affected}, |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
419 | {"close", statement_close}, |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
420 | {"columns", statement_columns}, |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
421 | {"execute", statement_execute}, |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
422 | {"fetch", statement_fetch}, |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
423 | {"rowcount", statement_rowcount}, |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
424 | {"rows", statement_rows}, |
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
425 | {NULL, NULL} |
2 | 426 | }; |
427 | ||
428 | static const luaL_Reg statement_class_methods[] = { | |
30
8599f34c139b
Add 'columns' method to statement handles to retrieve column names from a result set
nrich@ii.net
parents:
21
diff
changeset
|
429 | {NULL, NULL} |
2 | 430 | }; |
431 | ||
1 | 432 | luaL_newmetatable(L, DBD_POSTGRESQL_STATEMENT); |
433 | luaL_register(L, 0, statement_methods); | |
434 | lua_pushvalue(L,-1); | |
435 | lua_setfield(L, -2, "__index"); | |
436 | ||
437 | lua_pushcfunction(L, statement_gc); | |
438 | lua_setfield(L, -2, "__gc"); | |
439 | ||
32
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
440 | lua_pushcfunction(L, statement_tostring); |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
441 | lua_setfield(L, -2, "__tostring"); |
03ed0ca09837
Add __tostring method to connection and statement objects.
nrich@ii.net
parents:
30
diff
changeset
|
442 | |
1 | 443 | luaL_register(L, DBD_POSTGRESQL_STATEMENT, statement_class_methods); |
444 | ||
445 | return 1; | |
446 | } |