@@ -46,11 +46,16 @@ typedef struct {
46
46
unsigned short el_type , el_size ;
47
47
} ibase_array ;
48
48
49
+ typedef struct {
50
+ ibase_db_link * link ;
51
+ isc_stmt_handle stmt ;
52
+ } ibase_statement ;
53
+
49
54
typedef struct {
50
55
ibase_db_link * link ;
51
56
ibase_trans * trans ;
52
- struct _ib_query * query ;
53
57
isc_stmt_handle stmt ;
58
+ zend_resource * stmt_res ;
54
59
unsigned short type ;
55
60
unsigned char has_more_rows , statement_type ;
56
61
XSQLDA * out_sqlda ;
@@ -60,9 +65,9 @@ typedef struct {
60
65
typedef struct _ib_query {
61
66
ibase_db_link * link ;
62
67
ibase_trans * trans ;
63
- ibase_result * result ;
64
68
zend_resource * result_res ;
65
69
isc_stmt_handle stmt ;
70
+ zend_resource * stmt_res ;
66
71
XSQLDA * in_sqlda , * out_sqlda ;
67
72
ibase_array * in_array , * out_array ;
68
73
unsigned short in_array_cnt , out_array_cnt ;
@@ -94,7 +99,7 @@ typedef struct {
94
99
short sqlind ;
95
100
} BIND_BUF ;
96
101
97
- static int le_result , le_query ;
102
+ static int le_statement , le_result , le_query ;
98
103
99
104
#define LE_RESULT "Firebird/InterBase result"
100
105
#define LE_QUERY "Firebird/InterBase query"
@@ -119,20 +124,25 @@ static void _php_ibase_free_xsqlda(XSQLDA *sqlda) /* {{{ */
119
124
}
120
125
/* }}} */
121
126
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 ) /* {{{ */
123
128
{
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
+ }
134
143
}
135
144
}
145
+ efree (ib_stmt );
136
146
}
137
147
}
138
148
/* }}} */
@@ -144,14 +154,9 @@ static void _php_ibase_free_result(zend_resource *rsrc) /* {{{ */
144
154
IBDEBUG ("Freeing result by dtor..." );
145
155
if (ib_result ) {
146
156
_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 ;
155
160
}
156
161
efree (ib_result );
157
162
}
@@ -168,13 +173,9 @@ static void _php_ibase_free_query(ibase_query *ib_query) /* {{{ */
168
173
if (ib_query -> out_sqlda ) {
169
174
efree (ib_query -> out_sqlda );
170
175
}
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 ;
178
179
}
179
180
if (ib_query -> in_array ) {
180
181
efree (ib_query -> in_array );
@@ -202,6 +203,8 @@ static void php_ibase_free_query_rsrc(zend_resource *rsrc) /* {{{ */
202
203
203
204
void php_ibase_query_minit (INIT_FUNC_ARGS ) /* {{{ */
204
205
{
206
+ le_statement = zend_register_list_destructors_ex (_php_ibase_free_statement , NULL ,
207
+ "interbase statement" , module_number );
205
208
le_result = zend_register_list_destructors_ex (_php_ibase_free_result , NULL ,
206
209
"interbase result" , module_number );
207
210
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, /*
339
342
ib_query -> link = link ;
340
343
ib_query -> trans = trans ;
341
344
ib_query -> result_res = NULL ;
342
- ib_query -> result = NULL ;
343
345
ib_query -> stmt = 0 ;
346
+ ib_query -> stmt_res = NULL ;
344
347
ib_query -> in_array = NULL ;
345
348
ib_query -> out_array = NULL ;
346
349
ib_query -> dialect = dialect ;
@@ -353,6 +356,12 @@ static int _php_ibase_alloc_query(ibase_query *ib_query, ibase_db_link *link, /*
353
356
_php_ibase_error ();
354
357
goto _php_ibase_alloc_query_error ;
355
358
}
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
+ }
356
365
357
366
ib_query -> out_sqlda = (XSQLDA * ) emalloc (XSQLDA_LENGTH (1 ));
358
367
ib_query -> out_sqlda -> sqln = 1 ;
@@ -1002,9 +1011,8 @@ static int _php_ibase_exec(INTERNAL_FUNCTION_PARAMETERS, ibase_result **ib_resul
1002
1011
res -> link = ib_query -> link ;
1003
1012
res -> trans = ib_query -> trans ;
1004
1013
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
+
1008
1016
res -> statement_type = ib_query -> statement_type ;
1009
1017
res -> has_more_rows = 1 ;
1010
1018
0 commit comments