@@ -163,6 +163,18 @@ static int describe_columns(pdo_stmt_t *stmt TSRMLS_DC)
163
163
return 1 ;
164
164
}
165
165
166
+ static void get_lazy_object (pdo_stmt_t * stmt , zval * return_value TSRMLS_DC )
167
+ {
168
+ if (Z_TYPE (stmt -> lazy_object_ref ) == IS_NULL ) {
169
+ Z_TYPE (stmt -> lazy_object_ref ) = IS_OBJECT ;
170
+ Z_OBJ_HANDLE (stmt -> lazy_object_ref ) = zend_objects_store_put (stmt , NULL , pdo_row_free_storage , NULL TSRMLS_CC );
171
+ Z_OBJ_HT (stmt -> lazy_object_ref ) = & pdo_row_object_handlers ;
172
+ }
173
+ Z_TYPE_P (return_value ) = IS_OBJECT ;
174
+ Z_OBJ_HANDLE_P (return_value ) = Z_OBJ_HANDLE (stmt -> lazy_object_ref );
175
+ Z_OBJ_HT_P (return_value ) = Z_OBJ_HT (stmt -> lazy_object_ref );
176
+ }
177
+
166
178
static void param_dtor (void * data )
167
179
{
168
180
struct pdo_bound_param_data * param = (struct pdo_bound_param_data * )data ;
@@ -428,12 +440,15 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_
428
440
if (return_value ) {
429
441
int i ;
430
442
443
+ if (how == PDO_FETCH_LAZY ) {
444
+ get_lazy_object (stmt , return_value TSRMLS_CC );
445
+ return 1 ;
446
+ }
447
+
431
448
array_init (return_value );
432
449
433
450
if (how == PDO_FETCH_OBJ ) {
434
451
how = PDO_FETCH_ASSOC ;
435
- } else if (how == PDO_FETCH_LAZY ) {
436
- how = PDO_FETCH_BOTH ;
437
452
}
438
453
439
454
for (i = 0 ; i < stmt -> column_count ; i ++ ) {
@@ -698,12 +713,12 @@ static int dbstmt_dim_exists(zval *object, zval *member, int check_empty TSRMLS_
698
713
699
714
static void dbstmt_prop_delete (zval * object , zval * offset TSRMLS_DC )
700
715
{
701
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "Cannot delete properties from a PDO STMT " );
716
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Cannot delete properties from a PDOStatement " );
702
717
}
703
718
704
719
static void dbstmt_dim_delete (zval * object , zval * offset TSRMLS_DC )
705
720
{
706
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "Cannot delete dimensions from a PDO STMT " );
721
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Cannot delete dimensions from a PDOStatement " );
707
722
}
708
723
709
724
static HashTable * dbstmt_get_properties (zval * object TSRMLS_DC )
@@ -793,10 +808,16 @@ void pdo_dbstmt_free_storage(zend_object *object TSRMLS_DC)
793
808
if (stmt -> methods && stmt -> methods -> dtor ) {
794
809
stmt -> methods -> dtor (stmt TSRMLS_CC );
795
810
}
796
- if (stmt -> query_string ) {
811
+ if (stmt -> query_string ) {
797
812
efree (stmt -> query_string );
798
813
}
799
814
zend_objects_store_del_ref (& stmt -> database_object_handle TSRMLS_CC );
815
+ #if 0
816
+ /* declared in the header, but not implemented... */
817
+ zend_objects_store_delete_obj (& stmt -> lazy_object_ref TSRMLS_CC );
818
+ #else
819
+ zend_objects_store_del_ref (& stmt -> lazy_object_ref TSRMLS_CC );
820
+ #endif
800
821
801
822
efree (stmt );
802
823
}
@@ -812,6 +833,181 @@ zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC)
812
833
}
813
834
/* }}} */
814
835
836
+ /* {{{ overloaded handlers for PDORow class (used by PDO_FETCH_LAZY) */
837
+
838
+ function_entry pdo_row_functions [] = {
839
+ {NULL , NULL , NULL }
840
+ };
841
+
842
+ static zval * row_prop_or_dim_read (zval * object , zval * member , int type TSRMLS_DC )
843
+ {
844
+ zval * return_value ;
845
+ pdo_stmt_t * stmt = (pdo_stmt_t * ) zend_object_store_get_object (object TSRMLS_CC );
846
+ int colno = -1 ;
847
+
848
+ MAKE_STD_ZVAL (return_value );
849
+ convert_to_string (member );
850
+
851
+ /* look up the column */
852
+ /* TODO: replace this with a hash of available column names to column
853
+ * numbers */
854
+ for (colno = 0 ; colno < stmt -> column_count ; colno ++ ) {
855
+ if (strcmp (stmt -> columns [colno ].name , Z_STRVAL_P (member )) == 0 ) {
856
+ fetch_value (stmt , return_value , colno TSRMLS_CC );
857
+ break ;
858
+ }
859
+ }
860
+
861
+ return return_value ;
862
+ }
863
+
864
+ static void row_prop_or_dim_write (zval * object , zval * member , zval * value TSRMLS_DC )
865
+ {
866
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "This PDORow is not from a writable result set" );
867
+ }
868
+
869
+ static int row_prop_or_dim_exists (zval * object , zval * member , int check_empty TSRMLS_DC )
870
+ {
871
+ pdo_stmt_t * stmt = (pdo_stmt_t * ) zend_object_store_get_object (object TSRMLS_CC );
872
+ int colno = -1 ;
873
+
874
+ convert_to_string (member );
875
+
876
+ /* TODO: replace this with a hash of available column names to column
877
+ * numbers */
878
+ for (colno = 0 ; colno < stmt -> column_count ; colno ++ ) {
879
+ if (strcmp (stmt -> columns [colno ].name , Z_STRVAL_P (member )) == 0 ) {
880
+ return 1 ;
881
+ }
882
+ }
883
+
884
+ return 0 ;
885
+ }
886
+
887
+ static void row_prop_or_dim_delete (zval * object , zval * offset TSRMLS_DC )
888
+ {
889
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Cannot delete properties from a PDORow" );
890
+ }
891
+
892
+ static HashTable * row_get_properties (zval * object TSRMLS_DC )
893
+ {
894
+ zval * tmp ;
895
+ pdo_stmt_t * stmt = (pdo_stmt_t * ) zend_object_store_get_object (object TSRMLS_CC );
896
+ int i ;
897
+ HashTable * ht ;
898
+
899
+ MAKE_STD_ZVAL (tmp );
900
+ array_init (tmp );
901
+
902
+ for (i = 0 ; i < stmt -> column_count ; i ++ ) {
903
+ zval * val ;
904
+ MAKE_STD_ZVAL (val );
905
+ fetch_value (stmt , val , i TSRMLS_CC );
906
+
907
+ add_assoc_zval (tmp , stmt -> columns [i ].name , val );
908
+ }
909
+
910
+ ht = Z_ARRVAL_P (tmp );
911
+
912
+ ZVAL_NULL (tmp );
913
+ FREE_ZVAL (tmp );
914
+
915
+ return ht ;
916
+ }
917
+
918
+ static union _zend_function * row_method_get (zval * object , char * method_name , int method_len TSRMLS_DC )
919
+ {
920
+ zend_function * fbc ;
921
+ char * lc_method_name ;
922
+
923
+ lc_method_name = do_alloca (method_len + 1 );
924
+ zend_str_tolower_copy (lc_method_name , method_name , method_len );
925
+
926
+ if (zend_hash_find (& pdo_row_ce -> function_table , lc_method_name , method_len + 1 , (void * * )& fbc ) == FAILURE ) {
927
+ free_alloca (lc_method_name );
928
+ return NULL ;
929
+ }
930
+
931
+ free_alloca (lc_method_name );
932
+ return fbc ;
933
+ }
934
+
935
+ static int row_call_method (char * method , INTERNAL_FUNCTION_PARAMETERS )
936
+ {
937
+ return FAILURE ;
938
+ }
939
+
940
+ static union _zend_function * row_get_ctor (zval * object TSRMLS_DC )
941
+ {
942
+ static zend_internal_function ctor = {0 };
943
+
944
+ ctor .type = ZEND_INTERNAL_FUNCTION ;
945
+ ctor .function_name = "__construct" ;
946
+ ctor .scope = pdo_row_ce ;
947
+ ctor .handler = ZEND_FN (dbstmt_constructor );
948
+
949
+ return (union _zend_function * )& ctor ;
950
+ }
951
+
952
+ static zend_class_entry * row_get_ce (zval * object TSRMLS_DC )
953
+ {
954
+ return pdo_dbstmt_ce ;
955
+ }
956
+
957
+ static int row_get_classname (zval * object , char * * class_name , zend_uint * class_name_len , int parent TSRMLS_DC )
958
+ {
959
+ * class_name = estrndup ("PDORow" , sizeof ("PDORow" )- 1 );
960
+ * class_name_len = sizeof ("PDORow" )- 1 ;
961
+ return 0 ;
962
+ }
963
+
964
+ static int row_compare (zval * object1 , zval * object2 TSRMLS_DC )
965
+ {
966
+ return -1 ;
967
+ }
968
+
969
+ zend_object_handlers pdo_row_object_handlers = {
970
+ ZEND_OBJECTS_STORE_HANDLERS ,
971
+ row_prop_or_dim_read ,
972
+ row_prop_or_dim_write ,
973
+ row_prop_or_dim_read ,
974
+ row_prop_or_dim_write ,
975
+ NULL ,
976
+ NULL ,
977
+ NULL ,
978
+ row_prop_or_dim_exists ,
979
+ row_prop_or_dim_delete ,
980
+ row_prop_or_dim_exists ,
981
+ row_prop_or_dim_delete ,
982
+ row_get_properties ,
983
+ row_method_get ,
984
+ row_call_method ,
985
+ row_get_ctor ,
986
+ row_get_ce ,
987
+ row_get_classname ,
988
+ row_compare ,
989
+ NULL , /* cast */
990
+ NULL
991
+ };
992
+
993
+ void pdo_row_free_storage (zend_object * object TSRMLS_DC )
994
+ {
995
+ pdo_stmt_t * stmt = (pdo_stmt_t * )object ;
996
+
997
+ /* nothing to do here */
998
+ }
999
+
1000
+ zend_object_value pdo_row_new (zend_class_entry * ce TSRMLS_DC )
1001
+ {
1002
+ zend_object_value retval ;
1003
+
1004
+ retval .handle = zend_objects_store_put (NULL , NULL , pdo_row_free_storage , NULL TSRMLS_CC );
1005
+ retval .handlers = & pdo_row_object_handlers ;
1006
+
1007
+ return retval ;
1008
+ }
1009
+ /* }}} */
1010
+
815
1011
/*
816
1012
* Local variables:
817
1013
* tab-width: 4
0 commit comments