1414
1515class WP_PDO_Synthetic_Statement extends PDOStatement {
1616 /**
17- * Column names of the columns in the result set.
17+ * The PDO connection.
18+ *
19+ * @var PDO
20+ */
21+ private $ pdo ;
22+
23+ /**
24+ * Column metadata as reported by SQLite.
1825 *
1926 * @var array<string>
2027 */
21- private $ columns = array ();
28+ private $ sqlite_column_meta = array ();
2229
2330 /**
2431 * Rows of the result set.
@@ -44,9 +51,18 @@ class WP_PDO_Synthetic_Statement extends PDOStatement {
4451 /**
4552 * The current fetch mode.
4653 *
54+ * The PDO::FETCH_DEFAULT constant is available from PHP 8.0.
55+ *
4756 * @var int
4857 */
49- private $ fetch_mode = PDO ::FETCH_DEFAULT ;
58+ private $ fetch_mode = 0 ; // PDO::FETCH_DEFAULT
59+
60+ /**
61+ * The PDO attributes of the statement.
62+ *
63+ * @var array<int, mixed>
64+ */
65+ private $ attributes = array ();
5066
5167 /**
5268 * Additional arguments for the current fetch mode.
@@ -56,21 +72,23 @@ class WP_PDO_Synthetic_Statement extends PDOStatement {
5672 private $ fetch_mode_args = array ();
5773
5874 public function __construct (
75+ PDO $ pdo ,
76+ array $ sqlite_column_metadata ,
5977 array $ rows ,
60- array $ columns ,
6178 int $ affected_rows = 0
6279 ) {
63- $ this ->rows = $ rows ;
64- $ this ->columns = $ columns ;
65- $ this ->affected_rows = $ affected_rows ;
80+ $ this ->pdo = $ pdo ;
81+ $ this ->sqlite_column_meta = $ sqlite_column_metadata ;
82+ $ this ->rows = $ rows ;
83+ $ this ->affected_rows = $ affected_rows ;
6684 }
6785
6886 public function execute ( ?array $ params = null ): bool {
6987 return true ;
7088 }
7189
7290 public function columnCount (): int {
73- return count ( $ this ->columns );
91+ return count ( $ this ->sqlite_column_meta );
7492 }
7593
7694 public function rowCount (): int {
@@ -88,18 +106,32 @@ public function fetch(
88106 }
89107 // TODO: $cursorOffset
90108
91- if ( PDO ::FETCH_DEFAULT === $ mode ) {
109+ // 0 is PDO::FETCH_DEFAULT (the constant is available from PHP 8.0).
110+ if ( 0 === $ mode ) {
92111 $ mode = $ this ->fetch_mode ;
93112 }
94113
95114 $ row = $ this ->rows [ $ this ->row_offset ];
96115 $ this ->row_offset += 1 ;
97116
117+ $ column_names = array_column ( $ this ->sqlite_column_meta , 'name ' );
118+
119+ if ( PHP_VERSION_ID < 80100 && ! $ this ->getAttribute ( PDO ::ATTR_STRINGIFY_FETCHES ) ) {
120+ foreach ( $ row as $ i => $ value ) {
121+ $ type = $ this ->sqlite_column_meta [ $ i ]['native_type ' ];
122+ if ( 'integer ' === $ type ) {
123+ $ row [ $ i ] = (int ) $ value ;
124+ } elseif ( 'float ' === $ type ) {
125+ $ row [ $ i ] = (float ) $ value ;
126+ }
127+ }
128+ }
129+
98130 switch ( $ mode ) {
99131 case PDO ::FETCH_BOTH :
100132 $ values = array ();
101133 foreach ( $ row as $ i => $ value ) {
102- $ name = $ this -> columns [ $ i ];
134+ $ name = $ column_names [ $ i ];
103135 $ values [ $ name ] = $ value ;
104136 if ( ! array_key_exists ( $ i , $ values ) ) {
105137 $ values [ $ i ] = $ value ;
@@ -109,11 +141,11 @@ public function fetch(
109141 case PDO ::FETCH_NUM :
110142 return $ row ;
111143 case PDO ::FETCH_ASSOC :
112- return array_combine ( $ this -> columns , $ row );
144+ return array_combine ( $ column_names , $ row );
113145 case PDO ::FETCH_NAMED :
114146 $ values = array ();
115147 foreach ( $ row as $ i => $ value ) {
116- $ name = $ this -> columns [ $ i ];
148+ $ name = $ column_names [ $ i ];
117149 if ( is_array ( $ values [ $ name ] ?? null ) ) {
118150 $ values [ $ name ][] = $ value ;
119151 } elseif ( array_key_exists ( $ name , $ values ) ) {
@@ -124,7 +156,7 @@ public function fetch(
124156 }
125157 return $ values ;
126158 case PDO ::FETCH_OBJ :
127- $ assoc = array_combine ( $ this -> columns , $ row );
159+ $ assoc = array_combine ( $ column_names , $ row );
128160 return (object ) $ assoc ;
129161 default :
130162 throw new ValueError ( sprintf ( 'Unsupported fetch mode: %d ' , $ mode ) );
@@ -167,6 +199,16 @@ public function setFetchMode( int $mode, ...$args ): bool {
167199 return true ;
168200 }
169201
202+ #[ReturnTypeWillChange]
203+ public function getAttribute ( int $ attribute ) {
204+ return $ this ->attributes [ $ attribute ] ?? $ this ->pdo ->getAttribute ( $ attribute );
205+ }
206+
207+ public function setAttribute ( int $ attribute , $ value ): bool {
208+ $ this ->attributes [ $ attribute ] = $ value ;
209+ return true ;
210+ }
211+
170212 // TODO:
171213 // public function bindColumn()
172214 // public function bindParam()
0 commit comments