@@ -46,11 +46,16 @@ typedef struct {
4646 unsigned short el_type , el_size ;
4747} ibase_array ;
4848
49+ typedef struct {
50+ ibase_db_link * link ;
51+ isc_stmt_handle stmt ;
52+ } ibase_statement ;
53+
4954typedef struct {
5055 ibase_db_link * link ;
5156 ibase_trans * trans ;
52- struct _ib_query * query ;
5357 isc_stmt_handle stmt ;
58+ zend_resource * stmt_res ;
5459 unsigned short type ;
5560 unsigned char has_more_rows , statement_type ;
5661 XSQLDA * out_sqlda ;
@@ -60,9 +65,9 @@ typedef struct {
6065typedef struct _ib_query {
6166 ibase_db_link * link ;
6267 ibase_trans * trans ;
63- ibase_result * result ;
6468 zend_resource * result_res ;
6569 isc_stmt_handle stmt ;
70+ zend_resource * stmt_res ;
6671 XSQLDA * in_sqlda , * out_sqlda ;
6772 ibase_array * in_array , * out_array ;
6873 unsigned short in_array_cnt , out_array_cnt ;
@@ -94,7 +99,7 @@ typedef struct {
9499 short sqlind ;
95100} BIND_BUF ;
96101
97- static int le_result , le_query ;
102+ static int le_statement , le_result , le_query ;
98103
99104#define LE_RESULT "Firebird/InterBase result"
100105#define LE_QUERY "Firebird/InterBase query"
@@ -119,20 +124,25 @@ static void _php_ibase_free_xsqlda(XSQLDA *sqlda) /* {{{ */
119124}
120125/* }}} */
121126
122- static void _php_ibase_free_stmt_handle ( ibase_db_link * link , isc_stmt_handle stmt ) /* {{{ */
127+ static void _php_ibase_free_statement ( zend_resource * rsrc ) /* {{{ */
123128{
124- static char info [] = { isc_info_base_level , isc_info_end };
125-
126- if (stmt ) {
127- char res_buf [8 ];
128- IBDEBUG ("Dropping statement handle (free_stmt_handle)..." );
129- /* Only free statement if db-connection is still open */
130- if (SUCCESS == isc_database_info (IB_STATUS , & link -> handle ,
131- sizeof (info ), info , sizeof (res_buf ), res_buf )) {
132- if (isc_dsql_free_statement (IB_STATUS , & stmt , DSQL_drop )) {
133- _php_ibase_error ();
129+ ibase_statement * ib_stmt = (ibase_statement * )rsrc -> ptr ;
130+
131+ IBDEBUG ("Freeing statement by dtor..." );
132+ if (ib_stmt ) {
133+ if (ib_stmt -> stmt ) {
134+ static char info [] = { isc_info_base_level , isc_info_end };
135+ char res_buf [8 ];
136+ IBDEBUG ("Dropping statement handle (free_stmt_handle)..." );
137+ /* Only free statement if db-connection is still open */
138+ if (SUCCESS == isc_database_info (IB_STATUS , & ib_stmt -> link -> handle ,
139+ sizeof (info ), info , sizeof (res_buf ), res_buf )) {
140+ if (isc_dsql_free_statement (IB_STATUS , & ib_stmt -> stmt , DSQL_drop )) {
141+ _php_ibase_error ();
142+ }
134143 }
135144 }
145+ efree (ib_stmt );
136146 }
137147}
138148/* }}} */
@@ -144,14 +154,9 @@ static void _php_ibase_free_result(zend_resource *rsrc) /* {{{ */
144154 IBDEBUG ("Freeing result by dtor..." );
145155 if (ib_result ) {
146156 _php_ibase_free_xsqlda (ib_result -> out_sqlda );
147- if (ib_result -> query != NULL ) {
148- IBDEBUG ("query still valid; don't drop statement handle" );
149- if (ib_result -> query -> result == ib_result ) {
150- /* If we are the last execution result on the query */
151- ib_result -> query -> result = NULL ; /* Indicate to query, that result is released */
152- }
153- } else {
154- _php_ibase_free_stmt_handle (ib_result -> link , ib_result -> stmt );
157+ if (ib_result -> stmt_res != NULL ) {
158+ zend_list_delete (ib_result -> stmt_res );
159+ ib_result -> stmt_res == NULL ;
155160 }
156161 efree (ib_result );
157162 }
@@ -168,13 +173,9 @@ static void _php_ibase_free_query(ibase_query *ib_query) /* {{{ */
168173 if (ib_query -> out_sqlda ) {
169174 efree (ib_query -> out_sqlda );
170175 }
171- if (ib_query -> result != NULL ) {
172- IBDEBUG ("result still valid; don't drop statement handle" );
173- if (ib_query -> result -> query == ib_query ) {
174- ib_query -> result -> query = NULL ; /* Indicate to result, that query is released */
175- }
176- } else {
177- _php_ibase_free_stmt_handle (ib_query -> link , ib_query -> stmt );
176+ if (ib_query -> stmt_res != NULL ) {
177+ zend_list_delete (ib_query -> stmt_res );
178+ ib_query -> stmt_res == NULL ;
178179 }
179180 if (ib_query -> in_array ) {
180181 efree (ib_query -> in_array );
@@ -202,6 +203,8 @@ static void php_ibase_free_query_rsrc(zend_resource *rsrc) /* {{{ */
202203
203204void php_ibase_query_minit (INIT_FUNC_ARGS ) /* {{{ */
204205{
206+ le_statement = zend_register_list_destructors_ex (_php_ibase_free_statement , NULL ,
207+ "interbase statement" , module_number );
205208 le_result = zend_register_list_destructors_ex (_php_ibase_free_result , NULL ,
206209 "interbase result" , module_number );
207210 le_query = zend_register_list_destructors_ex (php_ibase_free_query_rsrc , NULL ,
@@ -339,8 +342,8 @@ static int _php_ibase_alloc_query(ibase_query *ib_query, ibase_db_link *link, /*
339342 ib_query -> link = link ;
340343 ib_query -> trans = trans ;
341344 ib_query -> result_res = NULL ;
342- ib_query -> result = NULL ;
343345 ib_query -> stmt = 0 ;
346+ ib_query -> stmt_res = NULL ;
344347 ib_query -> in_array = NULL ;
345348 ib_query -> out_array = NULL ;
346349 ib_query -> dialect = dialect ;
@@ -353,6 +356,12 @@ static int _php_ibase_alloc_query(ibase_query *ib_query, ibase_db_link *link, /*
353356 _php_ibase_error ();
354357 goto _php_ibase_alloc_query_error ;
355358 }
359+ { /* allocate zend resource for statement*/
360+ ibase_statement * ib_stmt = emalloc (sizeof (ibase_statement ));
361+ ib_stmt -> link = link ;
362+ ib_stmt -> stmt = ib_query -> stmt ;
363+ ib_query -> stmt_res = zend_register_resource (ib_stmt , le_statement );
364+ }
356365
357366 ib_query -> out_sqlda = (XSQLDA * ) emalloc (XSQLDA_LENGTH (1 ));
358367 ib_query -> out_sqlda -> sqln = 1 ;
@@ -1002,9 +1011,8 @@ static int _php_ibase_exec(INTERNAL_FUNCTION_PARAMETERS, ibase_result **ib_resul
10021011 res -> link = ib_query -> link ;
10031012 res -> trans = ib_query -> trans ;
10041013 res -> stmt = ib_query -> stmt ;
1005- /* ib_result and ib_query point at each other to handle release of statement handle properly */
1006- res -> query = ib_query ;
1007- ib_query -> result = res ;
1014+ GC_ADDREF (res -> stmt_res = ib_query -> stmt_res );
1015+
10081016 res -> statement_type = ib_query -> statement_type ;
10091017 res -> has_more_rows = 1 ;
10101018
0 commit comments