@@ -586,6 +586,8 @@ PHP_METHOD(SQLite3, query)
586
586
result = Z_SQLITE3_RESULT_P (return_value );
587
587
result -> db_obj = db_obj ;
588
588
result -> stmt_obj = stmt_obj ;
589
+ result -> column_names = NULL ;
590
+ result -> column_count = -1 ;
589
591
ZVAL_OBJ (& result -> stmt_obj_zval , Z_OBJ (stmt ));
590
592
591
593
return_code = sqlite3_step (result -> stmt_obj -> stmt );
@@ -1792,6 +1794,8 @@ PHP_METHOD(SQLite3Stmt, execute)
1792
1794
result -> is_prepared_statement = 1 ;
1793
1795
result -> db_obj = stmt_obj -> db_obj ;
1794
1796
result -> stmt_obj = stmt_obj ;
1797
+ result -> column_names = NULL ;
1798
+ result -> column_count = -1 ;
1795
1799
ZVAL_OBJ_COPY (& result -> stmt_obj_zval , Z_OBJ_P (object ));
1796
1800
1797
1801
break ;
@@ -1945,11 +1949,25 @@ PHP_METHOD(SQLite3Result, fetchArray)
1945
1949
RETURN_FALSE ;
1946
1950
}
1947
1951
1952
+ if (result_obj -> column_count == -1 ) {
1953
+ result_obj -> column_count = sqlite3_column_count (result_obj -> stmt_obj -> stmt );
1954
+ }
1955
+
1956
+ int n_cols = result_obj -> column_count ;
1957
+
1958
+ /* Cache column names to speed up repeated fetchArray calls. */
1959
+ if (mode & PHP_SQLITE3_ASSOC && !result_obj -> column_names ) {
1960
+ result_obj -> column_names = emalloc (n_cols * sizeof (zend_string * ));
1961
+
1962
+ for (int i = 0 ; i < n_cols ; i ++ ) {
1963
+ const char * column = sqlite3_column_name (result_obj -> stmt_obj -> stmt , i );
1964
+ result_obj -> column_names [i ] = zend_string_init (column , strlen (column ), 0 );
1965
+ }
1966
+ }
1967
+
1948
1968
array_init (return_value );
1949
-
1950
- int column_count = sqlite3_data_count (result_obj -> stmt_obj -> stmt );
1951
1969
1952
- for (i = 0 ; i < column_count ; i ++ ) {
1970
+ for (i = 0 ; i < n_cols ; i ++ ) {
1953
1971
zval data ;
1954
1972
1955
1973
sqlite_value_to_zval (result_obj -> stmt_obj -> stmt , i , & data );
@@ -1964,7 +1982,7 @@ PHP_METHOD(SQLite3Result, fetchArray)
1964
1982
Z_ADDREF (data );
1965
1983
}
1966
1984
}
1967
- add_assoc_zval ( return_value , ( char * ) sqlite3_column_name ( result_obj -> stmt_obj -> stmt , i ) , & data );
1985
+ zend_symtable_add_new ( Z_ARR_P ( return_value ), result_obj -> column_names [ i ] , & data );
1968
1986
}
1969
1987
}
1970
1988
break ;
@@ -1979,6 +1997,17 @@ PHP_METHOD(SQLite3Result, fetchArray)
1979
1997
}
1980
1998
/* }}} */
1981
1999
2000
+ static void sqlite3result_clear_column_names_cache (php_sqlite3_result * result ) {
2001
+ if (result -> column_names ) {
2002
+ for (int i = 0 ; i < result -> column_count ; i ++ ) {
2003
+ zend_string_release (result -> column_names [i ]);
2004
+ }
2005
+ efree (result -> column_names );
2006
+ }
2007
+ result -> column_names = NULL ;
2008
+ result -> column_count = -1 ;
2009
+ }
2010
+
1982
2011
/* {{{ Resets the result set back to the first row. */
1983
2012
PHP_METHOD (SQLite3Result , reset )
1984
2013
{
@@ -1990,6 +2019,8 @@ PHP_METHOD(SQLite3Result, reset)
1990
2019
1991
2020
SQLITE3_CHECK_INITIALIZED (result_obj -> db_obj , result_obj -> stmt_obj -> initialised , SQLite3Result )
1992
2021
2022
+ sqlite3result_clear_column_names_cache (result_obj );
2023
+
1993
2024
if (sqlite3_reset (result_obj -> stmt_obj -> stmt ) != SQLITE_OK ) {
1994
2025
RETURN_FALSE ;
1995
2026
}
@@ -2009,6 +2040,8 @@ PHP_METHOD(SQLite3Result, finalize)
2009
2040
2010
2041
SQLITE3_CHECK_INITIALIZED (result_obj -> db_obj , result_obj -> stmt_obj -> initialised , SQLite3Result )
2011
2042
2043
+ sqlite3result_clear_column_names_cache (result_obj );
2044
+
2012
2045
/* We need to finalize an internal statement */
2013
2046
if (result_obj -> is_prepared_statement == 0 ) {
2014
2047
zend_llist_del_element (& (result_obj -> db_obj -> free_list ), & result_obj -> stmt_obj_zval ,
@@ -2235,6 +2268,8 @@ static void php_sqlite3_result_object_free_storage(zend_object *object) /* {{{ *
2235
2268
return ;
2236
2269
}
2237
2270
2271
+ sqlite3result_clear_column_names_cache (intern );
2272
+
2238
2273
if (!Z_ISNULL (intern -> stmt_obj_zval )) {
2239
2274
if (intern -> stmt_obj && intern -> stmt_obj -> initialised ) {
2240
2275
sqlite3_reset (intern -> stmt_obj -> stmt );
0 commit comments