@@ -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,11 +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- ib_result -> query -> result = NULL ; /* Indicate to query, that result is released */
150- } else {
151- _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 ;
152160 }
153161 efree (ib_result );
154162 }
@@ -165,11 +173,9 @@ static void _php_ibase_free_query(ibase_query *ib_query) /* {{{ */
165173 if (ib_query -> out_sqlda ) {
166174 efree (ib_query -> out_sqlda );
167175 }
168- if (ib_query -> result != NULL ) {
169- IBDEBUG ("result still valid; don't drop statement handle" );
170- ib_query -> result -> query = NULL ; /* Indicate to result, that query is released */
171- } else {
172- _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 ;
173179 }
174180 if (ib_query -> in_array ) {
175181 efree (ib_query -> in_array );
@@ -197,6 +203,8 @@ static void php_ibase_free_query_rsrc(zend_resource *rsrc) /* {{{ */
197203
198204void php_ibase_query_minit (INIT_FUNC_ARGS ) /* {{{ */
199205{
206+ le_statement = zend_register_list_destructors_ex (_php_ibase_free_statement , NULL ,
207+ "interbase statement" , module_number );
200208 le_result = zend_register_list_destructors_ex (_php_ibase_free_result , NULL ,
201209 "interbase result" , module_number );
202210 le_query = zend_register_list_destructors_ex (php_ibase_free_query_rsrc , NULL ,
@@ -334,8 +342,8 @@ static int _php_ibase_alloc_query(ibase_query *ib_query, ibase_db_link *link, /*
334342 ib_query -> link = link ;
335343 ib_query -> trans = trans ;
336344 ib_query -> result_res = NULL ;
337- ib_query -> result = NULL ;
338345 ib_query -> stmt = 0 ;
346+ ib_query -> stmt_res = NULL ;
339347 ib_query -> in_array = NULL ;
340348 ib_query -> out_array = NULL ;
341349 ib_query -> dialect = dialect ;
@@ -348,6 +356,12 @@ static int _php_ibase_alloc_query(ibase_query *ib_query, ibase_db_link *link, /*
348356 _php_ibase_error ();
349357 goto _php_ibase_alloc_query_error ;
350358 }
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+ }
351365
352366 ib_query -> out_sqlda = (XSQLDA * ) emalloc (XSQLDA_LENGTH (1 ));
353367 ib_query -> out_sqlda -> sqln = 1 ;
@@ -997,9 +1011,8 @@ static int _php_ibase_exec(INTERNAL_FUNCTION_PARAMETERS, ibase_result **ib_resul
9971011 res -> link = ib_query -> link ;
9981012 res -> trans = ib_query -> trans ;
9991013 res -> stmt = ib_query -> stmt ;
1000- /* ib_result and ib_query point at each other to handle release of statement handle properly */
1001- res -> query = ib_query ;
1002- ib_query -> result = res ;
1014+ GC_ADDREF (res -> stmt_res = ib_query -> stmt_res );
1015+
10031016 res -> statement_type = ib_query -> statement_type ;
10041017 res -> has_more_rows = 1 ;
10051018
0 commit comments