@@ -79,13 +79,10 @@ static zend_object_handlers odbc_connection_object_handlers, odbc_result_object_
79
79
80
80
static void odbc_insert_new_result (odbc_connection * connection , zval * result ) {
81
81
ZEND_ASSERT (Z_TYPE_P (result ) == IS_OBJECT && instanceof_function (Z_OBJCE_P (result ), odbc_result_ce ));
82
- if (!connection -> results ) {
83
- connection -> results = zend_new_array (1 );
84
- }
85
82
86
- zend_hash_next_index_insert_new (connection -> results , result );
87
83
odbc_result * res = Z_ODBC_RESULT_P (result );
88
- res -> index = zend_hash_num_elements (connection -> results ) - 1 ;
84
+ res -> index = connection -> results .nNextFreeElement ;
85
+ zend_hash_next_index_insert_new (& connection -> results , result );
89
86
Z_ADDREF_P (result );
90
87
}
91
88
@@ -107,13 +104,17 @@ static void odbc_link_free(odbc_link *link)
107
104
efree (link -> connection );
108
105
ODBCG (num_links )-- ;
109
106
110
- zend_hash_del (& ODBCG (non_persistent_connections ), link -> hash );
107
+ if (link -> hash ) {
108
+ zend_hash_del (& ODBCG (non_persistent_connections ), link -> hash );
109
+ }
111
110
}
112
111
113
112
link -> connection = NULL ;
114
113
115
- zend_string_release (link -> hash );
116
- link -> hash = NULL ;
114
+ if (link -> hash ) {
115
+ zend_string_release_ex (link -> hash , link -> persistent );
116
+ link -> hash = NULL ;
117
+ }
117
118
}
118
119
119
120
static inline odbc_link * odbc_link_from_obj (zend_object * obj ) {
@@ -197,11 +198,9 @@ static void odbc_result_free(odbc_result *res)
197
198
res -> param_info = NULL ;
198
199
}
199
200
200
- HashTable * tmp = res -> conn_ptr -> results ;
201
+ HashTable * tmp = & res -> conn_ptr -> results ;
201
202
res -> conn_ptr = NULL ;
202
- if (tmp ) {
203
- zend_hash_index_del (tmp , res -> index );
204
- }
203
+ zend_hash_index_del (tmp , res -> index );
205
204
}
206
205
207
206
static void odbc_result_free_obj (zend_object * obj ) {
@@ -249,20 +248,14 @@ ZEND_GET_MODULE(odbc)
249
248
static void close_results_with_connection (odbc_connection * conn ) {
250
249
zval * p ;
251
250
252
- if (conn -> results == NULL ) {
253
- return ;
254
- }
255
-
256
- ZEND_HASH_FOREACH_VAL (conn -> results , p ) {
251
+ ZEND_HASH_FOREACH_VAL (& conn -> results , p ) {
257
252
odbc_result * result = Z_ODBC_RESULT_P (p );
258
253
if (result -> conn_ptr ) {
259
254
odbc_result_free (result );
260
255
}
261
256
} ZEND_HASH_FOREACH_END ();
262
257
263
- zend_hash_destroy (conn -> results );
264
- FREE_HASHTABLE (conn -> results );
265
- conn -> results = NULL ;
258
+ zend_hash_destroy (& conn -> results );
266
259
}
267
260
268
261
/* disconnect, and if it fails, then issue a rollback for any pending transaction (lurcher) */
@@ -852,14 +845,14 @@ PHP_FUNCTION(odbc_close_all)
852
845
RETURN_THROWS ();
853
846
}
854
847
848
+ /* Loop through the non-persistent connection list, now close all non-persistent connections and their results */
855
849
ZEND_HASH_FOREACH_VAL (& ODBCG (non_persistent_connections ), zv ) {
856
850
odbc_link * link = Z_ODBC_LINK_P (zv );
857
851
if (link -> connection ) {
858
852
odbc_link_free (link );
859
853
}
860
854
} ZEND_HASH_FOREACH_END ();
861
855
862
- /* Loop through the non-persistent connection list, now close all non-persistent connections and their results */
863
856
zend_hash_clean (& ODBCG (non_persistent_connections ));
864
857
865
858
/* Loop through the persistent connection list, now close all persistent connections and their results */
@@ -1529,7 +1522,7 @@ PHP_FUNCTION(odbc_fetch_into)
1529
1522
SQLSMALLINT sql_c_type ;
1530
1523
char * buf = NULL ;
1531
1524
zval * pv_res , * pv_res_arr , tmp ;
1532
- zend_long pv_row = -1 ;
1525
+ zend_long pv_row = 0 ;
1533
1526
bool pv_row_is_null = true;
1534
1527
#ifdef HAVE_SQL_EXTENDED_FETCH
1535
1528
SQLULEN crow ;
@@ -1658,7 +1651,7 @@ PHP_FUNCTION(odbc_fetch_row)
1658
1651
odbc_result * result ;
1659
1652
RETCODE rc ;
1660
1653
zval * pv_res ;
1661
- zend_long pv_row = -1 ;
1654
+ zend_long pv_row = 0 ;
1662
1655
bool pv_row_is_null = true;
1663
1656
#ifdef HAVE_SQL_EXTENDED_FETCH
1664
1657
SQLULEN crow ;
@@ -2100,26 +2093,25 @@ PHP_FUNCTION(odbc_pconnect)
2100
2093
/* }}} */
2101
2094
2102
2095
/* {{{ odbc_sqlconnect */
2103
- bool odbc_sqlconnect (zval * zv , char * db , char * uid , char * pwd , int cur_opt , bool persistent , zend_string * hash )
2096
+ bool odbc_sqlconnect (zval * zv , char * db , char * uid , char * pwd , int cur_opt , bool persistent , char * hash , int hash_len )
2104
2097
{
2105
2098
RETCODE rc ;
2106
2099
SQLRETURN ret ;
2107
2100
odbc_link * link ;
2108
2101
2109
2102
object_init_ex (zv , odbc_connection_ce );
2110
2103
link = Z_ODBC_LINK_P (zv );
2111
- link -> connection = (odbc_connection * )pemalloc (sizeof (odbc_connection ), persistent );
2112
- memset (link -> connection , 0 , sizeof (odbc_connection ));
2113
-
2104
+ link -> connection = pecalloc (1 , sizeof (odbc_connection ), persistent );
2105
+ zend_hash_init (& link -> connection -> results , 0 , NULL , NULL , 1 );
2114
2106
link -> persistent = persistent ;
2115
- link -> hash = zend_string_copy (hash );
2116
- ret = SQLAllocEnv (& (( * link -> connection ). henv ) );
2107
+ link -> hash = zend_string_init (hash , hash_len , persistent );
2108
+ ret = SQLAllocEnv (& link -> connection -> henv );
2117
2109
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO ) {
2118
2110
odbc_sql_error (link -> connection , SQL_NULL_HSTMT , "SQLAllocEnv" );
2119
2111
return false;
2120
2112
}
2121
2113
2122
- ret = SQLAllocConnect (( * link -> connection ). henv , & ((* link -> connection ).hdbc ));
2114
+ ret = SQLAllocConnect (link -> connection -> henv , & ((* link -> connection ).hdbc ));
2123
2115
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO ) {
2124
2116
odbc_sql_error (link -> connection , SQL_NULL_HSTMT , "SQLAllocConnect" );
2125
2117
return false;
@@ -2244,11 +2236,6 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool
2244
2236
}
2245
2237
/* }}} */
2246
2238
2247
- /* Persistent connections: two list-types le_pconn, le_conn and a plist
2248
- * where hashed connection info is stored together with index pointer to
2249
- * the actual link of type le_pconn in the list. Only persistent
2250
- * connections get hashed up.
2251
- */
2252
2239
/* {{{ odbc_do_connect */
2253
2240
void odbc_do_connect (INTERNAL_FUNCTION_PARAMETERS , int persistent )
2254
2241
{
@@ -2284,37 +2271,39 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
2284
2271
persistent = 0 ;
2285
2272
}
2286
2273
2287
- smart_str hashed_details = {0 };
2288
- smart_str_append_printf (& hashed_details , "%s_%s_%s_%s_%d" , ODBC_TYPE , db , uid , pwd , cur_opt );
2274
+ char * hashed_details ;
2275
+ int hashed_details_len ;
2276
+
2277
+ hashed_details_len = spprintf (& hashed_details , 0 , "%s_%s_%s_%s_%d" , ODBC_TYPE , db , uid , pwd , cur_opt );
2289
2278
2290
2279
try_and_get_another_connection :
2291
2280
2292
2281
if (persistent ) {
2293
2282
zend_resource * le ;
2294
2283
2295
2284
/* the link is not in the persistent list */
2296
- if ((le = zend_hash_find_ptr (& EG (persistent_list ), hashed_details . s )) == NULL ) {
2285
+ if ((le = zend_hash_str_find_ptr (& EG (persistent_list ), hashed_details , hashed_details_len )) == NULL ) {
2297
2286
if (ODBCG (max_links ) != -1 && ODBCG (num_links ) >= ODBCG (max_links )) {
2298
2287
php_error_docref (NULL , E_WARNING , "Too many open links (" ZEND_LONG_FMT ")" , ODBCG (num_links ));
2299
- smart_str_free ( & hashed_details );
2288
+ efree ( hashed_details );
2300
2289
RETURN_FALSE ;
2301
2290
}
2302
2291
if (ODBCG (max_persistent ) != -1 && ODBCG (num_persistent ) >= ODBCG (max_persistent )) {
2303
2292
php_error_docref (NULL , E_WARNING ,"Too many open persistent links (" ZEND_LONG_FMT ")" , ODBCG (num_persistent ));
2304
- smart_str_free ( & hashed_details );
2293
+ efree ( hashed_details );
2305
2294
RETURN_FALSE ;
2306
2295
}
2307
2296
2308
- if (!odbc_sqlconnect (return_value , db , uid , pwd , cur_opt , true, hashed_details . s )) {
2309
- smart_str_free ( & hashed_details );
2297
+ if (!odbc_sqlconnect (return_value , db , uid , pwd , cur_opt , true, hashed_details , hashed_details_len )) {
2298
+ efree ( hashed_details );
2310
2299
zval_ptr_dtor (return_value );
2311
2300
RETURN_FALSE ;
2312
2301
}
2313
2302
2314
2303
db_conn = Z_ODBC_CONNECTION_P (return_value );
2315
2304
2316
- if (zend_register_persistent_resource (ZSTR_VAL ( hashed_details . s ), ZSTR_LEN ( hashed_details . s ) , db_conn , le_pconn ) == NULL ) {
2317
- smart_str_free ( & hashed_details );
2305
+ if (zend_register_persistent_resource (hashed_details , hashed_details_len , db_conn , le_pconn ) == NULL ) {
2306
+ efree ( hashed_details );
2318
2307
zval_ptr_dtor (return_value );
2319
2308
RETURN_FALSE ;
2320
2309
}
@@ -2343,7 +2332,7 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
2343
2332
& dead , 0 , NULL );
2344
2333
if (ret == SQL_SUCCESS && dead == SQL_CD_TRUE ) {
2345
2334
/* Bail early here, since we know it's gone */
2346
- zend_hash_del (& EG (persistent_list ), hashed_details . s );
2335
+ zend_hash_str_del (& EG (persistent_list ), hashed_details , hashed_details_len );
2347
2336
goto try_and_get_another_connection ;
2348
2337
}
2349
2338
/* If the driver doesn't support it, or returns
@@ -2355,7 +2344,7 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
2355
2344
d_name , sizeof (d_name ), & len );
2356
2345
2357
2346
if (ret != SQL_SUCCESS || len == 0 ) {
2358
- zend_hash_del (& EG (persistent_list ), hashed_details . s );
2347
+ zend_hash_str_del (& EG (persistent_list ), hashed_details , hashed_details_len );
2359
2348
/* Commented out to fix a possible double closure error
2360
2349
* when working with persistent connections as submitted by
2361
2350
* bug #15758
@@ -2370,38 +2359,38 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
2370
2359
object_init_ex (return_value , odbc_connection_ce );
2371
2360
odbc_link * link = Z_ODBC_LINK_P (return_value );
2372
2361
link -> connection = db_conn ;
2373
- link -> hash = zend_string_copy (hashed_details . s );
2362
+ link -> hash = zend_string_init (hashed_details , hashed_details_len , persistent );
2374
2363
link -> persistent = true;
2375
2364
}
2376
2365
} else {
2377
2366
zval * tmp ;
2378
- if ((tmp = zend_hash_find (& ODBCG (non_persistent_connections ), hashed_details . s )) == NULL ) { /* non-persistent, new */
2367
+ if ((tmp = zend_hash_str_find (& ODBCG (non_persistent_connections ), hashed_details , hashed_details_len )) == NULL ) { /* non-persistent, new */
2379
2368
if (ODBCG (max_links ) != -1 && ODBCG (num_links ) >= ODBCG (max_links )) {
2380
2369
php_error_docref (NULL , E_WARNING , "Too many open connections (" ZEND_LONG_FMT ")" , ODBCG (num_links ));
2381
- smart_str_free ( & hashed_details );
2370
+ efree ( hashed_details );
2382
2371
RETURN_FALSE ;
2383
2372
}
2384
2373
2385
- if (!odbc_sqlconnect (return_value , db , uid , pwd , cur_opt , false, hashed_details . s )) {
2386
- smart_str_free ( & hashed_details );
2374
+ if (!odbc_sqlconnect (return_value , db , uid , pwd , cur_opt , false, hashed_details , hashed_details_len )) {
2375
+ efree ( hashed_details );
2387
2376
zval_ptr_dtor (return_value );
2388
2377
RETURN_FALSE ;
2389
2378
}
2390
2379
ODBCG (num_links )++ ;
2391
2380
2392
- zend_hash_add_new (& ODBCG (non_persistent_connections ), hashed_details . s , return_value );
2381
+ zend_hash_str_add_new (& ODBCG (non_persistent_connections ), hashed_details , hashed_details_len , return_value );
2393
2382
} else { /* non-persistent, pre-existing */
2394
2383
ZVAL_COPY (return_value , tmp );
2395
2384
}
2396
2385
}
2397
- smart_str_free ( & hashed_details );
2386
+ efree ( hashed_details );
2398
2387
}
2399
2388
/* }}} */
2400
2389
2401
2390
/* {{{ Close an ODBC connection */
2402
2391
PHP_FUNCTION (odbc_close )
2403
2392
{
2404
- zval * pv_conn ;
2393
+ zval * pv_conn , * zv ;
2405
2394
odbc_link * link ;
2406
2395
2407
2396
if (zend_parse_parameters (ZEND_NUM_ARGS (), "O" , & pv_conn , odbc_connection_ce ) == FAILURE ) {
@@ -2412,6 +2401,12 @@ PHP_FUNCTION(odbc_close)
2412
2401
CHECK_ODBC_CONNECTION (link -> connection );
2413
2402
2414
2403
odbc_link_free (link );
2404
+
2405
+ ZEND_HASH_FOREACH_VAL (& EG (persistent_list ), zv ) {
2406
+ if (Z_RES_P (zv )-> type == le_pconn && link -> connection == Z_RES_P (zv )-> ptr ) {
2407
+ zend_list_close (Z_RES_P (zv ));
2408
+ }
2409
+ } ZEND_HASH_FOREACH_END ();
2415
2410
}
2416
2411
/* }}} */
2417
2412
0 commit comments