This source file includes following definitions.
- ZEND_GET_MODULE
- safe_odbc_disconnect
- _close_odbc_conn
- _close_odbc_pconn
- PHP_INI_DISP
- PHP_INI_DISP
- PHP_INI_DISP
- PHP_INI_DISP
- PHP_INI_DISP
- PHP_INI_BEGIN
- PHP_MINIT_FUNCTION
- PHP_RINIT_FUNCTION
- PHP_RSHUTDOWN_FUNCTION
- PHP_MSHUTDOWN_FUNCTION
- PHP_MINFO_FUNCTION
- odbc_sql_error
- php_odbc_fetch_attribs
- odbc_bindcols
- odbc_transact
- _close_pconn_with_id
- odbc_column_lengths
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- php_odbc_fetch_hash
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- odbc_sqlconnect
- odbc_do_connect
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- php_odbc_lasterror
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "php.h"
30 #include "php_globals.h"
31
32 #include "ext/standard/info.h"
33 #include "ext/standard/php_string.h"
34 #include "ext/standard/php_standard.h"
35
36 #include "php_odbc.h"
37 #include "php_odbc_includes.h"
38 #include "php_globals.h"
39
40 #if HAVE_UODBC
41
42 #include <fcntl.h>
43 #include "ext/standard/head.h"
44 #include "php_ini.h"
45
46 #ifdef PHP_WIN32
47 #include <winsock2.h>
48
49 #define ODBC_TYPE "Win32"
50 #define PHP_ODBC_TYPE ODBC_TYPE
51
52 #endif
53
54
55
56
57
58 #ifndef TRUE
59 #define TRUE 1
60 #define FALSE 0
61 #endif
62
63 void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent);
64
65 static int le_result, le_conn, le_pconn;
66
67 #define SAFE_SQL_NTS(n) ((SQLSMALLINT) ((n)?(SQL_NTS):0))
68
69
70 ZEND_BEGIN_ARG_INFO(arginfo_odbc_close_all, 0)
71 ZEND_END_ARG_INFO()
72
73 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_binmode, 0, 0, 2)
74 ZEND_ARG_INFO(0, result_id)
75 ZEND_ARG_INFO(0, mode)
76 ZEND_END_ARG_INFO()
77
78 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_longreadlen, 0, 0, 2)
79 ZEND_ARG_INFO(0, result_id)
80 ZEND_ARG_INFO(0, length)
81 ZEND_END_ARG_INFO()
82
83 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_prepare, 0, 0, 2)
84 ZEND_ARG_INFO(0, connection_id)
85 ZEND_ARG_INFO(0, query)
86 ZEND_END_ARG_INFO()
87
88 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_execute, 0, 0, 1)
89 ZEND_ARG_INFO(0, result_id)
90 ZEND_ARG_INFO(0, parameters_array)
91 ZEND_END_ARG_INFO()
92
93 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_cursor, 0, 0, 1)
94 ZEND_ARG_INFO(0, result_id)
95 ZEND_END_ARG_INFO()
96
97 #ifdef HAVE_SQLDATASOURCES
98 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_data_source, 0, 0, 2)
99 ZEND_ARG_INFO(0, connection_id)
100 ZEND_ARG_INFO(0, fetch_type)
101 ZEND_END_ARG_INFO()
102 #endif
103
104 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_exec, 0, 0, 2)
105 ZEND_ARG_INFO(0, connection_id)
106 ZEND_ARG_INFO(0, query)
107 ZEND_ARG_INFO(0, flags)
108 ZEND_END_ARG_INFO()
109
110 #ifdef PHP_ODBC_HAVE_FETCH_HASH
111 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_fetch_object, 0, 0, 1)
112 ZEND_ARG_INFO(0, result)
113 ZEND_ARG_INFO(0, rownumber)
114 ZEND_END_ARG_INFO()
115
116 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_fetch_array, 0, 0, 1)
117 ZEND_ARG_INFO(0, result)
118 ZEND_ARG_INFO(0, rownumber)
119 ZEND_END_ARG_INFO()
120 #endif
121
122 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_fetch_into, 0, 0, 2)
123 ZEND_ARG_INFO(0, result_id)
124 ZEND_ARG_INFO(1, result_array)
125 ZEND_ARG_INFO(0, rownumber)
126 ZEND_END_ARG_INFO()
127
128 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_fetch_row, 0, 0, 1)
129 ZEND_ARG_INFO(0, result_id)
130 ZEND_ARG_INFO(0, row_number)
131 ZEND_END_ARG_INFO()
132
133 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_result, 0, 0, 2)
134 ZEND_ARG_INFO(0, result_id)
135 ZEND_ARG_INFO(0, field)
136 ZEND_END_ARG_INFO()
137
138 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_result_all, 0, 0, 1)
139 ZEND_ARG_INFO(0, result_id)
140 ZEND_ARG_INFO(0, format)
141 ZEND_END_ARG_INFO()
142
143 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_free_result, 0, 0, 1)
144 ZEND_ARG_INFO(0, result_id)
145 ZEND_END_ARG_INFO()
146
147 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_connect, 0, 0, 3)
148 ZEND_ARG_INFO(0, dsn)
149 ZEND_ARG_INFO(0, user)
150 ZEND_ARG_INFO(0, password)
151 ZEND_ARG_INFO(0, cursor_option)
152 ZEND_END_ARG_INFO()
153
154 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_pconnect, 0, 0, 3)
155 ZEND_ARG_INFO(0, dsn)
156 ZEND_ARG_INFO(0, user)
157 ZEND_ARG_INFO(0, password)
158 ZEND_ARG_INFO(0, cursor_option)
159 ZEND_END_ARG_INFO()
160
161 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_close, 0, 0, 1)
162 ZEND_ARG_INFO(0, connection_id)
163 ZEND_END_ARG_INFO()
164
165 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_num_rows, 0, 0, 1)
166 ZEND_ARG_INFO(0, result_id)
167 ZEND_END_ARG_INFO()
168
169 #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30)
170 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_next_result, 0, 0, 1)
171 ZEND_ARG_INFO(0, result_id)
172 ZEND_END_ARG_INFO()
173 #endif
174
175 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_num_fields, 0, 0, 1)
176 ZEND_ARG_INFO(0, result_id)
177 ZEND_END_ARG_INFO()
178
179 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_field_name, 0, 0, 2)
180 ZEND_ARG_INFO(0, result_id)
181 ZEND_ARG_INFO(0, field_number)
182 ZEND_END_ARG_INFO()
183
184 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_field_type, 0, 0, 2)
185 ZEND_ARG_INFO(0, result_id)
186 ZEND_ARG_INFO(0, field_number)
187 ZEND_END_ARG_INFO()
188
189 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_field_len, 0, 0, 2)
190 ZEND_ARG_INFO(0, result_id)
191 ZEND_ARG_INFO(0, field_number)
192 ZEND_END_ARG_INFO()
193
194 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_field_scale, 0, 0, 2)
195 ZEND_ARG_INFO(0, result_id)
196 ZEND_ARG_INFO(0, field_number)
197 ZEND_END_ARG_INFO()
198
199 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_field_num, 0, 0, 2)
200 ZEND_ARG_INFO(0, result_id)
201 ZEND_ARG_INFO(0, field_name)
202 ZEND_END_ARG_INFO()
203
204 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_autocommit, 0, 0, 1)
205 ZEND_ARG_INFO(0, connection_id)
206 ZEND_ARG_INFO(0, onoff)
207 ZEND_END_ARG_INFO()
208
209 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_commit, 0, 0, 1)
210 ZEND_ARG_INFO(0, connection_id)
211 ZEND_END_ARG_INFO()
212
213 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_rollback, 0, 0, 1)
214 ZEND_ARG_INFO(0, connection_id)
215 ZEND_END_ARG_INFO()
216
217 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_error, 0, 0, 0)
218 ZEND_ARG_INFO(0, connection_id)
219 ZEND_END_ARG_INFO()
220
221 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_errormsg, 0, 0, 0)
222 ZEND_ARG_INFO(0, connection_id)
223 ZEND_END_ARG_INFO()
224
225 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_setoption, 0, 0, 4)
226 ZEND_ARG_INFO(0, conn_id)
227 ZEND_ARG_INFO(0, which)
228 ZEND_ARG_INFO(0, option)
229 ZEND_ARG_INFO(0, value)
230 ZEND_END_ARG_INFO()
231
232 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_tables, 0, 0, 1)
233 ZEND_ARG_INFO(0, connection_id)
234 ZEND_ARG_INFO(0, qualifier)
235 ZEND_ARG_INFO(0, owner)
236 ZEND_ARG_INFO(0, name)
237 ZEND_ARG_INFO(0, table_types)
238 ZEND_END_ARG_INFO()
239
240 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_columns, 0, 0, 1)
241 ZEND_ARG_INFO(0, connection_id)
242 ZEND_ARG_INFO(0, qualifier)
243 ZEND_ARG_INFO(0, owner)
244 ZEND_ARG_INFO(0, table_name)
245 ZEND_ARG_INFO(0, column_name)
246 ZEND_END_ARG_INFO()
247
248 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_gettypeinfo, 0, 0, 1)
249 ZEND_ARG_INFO(0, connection_id)
250 ZEND_ARG_INFO(0, data_type)
251 ZEND_END_ARG_INFO()
252
253 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_primarykeys, 0, 0, 4)
254 ZEND_ARG_INFO(0, connection_id)
255 ZEND_ARG_INFO(0, qualifier)
256 ZEND_ARG_INFO(0, owner)
257 ZEND_ARG_INFO(0, table)
258 ZEND_END_ARG_INFO()
259
260 #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35)
261 #if !defined(HAVE_BIRDSTEP)
262 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_procedurecolumns, 0, 0, 1)
263 ZEND_ARG_INFO(0, connection_id)
264 ZEND_ARG_INFO(0, qualifier)
265 ZEND_ARG_INFO(0, owner)
266 ZEND_ARG_INFO(0, proc)
267 ZEND_ARG_INFO(0, column)
268 ZEND_END_ARG_INFO()
269 #endif
270
271 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_procedures, 0, 0, 1)
272 ZEND_ARG_INFO(0, connection_id)
273 ZEND_ARG_INFO(0, qualifier)
274 ZEND_ARG_INFO(0, owner)
275 ZEND_ARG_INFO(0, name)
276 ZEND_END_ARG_INFO()
277
278 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_foreignkeys, 0, 0, 7)
279 ZEND_ARG_INFO(0, connection_id)
280 ZEND_ARG_INFO(0, pk_qualifier)
281 ZEND_ARG_INFO(0, pk_owner)
282 ZEND_ARG_INFO(0, pk_table)
283 ZEND_ARG_INFO(0, fk_qualifier)
284 ZEND_ARG_INFO(0, fk_owner)
285 ZEND_ARG_INFO(0, fk_table)
286 ZEND_END_ARG_INFO()
287 #endif
288
289 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_specialcolumns, 0, 0, 7)
290 ZEND_ARG_INFO(0, connection_id)
291 ZEND_ARG_INFO(0, type)
292 ZEND_ARG_INFO(0, qualifier)
293 ZEND_ARG_INFO(0, owner)
294 ZEND_ARG_INFO(0, table)
295 ZEND_ARG_INFO(0, scope)
296 ZEND_ARG_INFO(0, nullable)
297 ZEND_END_ARG_INFO()
298
299 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_statistics, 0, 0, 6)
300 ZEND_ARG_INFO(0, connection_id)
301 ZEND_ARG_INFO(0, qualifier)
302 ZEND_ARG_INFO(0, owner)
303 ZEND_ARG_INFO(0, name)
304 ZEND_ARG_INFO(0, unique)
305 ZEND_ARG_INFO(0, accuracy)
306 ZEND_END_ARG_INFO()
307
308 #if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35) && !defined(HAVE_BIRDSTEP)
309 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_tableprivileges, 0, 0, 4)
310 ZEND_ARG_INFO(0, connection_id)
311 ZEND_ARG_INFO(0, qualifier)
312 ZEND_ARG_INFO(0, owner)
313 ZEND_ARG_INFO(0, name)
314 ZEND_END_ARG_INFO()
315
316 ZEND_BEGIN_ARG_INFO_EX(arginfo_odbc_columnprivileges, 0, 0, 5)
317 ZEND_ARG_INFO(0, connection_id)
318 ZEND_ARG_INFO(0, catalog)
319 ZEND_ARG_INFO(0, schema)
320 ZEND_ARG_INFO(0, table)
321 ZEND_ARG_INFO(0, column)
322 ZEND_END_ARG_INFO()
323 #endif
324
325
326
327
328 const zend_function_entry odbc_functions[] = {
329 PHP_FE(odbc_autocommit, arginfo_odbc_autocommit)
330 PHP_FE(odbc_binmode, arginfo_odbc_binmode)
331 PHP_FE(odbc_close, arginfo_odbc_close)
332 PHP_FE(odbc_close_all, arginfo_odbc_close_all)
333 PHP_FE(odbc_columns, arginfo_odbc_columns)
334 PHP_FE(odbc_commit, arginfo_odbc_commit)
335 PHP_FE(odbc_connect, arginfo_odbc_connect)
336 PHP_FE(odbc_cursor, arginfo_odbc_cursor)
337 #ifdef HAVE_SQLDATASOURCES
338 PHP_FE(odbc_data_source, arginfo_odbc_data_source)
339 #endif
340 PHP_FE(odbc_execute, arginfo_odbc_execute)
341 PHP_FE(odbc_error, arginfo_odbc_error)
342 PHP_FE(odbc_errormsg, arginfo_odbc_errormsg)
343 PHP_FE(odbc_exec, arginfo_odbc_exec)
344 #ifdef PHP_ODBC_HAVE_FETCH_HASH
345 PHP_FE(odbc_fetch_array, arginfo_odbc_fetch_array)
346 PHP_FE(odbc_fetch_object, arginfo_odbc_fetch_object)
347 #endif
348 PHP_FE(odbc_fetch_row, arginfo_odbc_fetch_row)
349 PHP_FE(odbc_fetch_into, arginfo_odbc_fetch_into)
350 PHP_FE(odbc_field_len, arginfo_odbc_field_len)
351 PHP_FE(odbc_field_scale, arginfo_odbc_field_scale)
352 PHP_FE(odbc_field_name, arginfo_odbc_field_name)
353 PHP_FE(odbc_field_type, arginfo_odbc_field_type)
354 PHP_FE(odbc_field_num, arginfo_odbc_field_num)
355 PHP_FE(odbc_free_result, arginfo_odbc_free_result)
356 PHP_FE(odbc_gettypeinfo, arginfo_odbc_gettypeinfo)
357 PHP_FE(odbc_longreadlen, arginfo_odbc_longreadlen)
358 #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30)
359 PHP_FE(odbc_next_result, arginfo_odbc_next_result)
360 #endif
361 PHP_FE(odbc_num_fields, arginfo_odbc_num_fields)
362 PHP_FE(odbc_num_rows, arginfo_odbc_num_rows)
363 PHP_FE(odbc_pconnect, arginfo_odbc_pconnect)
364 PHP_FE(odbc_prepare, arginfo_odbc_prepare)
365 PHP_FE(odbc_result, arginfo_odbc_result)
366 PHP_FE(odbc_result_all, arginfo_odbc_result_all)
367 PHP_FE(odbc_rollback, arginfo_odbc_rollback)
368 PHP_FE(odbc_setoption, arginfo_odbc_setoption)
369 PHP_FE(odbc_specialcolumns, arginfo_odbc_specialcolumns)
370 PHP_FE(odbc_statistics, arginfo_odbc_statistics)
371 PHP_FE(odbc_tables, arginfo_odbc_tables)
372 PHP_FE(odbc_primarykeys, arginfo_odbc_primarykeys)
373 #if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35) && !defined(HAVE_BIRDSTEP)
374 PHP_FE(odbc_columnprivileges, arginfo_odbc_columnprivileges)
375 PHP_FE(odbc_tableprivileges, arginfo_odbc_tableprivileges)
376 #endif
377 #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35)
378 PHP_FE(odbc_foreignkeys, arginfo_odbc_foreignkeys)
379 PHP_FE(odbc_procedures, arginfo_odbc_procedures)
380 #if !defined(HAVE_BIRDSTEP)
381 PHP_FE(odbc_procedurecolumns, arginfo_odbc_procedurecolumns)
382 #endif
383 #endif
384 PHP_FALIAS(odbc_do, odbc_exec, arginfo_odbc_exec)
385 PHP_FALIAS(odbc_field_precision, odbc_field_len, arginfo_odbc_field_len)
386 PHP_FE_END
387 };
388
389
390 ZEND_DECLARE_MODULE_GLOBALS(odbc)
391 static PHP_GINIT_FUNCTION(odbc);
392
393
394
395 zend_module_entry odbc_module_entry = {
396 STANDARD_MODULE_HEADER,
397 "odbc",
398 odbc_functions,
399 PHP_MINIT(odbc),
400 PHP_MSHUTDOWN(odbc),
401 PHP_RINIT(odbc),
402 PHP_RSHUTDOWN(odbc),
403 PHP_MINFO(odbc),
404 "1.0",
405 PHP_MODULE_GLOBALS(odbc),
406 PHP_GINIT(odbc),
407 NULL,
408 NULL,
409 STANDARD_MODULE_PROPERTIES_EX
410 };
411
412
413 #ifdef COMPILE_DL_ODBC
414 ZEND_GET_MODULE(odbc)
415 #endif
416
417
418
419 static void _free_odbc_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
420 {
421 odbc_result *res = (odbc_result *)rsrc->ptr;
422 int i;
423 RETCODE rc;
424
425 if (res) {
426 if (res->values) {
427 for(i = 0; i < res->numcols; i++) {
428 if (res->values[i].value)
429 efree(res->values[i].value);
430 }
431 efree(res->values);
432 res->values = NULL;
433 }
434 if (res->stmt) {
435 #if defined(HAVE_SOLID) || defined(HAVE_SOLID_30) || defined(HAVE_SOLID_35)
436 SQLTransact(res->conn_ptr->henv, res->conn_ptr->hdbc,
437 (SQLUSMALLINT) SQL_COMMIT);
438 #endif
439 rc = SQLFreeStmt(res->stmt,SQL_DROP);
440
441
442
443
444 }
445 if (res->param_info) {
446 efree(res->param_info);
447 }
448 efree(res);
449 }
450 }
451
452
453
454
455
456 static void safe_odbc_disconnect( void *handle )
457 {
458 int ret;
459
460 ret = SQLDisconnect( handle );
461 if ( ret == SQL_ERROR )
462 {
463 SQLTransact( NULL, handle, SQL_ROLLBACK );
464 SQLDisconnect( handle );
465 }
466 }
467
468
469
470
471 static void _close_odbc_conn(zend_rsrc_list_entry *rsrc TSRMLS_DC)
472 {
473 int i, nument, type;
474 void *ptr;
475 odbc_result *res;
476
477 odbc_connection *conn = (odbc_connection *)rsrc->ptr;
478
479 nument = zend_hash_next_free_element(&EG(regular_list));
480 for(i = 1; i < nument; i++) {
481 ptr = zend_list_find(i, &type);
482 if (ptr && (type == le_result)) {
483 res = (odbc_result *)ptr;
484 if (res->conn_ptr == conn) {
485 zend_list_delete(i);
486 }
487 }
488 }
489
490 safe_odbc_disconnect(conn->hdbc);
491 SQLFreeConnect(conn->hdbc);
492 SQLFreeEnv(conn->henv);
493 efree(conn);
494 ODBCG(num_links)--;
495 }
496
497
498
499
500 static void _close_odbc_pconn(zend_rsrc_list_entry *rsrc TSRMLS_DC)
501 {
502 int i, nument, type;
503 void *ptr;
504 odbc_result *res;
505 odbc_connection *conn = (odbc_connection *)rsrc->ptr;
506
507 nument = zend_hash_next_free_element(&EG(persistent_list));
508 for(i = 1; i < nument; i++) {
509 ptr = zend_list_find(i, &type);
510 if (ptr && (type == le_result)) {
511 res = (odbc_result *)ptr;
512 if (res->conn_ptr == conn) {
513 zend_list_delete(i);
514 }
515 }
516 }
517
518 safe_odbc_disconnect(conn->hdbc);
519 SQLFreeConnect(conn->hdbc);
520 SQLFreeEnv(conn->henv);
521 free(conn);
522
523 ODBCG(num_links)--;
524 ODBCG(num_persistent)--;
525 }
526
527
528
529
530 static PHP_INI_DISP(display_link_nums)
531 {
532 char *value;
533 TSRMLS_FETCH();
534
535 if (type == PHP_INI_DISPLAY_ORIG && ini_entry->modified) {
536 value = ini_entry->orig_value;
537 } else if (ini_entry->value) {
538 value = ini_entry->value;
539 } else {
540 value = NULL;
541 }
542
543 if (value) {
544 if (atoi(value) == -1) {
545 PUTS("Unlimited");
546 } else {
547 php_printf("%s", value);
548 }
549 }
550 }
551
552
553
554
555 static PHP_INI_DISP(display_defPW)
556 {
557 char *value;
558 TSRMLS_FETCH();
559
560 if (type == PHP_INI_DISPLAY_ORIG && ini_entry->modified) {
561 value = ini_entry->orig_value;
562 } else if (ini_entry->value) {
563 value = ini_entry->value;
564 } else {
565 value = NULL;
566 }
567
568 if (value) {
569 #if PHP_DEBUG
570 php_printf("%s", value);
571 #else
572 PUTS("********");
573 #endif
574 } else {
575 if (PG(html_errors)) {
576 PUTS("<i>no value</i>");
577 } else {
578 PUTS("no value");
579 }
580 }
581 }
582
583
584
585
586 static PHP_INI_DISP(display_binmode)
587 {
588 char *value;
589 TSRMLS_FETCH();
590
591 if (type == PHP_INI_DISPLAY_ORIG && ini_entry->modified) {
592 value = ini_entry->orig_value;
593 } else if (ini_entry->value) {
594 value = ini_entry->value;
595 } else {
596 value = NULL;
597 }
598
599 if (value) {
600 switch(atoi(value)) {
601 case 0:
602 PUTS("passthru");
603 break;
604 case 1:
605 PUTS("return as is");
606 break;
607 case 2:
608 PUTS("return as char");
609 break;
610 }
611 }
612 }
613
614
615
616
617 static PHP_INI_DISP(display_lrl)
618 {
619 char *value;
620 TSRMLS_FETCH();
621
622 if (type == PHP_INI_DISPLAY_ORIG && ini_entry->modified) {
623 value = ini_entry->orig_value;
624 } else if (ini_entry->value) {
625 value = ini_entry->value;
626 } else {
627 value = NULL;
628 }
629
630 if (value) {
631 if (atoi(value) <= 0) {
632 PUTS("Passthru");
633 } else {
634 php_printf("return up to %s bytes", value);
635 }
636 }
637 }
638
639
640
641
642
643 static PHP_INI_DISP(display_cursortype)
644 {
645 char *value;
646 TSRMLS_FETCH();
647
648 if (type == PHP_INI_DISPLAY_ORIG && ini_entry->modified) {
649 value = ini_entry->orig_value;
650 } else if (ini_entry->value) {
651 value = ini_entry->value;
652 } else {
653 value = NULL;
654 }
655
656 if (value) {
657 switch (atoi (value))
658 {
659 case SQL_CURSOR_FORWARD_ONLY:
660 PUTS ("Forward Only cursor");
661 break;
662
663 case SQL_CURSOR_STATIC:
664 PUTS ("Static cursor");
665 break;
666
667 case SQL_CURSOR_KEYSET_DRIVEN:
668 PUTS ("Keyset driven cursor");
669 break;
670
671 case SQL_CURSOR_DYNAMIC:
672 PUTS ("Dynamic cursor");
673 break;
674
675 default:
676 php_printf("Unknown cursor model %s", value);
677 break;
678 }
679 }
680 }
681
682
683
684
685
686 PHP_INI_BEGIN()
687 STD_PHP_INI_BOOLEAN("odbc.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateLong,
688 allow_persistent, zend_odbc_globals, odbc_globals)
689 STD_PHP_INI_ENTRY_EX("odbc.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong,
690 max_persistent, zend_odbc_globals, odbc_globals, display_link_nums)
691 STD_PHP_INI_ENTRY_EX("odbc.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong,
692 max_links, zend_odbc_globals, odbc_globals, display_link_nums)
693 STD_PHP_INI_ENTRY("odbc.default_db", NULL, PHP_INI_ALL, OnUpdateString,
694 defDB, zend_odbc_globals, odbc_globals)
695 STD_PHP_INI_ENTRY("odbc.default_user", NULL, PHP_INI_ALL, OnUpdateString,
696 defUser, zend_odbc_globals, odbc_globals)
697 STD_PHP_INI_ENTRY_EX("odbc.default_pw", NULL, PHP_INI_ALL, OnUpdateString,
698 defPW, zend_odbc_globals, odbc_globals, display_defPW)
699 STD_PHP_INI_ENTRY_EX("odbc.defaultlrl", "4096", PHP_INI_ALL, OnUpdateLong,
700 defaultlrl, zend_odbc_globals, odbc_globals, display_lrl)
701 STD_PHP_INI_ENTRY_EX("odbc.defaultbinmode", "1", PHP_INI_ALL, OnUpdateLong,
702 defaultbinmode, zend_odbc_globals, odbc_globals, display_binmode)
703 STD_PHP_INI_BOOLEAN("odbc.check_persistent", "1", PHP_INI_SYSTEM, OnUpdateLong,
704 check_persistent, zend_odbc_globals, odbc_globals)
705 STD_PHP_INI_ENTRY_EX("odbc.default_cursortype", "3", PHP_INI_ALL, OnUpdateLong,
706 default_cursortype, zend_odbc_globals, odbc_globals, display_cursortype)
707 PHP_INI_END()
708
709
710 static PHP_GINIT_FUNCTION(odbc)
711 {
712 odbc_globals->num_persistent = 0;
713 }
714
715
716 PHP_MINIT_FUNCTION(odbc)
717 {
718 #ifdef SQLANY_BUG
719 ODBC_SQL_CONN_T foobar;
720 RETCODE rc;
721 #endif
722
723 REGISTER_INI_ENTRIES();
724 le_result = zend_register_list_destructors_ex(_free_odbc_result, NULL, "odbc result", module_number);
725 le_conn = zend_register_list_destructors_ex(_close_odbc_conn, NULL, "odbc link", module_number);
726 le_pconn = zend_register_list_destructors_ex(NULL, _close_odbc_pconn, "odbc link persistent", module_number);
727 Z_TYPE(odbc_module_entry) = type;
728
729 REGISTER_STRING_CONSTANT("ODBC_TYPE", PHP_ODBC_TYPE, CONST_CS | CONST_PERSISTENT);
730 REGISTER_LONG_CONSTANT("ODBC_BINMODE_PASSTHRU", 0, CONST_CS | CONST_PERSISTENT);
731 REGISTER_LONG_CONSTANT("ODBC_BINMODE_RETURN", 1, CONST_CS | CONST_PERSISTENT);
732 REGISTER_LONG_CONSTANT("ODBC_BINMODE_CONVERT", 2, CONST_CS | CONST_PERSISTENT);
733
734
735
736 REGISTER_LONG_CONSTANT("SQL_ODBC_CURSORS", SQL_ODBC_CURSORS, CONST_PERSISTENT | CONST_CS);
737 REGISTER_LONG_CONSTANT("SQL_CUR_USE_DRIVER", SQL_CUR_USE_DRIVER, CONST_PERSISTENT | CONST_CS);
738 REGISTER_LONG_CONSTANT("SQL_CUR_USE_IF_NEEDED", SQL_CUR_USE_IF_NEEDED, CONST_PERSISTENT | CONST_CS);
739 REGISTER_LONG_CONSTANT("SQL_CUR_USE_ODBC", SQL_CUR_USE_ODBC, CONST_PERSISTENT | CONST_CS);
740
741
742 REGISTER_LONG_CONSTANT("SQL_CONCURRENCY", SQL_CONCURRENCY, CONST_PERSISTENT | CONST_CS);
743 REGISTER_LONG_CONSTANT("SQL_CONCUR_READ_ONLY", SQL_CONCUR_READ_ONLY, CONST_PERSISTENT | CONST_CS);
744 REGISTER_LONG_CONSTANT("SQL_CONCUR_LOCK", SQL_CONCUR_LOCK, CONST_PERSISTENT | CONST_CS);
745 REGISTER_LONG_CONSTANT("SQL_CONCUR_ROWVER", SQL_CONCUR_ROWVER, CONST_PERSISTENT | CONST_CS);
746 REGISTER_LONG_CONSTANT("SQL_CONCUR_VALUES", SQL_CONCUR_VALUES, CONST_PERSISTENT | CONST_CS);
747
748 REGISTER_LONG_CONSTANT("SQL_CURSOR_TYPE", SQL_CURSOR_TYPE, CONST_PERSISTENT | CONST_CS);
749 REGISTER_LONG_CONSTANT("SQL_CURSOR_FORWARD_ONLY", SQL_CURSOR_FORWARD_ONLY, CONST_PERSISTENT | CONST_CS);
750 REGISTER_LONG_CONSTANT("SQL_CURSOR_KEYSET_DRIVEN", SQL_CURSOR_KEYSET_DRIVEN, CONST_PERSISTENT | CONST_CS);
751 REGISTER_LONG_CONSTANT("SQL_CURSOR_DYNAMIC", SQL_CURSOR_DYNAMIC, CONST_PERSISTENT | CONST_CS);
752 REGISTER_LONG_CONSTANT("SQL_CURSOR_STATIC", SQL_CURSOR_STATIC, CONST_PERSISTENT | CONST_CS);
753
754 REGISTER_LONG_CONSTANT("SQL_KEYSET_SIZE", SQL_KEYSET_SIZE, CONST_PERSISTENT | CONST_CS);
755
756
757 REGISTER_LONG_CONSTANT("SQL_FETCH_FIRST", SQL_FETCH_FIRST, CONST_PERSISTENT | CONST_CS);
758 REGISTER_LONG_CONSTANT("SQL_FETCH_NEXT", SQL_FETCH_NEXT, CONST_PERSISTENT | CONST_CS);
759
760
761
762
763 REGISTER_LONG_CONSTANT("SQL_CHAR", SQL_CHAR, CONST_PERSISTENT | CONST_CS);
764 REGISTER_LONG_CONSTANT("SQL_VARCHAR", SQL_VARCHAR, CONST_PERSISTENT | CONST_CS);
765 REGISTER_LONG_CONSTANT("SQL_LONGVARCHAR", SQL_LONGVARCHAR, CONST_PERSISTENT | CONST_CS);
766 REGISTER_LONG_CONSTANT("SQL_DECIMAL", SQL_DECIMAL, CONST_PERSISTENT | CONST_CS);
767 REGISTER_LONG_CONSTANT("SQL_NUMERIC", SQL_NUMERIC, CONST_PERSISTENT | CONST_CS);
768 REGISTER_LONG_CONSTANT("SQL_BIT", SQL_BIT, CONST_PERSISTENT | CONST_CS);
769 REGISTER_LONG_CONSTANT("SQL_TINYINT", SQL_TINYINT, CONST_PERSISTENT | CONST_CS);
770 REGISTER_LONG_CONSTANT("SQL_SMALLINT", SQL_SMALLINT, CONST_PERSISTENT | CONST_CS);
771 REGISTER_LONG_CONSTANT("SQL_INTEGER", SQL_INTEGER, CONST_PERSISTENT | CONST_CS);
772 REGISTER_LONG_CONSTANT("SQL_BIGINT", SQL_BIGINT, CONST_PERSISTENT | CONST_CS);
773 REGISTER_LONG_CONSTANT("SQL_REAL", SQL_REAL, CONST_PERSISTENT | CONST_CS);
774 REGISTER_LONG_CONSTANT("SQL_FLOAT", SQL_FLOAT, CONST_PERSISTENT | CONST_CS);
775 REGISTER_LONG_CONSTANT("SQL_DOUBLE", SQL_DOUBLE, CONST_PERSISTENT | CONST_CS);
776 REGISTER_LONG_CONSTANT("SQL_BINARY", SQL_BINARY, CONST_PERSISTENT | CONST_CS);
777 REGISTER_LONG_CONSTANT("SQL_VARBINARY", SQL_VARBINARY, CONST_PERSISTENT | CONST_CS);
778 REGISTER_LONG_CONSTANT("SQL_LONGVARBINARY", SQL_LONGVARBINARY, CONST_PERSISTENT | CONST_CS);
779 REGISTER_LONG_CONSTANT("SQL_DATE", SQL_DATE, CONST_PERSISTENT | CONST_CS);
780 REGISTER_LONG_CONSTANT("SQL_TIME", SQL_TIME, CONST_PERSISTENT | CONST_CS);
781 REGISTER_LONG_CONSTANT("SQL_TIMESTAMP", SQL_TIMESTAMP, CONST_PERSISTENT | CONST_CS);
782 #if defined(ODBCVER) && (ODBCVER >= 0x0300)
783 REGISTER_LONG_CONSTANT("SQL_TYPE_DATE", SQL_TYPE_DATE, CONST_PERSISTENT | CONST_CS);
784 REGISTER_LONG_CONSTANT("SQL_TYPE_TIME", SQL_TYPE_TIME, CONST_PERSISTENT | CONST_CS);
785 REGISTER_LONG_CONSTANT("SQL_TYPE_TIMESTAMP", SQL_TYPE_TIMESTAMP, CONST_PERSISTENT | CONST_CS);
786 REGISTER_LONG_CONSTANT("SQL_WCHAR", SQL_WCHAR, CONST_PERSISTENT | CONST_CS);
787 REGISTER_LONG_CONSTANT("SQL_WVARCHAR", SQL_WVARCHAR, CONST_PERSISTENT | CONST_CS);
788 REGISTER_LONG_CONSTANT("SQL_WLONGVARCHAR", SQL_WLONGVARCHAR, CONST_PERSISTENT | CONST_CS);
789
790
791
792
793 REGISTER_LONG_CONSTANT("SQL_BEST_ROWID", SQL_BEST_ROWID, CONST_PERSISTENT | CONST_CS);
794 REGISTER_LONG_CONSTANT("SQL_ROWVER", SQL_ROWVER, CONST_PERSISTENT | CONST_CS);
795 REGISTER_LONG_CONSTANT("SQL_SCOPE_CURROW", SQL_SCOPE_CURROW, CONST_PERSISTENT | CONST_CS);
796 REGISTER_LONG_CONSTANT("SQL_SCOPE_TRANSACTION", SQL_SCOPE_TRANSACTION, CONST_PERSISTENT | CONST_CS);
797 REGISTER_LONG_CONSTANT("SQL_SCOPE_SESSION", SQL_SCOPE_SESSION, CONST_PERSISTENT | CONST_CS);
798 REGISTER_LONG_CONSTANT("SQL_NO_NULLS", SQL_NO_NULLS, CONST_PERSISTENT | CONST_CS);
799 REGISTER_LONG_CONSTANT("SQL_NULLABLE", SQL_NULLABLE, CONST_PERSISTENT | CONST_CS);
800
801
802
803
804 REGISTER_LONG_CONSTANT("SQL_INDEX_UNIQUE", SQL_INDEX_UNIQUE, CONST_PERSISTENT | CONST_CS);
805 REGISTER_LONG_CONSTANT("SQL_INDEX_ALL", SQL_INDEX_ALL, CONST_PERSISTENT | CONST_CS);
806 REGISTER_LONG_CONSTANT("SQL_ENSURE", SQL_ENSURE, CONST_PERSISTENT | CONST_CS);
807 REGISTER_LONG_CONSTANT("SQL_QUICK", SQL_QUICK, CONST_PERSISTENT | CONST_CS);
808 #endif
809
810 #if defined(HAVE_IBMDB2) && defined(_AIX)
811
812
813 putenv("DB2NOEXITLIST=TRUE");
814 #endif
815
816 return SUCCESS;
817 }
818
819
820
821 PHP_RINIT_FUNCTION(odbc)
822 {
823 ODBCG(defConn) = -1;
824 ODBCG(num_links) = ODBCG(num_persistent);
825 memset(ODBCG(laststate), '\0', 6);
826 memset(ODBCG(lasterrormsg), '\0', SQL_MAX_MESSAGE_LENGTH);
827 return SUCCESS;
828 }
829
830
831
832 PHP_RSHUTDOWN_FUNCTION(odbc)
833 {
834 return SUCCESS;
835 }
836
837
838
839 PHP_MSHUTDOWN_FUNCTION(odbc)
840 {
841 UNREGISTER_INI_ENTRIES();
842 return SUCCESS;
843 }
844
845
846
847 PHP_MINFO_FUNCTION(odbc)
848 {
849 char buf[32];
850
851 php_info_print_table_start();
852 php_info_print_table_header(2, "ODBC Support", "enabled");
853 snprintf(buf, sizeof(buf), "%ld", ODBCG(num_persistent));
854 php_info_print_table_row(2, "Active Persistent Links", buf);
855 snprintf(buf, sizeof(buf), "%ld", ODBCG(num_links));
856 php_info_print_table_row(2, "Active Links", buf);
857 php_info_print_table_row(2, "ODBC library", PHP_ODBC_TYPE);
858 #ifndef PHP_WIN32
859 php_info_print_table_row(2, "ODBC_INCLUDE", PHP_ODBC_INCLUDE);
860 php_info_print_table_row(2, "ODBC_LFLAGS", PHP_ODBC_LFLAGS);
861 php_info_print_table_row(2, "ODBC_LIBS", PHP_ODBC_LIBS);
862 #endif
863 php_info_print_table_end();
864
865 DISPLAY_INI_ENTRIES();
866
867 }
868
869
870
871 void odbc_sql_error(ODBC_SQL_ERROR_PARAMS)
872 {
873 char state[6];
874 SQLINTEGER error;
875 char errormsg[SQL_MAX_MESSAGE_LENGTH];
876 SQLSMALLINT errormsgsize;
877 RETCODE rc;
878 ODBC_SQL_ENV_T henv;
879 ODBC_SQL_CONN_T conn;
880 TSRMLS_FETCH();
881
882 if (conn_resource) {
883 henv = conn_resource->henv;
884 conn = conn_resource->hdbc;
885 } else {
886 henv = SQL_NULL_HENV;
887 conn = SQL_NULL_HDBC;
888 }
889
890
891
892
893
894
895 rc = SQLError(henv, conn, stmt, state, &error, errormsg, sizeof(errormsg)-1, &errormsgsize);
896 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
897 snprintf(state, sizeof(state), "HY000");
898 snprintf(errormsg, sizeof(errormsg), "Failed to fetch error message");
899 }
900 if (conn_resource) {
901 memcpy(conn_resource->laststate, state, sizeof(state));
902 memcpy(conn_resource->lasterrormsg, errormsg, sizeof(errormsg));
903 }
904 memcpy(ODBCG(laststate), state, sizeof(state));
905 memcpy(ODBCG(lasterrormsg), errormsg, sizeof(errormsg));
906 if (func) {
907 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQL error: %s, SQL state %s in %s", errormsg, state, func);
908 } else {
909 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQL error: %s, SQL state %s", errormsg, state);
910 }
911
912
913
914
915 }
916
917
918
919 void php_odbc_fetch_attribs(INTERNAL_FUNCTION_PARAMETERS, int mode)
920 {
921 odbc_result *result;
922 zval *pv_res;
923 long flag;
924
925 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &pv_res, &flag) == FAILURE) {
926 return;
927 }
928
929 if (Z_LVAL_P(pv_res)) {
930 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
931 if (mode) {
932 result->longreadlen = flag;
933 } else {
934 result->binmode = flag;
935 }
936 } else {
937 if (mode) {
938 ODBCG(defaultlrl) = flag;
939 } else {
940 ODBCG(defaultbinmode) = flag;
941 }
942 }
943 RETURN_TRUE;
944 }
945
946
947
948 int odbc_bindcols(odbc_result *result TSRMLS_DC)
949 {
950 RETCODE rc;
951 int i;
952 SQLSMALLINT colnamelen;
953 SQLLEN displaysize;
954 SQLUSMALLINT colfieldid;
955 int charextraalloc;
956
957 result->values = (odbc_result_value *) safe_emalloc(sizeof(odbc_result_value), result->numcols, 0);
958
959 result->longreadlen = ODBCG(defaultlrl);
960 result->binmode = ODBCG(defaultbinmode);
961
962 for(i = 0; i < result->numcols; i++) {
963 charextraalloc = 0;
964 colfieldid = SQL_COLUMN_DISPLAY_SIZE;
965
966 rc = PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)(i+1), PHP_ODBC_SQL_DESC_NAME,
967 result->values[i].name, sizeof(result->values[i].name), &colnamelen, 0);
968 rc = PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)(i+1), SQL_COLUMN_TYPE,
969 NULL, 0, NULL, &result->values[i].coltype);
970
971
972
973
974
975 switch(result->values[i].coltype) {
976 case SQL_BINARY:
977 case SQL_VARBINARY:
978 case SQL_LONGVARBINARY:
979 case SQL_LONGVARCHAR:
980 #if defined(ODBCVER) && (ODBCVER >= 0x0300)
981 case SQL_WLONGVARCHAR:
982 #endif
983 result->values[i].value = NULL;
984 break;
985
986 #ifdef HAVE_ADABAS
987 case SQL_TIMESTAMP:
988 result->values[i].value = (char *)emalloc(27);
989 SQLBindCol(result->stmt, (SQLUSMALLINT)(i+1), SQL_C_CHAR, result->values[i].value,
990 27, &result->values[i].vallen);
991 break;
992 #endif
993 case SQL_CHAR:
994 case SQL_VARCHAR:
995 #if defined(ODBCVER) && (ODBCVER >= 0x0300)
996 case SQL_WCHAR:
997 case SQL_WVARCHAR:
998 colfieldid = SQL_DESC_OCTET_LENGTH;
999 #else
1000 charextraalloc = 1;
1001 #endif
1002 default:
1003 rc = PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)(i+1), colfieldid,
1004 NULL, 0, NULL, &displaysize);
1005 #if defined(ODBCVER) && (ODBCVER >= 0x0300)
1006 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO && colfieldid == SQL_DESC_OCTET_LENGTH) {
1007
1008
1009 charextraalloc = 1;
1010 rc = SQLColAttributes(result->stmt, (SQLUSMALLINT)(i+1), SQL_COLUMN_DISPLAY_SIZE,
1011 NULL, 0, NULL, &displaysize);
1012 }
1013
1014
1015 if (result->values[i].coltype == SQL_WVARCHAR && displaysize == 0) {
1016 result->values[i].coltype = SQL_WLONGVARCHAR;
1017 result->values[i].value = NULL;
1018 break;
1019 }
1020 #endif
1021
1022 if (result->values[i].coltype == SQL_TIMESTAMP) {
1023 displaysize += 3;
1024 }
1025
1026 if (charextraalloc) {
1027
1028 displaysize *= 4;
1029 }
1030 result->values[i].value = (char *)emalloc(displaysize + 1);
1031 rc = SQLBindCol(result->stmt, (SQLUSMALLINT)(i+1), SQL_C_CHAR, result->values[i].value,
1032 displaysize + 1, &result->values[i].vallen);
1033 break;
1034 }
1035 }
1036 return 1;
1037 }
1038
1039
1040
1041 void odbc_transact(INTERNAL_FUNCTION_PARAMETERS, int type)
1042 {
1043 odbc_connection *conn;
1044 RETCODE rc;
1045 zval *pv_conn;
1046
1047 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
1048 return;
1049 }
1050
1051 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
1052
1053 rc = SQLTransact(conn->henv, conn->hdbc, (SQLUSMALLINT)((type)?SQL_COMMIT:SQL_ROLLBACK));
1054 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
1055 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLTransact");
1056 RETURN_FALSE;
1057 }
1058
1059 RETURN_TRUE;
1060 }
1061
1062
1063
1064 static int _close_pconn_with_id(zend_rsrc_list_entry *le, int *id TSRMLS_DC)
1065 {
1066 if(Z_TYPE_P(le) == le_pconn && (((odbc_connection *)(le->ptr))->id == *id)){
1067 return 1;
1068 }else{
1069 return 0;
1070 }
1071 }
1072
1073
1074
1075 void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type)
1076 {
1077 odbc_result *result;
1078 #if defined(HAVE_SOLID) || defined(HAVE_SOLID_30)
1079
1080
1081
1082
1083
1084
1085 SDWORD len;
1086 #else
1087 SQLLEN len;
1088 #endif
1089 zval *pv_res;
1090 long pv_num;
1091
1092 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &pv_res, &pv_num) == FAILURE) {
1093 return;
1094 }
1095
1096 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
1097
1098 if (result->numcols == 0) {
1099 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No tuples available at this result index");
1100 RETURN_FALSE;
1101 }
1102
1103 if (pv_num > result->numcols) {
1104 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field index larger than number of fields");
1105 RETURN_FALSE;
1106 }
1107
1108 if (pv_num < 1) {
1109 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field numbering starts at 1");
1110 RETURN_FALSE;
1111 }
1112
1113 PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)pv_num, (SQLUSMALLINT) (type?SQL_COLUMN_SCALE:SQL_COLUMN_PRECISION), NULL, 0, NULL, &len);
1114
1115 RETURN_LONG(len);
1116 }
1117
1118
1119
1120
1121
1122
1123 PHP_FUNCTION(odbc_close_all)
1124 {
1125 void *ptr;
1126 int type;
1127 int i;
1128 int nument;
1129
1130 if (zend_parse_parameters_none() == FAILURE) {
1131 return;
1132 }
1133
1134 nument = zend_hash_next_free_element(&EG(regular_list));
1135
1136
1137 for(i = 1; i < nument; i++) {
1138 ptr = zend_list_find(i, &type);
1139 if (ptr && (type == le_result)){
1140 zend_list_delete(i);
1141 }
1142 }
1143
1144
1145 nument = zend_hash_next_free_element(&EG(regular_list));
1146
1147 for(i = 1; i < nument; i++) {
1148 ptr = zend_list_find(i, &type);
1149 if (ptr){
1150 if(type == le_conn){
1151 zend_list_delete(i);
1152 }else if(type == le_pconn){
1153 zend_list_delete(i);
1154
1155 zend_hash_apply_with_argument(&EG(persistent_list),
1156 (apply_func_arg_t) _close_pconn_with_id, (void *) &i TSRMLS_CC);
1157 }
1158 }
1159 }
1160 }
1161
1162
1163
1164
1165 PHP_FUNCTION(odbc_binmode)
1166 {
1167 php_odbc_fetch_attribs(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1168 }
1169
1170
1171
1172
1173 PHP_FUNCTION(odbc_longreadlen)
1174 {
1175 php_odbc_fetch_attribs(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
1176 }
1177
1178
1179
1180
1181 PHP_FUNCTION(odbc_prepare)
1182 {
1183 zval *pv_conn;
1184 char *query;
1185 int query_len;
1186 odbc_result *result = NULL;
1187 odbc_connection *conn;
1188 RETCODE rc;
1189 int i;
1190 #ifdef HAVE_SQL_EXTENDED_FETCH
1191 SQLUINTEGER scrollopts;
1192 #endif
1193
1194 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pv_conn, &query, &query_len) == FAILURE) {
1195 return;
1196 }
1197
1198 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
1199
1200 result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
1201
1202 result->numparams = 0;
1203 result->param_info = NULL;
1204
1205 rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
1206 if (rc == SQL_INVALID_HANDLE) {
1207 efree(result);
1208 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
1209 RETURN_FALSE;
1210 }
1211
1212 if (rc == SQL_ERROR) {
1213 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt");
1214 efree(result);
1215 RETURN_FALSE;
1216 }
1217
1218 #ifdef HAVE_SQL_EXTENDED_FETCH
1219
1220
1221 rc = SQLGetInfo(conn->hdbc, SQL_FETCH_DIRECTION, (void *) &scrollopts, sizeof(scrollopts), NULL);
1222 if (rc == SQL_SUCCESS) {
1223 if ((result->fetch_abs = (scrollopts & SQL_FD_FETCH_ABSOLUTE))) {
1224
1225
1226
1227 SQLSetStmtOption(result->stmt, SQL_CURSOR_TYPE, ODBCG(default_cursortype));
1228 }
1229 } else {
1230 result->fetch_abs = 0;
1231 }
1232 #endif
1233
1234 rc = SQLPrepare(result->stmt, query, SQL_NTS);
1235 switch (rc) {
1236 case SQL_SUCCESS:
1237 break;
1238 case SQL_SUCCESS_WITH_INFO:
1239 odbc_sql_error(conn, result->stmt, "SQLPrepare");
1240 break;
1241 default:
1242 odbc_sql_error(conn, result->stmt, "SQLPrepare");
1243 RETURN_FALSE;
1244 }
1245
1246 SQLNumParams(result->stmt, &(result->numparams));
1247 SQLNumResultCols(result->stmt, &(result->numcols));
1248
1249 if (result->numcols > 0) {
1250 if (!odbc_bindcols(result TSRMLS_CC)) {
1251 efree(result);
1252 RETURN_FALSE;
1253 }
1254 } else {
1255 result->values = NULL;
1256 }
1257 zend_list_addref(conn->id);
1258 result->conn_ptr = conn;
1259 result->fetched = 0;
1260
1261 result->param_info = (odbc_param_info *) safe_emalloc(sizeof(odbc_param_info), result->numparams, 0);
1262 for (i=0;i<result->numparams;i++) {
1263 rc = SQLDescribeParam(result->stmt, (SQLUSMALLINT)(i+1), &result->param_info[i].sqltype, &result->param_info[i].precision,
1264 &result->param_info[i].scale, &result->param_info[i].nullable);
1265 if (rc == SQL_ERROR) {
1266 odbc_sql_error(result->conn_ptr, result->stmt, "SQLDescribeParameter");
1267 SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
1268 efree(result->param_info);
1269 efree(result);
1270 RETURN_FALSE;
1271 }
1272 }
1273 ZEND_REGISTER_RESOURCE(return_value, result, le_result);
1274 }
1275
1276
1277
1278
1279
1280
1281
1282
1283 PHP_FUNCTION(odbc_execute)
1284 {
1285 zval *pv_res, *pv_param_arr, **tmp;
1286 typedef struct params_t {
1287 SQLLEN vallen;
1288 int fp;
1289 } params_t;
1290 params_t *params = NULL;
1291 char *filename;
1292 unsigned char otype;
1293 SQLSMALLINT ctype;
1294 odbc_result *result;
1295 int numArgs, i, ne;
1296 RETCODE rc;
1297
1298 numArgs = ZEND_NUM_ARGS();
1299
1300 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|a", &pv_res, &pv_param_arr) == FAILURE) {
1301 return;
1302 }
1303
1304 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
1305
1306
1307 if (result->numparams > 0 && numArgs == 1) {
1308 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No parameters to SQL statement given");
1309 RETURN_FALSE;
1310 }
1311
1312 if (result->numparams > 0) {
1313 if ((ne = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr))) < result->numparams) {
1314 php_error_docref(NULL TSRMLS_CC, E_WARNING,"Not enough parameters (%d should be %d) given", ne, result->numparams);
1315 RETURN_FALSE;
1316 }
1317
1318 zend_hash_internal_pointer_reset(Z_ARRVAL_P(pv_param_arr));
1319 params = (params_t *)safe_emalloc(sizeof(params_t), result->numparams, 0);
1320 for(i = 0; i < result->numparams; i++) {
1321 params[i].fp = -1;
1322 }
1323
1324 for(i = 1; i <= result->numparams; i++) {
1325 if (zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr), (void **) &tmp) == FAILURE) {
1326 php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter");
1327 SQLFreeStmt(result->stmt,SQL_RESET_PARAMS);
1328 for (i = 0; i < result->numparams; i++) {
1329 if (params[i].fp != -1) {
1330 close(params[i].fp);
1331 }
1332 }
1333 efree(params);
1334 RETURN_FALSE;
1335 }
1336
1337 otype = (*tmp)->type;
1338 convert_to_string_ex(tmp);
1339 if (Z_TYPE_PP(tmp) != IS_STRING) {
1340 php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter");
1341 SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
1342 for (i = 0; i < result->numparams; i++) {
1343 if (params[i].fp != -1) {
1344 close(params[i].fp);
1345 }
1346 }
1347 efree(params);
1348 RETURN_FALSE;
1349 }
1350
1351 params[i-1].vallen = Z_STRLEN_PP(tmp);
1352 params[i-1].fp = -1;
1353
1354 if (IS_SQL_BINARY(result->param_info[i-1].sqltype)) {
1355 ctype = SQL_C_BINARY;
1356 } else {
1357 ctype = SQL_C_CHAR;
1358 }
1359
1360 if (Z_STRLEN_PP(tmp) > 2 &&
1361 Z_STRVAL_PP(tmp)[0] == '\'' &&
1362 Z_STRVAL_PP(tmp)[Z_STRLEN_PP(tmp) - 1] == '\'') {
1363
1364 if (CHECK_ZVAL_NULL_PATH(*tmp)) {
1365 RETURN_FALSE;
1366 }
1367 filename = estrndup(&Z_STRVAL_PP(tmp)[1], Z_STRLEN_PP(tmp) - 2);
1368 filename[strlen(filename)] = '\0';
1369
1370
1371 if (php_check_open_basedir(filename TSRMLS_CC)) {
1372 efree(filename);
1373 SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
1374 for (i = 0; i < result->numparams; i++) {
1375 if (params[i].fp != -1) {
1376 close(params[i].fp);
1377 }
1378 }
1379 efree(params);
1380 RETURN_FALSE;
1381 }
1382
1383 if ((params[i-1].fp = open(filename,O_RDONLY)) == -1) {
1384 php_error_docref(NULL TSRMLS_CC, E_WARNING,"Can't open file %s", filename);
1385 SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
1386 for (i = 0; i < result->numparams; i++) {
1387 if (params[i].fp != -1) {
1388 close(params[i].fp);
1389 }
1390 }
1391 efree(params);
1392 efree(filename);
1393 RETURN_FALSE;
1394 }
1395
1396 efree(filename);
1397
1398 params[i-1].vallen = SQL_LEN_DATA_AT_EXEC(0);
1399
1400 rc = SQLBindParameter(result->stmt, (SQLUSMALLINT)i, SQL_PARAM_INPUT,
1401 ctype, result->param_info[i-1].sqltype, result->param_info[i-1].precision, result->param_info[i-1].scale,
1402 (void *)params[i-1].fp, 0,
1403 ¶ms[i-1].vallen);
1404 } else {
1405 #ifdef HAVE_DBMAKER
1406 precision = params[i-1].vallen;
1407 #endif
1408 if (otype == IS_NULL) {
1409 params[i-1].vallen = SQL_NULL_DATA;
1410 }
1411
1412 rc = SQLBindParameter(result->stmt, (SQLUSMALLINT)i, SQL_PARAM_INPUT,
1413 ctype, result->param_info[i-1].sqltype, result->param_info[i-1].precision, result->param_info[i-1].scale,
1414 Z_STRVAL_PP(tmp), 0,
1415 ¶ms[i-1].vallen);
1416 }
1417 if (rc == SQL_ERROR) {
1418 odbc_sql_error(result->conn_ptr, result->stmt, "SQLBindParameter");
1419 SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
1420 for (i = 0; i < result->numparams; i++) {
1421 if (params[i].fp != -1) {
1422 close(params[i].fp);
1423 }
1424 }
1425 efree(params);
1426 RETURN_FALSE;
1427 }
1428 zend_hash_move_forward(Z_ARRVAL_P(pv_param_arr));
1429 }
1430 }
1431
1432 rc = SQLFreeStmt(result->stmt, SQL_CLOSE);
1433
1434 if (rc == SQL_ERROR) {
1435 odbc_sql_error(result->conn_ptr, result->stmt, "SQLFreeStmt");
1436 }
1437
1438 rc = SQLExecute(result->stmt);
1439
1440 result->fetched = 0;
1441 if (rc == SQL_NEED_DATA) {
1442 char buf[4096];
1443 int fp, nbytes;
1444 while (rc == SQL_NEED_DATA) {
1445 rc = SQLParamData(result->stmt, (void*)&fp);
1446 if (rc == SQL_NEED_DATA) {
1447 while ((nbytes = read(fp, &buf, 4096)) > 0) {
1448 SQLPutData(result->stmt, (void*)&buf, nbytes);
1449 }
1450 }
1451 }
1452 } else {
1453 switch (rc) {
1454 case SQL_SUCCESS:
1455 break;
1456 case SQL_NO_DATA_FOUND:
1457 case SQL_SUCCESS_WITH_INFO:
1458 odbc_sql_error(result->conn_ptr, result->stmt, "SQLExecute");
1459 break;
1460 default:
1461 odbc_sql_error(result->conn_ptr, result->stmt, "SQLExecute");
1462 RETVAL_FALSE;
1463 }
1464 }
1465
1466 if (result->numparams > 0) {
1467 SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
1468 for(i = 0; i < result->numparams; i++) {
1469 if (params[i].fp != -1) {
1470 close(params[i].fp);
1471 }
1472 }
1473 efree(params);
1474 }
1475
1476 if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO || rc == SQL_NO_DATA_FOUND) {
1477 RETVAL_TRUE;
1478 }
1479
1480 if (result->numcols == 0) {
1481 SQLNumResultCols(result->stmt, &(result->numcols));
1482
1483 if (result->numcols > 0) {
1484 if (!odbc_bindcols(result TSRMLS_CC)) {
1485 efree(result);
1486 RETVAL_FALSE;
1487 }
1488 } else {
1489 result->values = NULL;
1490 }
1491 }
1492 }
1493
1494
1495
1496
1497 PHP_FUNCTION(odbc_cursor)
1498 {
1499 zval *pv_res;
1500 SQLUSMALLINT max_len;
1501 SQLSMALLINT len;
1502 char *cursorname;
1503 odbc_result *result;
1504 RETCODE rc;
1505
1506 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_res) == FAILURE) {
1507 return;
1508 }
1509
1510 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
1511
1512 rc = SQLGetInfo(result->conn_ptr->hdbc,SQL_MAX_CURSOR_NAME_LEN, (void *)&max_len,sizeof(max_len),&len);
1513 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
1514 RETURN_FALSE;
1515 }
1516
1517 if (max_len > 0) {
1518 cursorname = emalloc(max_len + 1);
1519 rc = SQLGetCursorName(result->stmt,cursorname,(SQLSMALLINT)max_len,&len);
1520 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
1521 char state[6];
1522 SQLINTEGER error;
1523 char errormsg[SQL_MAX_MESSAGE_LENGTH];
1524 SQLSMALLINT errormsgsize;
1525
1526 SQLError( result->conn_ptr->henv, result->conn_ptr->hdbc,
1527 result->stmt, state, &error, errormsg,
1528 sizeof(errormsg)-1, &errormsgsize);
1529 if (!strncmp(state,"S1015",5)) {
1530 snprintf(cursorname, max_len+1, "php_curs_%d", (int)result->stmt);
1531 if (SQLSetCursorName(result->stmt,cursorname,SQL_NTS) != SQL_SUCCESS) {
1532 odbc_sql_error(result->conn_ptr, result->stmt, "SQLSetCursorName");
1533 RETVAL_FALSE;
1534 } else {
1535 RETVAL_STRING(cursorname,1);
1536 }
1537 } else {
1538 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQL error: %s, SQL state %s", errormsg, state);
1539 RETVAL_FALSE;
1540 }
1541 } else {
1542 RETVAL_STRING(cursorname,1);
1543 }
1544 efree(cursorname);
1545 } else {
1546 RETVAL_FALSE;
1547 }
1548 }
1549
1550
1551 #ifdef HAVE_SQLDATASOURCES
1552
1553
1554 PHP_FUNCTION(odbc_data_source)
1555 {
1556 zval *zv_conn;
1557 long zv_fetch_type;
1558 RETCODE rc = 0;
1559 odbc_connection *conn;
1560 UCHAR server_name[100], desc[200];
1561 SQLSMALLINT len1=0, len2=0, fetch_type;
1562
1563 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zv_conn, &zv_fetch_type) == FAILURE) {
1564 return;
1565 }
1566
1567 fetch_type = (SQLSMALLINT) zv_fetch_type;
1568
1569 if (!(fetch_type == SQL_FETCH_FIRST || fetch_type == SQL_FETCH_NEXT)) {
1570 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid fetch type (%d)", fetch_type);
1571 RETURN_FALSE;
1572 }
1573
1574 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &zv_conn, -1, "ODBC-Link", le_conn, le_pconn);
1575
1576
1577 rc = SQLDataSources(conn->henv,
1578 fetch_type,
1579 server_name,
1580 (SQLSMALLINT)sizeof(server_name),
1581 &len1,
1582 desc,
1583 (SQLSMALLINT)sizeof(desc),
1584 &len2);
1585
1586 if (rc != SQL_SUCCESS) {
1587
1588 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLDataSources");
1589 RETURN_FALSE;
1590 }
1591
1592 if (len1 == 0 || len2 == 0) {
1593
1594 RETURN_FALSE;
1595 }
1596
1597 array_init(return_value);
1598
1599 add_assoc_string_ex(return_value, "server", sizeof("server"), server_name, 1);
1600 add_assoc_string_ex(return_value, "description", sizeof("description"), desc, 1);
1601
1602 }
1603
1604 #endif
1605
1606
1607
1608
1609 PHP_FUNCTION(odbc_exec)
1610 {
1611 zval *pv_conn;
1612 long pv_flags;
1613 char *query;
1614 int numArgs, query_len;
1615 odbc_result *result = NULL;
1616 odbc_connection *conn;
1617 RETCODE rc;
1618 #ifdef HAVE_SQL_EXTENDED_FETCH
1619 SQLUINTEGER scrollopts;
1620 #endif
1621
1622 numArgs = ZEND_NUM_ARGS();
1623
1624 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &pv_conn, &query, &query_len, &pv_flags) == FAILURE) {
1625 return;
1626 }
1627
1628 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
1629
1630 result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
1631
1632 rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
1633 if (rc == SQL_INVALID_HANDLE) {
1634 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
1635 efree(result);
1636 RETURN_FALSE;
1637 }
1638
1639 if (rc == SQL_ERROR) {
1640 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt");
1641 efree(result);
1642 RETURN_FALSE;
1643 }
1644
1645 #ifdef HAVE_SQL_EXTENDED_FETCH
1646
1647
1648 rc = SQLGetInfo(conn->hdbc, SQL_FETCH_DIRECTION, (void *) &scrollopts, sizeof(scrollopts), NULL);
1649 if (rc == SQL_SUCCESS) {
1650 if ((result->fetch_abs = (scrollopts & SQL_FD_FETCH_ABSOLUTE))) {
1651
1652
1653
1654 SQLSetStmtOption(result->stmt, SQL_CURSOR_TYPE, ODBCG(default_cursortype));
1655 }
1656 } else {
1657 result->fetch_abs = 0;
1658 }
1659 #endif
1660
1661 rc = SQLExecDirect(result->stmt, query, SQL_NTS);
1662 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO && rc != SQL_NO_DATA_FOUND) {
1663
1664
1665
1666 odbc_sql_error(conn, result->stmt, "SQLExecDirect");
1667 SQLFreeStmt(result->stmt, SQL_DROP);
1668 efree(result);
1669 RETURN_FALSE;
1670 }
1671
1672 SQLNumResultCols(result->stmt, &(result->numcols));
1673
1674
1675 if (result->numcols > 0) {
1676 if (!odbc_bindcols(result TSRMLS_CC)) {
1677 efree(result);
1678 RETURN_FALSE;
1679 }
1680 } else {
1681 result->values = NULL;
1682 }
1683 zend_list_addref(conn->id);
1684 result->conn_ptr = conn;
1685 result->fetched = 0;
1686 ZEND_REGISTER_RESOURCE(return_value, result, le_result);
1687 }
1688
1689
1690 #ifdef PHP_ODBC_HAVE_FETCH_HASH
1691 #define ODBC_NUM 1
1692 #define ODBC_OBJECT 2
1693
1694
1695 static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type)
1696 {
1697 int i;
1698 odbc_result *result;
1699 RETCODE rc;
1700 SQLSMALLINT sql_c_type;
1701 char *buf = NULL;
1702 #ifdef HAVE_SQL_EXTENDED_FETCH
1703 SQLULEN crow;
1704 SQLUSMALLINT RowStatus[1];
1705 SQLLEN rownum;
1706 zval *pv_res, *tmp;
1707 long pv_row = -1;
1708
1709 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &pv_res, &pv_row) == FAILURE) {
1710 return;
1711 }
1712
1713 rownum = pv_row;
1714 #else
1715 zval *pv_res, *tmp;
1716
1717 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_res) == FAILURE) {
1718 return;
1719 }
1720 #endif
1721
1722 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
1723
1724 if (result->numcols == 0) {
1725 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No tuples available at this result index");
1726 RETURN_FALSE;
1727 }
1728
1729 #ifdef HAVE_SQL_EXTENDED_FETCH
1730 if (result->fetch_abs) {
1731 if (rownum > 0) {
1732 rc = SQLExtendedFetch(result->stmt,SQL_FETCH_ABSOLUTE,rownum,&crow,RowStatus);
1733 } else {
1734 rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus);
1735 }
1736 } else
1737 #endif
1738 rc = SQLFetch(result->stmt);
1739
1740 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
1741 RETURN_FALSE;
1742 }
1743
1744 array_init(return_value);
1745
1746 #ifdef HAVE_SQL_EXTENDED_FETCH
1747 if (rownum > 0 && result->fetch_abs)
1748 result->fetched = rownum;
1749 else
1750 #endif
1751 result->fetched++;
1752
1753 for(i = 0; i < result->numcols; i++) {
1754 ALLOC_INIT_ZVAL(tmp);
1755 Z_TYPE_P(tmp) = IS_STRING;
1756 Z_STRLEN_P(tmp) = 0;
1757 sql_c_type = SQL_C_CHAR;
1758
1759 switch(result->values[i].coltype) {
1760 case SQL_BINARY:
1761 case SQL_VARBINARY:
1762 case SQL_LONGVARBINARY:
1763 if (result->binmode <= 0) {
1764 Z_STRVAL_P(tmp) = STR_EMPTY_ALLOC();
1765 break;
1766 }
1767 if (result->binmode == 1) {
1768 sql_c_type = SQL_C_BINARY;
1769 }
1770 case SQL_LONGVARCHAR:
1771 #if defined(ODBCVER) && (ODBCVER >= 0x0300)
1772 case SQL_WLONGVARCHAR:
1773 #endif
1774 if (IS_SQL_LONG(result->values[i].coltype) && result->longreadlen <= 0) {
1775 Z_STRVAL_P(tmp) = STR_EMPTY_ALLOC();
1776 break;
1777 }
1778 if (buf == NULL) {
1779 buf = emalloc(result->longreadlen + 1);
1780 }
1781
1782 rc = SQLGetData(result->stmt, (SQLUSMALLINT)(i + 1), sql_c_type, buf, result->longreadlen + 1, &result->values[i].vallen);
1783
1784 if (rc == SQL_ERROR) {
1785 odbc_sql_error(result->conn_ptr, result->stmt, "SQLGetData");
1786 efree(buf);
1787 RETURN_FALSE;
1788 }
1789
1790 if (rc == SQL_SUCCESS_WITH_INFO) {
1791 Z_STRLEN_P(tmp) = result->longreadlen;
1792 } else if (result->values[i].vallen == SQL_NULL_DATA) {
1793 ZVAL_NULL(tmp);
1794 break;
1795 } else {
1796 Z_STRLEN_P(tmp) = result->values[i].vallen;
1797 }
1798 Z_STRVAL_P(tmp) = estrndup(buf, Z_STRLEN_P(tmp));
1799 break;
1800
1801 default:
1802 if (result->values[i].vallen == SQL_NULL_DATA) {
1803 ZVAL_NULL(tmp);
1804 break;
1805 }
1806 Z_STRLEN_P(tmp) = result->values[i].vallen;
1807 Z_STRVAL_P(tmp) = estrndup(result->values[i].value,Z_STRLEN_P(tmp));
1808 break;
1809 }
1810
1811 if (result_type & ODBC_NUM) {
1812 zend_hash_index_update(Z_ARRVAL_P(return_value), i, &tmp, sizeof(zval *), NULL);
1813 } else {
1814 if (!*(result->values[i].name) && Z_TYPE_P(tmp) == IS_STRING) {
1815 zend_hash_update(Z_ARRVAL_P(return_value), Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)+1, &tmp, sizeof(zval *), NULL);
1816 } else {
1817 zend_hash_update(Z_ARRVAL_P(return_value), result->values[i].name, strlen(result->values[i].name)+1, &tmp, sizeof(zval *), NULL);
1818 }
1819 }
1820 }
1821 if (buf) {
1822 efree(buf);
1823 }
1824 }
1825
1826
1827
1828
1829
1830 PHP_FUNCTION(odbc_fetch_object)
1831 {
1832 php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, ODBC_OBJECT);
1833 if (Z_TYPE_P(return_value) == IS_ARRAY) {
1834 object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value));
1835 }
1836 }
1837
1838
1839
1840
1841 PHP_FUNCTION(odbc_fetch_array)
1842 {
1843 php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, ODBC_OBJECT);
1844 }
1845
1846 #endif
1847
1848
1849
1850 PHP_FUNCTION(odbc_fetch_into)
1851 {
1852 int i;
1853 odbc_result *result;
1854 RETCODE rc;
1855 SQLSMALLINT sql_c_type;
1856 char *buf = NULL;
1857 zval *pv_res, **pv_res_arr, *tmp;
1858 #ifdef HAVE_SQL_EXTENDED_FETCH
1859 long pv_row = 0;
1860 SQLULEN crow;
1861 SQLUSMALLINT RowStatus[1];
1862 SQLLEN rownum = -1;
1863 #endif
1864
1865 #ifdef HAVE_SQL_EXTENDED_FETCH
1866 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ|l", &pv_res, &pv_res_arr, &pv_row) == FAILURE) {
1867 return;
1868 }
1869
1870 rownum = pv_row;
1871 #else
1872 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pv_res, &pv_res_arr) == FAILURE) {
1873 return;
1874 }
1875 #endif
1876
1877 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
1878
1879 if (result->numcols == 0) {
1880 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No tuples available at this result index");
1881 RETURN_FALSE;
1882 }
1883
1884 if (Z_TYPE_PP(pv_res_arr) != IS_ARRAY) {
1885 array_init(*pv_res_arr);
1886 }
1887
1888 #ifdef HAVE_SQL_EXTENDED_FETCH
1889 if (result->fetch_abs) {
1890 if (rownum > 0) {
1891 rc = SQLExtendedFetch(result->stmt,SQL_FETCH_ABSOLUTE,rownum,&crow,RowStatus);
1892 } else {
1893 rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus);
1894 }
1895 } else
1896 #endif
1897 rc = SQLFetch(result->stmt);
1898
1899 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
1900 RETURN_FALSE;
1901 }
1902
1903 #ifdef HAVE_SQL_EXTENDED_FETCH
1904 if (rownum > 0 && result->fetch_abs)
1905 result->fetched = rownum;
1906 else
1907 #endif
1908 result->fetched++;
1909
1910 for(i = 0; i < result->numcols; i++) {
1911 MAKE_STD_ZVAL(tmp);
1912 Z_TYPE_P(tmp) = IS_STRING;
1913 Z_STRLEN_P(tmp) = 0;
1914 sql_c_type = SQL_C_CHAR;
1915
1916 switch(result->values[i].coltype) {
1917 case SQL_BINARY:
1918 case SQL_VARBINARY:
1919 case SQL_LONGVARBINARY:
1920 if (result->binmode <= 0) {
1921 Z_STRVAL_P(tmp) = STR_EMPTY_ALLOC();
1922 break;
1923 }
1924 if (result->binmode == 1) sql_c_type = SQL_C_BINARY;
1925
1926 case SQL_LONGVARCHAR:
1927 #if defined(ODBCVER) && (ODBCVER >= 0x0300)
1928 case SQL_WLONGVARCHAR:
1929 #endif
1930 if (IS_SQL_LONG(result->values[i].coltype) && result->longreadlen <= 0) {
1931 Z_STRVAL_P(tmp) = STR_EMPTY_ALLOC();
1932 break;
1933 }
1934
1935 if (buf == NULL) {
1936 buf = emalloc(result->longreadlen + 1);
1937 }
1938 rc = SQLGetData(result->stmt, (SQLUSMALLINT)(i + 1),sql_c_type, buf, result->longreadlen + 1, &result->values[i].vallen);
1939
1940 if (rc == SQL_ERROR) {
1941 odbc_sql_error(result->conn_ptr, result->stmt, "SQLGetData");
1942 efree(buf);
1943 RETURN_FALSE;
1944 }
1945 if (rc == SQL_SUCCESS_WITH_INFO) {
1946 Z_STRLEN_P(tmp) = result->longreadlen;
1947 } else if (result->values[i].vallen == SQL_NULL_DATA) {
1948 ZVAL_NULL(tmp);
1949 break;
1950 } else {
1951 Z_STRLEN_P(tmp) = result->values[i].vallen;
1952 }
1953 Z_STRVAL_P(tmp) = estrndup(buf, Z_STRLEN_P(tmp));
1954 break;
1955
1956 default:
1957 if (result->values[i].vallen == SQL_NULL_DATA) {
1958 ZVAL_NULL(tmp);
1959 break;
1960 }
1961 Z_STRLEN_P(tmp) = result->values[i].vallen;
1962 Z_STRVAL_P(tmp) = estrndup(result->values[i].value,Z_STRLEN_P(tmp));
1963 break;
1964 }
1965 zend_hash_index_update(Z_ARRVAL_PP(pv_res_arr), i, &tmp, sizeof(zval *), NULL);
1966 }
1967 if (buf) efree(buf);
1968 RETURN_LONG(result->numcols);
1969 }
1970
1971
1972
1973
1974 #if defined(HAVE_SOLID) || defined(HAVE_SOLID_30) || defined(HAVE_SOLID_35)
1975 PHP_FUNCTION(solid_fetch_prev)
1976 {
1977 odbc_result *result;
1978 RETCODE rc;
1979 zval *pv_res;
1980
1981 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_res) == FAILURE) {
1982 return;
1983 }
1984
1985 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
1986 if (result->numcols == 0) {
1987 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No tuples available at this result index");
1988 RETURN_FALSE;
1989 }
1990 rc = SQLFetchPrev(result->stmt);
1991
1992 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
1993 RETURN_FALSE;
1994 }
1995
1996 if (result->fetched > 1) {
1997 result->fetched--;
1998 }
1999
2000 RETURN_TRUE;
2001 }
2002 #endif
2003
2004
2005
2006
2007 PHP_FUNCTION(odbc_fetch_row)
2008 {
2009 SQLLEN rownum;
2010 odbc_result *result;
2011 RETCODE rc;
2012 zval *pv_res;
2013 long pv_row = 1;
2014 #ifdef HAVE_SQL_EXTENDED_FETCH
2015 SQLULEN crow;
2016 SQLUSMALLINT RowStatus[1];
2017 #endif
2018
2019 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &pv_res, &pv_row) == FAILURE) {
2020 return;
2021 }
2022
2023 rownum = pv_row;
2024
2025 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
2026
2027 if (result->numcols == 0) {
2028 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No tuples available at this result index");
2029 RETURN_FALSE;
2030 }
2031
2032 #ifdef HAVE_SQL_EXTENDED_FETCH
2033 if (result->fetch_abs) {
2034 if (ZEND_NUM_ARGS() > 1) {
2035 rc = SQLExtendedFetch(result->stmt,SQL_FETCH_ABSOLUTE,rownum,&crow,RowStatus);
2036 } else {
2037 rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus);
2038 }
2039 } else
2040 #endif
2041 rc = SQLFetch(result->stmt);
2042
2043 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
2044 RETURN_FALSE;
2045 }
2046
2047 if (ZEND_NUM_ARGS() > 1) {
2048 result->fetched = rownum;
2049 } else {
2050 result->fetched++;
2051 }
2052
2053 RETURN_TRUE;
2054 }
2055
2056
2057
2058
2059 PHP_FUNCTION(odbc_result)
2060 {
2061 char *field;
2062 int field_ind;
2063 SQLSMALLINT sql_c_type = SQL_C_CHAR;
2064 odbc_result *result;
2065 int i = 0;
2066 RETCODE rc;
2067 SQLLEN fieldsize;
2068 zval *pv_res, **pv_field;
2069 #ifdef HAVE_SQL_EXTENDED_FETCH
2070 SQLULEN crow;
2071 SQLUSMALLINT RowStatus[1];
2072 #endif
2073
2074 field_ind = -1;
2075 field = NULL;
2076
2077 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rZ", &pv_res, &pv_field) == FAILURE) {
2078 return;
2079 }
2080
2081 if (Z_TYPE_PP(pv_field) == IS_STRING) {
2082 field = Z_STRVAL_PP(pv_field);
2083 } else {
2084 convert_to_long_ex(pv_field);
2085 field_ind = Z_LVAL_PP(pv_field) - 1;
2086 }
2087
2088 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
2089
2090 if ((result->numcols == 0)) {
2091 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No tuples available at this result index");
2092 RETURN_FALSE;
2093 }
2094
2095
2096 if (field != NULL) {
2097 if (result->values == NULL) {
2098 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result set contains no data");
2099 RETURN_FALSE;
2100 }
2101
2102 for(i = 0; i < result->numcols; i++) {
2103 if (!strcasecmp(result->values[i].name, field)) {
2104 field_ind = i;
2105 break;
2106 }
2107 }
2108
2109 if (field_ind < 0) {
2110 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field %s not found", field);
2111 RETURN_FALSE;
2112 }
2113 } else {
2114
2115 if (field_ind >= result->numcols || field_ind < 0) {
2116 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field index is larger than the number of fields");
2117 RETURN_FALSE;
2118 }
2119 }
2120
2121 if (result->fetched == 0) {
2122
2123 #ifdef HAVE_SQL_EXTENDED_FETCH
2124 if (result->fetch_abs)
2125 rc = SQLExtendedFetch(result->stmt, SQL_FETCH_NEXT, 1, &crow,RowStatus);
2126 else
2127 #endif
2128 rc = SQLFetch(result->stmt);
2129
2130 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
2131 RETURN_FALSE;
2132 }
2133
2134 result->fetched++;
2135 }
2136
2137 switch(result->values[field_ind].coltype) {
2138 case SQL_BINARY:
2139 case SQL_VARBINARY:
2140 case SQL_LONGVARBINARY:
2141 if (result->binmode <= 1) {
2142 sql_c_type = SQL_C_BINARY;
2143 }
2144 if (result->binmode <= 0) {
2145 break;
2146 }
2147 case SQL_LONGVARCHAR:
2148 #if defined(ODBCVER) && (ODBCVER >= 0x0300)
2149 case SQL_WLONGVARCHAR:
2150 #endif
2151 if (IS_SQL_LONG(result->values[field_ind].coltype)) {
2152 if (result->longreadlen <= 0) {
2153 break;
2154 } else {
2155 fieldsize = result->longreadlen;
2156 }
2157 } else {
2158 PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)(field_ind + 1),
2159 (SQLUSMALLINT)((sql_c_type == SQL_C_BINARY) ? SQL_COLUMN_LENGTH :
2160 SQL_COLUMN_DISPLAY_SIZE),
2161 NULL, 0, NULL, &fieldsize);
2162 }
2163
2164 fieldsize = (result->longreadlen <= 0) ? 4096 : result->longreadlen;
2165 field = emalloc(fieldsize);
2166
2167
2168
2169
2170 rc = SQLGetData(result->stmt, (SQLUSMALLINT)(field_ind + 1), sql_c_type,
2171 field, fieldsize, &result->values[field_ind].vallen);
2172
2173 if (rc == SQL_ERROR) {
2174 odbc_sql_error(result->conn_ptr, result->stmt, "SQLGetData");
2175 efree(field);
2176 RETURN_FALSE;
2177 }
2178
2179 if (result->values[field_ind].vallen == SQL_NULL_DATA) {
2180 efree(field);
2181 RETURN_NULL();
2182 } else if (rc == SQL_NO_DATA_FOUND) {
2183 efree(field);
2184 RETURN_FALSE;
2185 }
2186
2187
2188 if ((result->values[field_ind].coltype == SQL_LONGVARCHAR)
2189 #if defined(ODBCVER) && (ODBCVER >= 0x0300)
2190 || (result->values[field_ind].coltype == SQL_WLONGVARCHAR)
2191 #endif
2192 ) {
2193 fieldsize -= 1;
2194 }
2195
2196
2197
2198 RETURN_STRINGL(field, (rc == SQL_SUCCESS_WITH_INFO) ? fieldsize : result->values[field_ind].vallen, 0);
2199 break;
2200
2201 default:
2202 if (result->values[field_ind].vallen == SQL_NULL_DATA) {
2203 RETURN_NULL();
2204 } else {
2205 RETURN_STRINGL(result->values[field_ind].value, result->values[field_ind].vallen, 1);
2206 }
2207 break;
2208 }
2209
2210
2211
2212
2213 fieldsize = (sql_c_type == SQL_C_CHAR) ? 4096 : 4095;
2214 field = emalloc(fieldsize);
2215
2216
2217 while(1) {
2218 rc = SQLGetData(result->stmt, (SQLUSMALLINT)(field_ind + 1),sql_c_type, field, fieldsize, &result->values[field_ind].vallen);
2219
2220 if (rc == SQL_ERROR) {
2221 odbc_sql_error(result->conn_ptr, result->stmt, "SQLGetData");
2222 efree(field);
2223 RETURN_FALSE;
2224 }
2225
2226 if (result->values[field_ind].vallen == SQL_NULL_DATA) {
2227 efree(field);
2228 RETURN_NULL();
2229 }
2230
2231 PHPWRITE(field,(rc == SQL_SUCCESS_WITH_INFO) ? 4095 : result->values[field_ind].vallen);
2232
2233 if (rc == SQL_SUCCESS) {
2234 efree(field);
2235 RETURN_TRUE;
2236 }
2237 }
2238 RETURN_TRUE;
2239 }
2240
2241
2242
2243
2244 PHP_FUNCTION(odbc_result_all)
2245 {
2246 char *buf = NULL;
2247 odbc_result *result;
2248 RETCODE rc;
2249 zval *pv_res;
2250 char *pv_format = NULL;
2251 int i, pv_format_len = 0;
2252 SQLSMALLINT sql_c_type;
2253 #ifdef HAVE_SQL_EXTENDED_FETCH
2254 SQLULEN crow;
2255 SQLUSMALLINT RowStatus[1];
2256 #endif
2257
2258 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s", &pv_res, &pv_format, &pv_format_len) == FAILURE) {
2259 return;
2260 }
2261
2262 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
2263
2264 if (result->numcols == 0) {
2265 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No tuples available at this result index");
2266 RETURN_FALSE;
2267 }
2268 #ifdef HAVE_SQL_EXTENDED_FETCH
2269 if (result->fetch_abs)
2270 rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus);
2271 else
2272 #endif
2273 rc = SQLFetch(result->stmt);
2274
2275 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
2276 php_printf("<h2>No rows found</h2>\n");
2277 RETURN_LONG(0);
2278 }
2279
2280
2281 if (ZEND_NUM_ARGS() == 1) {
2282 php_printf("<table><tr>");
2283 } else {
2284 php_printf("<table %s ><tr>", pv_format);
2285 }
2286
2287 for (i = 0; i < result->numcols; i++) {
2288 php_printf("<th>%s</th>", result->values[i].name);
2289 }
2290
2291 php_printf("</tr>\n");
2292
2293 while(rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
2294 result->fetched++;
2295 php_printf("<tr>");
2296 for(i = 0; i < result->numcols; i++) {
2297 sql_c_type = SQL_C_CHAR;
2298 switch(result->values[i].coltype) {
2299 case SQL_BINARY:
2300 case SQL_VARBINARY:
2301 case SQL_LONGVARBINARY:
2302 if (result->binmode <= 0) {
2303 php_printf("<td>Not printable</td>");
2304 break;
2305 }
2306 if (result->binmode <= 1) sql_c_type = SQL_C_BINARY;
2307 case SQL_LONGVARCHAR:
2308 #if defined(ODBCVER) && (ODBCVER >= 0x0300)
2309 case SQL_WLONGVARCHAR:
2310 #endif
2311 if (IS_SQL_LONG(result->values[i].coltype) &&
2312 result->longreadlen <= 0) {
2313 php_printf("<td>Not printable</td>");
2314 break;
2315 }
2316
2317 if (buf == NULL) {
2318 buf = emalloc(result->longreadlen);
2319 }
2320
2321 rc = SQLGetData(result->stmt, (SQLUSMALLINT)(i + 1),sql_c_type, buf, result->longreadlen, &result->values[i].vallen);
2322
2323 php_printf("<td>");
2324
2325 if (rc == SQL_ERROR) {
2326 odbc_sql_error(result->conn_ptr, result->stmt, "SQLGetData");
2327 php_printf("</td></tr></table>");
2328 efree(buf);
2329 RETURN_FALSE;
2330 }
2331 if (rc == SQL_SUCCESS_WITH_INFO) {
2332 PHPWRITE(buf, result->longreadlen);
2333 } else if (result->values[i].vallen == SQL_NULL_DATA) {
2334 php_printf("<td>NULL</td>");
2335 break;
2336 } else {
2337 PHPWRITE(buf, result->values[i].vallen);
2338 }
2339 php_printf("</td>");
2340 break;
2341 default:
2342 if (result->values[i].vallen == SQL_NULL_DATA) {
2343 php_printf("<td>NULL</td>");
2344 } else {
2345 php_printf("<td>%s</td>", result->values[i].value);
2346 }
2347 break;
2348 }
2349 }
2350 php_printf("</tr>\n");
2351
2352 #ifdef HAVE_SQL_EXTENDED_FETCH
2353 if (result->fetch_abs)
2354 rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus);
2355 else
2356 #endif
2357 rc = SQLFetch(result->stmt);
2358 }
2359 php_printf("</table>\n");
2360 if (buf) efree(buf);
2361 RETURN_LONG(result->fetched);
2362 }
2363
2364
2365
2366
2367 PHP_FUNCTION(odbc_free_result)
2368 {
2369 zval *pv_res;
2370 odbc_result *result;
2371 int i;
2372
2373 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_res) == FAILURE) {
2374 return;
2375 }
2376
2377 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
2378 if (result->values) {
2379 for (i = 0; i < result->numcols; i++) {
2380 if (result->values[i].value) {
2381 efree(result->values[i].value);
2382 }
2383 }
2384 efree(result->values);
2385 result->values = NULL;
2386 }
2387
2388 zend_list_delete(Z_LVAL_P(pv_res));
2389
2390 RETURN_TRUE;
2391 }
2392
2393
2394
2395
2396 PHP_FUNCTION(odbc_connect)
2397 {
2398 odbc_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
2399 }
2400
2401
2402
2403
2404 PHP_FUNCTION(odbc_pconnect)
2405 {
2406 odbc_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
2407 }
2408
2409
2410
2411 int odbc_sqlconnect(odbc_connection **conn, char *db, char *uid, char *pwd, int cur_opt, int persistent TSRMLS_DC)
2412 {
2413 RETCODE rc;
2414
2415 *conn = (odbc_connection *)pemalloc(sizeof(odbc_connection), persistent);
2416 (*conn)->persistent = persistent;
2417 SQLAllocEnv(&((*conn)->henv));
2418 SQLAllocConnect((*conn)->henv, &((*conn)->hdbc));
2419
2420 #if defined(HAVE_SOLID) || defined(HAVE_SOLID_30)
2421 SQLSetConnectOption((*conn)->hdbc, SQL_TRANSLATE_OPTION,
2422 SQL_SOLID_XLATOPT_NOCNV);
2423 #endif
2424 #ifdef HAVE_ODBC_ROUTER
2425 {
2426 #define CONNSTRSIZE 2048
2427 char *lpszConnStr = emalloc(CONNSTRSIZE);
2428 if (lpszConnStr && db) {
2429 short cbszConnStr;
2430 if (strstr(db, ";")) {
2431
2432 if (strstr(db, "uid") || strstr(db, "UID")) {
2433 uid = NULL;
2434 }
2435 if (strstr(db, "pwd") || strstr(db, "PWD")) {
2436 pwd = NULL;
2437 }
2438 strlcpy( lpszConnStr, db, CONNSTRSIZE);
2439 }
2440 else {
2441 strcpy(lpszConnStr, "DSN=");
2442 strlcat(lpszConnStr, db, CONNSTRSIZE);
2443 }
2444 if (uid) {
2445 if (uid[0]) {
2446 strlcat(lpszConnStr, ";UID=", CONNSTRSIZE);
2447 strlcat(lpszConnStr, uid, CONNSTRSIZE);
2448 strlcat(lpszConnStr, ";", CONNSTRSIZE);
2449 }
2450 if (pwd) {
2451 if (pwd[0]) {
2452 strlcat(lpszConnStr, "PWD=", CONNSTRSIZE);
2453 strlcat(lpszConnStr, pwd, CONNSTRSIZE);
2454 strlcat(lpszConnStr, ";", CONNSTRSIZE);
2455 }
2456 }
2457 }
2458 rc = SQLDriverConnect((*conn)->hdbc, NULL, lpszConnStr, SQL_NTS, lpszConnStr, CONNSTRSIZE, &cbszConnStr, SQL_DRIVER_NOPROMPT);
2459 efree(lpszConnStr);
2460 }
2461 }
2462 #else
2463 #ifdef HAVE_OPENLINK
2464 {
2465 char dsnbuf[1024];
2466 short dsnbuflen;
2467
2468 rc = SQLDriverConnect((*conn)->hdbc, NULL, db, SQL_NTS, dsnbuf, sizeof(dsnbuf) - 1, &dsnbuflen, SQL_DRIVER_NOPROMPT);
2469 }
2470 #else
2471 if (cur_opt != SQL_CUR_DEFAULT) {
2472 rc = SQLSetConnectOption((*conn)->hdbc, SQL_ODBC_CURSORS, cur_opt);
2473 if (rc != SQL_SUCCESS) {
2474 odbc_sql_error(*conn, SQL_NULL_HSTMT, "SQLSetConnectOption");
2475 SQLFreeConnect((*conn)->hdbc);
2476 pefree(*conn, persistent);
2477 return FALSE;
2478 }
2479 }
2480
2481
2482 #if defined(HAVE_EMPRESS) || defined(HAVE_UNIXODBC) || defined(PHP_WIN32) || defined (HAVE_IODBC)
2483
2484
2485 {
2486 int direct = 0;
2487 char dsnbuf[1024];
2488 short dsnbuflen;
2489 char *ldb = 0;
2490 int ldb_len = 0;
2491
2492 if (strstr((char*)db, ";")) {
2493 direct = 1;
2494 if (uid && !strstr ((char*)db, "uid") && !strstr((char*)db, "UID")) {
2495 spprintf(&ldb, 0, "%s;UID=%s;PWD=%s", db, uid, pwd);
2496 } else {
2497 ldb_len = strlen(db)+1;
2498 ldb = (char*) emalloc(ldb_len);
2499 memcpy(ldb, db, ldb_len);
2500 }
2501 }
2502
2503 if (direct) {
2504 rc = SQLDriverConnect((*conn)->hdbc, NULL, ldb, strlen(ldb), dsnbuf, sizeof(dsnbuf) - 1, &dsnbuflen, SQL_DRIVER_NOPROMPT);
2505 } else {
2506 rc = SQLConnect((*conn)->hdbc, db, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS);
2507 }
2508
2509 if (ldb) {
2510 efree(ldb);
2511 }
2512 }
2513 #else
2514 rc = SQLConnect((*conn)->hdbc, db, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS);
2515 #endif
2516 #endif
2517 #endif
2518 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
2519 odbc_sql_error(*conn, SQL_NULL_HSTMT, "SQLConnect");
2520 SQLFreeConnect((*conn)->hdbc);
2521 pefree((*conn), persistent);
2522 return FALSE;
2523 }
2524
2525 return TRUE;
2526 }
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543 void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
2544 {
2545 char *db, *uid, *pwd;
2546 int db_len, uid_len, pwd_len;
2547 long pv_opt = SQL_CUR_DEFAULT;
2548 odbc_connection *db_conn;
2549 char *hashed_details;
2550 int hashed_len, cur_opt;
2551
2552
2553
2554
2555 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|l", &db, &db_len, &uid, &uid_len, &pwd, &pwd_len, &pv_opt) == FAILURE) {
2556 return;
2557 }
2558
2559 cur_opt = pv_opt;
2560
2561 if (ZEND_NUM_ARGS() > 3) {
2562
2563 if (! (cur_opt == SQL_CUR_USE_IF_NEEDED ||
2564 cur_opt == SQL_CUR_USE_ODBC ||
2565 cur_opt == SQL_CUR_USE_DRIVER ||
2566 cur_opt == SQL_CUR_DEFAULT) ) {
2567 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Cursor type (%d)", cur_opt);
2568 RETURN_FALSE;
2569 }
2570 }
2571
2572 if (ODBCG(allow_persistent) <= 0) {
2573 persistent = 0;
2574 }
2575
2576 hashed_len = spprintf(&hashed_details, 0, "%s_%s_%s_%s_%d", ODBC_TYPE, db, uid, pwd, cur_opt);
2577
2578
2579
2580
2581
2582
2583
2584
2585 try_and_get_another_connection:
2586
2587 if (persistent) {
2588 zend_rsrc_list_entry *le;
2589
2590
2591 if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_len + 1, (void **) &le) == FAILURE) {
2592 zend_rsrc_list_entry new_le;
2593
2594 if (ODBCG(max_links) != -1 && ODBCG(num_links) >= ODBCG(max_links)) {
2595 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", ODBCG(num_links));
2596 efree(hashed_details);
2597 RETURN_FALSE;
2598 }
2599 if (ODBCG(max_persistent) != -1 && ODBCG(num_persistent) >= ODBCG(max_persistent)) {
2600 php_error_docref(NULL TSRMLS_CC, E_WARNING,"Too many open persistent links (%ld)", ODBCG(num_persistent));
2601 efree(hashed_details);
2602 RETURN_FALSE;
2603 }
2604
2605 if (!odbc_sqlconnect(&db_conn, db, uid, pwd, cur_opt, 1 TSRMLS_CC)) {
2606 efree(hashed_details);
2607 RETURN_FALSE;
2608 }
2609
2610 Z_TYPE(new_le) = le_pconn;
2611 new_le.ptr = db_conn;
2612 if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_len + 1, &new_le,
2613 sizeof(zend_rsrc_list_entry), NULL) == FAILURE) {
2614 free(db_conn);
2615 efree(hashed_details);
2616 RETURN_FALSE;
2617 }
2618 ODBCG(num_persistent)++;
2619 ODBCG(num_links)++;
2620 db_conn->id = ZEND_REGISTER_RESOURCE(return_value, db_conn, le_pconn);
2621 } else {
2622 if (Z_TYPE_P(le) != le_pconn) {
2623 RETURN_FALSE;
2624 }
2625
2626
2627
2628 db_conn = (odbc_connection *)le->ptr;
2629
2630
2631
2632
2633 if(ODBCG(check_persistent)){
2634 RETCODE ret;
2635 UCHAR d_name[32];
2636 SQLSMALLINT len;
2637
2638 ret = SQLGetInfo(db_conn->hdbc,
2639 SQL_DATA_SOURCE_READ_ONLY,
2640 d_name, sizeof(d_name), &len);
2641
2642 if(ret != SQL_SUCCESS || len == 0) {
2643 zend_hash_del(&EG(persistent_list), hashed_details, hashed_len + 1);
2644
2645
2646
2647
2648
2649
2650
2651 goto try_and_get_another_connection;
2652 }
2653 }
2654 }
2655 db_conn->id = ZEND_REGISTER_RESOURCE(return_value, db_conn, le_pconn);
2656 } else {
2657 zend_rsrc_list_entry *index_ptr, new_index_ptr;
2658
2659 if (zend_hash_find(&EG(regular_list), hashed_details, hashed_len + 1, (void **) &index_ptr) == SUCCESS) {
2660 int type, conn_id;
2661 void *ptr;
2662
2663 if (Z_TYPE_P(index_ptr) != le_index_ptr) {
2664 RETURN_FALSE;
2665 }
2666 conn_id = (int)index_ptr->ptr;
2667 ptr = zend_list_find(conn_id, &type);
2668
2669 if (ptr && (type == le_conn || type == le_pconn)) {
2670 zend_list_addref(conn_id);
2671 Z_LVAL_P(return_value) = conn_id;
2672 Z_TYPE_P(return_value) = IS_RESOURCE;
2673 efree(hashed_details);
2674 return;
2675 } else {
2676 zend_hash_del(&EG(regular_list), hashed_details, hashed_len + 1);
2677 }
2678 }
2679 if (ODBCG(max_links) != -1 && ODBCG(num_links) >= ODBCG(max_links)) {
2680 php_error_docref(NULL TSRMLS_CC, E_WARNING,"Too many open connections (%ld)",ODBCG(num_links));
2681 efree(hashed_details);
2682 RETURN_FALSE;
2683 }
2684
2685 if (!odbc_sqlconnect(&db_conn, db, uid, pwd, cur_opt, 0 TSRMLS_CC)) {
2686 efree(hashed_details);
2687 RETURN_FALSE;
2688 }
2689 db_conn->id = ZEND_REGISTER_RESOURCE(return_value, db_conn, le_conn);
2690 new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);
2691 Z_TYPE(new_index_ptr) = le_index_ptr;
2692
2693 if (zend_hash_update(&EG(regular_list), hashed_details, hashed_len + 1, (void *) &new_index_ptr,
2694 sizeof(zend_rsrc_list_entry), NULL) == FAILURE) {
2695 efree(hashed_details);
2696 RETURN_FALSE;
2697
2698 }
2699 ODBCG(num_links)++;
2700 }
2701 efree(hashed_details);
2702 }
2703
2704
2705
2706
2707 PHP_FUNCTION(odbc_close)
2708 {
2709 zval *pv_conn;
2710 void *ptr;
2711 odbc_connection *conn;
2712 odbc_result *res;
2713 int nument;
2714 int i;
2715 int type;
2716 int is_pconn = 0;
2717 int found_resource_type = le_conn;
2718
2719 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_conn) == FAILURE) {
2720 return;
2721 }
2722
2723 conn = (odbc_connection *) zend_fetch_resource(&pv_conn TSRMLS_CC, -1, "ODBC-Link", &found_resource_type, 2, le_conn, le_pconn);
2724 if (found_resource_type==le_pconn) {
2725 is_pconn = 1;
2726 }
2727
2728 nument = zend_hash_next_free_element(&EG(regular_list));
2729
2730 for(i = 1; i < nument; i++){
2731 ptr = zend_list_find(i, &type);
2732 if(ptr && (type == le_result)){
2733 res = (odbc_result *)ptr;
2734 if(res->conn_ptr == conn){
2735 zend_list_delete(i);
2736 }
2737 }
2738 }
2739
2740 zend_list_delete(Z_LVAL_P(pv_conn));
2741
2742 if(is_pconn){
2743 zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) _close_pconn_with_id, (void *) &(Z_LVAL_P(pv_conn)) TSRMLS_CC);
2744 }
2745 }
2746
2747
2748
2749
2750 PHP_FUNCTION(odbc_num_rows)
2751 {
2752 odbc_result *result;
2753 SQLLEN rows;
2754 zval *pv_res;
2755
2756 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_res) == FAILURE) {
2757 return;
2758 }
2759 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
2760 SQLRowCount(result->stmt, &rows);
2761 RETURN_LONG(rows);
2762 }
2763
2764
2765 #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30)
2766
2767
2768 PHP_FUNCTION(odbc_next_result)
2769 {
2770 odbc_result *result;
2771 zval *pv_res;
2772 int rc, i;
2773
2774 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_res) == FAILURE) {
2775 return;
2776 }
2777 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
2778
2779 if (result->values) {
2780 for(i = 0; i < result->numcols; i++) {
2781 if (result->values[i].value) {
2782 efree(result->values[i].value);
2783 }
2784 }
2785 efree(result->values);
2786 result->values = NULL;
2787 }
2788
2789 result->fetched = 0;
2790 rc = SQLMoreResults(result->stmt);
2791 if (rc == SQL_SUCCESS_WITH_INFO || rc == SQL_SUCCESS) {
2792 rc = SQLFreeStmt(result->stmt, SQL_UNBIND);
2793 SQLNumParams(result->stmt, &(result->numparams));
2794 SQLNumResultCols(result->stmt, &(result->numcols));
2795
2796 if (result->numcols > 0) {
2797 if (!odbc_bindcols(result TSRMLS_CC)) {
2798 efree(result);
2799 RETVAL_FALSE;
2800 }
2801 } else {
2802 result->values = NULL;
2803 }
2804 RETURN_TRUE;
2805 } else if (rc == SQL_NO_DATA_FOUND) {
2806 RETURN_FALSE;
2807 } else {
2808 odbc_sql_error(result->conn_ptr, result->stmt, "SQLMoreResults");
2809 RETURN_FALSE;
2810 }
2811 }
2812
2813 #endif
2814
2815
2816
2817 PHP_FUNCTION(odbc_num_fields)
2818 {
2819 odbc_result *result;
2820 zval *pv_res;
2821
2822 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pv_res) == FAILURE) {
2823 return;
2824 }
2825 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
2826 RETURN_LONG(result->numcols);
2827 }
2828
2829
2830
2831
2832 PHP_FUNCTION(odbc_field_name)
2833 {
2834 odbc_result *result;
2835 zval *pv_res;
2836 long pv_num;
2837
2838 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &pv_res, &pv_num) == FAILURE) {
2839 return;
2840 }
2841
2842 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
2843
2844 if (result->numcols == 0) {
2845 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No tuples available at this result index");
2846 RETURN_FALSE;
2847 }
2848
2849 if (pv_num > result->numcols) {
2850 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field index larger than number of fields");
2851 RETURN_FALSE;
2852 }
2853
2854 if (pv_num < 1) {
2855 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field numbering starts at 1");
2856 RETURN_FALSE;
2857 }
2858
2859 RETURN_STRING(result->values[pv_num - 1].name, 1);
2860 }
2861
2862
2863
2864
2865 PHP_FUNCTION(odbc_field_type)
2866 {
2867 odbc_result *result;
2868 char tmp[32];
2869 SQLSMALLINT tmplen;
2870 zval *pv_res;
2871 long pv_num;
2872
2873 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &pv_res, &pv_num) == FAILURE) {
2874 return;
2875 }
2876
2877 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
2878
2879 if (result->numcols == 0) {
2880 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No tuples available at this result index");
2881 RETURN_FALSE;
2882 }
2883
2884 if (pv_num > result->numcols) {
2885 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field index larger than number of fields");
2886 RETURN_FALSE;
2887 }
2888
2889 if (pv_num < 1) {
2890 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field numbering starts at 1");
2891 RETURN_FALSE;
2892 }
2893
2894 PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)pv_num, SQL_COLUMN_TYPE_NAME, tmp, 31, &tmplen, NULL);
2895 RETURN_STRING(tmp,1)
2896 }
2897
2898
2899
2900
2901 PHP_FUNCTION(odbc_field_len)
2902 {
2903 odbc_column_lengths(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
2904 }
2905
2906
2907
2908
2909 PHP_FUNCTION(odbc_field_scale)
2910 {
2911 odbc_column_lengths(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
2912 }
2913
2914
2915
2916
2917 PHP_FUNCTION(odbc_field_num)
2918 {
2919 char *fname;
2920 int i, field_ind, fname_len;
2921 odbc_result *result;
2922 zval *pv_res;
2923
2924 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pv_res, &fname, &fname_len) == FAILURE) {
2925 return;
2926 }
2927
2928 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_res, -1, "ODBC result", le_result);
2929
2930 if (result->numcols == 0) {
2931 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No tuples available at this result index");
2932 RETURN_FALSE;
2933 }
2934
2935 field_ind = -1;
2936 for(i = 0; i < result->numcols; i++) {
2937 if (strcasecmp(result->values[i].name, fname) == 0) {
2938 field_ind = i + 1;
2939 }
2940 }
2941
2942 if (field_ind == -1) {
2943 RETURN_FALSE;
2944 }
2945 RETURN_LONG(field_ind);
2946 }
2947
2948
2949
2950
2951
2952 PHP_FUNCTION(odbc_autocommit)
2953 {
2954 odbc_connection *conn;
2955 RETCODE rc;
2956 zval *pv_conn;
2957 long pv_onoff = 0;
2958
2959 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &pv_conn, &pv_onoff) == FAILURE) {
2960 return;
2961 }
2962
2963 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
2964
2965 if (ZEND_NUM_ARGS() > 1) {
2966 rc = SQLSetConnectOption(conn->hdbc, SQL_AUTOCOMMIT, (pv_onoff) ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
2967 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
2968 odbc_sql_error(conn, SQL_NULL_HSTMT, "Set autocommit");
2969 RETURN_FALSE;
2970 }
2971 RETVAL_TRUE;
2972 } else {
2973 SQLINTEGER status;
2974
2975 rc = SQLGetConnectOption(conn->hdbc, SQL_AUTOCOMMIT, (PTR)&status);
2976 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
2977 odbc_sql_error(conn, SQL_NULL_HSTMT, "Get commit status");
2978 RETURN_FALSE;
2979 }
2980 RETVAL_LONG((long)status);
2981 }
2982 }
2983
2984
2985
2986
2987 PHP_FUNCTION(odbc_commit)
2988 {
2989 odbc_transact(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
2990 }
2991
2992
2993
2994
2995 PHP_FUNCTION(odbc_rollback)
2996 {
2997 odbc_transact(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
2998 }
2999
3000
3001
3002 static void php_odbc_lasterror(INTERNAL_FUNCTION_PARAMETERS, int mode)
3003 {
3004 odbc_connection *conn;
3005 zval *pv_handle;
3006 char *ptr;
3007 int len;
3008
3009 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &pv_handle) == FAILURE) {
3010 return;
3011 }
3012
3013 if (mode == 0) {
3014 len = 6;
3015 } else {
3016 len = SQL_MAX_MESSAGE_LENGTH;
3017 }
3018
3019 if (ZEND_NUM_ARGS() == 1) {
3020 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_handle, -1, "ODBC-Link", le_conn, le_pconn);
3021 ptr = ecalloc(len + 1, 1);
3022 if (mode == 0) {
3023 strlcpy(ptr, conn->laststate, len+1);
3024 } else {
3025 strlcpy(ptr, conn->lasterrormsg, len+1);
3026 }
3027 } else {
3028 ptr = ecalloc(len + 1, 1);
3029 if (mode == 0) {
3030 strlcpy(ptr, ODBCG(laststate), len+1);
3031 } else {
3032 strlcpy(ptr, ODBCG(lasterrormsg), len+1);
3033 }
3034 }
3035 RETVAL_STRING(ptr, 0);
3036 }
3037
3038
3039
3040
3041 PHP_FUNCTION(odbc_error)
3042 {
3043 php_odbc_lasterror(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
3044 }
3045
3046
3047
3048
3049 PHP_FUNCTION(odbc_errormsg)
3050 {
3051 php_odbc_lasterror(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
3052 }
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063 PHP_FUNCTION(odbc_setoption)
3064 {
3065 odbc_connection *conn;
3066 odbc_result *result;
3067 RETCODE rc;
3068 zval *pv_handle;
3069 long pv_which, pv_opt, pv_val;
3070
3071 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlll", &pv_handle, &pv_which, &pv_opt, &pv_val) == FAILURE) {
3072 return;
3073 }
3074
3075 switch (pv_which) {
3076 case 1:
3077 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_handle, -1, "ODBC-Link", le_conn, le_pconn);
3078
3079 if (conn->persistent) {
3080 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set option for persistent connection");
3081 RETURN_FALSE;
3082 }
3083 rc = SQLSetConnectOption(conn->hdbc, (unsigned short) pv_opt, pv_val);
3084 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
3085 odbc_sql_error(conn, SQL_NULL_HSTMT, "SetConnectOption");
3086 RETURN_FALSE;
3087 }
3088 break;
3089 case 2:
3090 ZEND_FETCH_RESOURCE(result, odbc_result *, &pv_handle, -1, "ODBC result", le_result);
3091
3092 rc = SQLSetStmtOption(result->stmt, (unsigned short) pv_opt, pv_val);
3093
3094 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
3095 odbc_sql_error(result->conn_ptr, result->stmt, "SetStmtOption");
3096 RETURN_FALSE;
3097 }
3098 break;
3099 default:
3100 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option type");
3101 RETURN_FALSE;
3102 break;
3103 }
3104
3105 RETURN_TRUE;
3106 }
3107
3108
3109
3110
3111
3112
3113
3114
3115 PHP_FUNCTION(odbc_tables)
3116 {
3117 zval *pv_conn;
3118 odbc_result *result = NULL;
3119 odbc_connection *conn;
3120 char *cat = NULL, *schema = NULL, *table = NULL, *type = NULL;
3121 int cat_len = 0, schema_len = 0, table_len = 0, type_len = 0;
3122 RETCODE rc;
3123
3124 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s!sss", &pv_conn, &cat, &cat_len, &schema, &schema_len,
3125 &table, &table_len, &type, &type_len) == FAILURE) {
3126 return;
3127 }
3128
3129 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
3130
3131 result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
3132
3133 rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
3134 if (rc == SQL_INVALID_HANDLE) {
3135 efree(result);
3136 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
3137 RETURN_FALSE;
3138 }
3139
3140 if (rc == SQL_ERROR) {
3141 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt");
3142 efree(result);
3143 RETURN_FALSE;
3144 }
3145
3146
3147 if (table && table_len && schema && schema_len == 0) {
3148 schema = NULL;
3149 }
3150
3151 rc = SQLTables(result->stmt,
3152 cat, SAFE_SQL_NTS(cat),
3153 schema, SAFE_SQL_NTS(schema),
3154 table, SAFE_SQL_NTS(table),
3155 type, SAFE_SQL_NTS(type));
3156
3157 if (rc == SQL_ERROR) {
3158 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLTables");
3159 efree(result);
3160 RETURN_FALSE;
3161 }
3162
3163 result->numparams = 0;
3164 SQLNumResultCols(result->stmt, &(result->numcols));
3165
3166 if (result->numcols > 0) {
3167 if (!odbc_bindcols(result TSRMLS_CC)) {
3168 efree(result);
3169 RETURN_FALSE;
3170 }
3171 } else {
3172 result->values = NULL;
3173 }
3174 result->conn_ptr = conn;
3175 result->fetched = 0;
3176 ZEND_REGISTER_RESOURCE(return_value, result, le_result);
3177 }
3178
3179
3180
3181
3182 PHP_FUNCTION(odbc_columns)
3183 {
3184 zval *pv_conn;
3185 odbc_result *result = NULL;
3186 odbc_connection *conn;
3187 char *cat = NULL, *schema = NULL, *table = NULL, *column = NULL;
3188 int cat_len = 0, schema_len = 0, table_len = 0, column_len = 0;
3189 RETCODE rc;
3190
3191 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s!sss", &pv_conn, &cat, &cat_len, &schema, &schema_len,
3192 &table, &table_len, &column, &column_len) == FAILURE) {
3193 return;
3194 }
3195
3196 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
3197
3198 result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
3199
3200 rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
3201 if (rc == SQL_INVALID_HANDLE) {
3202 efree(result);
3203 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
3204 RETURN_FALSE;
3205 }
3206
3207 if (rc == SQL_ERROR) {
3208 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt");
3209 efree(result);
3210 RETURN_FALSE;
3211 }
3212
3213
3214
3215
3216 if (table && table_len && schema && schema_len == 0) {
3217 schema = NULL;
3218 }
3219
3220 rc = SQLColumns(result->stmt,
3221 cat, (SQLSMALLINT) cat_len,
3222 schema, (SQLSMALLINT) schema_len,
3223 table, (SQLSMALLINT) table_len,
3224 column, (SQLSMALLINT) column_len);
3225
3226 if (rc == SQL_ERROR) {
3227 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLColumns");
3228 efree(result);
3229 RETURN_FALSE;
3230 }
3231
3232 result->numparams = 0;
3233 SQLNumResultCols(result->stmt, &(result->numcols));
3234
3235 if (result->numcols > 0) {
3236 if (!odbc_bindcols(result TSRMLS_CC)) {
3237 efree(result);
3238 RETURN_FALSE;
3239 }
3240 } else {
3241 result->values = NULL;
3242 }
3243 result->conn_ptr = conn;
3244 result->fetched = 0;
3245 ZEND_REGISTER_RESOURCE(return_value, result, le_result);
3246 }
3247
3248
3249 #if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) && !defined(HAVE_BIRDSTEP)
3250
3251
3252 PHP_FUNCTION(odbc_columnprivileges)
3253 {
3254 zval *pv_conn;
3255 odbc_result *result = NULL;
3256 odbc_connection *conn;
3257 char *cat = NULL, *schema, *table, *column;
3258 int cat_len = 0, schema_len, table_len, column_len;
3259 RETCODE rc;
3260
3261 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!sss", &pv_conn, &cat, &cat_len, &schema, &schema_len,
3262 &table, &table_len, &column, &column_len) == FAILURE) {
3263 return;
3264 }
3265
3266 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
3267
3268 result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
3269
3270 rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
3271 if (rc == SQL_INVALID_HANDLE) {
3272 efree(result);
3273 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
3274 RETURN_FALSE;
3275 }
3276
3277 if (rc == SQL_ERROR) {
3278 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt");
3279 efree(result);
3280 RETURN_FALSE;
3281 }
3282
3283 rc = SQLColumnPrivileges(result->stmt,
3284 cat, SAFE_SQL_NTS(cat),
3285 schema, SAFE_SQL_NTS(schema),
3286 table, SAFE_SQL_NTS(table),
3287 column, SAFE_SQL_NTS(column));
3288
3289 if (rc == SQL_ERROR) {
3290 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLColumnPrivileges");
3291 efree(result);
3292 RETURN_FALSE;
3293 }
3294
3295 result->numparams = 0;
3296 SQLNumResultCols(result->stmt, &(result->numcols));
3297
3298 if (result->numcols > 0) {
3299 if (!odbc_bindcols(result TSRMLS_CC)) {
3300 efree(result);
3301 RETURN_FALSE;
3302 }
3303 } else {
3304 result->values = NULL;
3305 }
3306 result->conn_ptr = conn;
3307 result->fetched = 0;
3308 ZEND_REGISTER_RESOURCE(return_value, result, le_result);
3309 }
3310
3311 #endif
3312
3313 #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35)
3314
3315
3316 PHP_FUNCTION(odbc_foreignkeys)
3317 {
3318 zval *pv_conn;
3319 odbc_result *result = NULL;
3320 odbc_connection *conn;
3321 char *pcat = NULL, *pschema, *ptable, *fcat, *fschema, *ftable;
3322 int pcat_len = 0, pschema_len, ptable_len, fcat_len, fschema_len, ftable_len;
3323 RETCODE rc;
3324
3325 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!sssss", &pv_conn, &pcat, &pcat_len, &pschema, &pschema_len,
3326 &ptable, &ptable_len, &fcat, &fcat_len, &fschema, &fschema_len, &ftable, &ftable_len) == FAILURE) {
3327 return;
3328 }
3329
3330 #if defined(HAVE_DBMAKER) || defined(HAVE_IBMDB2)
3331 #define EMPTY_TO_NULL(xstr) \
3332 if ((int)strlen((xstr)) == 0) (xstr) = NULL
3333
3334 EMPTY_TO_NULL(pcat);
3335 EMPTY_TO_NULL(pschema);
3336 EMPTY_TO_NULL(ptable);
3337 EMPTY_TO_NULL(fcat);
3338 EMPTY_TO_NULL(fschema);
3339 EMPTY_TO_NULL(ftable);
3340 #endif
3341
3342 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
3343
3344 result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
3345
3346 rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
3347 if (rc == SQL_INVALID_HANDLE) {
3348 efree(result);
3349 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
3350 RETURN_FALSE;
3351 }
3352
3353 if (rc == SQL_ERROR) {
3354 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt");
3355 efree(result);
3356 RETURN_FALSE;
3357 }
3358
3359 rc = SQLForeignKeys(result->stmt,
3360 pcat, SAFE_SQL_NTS(pcat),
3361 pschema, SAFE_SQL_NTS(pschema),
3362 ptable, SAFE_SQL_NTS(ptable),
3363 fcat, SAFE_SQL_NTS(fcat),
3364 fschema, SAFE_SQL_NTS(fschema),
3365 ftable, SAFE_SQL_NTS(ftable) );
3366
3367 if (rc == SQL_ERROR) {
3368 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLForeignKeys");
3369 efree(result);
3370 RETURN_FALSE;
3371 }
3372
3373 result->numparams = 0;
3374 SQLNumResultCols(result->stmt, &(result->numcols));
3375
3376 if (result->numcols > 0) {
3377 if (!odbc_bindcols(result TSRMLS_CC)) {
3378 efree(result);
3379 RETURN_FALSE;
3380 }
3381 } else {
3382 result->values = NULL;
3383 }
3384 result->conn_ptr = conn;
3385 result->fetched = 0;
3386 ZEND_REGISTER_RESOURCE(return_value, result, le_result);
3387 }
3388
3389 #endif
3390
3391
3392
3393 PHP_FUNCTION(odbc_gettypeinfo)
3394 {
3395 zval *pv_conn;
3396 long pv_data_type = SQL_ALL_TYPES;
3397 odbc_result *result = NULL;
3398 odbc_connection *conn;
3399 RETCODE rc;
3400 SQLSMALLINT data_type;
3401
3402 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &pv_conn, &pv_data_type) == FAILURE) {
3403 return;
3404 }
3405
3406 data_type = (SQLSMALLINT) pv_data_type;
3407
3408 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
3409
3410 result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
3411
3412 rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
3413 if (rc == SQL_INVALID_HANDLE) {
3414 efree(result);
3415 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
3416 RETURN_FALSE;
3417 }
3418
3419 if (rc == SQL_ERROR) {
3420 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt");
3421 efree(result);
3422 RETURN_FALSE;
3423 }
3424
3425 rc = SQLGetTypeInfo(result->stmt, data_type );
3426
3427 if (rc == SQL_ERROR) {
3428 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLGetTypeInfo");
3429 efree(result);
3430 RETURN_FALSE;
3431 }
3432
3433 result->numparams = 0;
3434 SQLNumResultCols(result->stmt, &(result->numcols));
3435
3436 if (result->numcols > 0) {
3437 if (!odbc_bindcols(result TSRMLS_CC)) {
3438 efree(result);
3439 RETURN_FALSE;
3440 }
3441 } else {
3442 result->values = NULL;
3443 }
3444 result->conn_ptr = conn;
3445 result->fetched = 0;
3446 ZEND_REGISTER_RESOURCE(return_value, result, le_result);
3447 }
3448
3449
3450
3451
3452 PHP_FUNCTION(odbc_primarykeys)
3453 {
3454 zval *pv_conn;
3455 odbc_result *result = NULL;
3456 odbc_connection *conn;
3457 char *cat = NULL, *schema = NULL, *table = NULL;
3458 int cat_len = 0, schema_len, table_len;
3459 RETCODE rc;
3460
3461 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!ss", &pv_conn, &cat, &cat_len, &schema, &schema_len, &table, &table_len) == FAILURE) {
3462 return;
3463 }
3464
3465 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
3466
3467 result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
3468
3469 rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
3470 if (rc == SQL_INVALID_HANDLE) {
3471 efree(result);
3472 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
3473 RETURN_FALSE;
3474 }
3475
3476 if (rc == SQL_ERROR) {
3477 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt");
3478 efree(result);
3479 RETURN_FALSE;
3480 }
3481
3482 rc = SQLPrimaryKeys(result->stmt,
3483 cat, SAFE_SQL_NTS(cat),
3484 schema, SAFE_SQL_NTS(schema),
3485 table, SAFE_SQL_NTS(table) );
3486
3487 if (rc == SQL_ERROR) {
3488 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLPrimaryKeys");
3489 efree(result);
3490 RETURN_FALSE;
3491 }
3492
3493 result->numparams = 0;
3494 SQLNumResultCols(result->stmt, &(result->numcols));
3495
3496 if (result->numcols > 0) {
3497 if (!odbc_bindcols(result TSRMLS_CC)) {
3498 efree(result);
3499 RETURN_FALSE;
3500 }
3501 } else {
3502 result->values = NULL;
3503 }
3504 result->conn_ptr = conn;
3505 result->fetched = 0;
3506 ZEND_REGISTER_RESOURCE(return_value, result, le_result);
3507 }
3508
3509
3510 #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) && !defined(HAVE_BIRDSTEP)
3511
3512
3513 PHP_FUNCTION(odbc_procedurecolumns)
3514 {
3515 zval *pv_conn;
3516 odbc_result *result = NULL;
3517 odbc_connection *conn;
3518 char *cat = NULL, *schema = NULL, *proc = NULL, *col = NULL;
3519 int cat_len = 0, schema_len = 0, proc_len = 0, col_len = 0;
3520 RETCODE rc;
3521
3522 if (ZEND_NUM_ARGS() != 1 && ZEND_NUM_ARGS() != 5) {
3523 WRONG_PARAM_COUNT;
3524 }
3525
3526 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s!sss", &pv_conn, &cat, &cat_len, &schema, &schema_len,
3527 &proc, &proc_len, &col, &col_len) == FAILURE) {
3528 return;
3529 }
3530
3531 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
3532
3533 result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
3534
3535 rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
3536 if (rc == SQL_INVALID_HANDLE) {
3537 efree(result);
3538 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
3539 RETURN_FALSE;
3540 }
3541
3542 if (rc == SQL_ERROR) {
3543 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt");
3544 efree(result);
3545 RETURN_FALSE;
3546 }
3547
3548 rc = SQLProcedureColumns(result->stmt,
3549 cat, SAFE_SQL_NTS(cat),
3550 schema, SAFE_SQL_NTS(schema),
3551 proc, SAFE_SQL_NTS(proc),
3552 col, SAFE_SQL_NTS(col) );
3553
3554 if (rc == SQL_ERROR) {
3555 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLProcedureColumns");
3556 efree(result);
3557 RETURN_FALSE;
3558 }
3559
3560 result->numparams = 0;
3561 SQLNumResultCols(result->stmt, &(result->numcols));
3562
3563 if (result->numcols > 0) {
3564 if (!odbc_bindcols(result TSRMLS_CC)) {
3565 efree(result);
3566 RETURN_FALSE;
3567 }
3568 } else {
3569 result->values = NULL;
3570 }
3571 result->conn_ptr = conn;
3572 result->fetched = 0;
3573 ZEND_REGISTER_RESOURCE(return_value, result, le_result);
3574 }
3575
3576 #endif
3577
3578 #if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35)
3579
3580
3581 PHP_FUNCTION(odbc_procedures)
3582 {
3583 zval *pv_conn;
3584 odbc_result *result = NULL;
3585 odbc_connection *conn;
3586 char *cat = NULL, *schema = NULL, *proc = NULL;
3587 int cat_len = 0, schema_len = 0, proc_len = 0;
3588 RETCODE rc;
3589
3590 if (ZEND_NUM_ARGS() != 1 && ZEND_NUM_ARGS() != 4) {
3591 WRONG_PARAM_COUNT;
3592 }
3593
3594 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s!ss", &pv_conn, &cat, &cat_len, &schema, &schema_len, &proc, &proc_len) == FAILURE) {
3595 return;
3596 }
3597
3598 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
3599
3600 result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
3601
3602 rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
3603 if (rc == SQL_INVALID_HANDLE) {
3604 efree(result);
3605 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
3606 RETURN_FALSE;
3607 }
3608
3609 if (rc == SQL_ERROR) {
3610 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt");
3611 efree(result);
3612 RETURN_FALSE;
3613 }
3614
3615 rc = SQLProcedures(result->stmt,
3616 cat, SAFE_SQL_NTS(cat),
3617 schema, SAFE_SQL_NTS(schema),
3618 proc, SAFE_SQL_NTS(proc) );
3619
3620 if (rc == SQL_ERROR) {
3621 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLProcedures");
3622 efree(result);
3623 RETURN_FALSE;
3624 }
3625
3626 result->numparams = 0;
3627 SQLNumResultCols(result->stmt, &(result->numcols));
3628
3629 if (result->numcols > 0) {
3630 if (!odbc_bindcols(result TSRMLS_CC)) {
3631 efree(result);
3632 RETURN_FALSE;
3633 }
3634 } else {
3635 result->values = NULL;
3636 }
3637 result->conn_ptr = conn;
3638 result->fetched = 0;
3639 ZEND_REGISTER_RESOURCE(return_value, result, le_result);
3640 }
3641
3642 #endif
3643
3644
3645
3646 PHP_FUNCTION(odbc_specialcolumns)
3647 {
3648 zval *pv_conn;
3649 long vtype, vscope, vnullable;
3650 odbc_result *result = NULL;
3651 odbc_connection *conn;
3652 char *cat = NULL, *schema = NULL, *name = NULL;
3653 int cat_len = 0, schema_len, name_len;
3654 SQLUSMALLINT type, scope, nullable;
3655 RETCODE rc;
3656
3657 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rls!ssll", &pv_conn, &vtype, &cat, &cat_len, &schema, &schema_len,
3658 &name, &name_len, &vscope, &vnullable) == FAILURE) {
3659 return;
3660 }
3661
3662 type = (SQLUSMALLINT) vtype;
3663 scope = (SQLUSMALLINT) vscope;
3664 nullable = (SQLUSMALLINT) vnullable;
3665
3666 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
3667
3668 result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
3669
3670 rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
3671 if (rc == SQL_INVALID_HANDLE) {
3672 efree(result);
3673 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
3674 RETURN_FALSE;
3675 }
3676
3677 if (rc == SQL_ERROR) {
3678 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt");
3679 efree(result);
3680 RETURN_FALSE;
3681 }
3682
3683 rc = SQLSpecialColumns(result->stmt,
3684 type,
3685 cat, SAFE_SQL_NTS(cat),
3686 schema, SAFE_SQL_NTS(schema),
3687 name, SAFE_SQL_NTS(name),
3688 scope,
3689 nullable);
3690
3691 if (rc == SQL_ERROR) {
3692 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLSpecialColumns");
3693 efree(result);
3694 RETURN_FALSE;
3695 }
3696
3697 result->numparams = 0;
3698 SQLNumResultCols(result->stmt, &(result->numcols));
3699
3700 if (result->numcols > 0) {
3701 if (!odbc_bindcols(result TSRMLS_CC)) {
3702 efree(result);
3703 RETURN_FALSE;
3704 }
3705 } else {
3706 result->values = NULL;
3707 }
3708 result->conn_ptr = conn;
3709 result->fetched = 0;
3710 ZEND_REGISTER_RESOURCE(return_value, result, le_result);
3711 }
3712
3713
3714
3715
3716 PHP_FUNCTION(odbc_statistics)
3717 {
3718 zval *pv_conn;
3719 long vunique, vreserved;
3720 odbc_result *result = NULL;
3721 odbc_connection *conn;
3722 char *cat = NULL, *schema, *name;
3723 int cat_len = 0, schema_len, name_len;
3724 SQLUSMALLINT unique, reserved;
3725 RETCODE rc;
3726
3727 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!ssll", &pv_conn, &cat, &cat_len, &schema, &schema_len,
3728 &name, &name_len, &vunique, &vreserved) == FAILURE) {
3729 return;
3730 }
3731
3732 unique = (SQLUSMALLINT) vunique;
3733 reserved = (SQLUSMALLINT) vreserved;
3734
3735 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
3736
3737 result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
3738
3739 rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
3740 if (rc == SQL_INVALID_HANDLE) {
3741 efree(result);
3742 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
3743 RETURN_FALSE;
3744 }
3745
3746 if (rc == SQL_ERROR) {
3747 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt");
3748 efree(result);
3749 RETURN_FALSE;
3750 }
3751
3752 rc = SQLStatistics(result->stmt,
3753 cat, SAFE_SQL_NTS(cat),
3754 schema, SAFE_SQL_NTS(schema),
3755 name, SAFE_SQL_NTS(name),
3756 unique,
3757 reserved);
3758
3759 if (rc == SQL_ERROR) {
3760 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLStatistics");
3761 efree(result);
3762 RETURN_FALSE;
3763 }
3764
3765 result->numparams = 0;
3766 SQLNumResultCols(result->stmt, &(result->numcols));
3767
3768 if (result->numcols > 0) {
3769 if (!odbc_bindcols(result TSRMLS_CC)) {
3770 efree(result);
3771 RETURN_FALSE;
3772 }
3773 } else {
3774 result->values = NULL;
3775 }
3776 result->conn_ptr = conn;
3777 result->fetched = 0;
3778 ZEND_REGISTER_RESOURCE(return_value, result, le_result);
3779 }
3780
3781
3782 #if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) && !defined(HAVE_BIRDSTEP)
3783
3784
3785 PHP_FUNCTION(odbc_tableprivileges)
3786 {
3787 zval *pv_conn;
3788 odbc_result *result = NULL;
3789 odbc_connection *conn;
3790 char *cat = NULL, *schema = NULL, *table = NULL;
3791 int cat_len = 0, schema_len, table_len;
3792 RETCODE rc;
3793
3794 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!ss", &pv_conn, &cat, &cat_len, &schema, &schema_len, &table, &table_len) == FAILURE) {
3795 return;
3796 }
3797
3798 ZEND_FETCH_RESOURCE2(conn, odbc_connection *, &pv_conn, -1, "ODBC-Link", le_conn, le_pconn);
3799
3800 result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
3801
3802 rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
3803 if (rc == SQL_INVALID_HANDLE) {
3804 efree(result);
3805 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLAllocStmt error 'Invalid Handle'");
3806 RETURN_FALSE;
3807 }
3808
3809 if (rc == SQL_ERROR) {
3810 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLAllocStmt");
3811 efree(result);
3812 RETURN_FALSE;
3813 }
3814
3815 rc = SQLTablePrivileges(result->stmt,
3816 cat, SAFE_SQL_NTS(cat),
3817 schema, SAFE_SQL_NTS(schema),
3818 table, SAFE_SQL_NTS(table));
3819
3820 if (rc == SQL_ERROR) {
3821 odbc_sql_error(conn, SQL_NULL_HSTMT, "SQLTablePrivileges");
3822 efree(result);
3823 RETURN_FALSE;
3824 }
3825
3826 result->numparams = 0;
3827 SQLNumResultCols(result->stmt, &(result->numcols));
3828
3829 if (result->numcols > 0) {
3830 if (!odbc_bindcols(result TSRMLS_CC)) {
3831 efree(result);
3832 RETURN_FALSE;
3833 }
3834 } else {
3835 result->values = NULL;
3836 }
3837 result->conn_ptr = conn;
3838 result->fetched = 0;
3839 ZEND_REGISTER_RESOURCE(return_value, result, le_result);
3840 }
3841
3842 #endif
3843
3844 #endif
3845
3846
3847
3848
3849
3850
3851
3852
3853