xref: /PHP-5.5/ext/odbc/birdstep.c (revision 73c1be26)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 5                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2015 The PHP Group                                |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 3.01 of the PHP license,      |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available through the world-wide-web at the following url:           |
10    | http://www.php.net/license/3_01.txt                                  |
11    | If you did not receive a copy of the PHP license and are unable to   |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@php.net so we can mail you a copy immediately.               |
14    +----------------------------------------------------------------------+
15    | Authors: Nikolay P. Romanyuk <mag@redcom.ru>                         |
16    +----------------------------------------------------------------------+
17  */
18 
19 /* $Id$ */
20 
21 /*
22  * TODO:
23  * birdstep_fetch_into(),
24  * Check all on real life apps.
25  */
26 
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30 
31 #include "php.h"
32 
33 #if WIN32
34 # include "config.w32.h"
35 # include "win95nt.h"
36 # ifdef PHP_EXPORTS
37 #  define PHPAPI __declspec(dllexport)
38 # else
39 #  define PHPAPI __declspec(dllimport)
40 # endif
41 #else
42 # include <php_config.h>
43 # define PHPAPI
44 # define THREAD_LS
45 #endif
46 
47 #ifdef HAVE_BIRDSTEP
48 #include "php_birdstep.h"
49 #include "ext/standard/info.h"
50 #include "php_ini.h"
51 
52 /* {{{ arginfo */
53 ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_connect, 0, 0, 3)
54 	ZEND_ARG_INFO(0, server)
55 	ZEND_ARG_INFO(0, user)
56 	ZEND_ARG_INFO(0, pass)
57 ZEND_END_ARG_INFO()
58 
59 ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_close, 0, 0, 1)
60 	ZEND_ARG_INFO(0, id)
61 ZEND_END_ARG_INFO()
62 
63 ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_exec, 0, 0, 2)
64 	ZEND_ARG_INFO(0, index)
65 	ZEND_ARG_INFO(0, exec_str)
66 ZEND_END_ARG_INFO()
67 
68 ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_fetch, 0, 0, 1)
69 	ZEND_ARG_INFO(0, index)
70 ZEND_END_ARG_INFO()
71 
72 ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_result, 0, 0, 2)
73 	ZEND_ARG_INFO(0, index)
74 	ZEND_ARG_INFO(0, col)
75 ZEND_END_ARG_INFO()
76 
77 ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_freeresult, 0, 0, 1)
78 	ZEND_ARG_INFO(0, index)
79 ZEND_END_ARG_INFO()
80 
81 ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_autocommit, 0, 0, 1)
82 	ZEND_ARG_INFO(0, index)
83 ZEND_END_ARG_INFO()
84 
85 ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_off_autocommit, 0, 0, 1)
86 	ZEND_ARG_INFO(0, index)
87 ZEND_END_ARG_INFO()
88 
89 ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_commit, 0, 0, 1)
90 	ZEND_ARG_INFO(0, index)
91 ZEND_END_ARG_INFO()
92 
93 ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_rollback, 0, 0, 1)
94 	ZEND_ARG_INFO(0, index)
95 ZEND_END_ARG_INFO()
96 
97 ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_fieldname, 0, 0, 2)
98 	ZEND_ARG_INFO(0, index)
99 	ZEND_ARG_INFO(0, col)
100 ZEND_END_ARG_INFO()
101 
102 ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_fieldnum, 0, 0, 1)
103 	ZEND_ARG_INFO(0, index)
104 ZEND_END_ARG_INFO()
105 /* }}} */
106 
107 const zend_function_entry birdstep_functions[] = {
108 	PHP_FE(birdstep_connect,        arginfo_birdstep_connect)
109 	PHP_FE(birdstep_close,          arginfo_birdstep_close)
110 	PHP_FE(birdstep_exec,           arginfo_birdstep_exec)
111 	PHP_FE(birdstep_fetch,          arginfo_birdstep_fetch)
112 	PHP_FE(birdstep_result,         arginfo_birdstep_result)
113 	PHP_FE(birdstep_freeresult,     arginfo_birdstep_freeresult)
114 	PHP_FE(birdstep_autocommit,     arginfo_birdstep_autocommit)
115 	PHP_FE(birdstep_off_autocommit, arginfo_birdstep_off_autocommit)
116 	PHP_FE(birdstep_commit,         arginfo_birdstep_commit)
117 	PHP_FE(birdstep_rollback,       arginfo_birdstep_rollback)
118 	PHP_FE(birdstep_fieldnum,       arginfo_birdstep_fieldnum)
119 	PHP_FE(birdstep_fieldname,      arginfo_birdstep_fieldname)
120 /*
121  * Temporary Function aliases until the next major upgrade to PHP.
122  * These should allow users to continue to use their current scripts,
123  * but should in reality warn the user that this functionality is
124  * deprecated.
125  */
126 	PHP_FALIAS(velocis_connect,        birdstep_connect,        arginfo_birdstep_connect)
127 	PHP_FALIAS(velocis_close,          birdstep_close,          arginfo_birdstep_close)
128 	PHP_FALIAS(velocis_exec,           birdstep_exec,           arginfo_birdstep_exec)
129 	PHP_FALIAS(velocis_fetch,          birdstep_fetch,          arginfo_birdstep_fetch)
130 	PHP_FALIAS(velocis_result,         birdstep_result,         arginfo_birdstep_result)
131 	PHP_FALIAS(velocis_freeresult,     birdstep_freeresult,     arginfo_birdstep_freeresult)
132 	PHP_FALIAS(velocis_autocommit,     birdstep_autocommit,     arginfo_birdstep_autocommit)
133 	PHP_FALIAS(velocis_off_autocommit, birdstep_off_autocommit, arginfo_birdstep_off_autocommit)
134 	PHP_FALIAS(velocis_commit,         birdstep_commit,         arginfo_birdstep_commit)
135 	PHP_FALIAS(velocis_rollback,       birdstep_rollback,       arginfo_birdstep_rollback)
136 	PHP_FALIAS(velocis_fieldnum,       birdstep_fieldnum,       arginfo_birdstep_fieldnum)
137 	PHP_FALIAS(velocis_fieldname,      birdstep_fieldname,      arginfo_birdstep_fieldname)
138 /* End temporary aliases */
139 	{NULL, NULL, NULL}
140 };
141 
142 zend_module_entry birdstep_module_entry = {
143 	STANDARD_MODULE_HEADER,
144 	"birdstep",
145 	birdstep_functions,
146 	PHP_MINIT(birdstep),
147 	PHP_MSHUTDOWN(birdstep),
148 	PHP_RINIT(birdstep),
149 	NULL,
150 	PHP_MINFO(birdstep),
151 	NO_VERSION_YET,
152 	STANDARD_MODULE_PROPERTIES
153 };
154 
155 #ifdef COMPILE_DL_ODBC
156 ZEND_GET_MODULE(birdstep)
157 #endif
158 
159 THREAD_LS birdstep_module php_birdstep_module;
160 THREAD_LS static HENV henv;
161 
162 #define PHP_GET_BIRDSTEP_RES_IDX(id) if (!(res = birdstep_find_result(list, id))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Not result index (%ld)", id); RETURN_FALSE; }
163 #define PHP_BIRDSTEP_CHK_LNK(id) if (!(conn = birdstep_find_conn(list, id))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Not connection index (%ld)", id); RETURN_FALSE; }
164 
165 
_close_birdstep_link(zend_rsrc_list_entry * rsrc TSRMLS_DC)166 static void _close_birdstep_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
167 {
168 	VConn *conn = (VConn *)rsrc->ptr;
169 
170 	if ( conn ) {
171 		efree(conn);
172 	}
173 }
174 
_free_birdstep_result(zend_rsrc_list_entry * rsrc TSRMLS_DC)175 static void _free_birdstep_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
176 {
177 	Vresult *res = (Vresult *)rsrc->ptr;
178 
179 	if ( res && res->values ) {
180 		register int i;
181 		for ( i=0; i < res->numcols; i++ ) {
182 			if ( res->values[i].value )
183 				efree(res->values[i].value);
184 		}
185 		efree(res->values);
186 	}
187 	if ( res ) {
188 		efree(res);
189 	}
190 }
191 
PHP_MINIT_FUNCTION(birdstep)192 PHP_MINIT_FUNCTION(birdstep)
193 {
194 	SQLAllocEnv(&henv);
195 
196 	if ( cfg_get_long("birdstep.max_links",&php_birdstep_module.max_links) == FAILURE ) {
197 		php_birdstep_module.max_links = -1;
198 	}
199 	php_birdstep_module.num_links = 0;
200 	php_birdstep_module.le_link   = zend_register_list_destructors_ex(_close_birdstep_link, NULL, "birdstep link", module_number);
201 	php_birdstep_module.le_result = zend_register_list_destructors_ex(_free_birdstep_result, NULL, "birdstep result", module_number);
202 
203 	return SUCCESS;
204 }
205 
PHP_RINIT_FUNCTION(birdstep)206 PHP_RINIT_FUNCTION(birdstep)
207 {
208 	return SUCCESS;
209 }
210 
211 
PHP_MINFO_FUNCTION(birdstep)212 PHP_MINFO_FUNCTION(birdstep)
213 {
214 	php_info_print_table_start();
215 	php_info_print_table_row(2, "RAIMA Birdstep Support", "enabled" );
216 	php_info_print_table_end();
217 }
218 
PHP_MSHUTDOWN_FUNCTION(birdstep)219 PHP_MSHUTDOWN_FUNCTION(birdstep)
220 {
221 	SQLFreeEnv(henv);
222 	return SUCCESS;
223 }
224 
225 /* Some internal functions. Connections and result manupulate */
226 
birdstep_add_conn(HashTable * list,VConn * conn,HDBC hdbc TSRMLS_DC)227 static int birdstep_add_conn(HashTable *list,VConn *conn,HDBC hdbc TSRMLS_DC)
228 {
229 	int ind;
230 
231 	ind = zend_list_insert(conn,php_birdstep_module.le_link TSRMLS_CC);
232 	conn->hdbc = hdbc;
233 	conn->index = ind;
234 
235 	return(ind);
236 }
237 
birdstep_find_conn(HashTable * list,int ind)238 static VConn * birdstep_find_conn(HashTable *list,int ind)
239 {
240 	VConn *conn;
241 	int type;
242 
243 	conn = zend_list_find(ind,&type);
244 	if ( !conn || type != php_birdstep_module.le_link ) {
245 		return(NULL);
246 	}
247 	return(conn);
248 }
249 
birdstep_del_conn(HashTable * list,int ind)250 static void birdstep_del_conn(HashTable *list,int ind)
251 {
252 	zend_list_delete(ind);
253 }
254 
birdstep_add_result(HashTable * list,Vresult * res,VConn * conn)255 static int birdstep_add_result(HashTable *list,Vresult *res,VConn *conn)
256 {
257 	int ind;
258 
259 	ind = zend_list_insert(res,php_birdstep_module.le_result);
260 	res->conn = conn;
261 	res->index = ind;
262 
263 	return(ind);
264 }
265 
birdstep_find_result(HashTable * list,int ind)266 static Vresult * birdstep_find_result(HashTable *list,int ind)
267 {
268 	Vresult *res;
269 	int type;
270 
271 	res = zend_list_find(ind,&type);
272 	if ( !res || type != php_birdstep_module.le_result ) {
273 		return(NULL);
274 	}
275 	return(res);
276 }
277 
birdstep_del_result(HashTable * list,int ind)278 static void birdstep_del_result(HashTable *list,int ind)
279 {
280 	zend_list_delete(ind);
281 }
282 
283 /* Users functions */
284 
285 /* {{{ proto int birdstep_connect(string server, string user, string pass)
286  */
PHP_FUNCTION(birdstep_connect)287 PHP_FUNCTION(birdstep_connect)
288 {
289 	char *serv, *user, *pass;
290 	int serv_len, user_len, pass_len;
291 	RETCODE stat;
292 	HDBC hdbc;
293 	VConn *new;
294 	long ind;
295 
296 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", &serv, &serv_len, &user, &user_len, &pass, &pass_len) == FAILURE) {
297 		return;
298 	}
299 
300 	if ( php_birdstep_module.max_links != -1 && php_birdstep_module.num_links == php_birdstep_module.max_links ) {
301 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Too many open connections (%d)",php_birdstep_module.num_links);
302 		RETURN_FALSE;
303 	}
304 
305 	stat = SQLAllocConnect(henv,&hdbc);
306 	if ( stat != SQL_SUCCESS ) {
307 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Could not allocate connection handle");
308 		RETURN_FALSE;
309 	}
310 	stat = SQLConnect(hdbc, serv, SQL_NTS, user, SQL_NTS, pass, SQL_NTS);
311 	if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
312 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Could not connect to server \"%s\" for %s", serv, user);
313 		SQLFreeConnect(hdbc);
314 		RETURN_FALSE;
315 	}
316 	new = (VConn *)emalloc(sizeof(VConn));
317 	ind = birdstep_add_conn(list,new,hdbc TSRMLS_CC);
318 	php_birdstep_module.num_links++;
319 	RETURN_LONG(ind);
320 }
321 /* }}} */
322 
323 /* {{{ proto bool birdstep_close(int id)
324  */
PHP_FUNCTION(birdstep_close)325 PHP_FUNCTION(birdstep_close)
326 {
327 	long id;
328 	VConn *conn;
329 
330 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) {
331 		return;
332 	}
333 
334 	PHP_BIRDSTEP_CHK_LNK(id);
335 
336 	SQLDisconnect(conn->hdbc);
337 	SQLFreeConnect(conn->hdbc);
338 	birdstep_del_conn(list, id);
339 	php_birdstep_module.num_links--;
340 	RETURN_TRUE;
341 }
342 /* }}} */
343 
344 /* {{{ proto int birdstep_exec(int index, string exec_str)
345  */
PHP_FUNCTION(birdstep_exec)346 PHP_FUNCTION(birdstep_exec)
347 {
348 	char *query;
349 	long ind;
350 	int query_len, indx;
351 	VConn *conn;
352 	Vresult *res;
353 	RETCODE stat;
354 	SWORD cols,i,colnamelen;
355 	SDWORD rows,coldesc;
356 
357 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &ind, &query, &query_len) == FAILURE) {
358 		return;
359 	}
360 
361 	PHP_BIRDSTEP_CHK_LNK(ind);
362 
363 	res = (Vresult *)emalloc(sizeof(Vresult));
364 	stat = SQLAllocStmt(conn->hdbc,&res->hstmt);
365 	if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
366 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: SQLAllocStmt return %d",stat);
367 		efree(res);
368 		RETURN_FALSE;
369 	}
370 	stat = SQLExecDirect(res->hstmt,query,SQL_NTS);
371 	if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
372 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Cannot execute \"%s\" query",query);
373 		SQLFreeStmt(res->hstmt,SQL_DROP);
374 		efree(res);
375 		RETURN_FALSE;
376 	}
377 	/* Success query */
378 	stat = SQLNumResultCols(res->hstmt,&cols);
379 	if ( stat != SQL_SUCCESS ) {
380 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: SQLNumResultCols return %d",stat);
381 		SQLFreeStmt(res->hstmt,SQL_DROP);
382 		efree(res);
383 		RETURN_FALSE;
384 	}
385 	if ( !cols ) { /* Was INSERT, UPDATE, DELETE, etc. query */
386 		stat = SQLRowCount(res->hstmt,&rows);
387 		if ( stat != SQL_SUCCESS ) {
388 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: SQLNumResultCols return %d",stat);
389 			SQLFreeStmt(res->hstmt,SQL_DROP);
390 			efree(res);
391 			RETURN_FALSE;
392 		}
393 		SQLFreeStmt(res->hstmt,SQL_DROP);
394 		efree(res);
395 		RETURN_LONG(rows);
396 	} else {  /* Was SELECT query */
397 		res->values = (VResVal *)safe_emalloc(sizeof(VResVal), cols, 0);
398 		res->numcols = cols;
399 		for ( i = 0; i < cols; i++ ) {
400 			SQLColAttributes(res->hstmt,i+1,SQL_COLUMN_NAME,
401 			   res->values[i].name,sizeof(res->values[i].name),
402 			   &colnamelen,NULL);
403 			SQLColAttributes(res->hstmt,i+1,SQL_COLUMN_TYPE,
404 			   NULL,0,NULL,&res->values[i].valtype);
405 			switch ( res->values[i].valtype ) {
406 				case SQL_LONGVARBINARY:
407 				case SQL_LONGVARCHAR:
408 					res->values[i].value = NULL;
409 					continue;
410 				default:
411 					break;
412 			}
413 			SQLColAttributes(res->hstmt,i+1,SQL_COLUMN_DISPLAY_SIZE,
414 			   NULL,0,NULL,&coldesc);
415 			res->values[i].value = (char *)emalloc(coldesc+1);
416 			SQLBindCol(res->hstmt,i+1,SQL_C_CHAR, res->values[i].value,coldesc+1, &res->values[i].vallen);
417 		}
418 	}
419 	res->fetched = 0;
420 	indx = birdstep_add_result(list,res,conn);
421 	RETURN_LONG(indx);
422 }
423 /* }}} */
424 
425 /* {{{ proto bool birdstep_fetch(int index)
426  */
PHP_FUNCTION(birdstep_fetch)427 PHP_FUNCTION(birdstep_fetch)
428 {
429 	long ind;
430 	Vresult *res;
431 	RETCODE stat;
432 	UDWORD  row;
433 	UWORD   RowStat[1];
434 
435 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ind) == FAILURE) {
436 		return;
437 	}
438 
439 	PHP_GET_BIRDSTEP_RES_IDX(ind);
440 
441 	stat = SQLExtendedFetch(res->hstmt,SQL_FETCH_NEXT,1,&row,RowStat);
442 	if ( stat == SQL_NO_DATA_FOUND ) {
443 		SQLFreeStmt(res->hstmt,SQL_DROP);
444 		birdstep_del_result(list,Z_LVAL_PP(ind));
445 		RETURN_FALSE;
446 	}
447 	if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
448 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: SQLFetch return error");
449 		SQLFreeStmt(res->hstmt,SQL_DROP);
450 		birdstep_del_result(list,Z_LVAL_PP(ind));
451 		RETURN_FALSE;
452 	}
453 	res->fetched = 1;
454 	RETURN_TRUE;
455 }
456 /* }}} */
457 
458 /* {{{ proto mixed birdstep_result(int index, mixed col)
459  */
PHP_FUNCTION(birdstep_result)460 PHP_FUNCTION(birdstep_result)
461 {
462 	zval **col;
463 	long ind;
464 	Vresult *res;
465 	RETCODE stat;
466 	int i,sql_c_type;
467 	UDWORD row;
468 	UWORD RowStat[1];
469 	SWORD indx = -1;
470 	char *field = NULL;
471 
472 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lZ", &ind, &col) == FAILURE) {
473 		return;
474 	}
475 
476 	PHP_GET_BIRDSTEP_RES_IDX(ind);
477 
478 	if ( Z_TYPE_PP(col) == IS_STRING ) {
479 		field = Z_STRVAL_PP(col);
480 	} else {
481 		convert_to_long_ex(col);
482 		indx = Z_LVAL_PP(col);
483 	}
484 	if ( field ) {
485 		for ( i = 0; i < res->numcols; i++ ) {
486 			if ( !strcasecmp(res->values[i].name,field)) {
487 				indx = i;
488 				break;
489 			}
490 		}
491 		if ( indx < 0 ) {
492 			php_error_docref(NULL TSRMLS_CC, E_WARNING,  "Field %s not found",field);
493 			RETURN_FALSE;
494 		}
495 	} else {
496 		if ( indx < 0 || indx >= res->numcols ) {
497 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Field index not in range");
498 			RETURN_FALSE;
499 		}
500 	}
501 	if ( !res->fetched ) {
502 		stat = SQLExtendedFetch(res->hstmt,SQL_FETCH_NEXT,1,&row,RowStat);
503 		if ( stat == SQL_NO_DATA_FOUND ) {
504 			SQLFreeStmt(res->hstmt,SQL_DROP);
505 			birdstep_del_result(list,Z_LVAL_PP(ind));
506 			RETURN_FALSE;
507 		}
508 		if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
509 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: SQLFetch return error");
510 			SQLFreeStmt(res->hstmt,SQL_DROP);
511 			birdstep_del_result(list,Z_LVAL_PP(ind));
512 			RETURN_FALSE;
513 		}
514 		res->fetched = 1;
515 	}
516 	switch ( res->values[indx].valtype ) {
517 		case SQL_LONGVARBINARY:
518 			sql_c_type = SQL_C_BINARY;
519 			goto l1;
520 		case SQL_LONGVARCHAR:
521 			sql_c_type = SQL_C_CHAR;
522 l1:
523 			if ( !res->values[indx].value ) {
524 				res->values[indx].value = emalloc(4096);
525 			}
526 			stat = SQLGetData(res->hstmt,indx+1,sql_c_type,
527 				res->values[indx].value,4095,&res->values[indx].vallen);
528 			if ( stat == SQL_NO_DATA_FOUND ) {
529 				SQLFreeStmt(res->hstmt,SQL_DROP);
530 				birdstep_del_result(list,Z_LVAL_PP(ind));
531 				RETURN_FALSE;
532 			}
533 			if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
534 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: SQLGetData return error");
535 				SQLFreeStmt(res->hstmt,SQL_DROP);
536 				birdstep_del_result(list,Z_LVAL_PP(ind));
537 				RETURN_FALSE;
538 			}
539 			if ( res->values[indx].valtype == SQL_LONGVARCHAR ) {
540 				RETURN_STRING(res->values[indx].value,TRUE);
541 			} else {
542 				RETURN_LONG((long)res->values[indx].value);
543 			}
544 		default:
545 			if ( res->values[indx].value != NULL ) {
546 				RETURN_STRING(res->values[indx].value,TRUE);
547 			}
548 	}
549 }
550 /* }}} */
551 
552 /* {{{ proto bool birdstep_freeresult(int index)
553  */
PHP_FUNCTION(birdstep_freeresult)554 PHP_FUNCTION(birdstep_freeresult)
555 {
556 	long ind;
557 	Vresult *res;
558 
559 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ind) == FAILURE) {
560 		return;
561 	}
562 
563 	PHP_GET_BIRDSTEP_RES_IDX(ind);
564 
565 	SQLFreeStmt(res->hstmt,SQL_DROP);
566 	birdstep_del_result(list, ind);
567 	RETURN_TRUE;
568 }
569 /* }}} */
570 
571 /* {{{ proto bool birdstep_autocommit(int index)
572  */
PHP_FUNCTION(birdstep_autocommit)573 PHP_FUNCTION(birdstep_autocommit)
574 {
575 	long id;
576 	RETCODE stat;
577 	VConn *conn;
578 
579 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) {
580 		return;
581 	}
582 
583 	PHP_BIRDSTEP_CHK_LNK(id);
584 
585 	stat = SQLSetConnectOption(conn->hdbc,SQL_AUTOCOMMIT,SQL_AUTOCOMMIT_ON);
586 	if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
587 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Set autocommit_on option failure");
588 		RETURN_FALSE;
589 	}
590 	RETURN_TRUE;
591 }
592 /* }}} */
593 
594 /* {{{ proto bool birdstep_off_autocommit(int index)
595  */
PHP_FUNCTION(birdstep_off_autocommit)596 PHP_FUNCTION(birdstep_off_autocommit)
597 {
598 	long id;
599 	RETCODE stat;
600 	VConn *conn;
601 
602 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) {
603 		return;
604 	}
605 
606 	PHP_BIRDSTEP_CHK_LNK(id);
607 
608 	stat = SQLSetConnectOption(conn->hdbc,SQL_AUTOCOMMIT,SQL_AUTOCOMMIT_OFF);
609 	if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
610 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Set autocommit_off option failure");
611 		RETURN_FALSE;
612 	}
613 	RETURN_TRUE;
614 }
615 /* }}} */
616 
617 /* {{{ proto bool birdstep_commit(int index)
618  */
PHP_FUNCTION(birdstep_commit)619 PHP_FUNCTION(birdstep_commit)
620 {
621 	long id;
622 	RETCODE stat;
623 	VConn *conn;
624 
625 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) {
626 		return;
627 	}
628 
629 	PHP_BIRDSTEP_CHK_LNK(id)
630 
631 	stat = SQLTransact(NULL,conn->hdbc,SQL_COMMIT);
632 	if ( stat != SQL_SUCCESS ) {
633 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Commit failure");
634 		RETURN_FALSE;
635 	}
636 	RETURN_TRUE;
637 }
638 /* }}} */
639 
640 /* {{{ proto bool birdstep_rollback(int index)
641  */
PHP_FUNCTION(birdstep_rollback)642 PHP_FUNCTION(birdstep_rollback)
643 {
644 	long id;
645 	RETCODE stat;
646 	VConn *conn;
647 
648 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) {
649 		return;
650 	}
651 
652 	PHP_BIRDSTEP_CHK_LNK(id);
653 
654 	stat = SQLTransact(NULL,conn->hdbc,SQL_ROLLBACK);
655 	if ( stat != SQL_SUCCESS ) {
656 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Rollback failure");
657 		RETURN_FALSE;
658 	}
659 	RETURN_TRUE;
660 }
661 /* }}} */
662 
663 /* {{{ proto string birdstep_fieldname(int index, int col)
664  */
PHP_FUNCTION(birdstep_fieldname)665 PHP_FUNCTION(birdstep_fieldname)
666 {
667 	long ind, col;
668 	Vresult *res;
669 	SWORD indx;
670 
671 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &ind, &col) == FAILURE) {
672 		return;
673 	}
674 
675 	PHP_GET_BIRDSTEP_RES_IDX(ind);
676 
677 	indx = col;
678 	if ( indx < 0 || indx >= res->numcols ) {
679 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Field index not in range");
680 		RETURN_FALSE;
681 	}
682 	RETURN_STRING(res->values[indx].name,TRUE);
683 }
684 /* }}} */
685 
686 /* {{{ proto int birdstep_fieldnum(int index)
687  */
PHP_FUNCTION(birdstep_fieldnum)688 PHP_FUNCTION(birdstep_fieldnum)
689 {
690 	long ind;
691 	Vresult *res;
692 
693 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ind) == FAILURE) {
694 		return;
695 	}
696 
697 	PHP_GET_BIRDSTEP_RES_IDX(ind);
698 
699 	RETURN_LONG(res->numcols);
700 }
701 /* }}} */
702 
703 #endif /* HAVE_BIRDSTEP */
704 
705 /*
706  * Local variables:
707  * tab-width: 4
708  * c-basic-offset: 4
709  * End:
710  */
711