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