dbd/mysql/statement.c

Sat, 29 Nov 2008 00:51:14 +0000

author
nrich@ii.net
date
Sat, 29 Nov 2008 00:51:14 +0000
changeset 7
4480ae002881
parent 6
22046b996150
child 9
06eb2850703f
permissions
-rw-r--r--

Bugfix - the size of strings for bind params pointed to the same memory

1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
1 #include "dbd_mysql.h"
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
2
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
3 static lua_push_type_t mysql_to_lua_push(unsigned int mysql_type) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
4 lua_push_type_t lua_type;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
5
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
6 switch(mysql_type) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
7 case MYSQL_TYPE_NULL:
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
8 lua_type = LUA_PUSH_NIL;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
9 break;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
10
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
11 case MYSQL_TYPE_TINY:
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
12 case MYSQL_TYPE_SHORT:
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
13 case MYSQL_TYPE_LONG:
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
14 lua_type = LUA_PUSH_INTEGER;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
15 break;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
16
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
17 case MYSQL_TYPE_DOUBLE:
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
18 case MYSQL_TYPE_LONGLONG:
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
19 lua_type = LUA_PUSH_NUMBER;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
20 break;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
21
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
22 default:
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
23 lua_type = LUA_PUSH_STRING;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
24 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
25
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
26 return lua_type;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
27 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
28
2
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
29 /*
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
30 * success = statement:close()
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
31 */
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
32 static int statement_close(lua_State *L) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
33 statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_MYSQL_STATEMENT);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
34
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
35 if (statement->metadata) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
36 mysql_free_result(statement->metadata);
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
37 statement->metadata = NULL;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
38 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
39
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
40 if (statement->stmt) {
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
41 mysql_stmt_close(statement->stmt);
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
42 statement->stmt = NULL;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
43 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
44
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
45 lua_pushboolean(L, 1);
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
46 return 1;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
47 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
48
2
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
49 /*
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
50 * success,err = statement:execute(...)
2
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
51 */
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
52 static int statement_execute(lua_State *L) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
53 int n = lua_gettop(L);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
54 statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_MYSQL_STATEMENT);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
55 int num_bind_params = n - 1;
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
56 int expected_params;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
57
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
58 MYSQL_BIND *bind = NULL;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
59 MYSQL_RES *metadata = NULL;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
60
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
61 char *error_message = NULL;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
62
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
63 int p;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
64
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
65 if (!statement->stmt) {
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
66 lua_pushboolean(L, 0);
4
c50b0e6f25d6 Clean up error messages for consistency.
nrich@ii.net
parents: 3
diff changeset
67 lua_pushstring(L, DBI_ERR_EXECUTE_INVALID);
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
68 return 2;
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
69 }
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
70
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
71 expected_params = mysql_stmt_param_count(statement->stmt);
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
72
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
73 if (expected_params != num_bind_params) {
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
74 /*
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
75 * mysql_stmt_bind_param does not handle this conndition,
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
76 * and the client library will segfault if these do no match
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
77 */
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
78 lua_pushboolean(L, 0);
4
c50b0e6f25d6 Clean up error messages for consistency.
nrich@ii.net
parents: 3
diff changeset
79 lua_pushfstring(L, DBI_ERR_PARAM_MISCOUNT, expected_params, num_bind_params);
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
80 return 2;
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
81 }
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
82
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
83 bind = malloc(sizeof(MYSQL_BIND) * num_bind_params);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
84 memset(bind, 0, sizeof(MYSQL_BIND) * num_bind_params);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
85
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
86 for (p = 2; p <= n; p++) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
87 int type = lua_type(L, p);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
88 int i = p - 2;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
89
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
90 const char *str = NULL;
7
4480ae002881 Bugfix - the size of strings for bind params pointed to the same memory
nrich@ii.net
parents: 6
diff changeset
91 size_t *str_len = NULL;
6
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
92 double *num = NULL;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
93
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
94 switch(type) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
95 case LUA_TNIL:
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
96 bind[i].buffer_type = MYSQL_TYPE_NULL;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
97 bind[i].is_null = (my_bool*)1;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
98 break;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
99
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
100 case LUA_TNUMBER:
6
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
101 /*
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
102 * num needs to be it's own
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
103 * memory here
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
104 */
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
105 num = (double *)malloc(sizeof(double));
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
106 *num = luaL_checknumber(L, p);
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
107
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
108 bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
109 bind[i].is_null = (my_bool*)0;
6
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
110 bind[i].buffer = (char *)num;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
111 bind[i].length = 0;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
112 break;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
113
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
114 case LUA_TSTRING:
7
4480ae002881 Bugfix - the size of strings for bind params pointed to the same memory
nrich@ii.net
parents: 6
diff changeset
115 str_len = malloc(sizeof(size_t));
4480ae002881 Bugfix - the size of strings for bind params pointed to the same memory
nrich@ii.net
parents: 6
diff changeset
116 str = luaL_checklstring(L, p, str_len);
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
117
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
118 bind[i].buffer_type = MYSQL_TYPE_STRING;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
119 bind[i].is_null = (my_bool*)0;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
120 bind[i].buffer = (char *)str;
7
4480ae002881 Bugfix - the size of strings for bind params pointed to the same memory
nrich@ii.net
parents: 6
diff changeset
121 bind[i].length = str_len;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
122 break;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
123
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
124 default:
4
c50b0e6f25d6 Clean up error messages for consistency.
nrich@ii.net
parents: 3
diff changeset
125 error_message = DBI_ERR_BINDING_UNKNOWN;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
126 goto cleanup;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
127 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
128 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
129
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
130 if (mysql_stmt_bind_param(statement->stmt, bind)) {
4
c50b0e6f25d6 Clean up error messages for consistency.
nrich@ii.net
parents: 3
diff changeset
131 error_message = DBI_ERR_BINDING_PARAMS;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
132 goto cleanup;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
133 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
134
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
135 if (mysql_stmt_execute(statement->stmt)) {
4
c50b0e6f25d6 Clean up error messages for consistency.
nrich@ii.net
parents: 3
diff changeset
136 error_message = DBI_ERR_BINDING_EXEC;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
137 goto cleanup;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
138 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
139
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
140 metadata = mysql_stmt_result_metadata(statement->stmt);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
141
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
142 cleanup:
6
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
143 if (bind) {
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
144 int i;
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
145
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
146 for (i = 0; i < num_bind_params; i++) {
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
147 /*
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
148 * Free the memory associated with
7
4480ae002881 Bugfix - the size of strings for bind params pointed to the same memory
nrich@ii.net
parents: 6
diff changeset
149 * the allocation of double and string
4480ae002881 Bugfix - the size of strings for bind params pointed to the same memory
nrich@ii.net
parents: 6
diff changeset
150 * bind params. If the interface are
6
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
151 * extended with other types they
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
152 * will need to be added here
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
153 */
7
4480ae002881 Bugfix - the size of strings for bind params pointed to the same memory
nrich@ii.net
parents: 6
diff changeset
154 if (bind[i].buffer_type == MYSQL_TYPE_DOUBLE) {
4480ae002881 Bugfix - the size of strings for bind params pointed to the same memory
nrich@ii.net
parents: 6
diff changeset
155 if (bind[i].buffer)
4480ae002881 Bugfix - the size of strings for bind params pointed to the same memory
nrich@ii.net
parents: 6
diff changeset
156 free(bind[i].buffer);
4480ae002881 Bugfix - the size of strings for bind params pointed to the same memory
nrich@ii.net
parents: 6
diff changeset
157 } else if (bind[i].buffer_type == MYSQL_TYPE_STRING) {
4480ae002881 Bugfix - the size of strings for bind params pointed to the same memory
nrich@ii.net
parents: 6
diff changeset
158 if (bind[i].length)
4480ae002881 Bugfix - the size of strings for bind params pointed to the same memory
nrich@ii.net
parents: 6
diff changeset
159 free(bind[i].length);
6
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
160 }
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
161 }
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
162
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
163 free(bind);
6
22046b996150 Fixed bug: double bind params were using the same variables memory space so they were all being set to the same number.
nrich@ii.net
parents: 4
diff changeset
164 }
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
165
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
166 if (error_message) {
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
167 lua_pushboolean(L, 0);
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
168 lua_pushfstring(L, error_message, mysql_stmt_error(statement->stmt));
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
169 return 2;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
170 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
171
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
172 statement->metadata = metadata;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
173
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
174 lua_pushboolean(L, 1);
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
175 return 1;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
176 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
177
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
178 static int statement_fetch_impl(lua_State *L, int named_columns) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
179 statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_MYSQL_STATEMENT);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
180 int column_count;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
181 MYSQL_BIND *bind = NULL;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
182 const char *error_message = NULL;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
183
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
184 if (!statement->stmt) {
4
c50b0e6f25d6 Clean up error messages for consistency.
nrich@ii.net
parents: 3
diff changeset
185 luaL_error(L, DBI_ERR_FETCH_INVALID);
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
186 return 0;
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
187 }
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
188
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
189 if (!statement->metadata) {
4
c50b0e6f25d6 Clean up error messages for consistency.
nrich@ii.net
parents: 3
diff changeset
190 luaL_error(L, DBI_ERR_FETCH_NO_EXECUTE);
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
191 return 0;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
192 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
193
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
194 if (!statement->metadata) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
195 lua_pushnil(L);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
196 return 1;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
197 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
198
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
199 column_count = mysql_num_fields(statement->metadata);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
200
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
201 if (column_count > 0) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
202 int i;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
203 MYSQL_FIELD *fields;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
204
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
205 bind = malloc(sizeof(MYSQL_BIND) * column_count);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
206 memset(bind, 0, sizeof(MYSQL_BIND) * column_count);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
207
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
208 fields = mysql_fetch_fields(statement->metadata);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
209
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
210 for (i = 0; i < column_count; i++) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
211 unsigned int length = fields[i].length;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
212
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
213 char *buffer = (char *)malloc(length);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
214 memset(buffer, 0, length);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
215
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
216 bind[i].buffer_type = fields[i].type;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
217 bind[i].buffer = buffer;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
218 bind[i].buffer_length = length;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
219 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
220
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
221 if (mysql_stmt_bind_result(statement->stmt, bind)) {
4
c50b0e6f25d6 Clean up error messages for consistency.
nrich@ii.net
parents: 3
diff changeset
222 error_message = DBI_ERR_BINDING_RESULTS;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
223 goto cleanup;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
224 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
225
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
226 if (!mysql_stmt_fetch(statement->stmt)) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
227 int d = 1;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
228
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
229 lua_newtable(L);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
230 for (i = 0; i < column_count; i++) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
231 lua_push_type_t lua_push = mysql_to_lua_push(fields[i].type);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
232 const char *name = fields[i].name;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
233
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
234 if (lua_push == LUA_PUSH_NIL) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
235 if (named_columns) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
236 LUA_PUSH_ATTRIB_NIL(name);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
237 } else {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
238 LUA_PUSH_ARRAY_NIL(d);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
239 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
240 } else if (lua_push == LUA_PUSH_INTEGER) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
241 if (named_columns) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
242 LUA_PUSH_ATTRIB_INT(name, *(int *)(bind[i].buffer));
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
243 } else {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
244 LUA_PUSH_ARRAY_INT(d, *(int *)(bind[i].buffer));
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
245 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
246 } else if (lua_push == LUA_PUSH_NUMBER) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
247 if (named_columns) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
248 LUA_PUSH_ATTRIB_FLOAT(name, *(double *)(bind[i].buffer));
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
249 } else {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
250 LUA_PUSH_ARRAY_FLOAT(d, *(double *)(bind[i].buffer));
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
251 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
252 } else if (lua_push == LUA_PUSH_STRING) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
253 if (named_columns) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
254 LUA_PUSH_ATTRIB_STRING(name, bind[i].buffer);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
255 } else {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
256 LUA_PUSH_ARRAY_STRING(d, bind[i].buffer);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
257 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
258 } else if (lua_push == LUA_PUSH_BOOLEAN) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
259 if (named_columns) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
260 LUA_PUSH_ATTRIB_BOOL(name, *(int *)(bind[i].buffer));
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
261 } else {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
262 LUA_PUSH_ARRAY_BOOL(d, *(int *)(bind[i].buffer));
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
263 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
264 } else {
4
c50b0e6f25d6 Clean up error messages for consistency.
nrich@ii.net
parents: 3
diff changeset
265 luaL_error(L, DBI_ERR_UNKNOWN_PUSH);
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
266 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
267 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
268 } else {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
269 lua_pushnil(L);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
270 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
271 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
272
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
273 cleanup:
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
274 if (bind) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
275 int i;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
276
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
277 for (i = 0; i < column_count; i++) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
278 free(bind[i].buffer);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
279 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
280
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
281 free(bind);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
282 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
283
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
284 if (error_message) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
285 luaL_error(L, error_message, mysql_stmt_error(statement->stmt));
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
286 return 0;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
287 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
288
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
289 return 1;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
290 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
291
2
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
292 /*
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
293 * array = statement:fetch()
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
294 */
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
295 static int statement_fetch(lua_State *L) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
296 return statement_fetch_impl(L, 0);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
297 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
298
2
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
299 /*
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
300 * hashmap = statement:fetchtable()
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
301 */
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
302 static int statement_fetchtable(lua_State *L) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
303 return statement_fetch_impl(L, 1);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
304 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
305
2
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
306 /*
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
307 * __gc
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
308 */
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
309 static int statement_gc(lua_State *L) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
310 /* always free the handle */
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
311 statement_close(L);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
312
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
313 return 0;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
314 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
315
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
316 int dbd_mysql_statement_create(lua_State *L, connection_t *conn, const char *sql_query) {
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
317 unsigned long sql_len = strlen(sql_query);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
318
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
319 statement_t *statement = NULL;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
320
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
321 MYSQL_STMT *stmt = mysql_stmt_init(conn->mysql);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
322
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
323 if (!stmt) {
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
324 lua_pushnil(L);
4
c50b0e6f25d6 Clean up error messages for consistency.
nrich@ii.net
parents: 3
diff changeset
325 lua_pushfstring(L, DBI_ERR_ALLOC_STATEMENT, mysql_error(conn->mysql));
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
326 return 2;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
327 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
328
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
329 if (mysql_stmt_prepare(stmt, sql_query, sql_len)) {
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
330 lua_pushnil(L);
4
c50b0e6f25d6 Clean up error messages for consistency.
nrich@ii.net
parents: 3
diff changeset
331 lua_pushfstring(L, DBI_ERR_PREP_STATEMENT, mysql_stmt_error(stmt));
3
b61020ca4753 Cleanup and 'assert' error handling.
nrich@ii.net
parents: 2
diff changeset
332 return 2;
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
333 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
334
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
335 statement = (statement_t *)lua_newuserdata(L, sizeof(statement_t));
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
336 statement->mysql = conn->mysql;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
337 statement->stmt = stmt;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
338 statement->metadata = NULL;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
339
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
340 luaL_getmetatable(L, DBD_MYSQL_STATEMENT);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
341 lua_setmetatable(L, -2);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
342
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
343 return 1;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
344 }
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
345
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
346 int dbd_mysql_statement(lua_State *L) {
2
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
347 static const luaL_Reg statement_methods[] = {
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
348 {"close", statement_close},
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
349 {"execute", statement_execute},
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
350 {"fetch", statement_fetch},
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
351 {"fetchtable", statement_fetchtable},
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
352 {NULL, NULL}
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
353 };
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
354
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
355 static const luaL_Reg statement_class_methods[] = {
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
356 {NULL, NULL}
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
357 };
c4f02fc67e5a Cleanup and commenting
nrich@ii.net
parents: 1
diff changeset
358
1
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
359 luaL_newmetatable(L, DBD_MYSQL_STATEMENT);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
360 luaL_register(L, 0, statement_methods);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
361 lua_pushvalue(L,-1);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
362 lua_setfield(L, -2, "__index");
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
363
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
364 lua_pushcfunction(L, statement_gc);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
365 lua_setfield(L, -2, "__gc");
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
366
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
367 luaL_register(L, DBD_MYSQL_STATEMENT, statement_class_methods);
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
368
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
369 return 1;
408291a6eb3e Initial import.
nrich@ii.net
parents:
diff changeset
370 }

mercurial