Skip to content

Commit 413a72d

Browse files
committed
Add basic implementation of column metadata
1 parent 14fc4ed commit 413a72d

File tree

2 files changed

+153
-5
lines changed

2 files changed

+153
-5
lines changed

tests/WP_SQLite_Driver_Tests.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5859,4 +5859,75 @@ public function testDropIndex(): void {
58595859
$result = $this->engine->execute_sqlite_query( "PRAGMA index_list('t')" )->fetchAll( PDO::FETCH_ASSOC );
58605860
$this->assertCount( 0, $result );
58615861
}
5862+
5863+
public function testColumnInfo(): void {
5864+
$this->assertQuery( 'CREATE TABLE t (id INT, name TEXT, score FLOAT, data BLOB)' );
5865+
$this->assertQuery( 'SELECT * FROM t' );
5866+
5867+
$this->assertEquals( 4, $this->engine->get_last_column_count() );
5868+
5869+
$column_info = $this->engine->get_last_column_meta();
5870+
$this->assertCount( 4, $column_info );
5871+
5872+
$this->assertSame(
5873+
array(
5874+
'native_type' => 'LONG',
5875+
'pdo_type' => PDO::PARAM_INT,
5876+
'flags' => array(),
5877+
'table' => 't',
5878+
'name' => 'id',
5879+
//'len' => 11,
5880+
'len' => -1,
5881+
'precision' => 0,
5882+
'sqlite:decl_type' => 'INTEGER',
5883+
),
5884+
$column_info[0]
5885+
);
5886+
5887+
$this->assertSame(
5888+
array(
5889+
'native_type' => 'BLOB',
5890+
'pdo_type' => PDO::PARAM_STR,
5891+
'flags' => array( 'blob' ),
5892+
'table' => 't',
5893+
'name' => 'name',
5894+
//'len' => 262140,
5895+
'len' => -1,
5896+
'precision' => 0,
5897+
'sqlite:decl_type' => 'TEXT',
5898+
),
5899+
$column_info[1]
5900+
);
5901+
5902+
$this->assertSame(
5903+
array(
5904+
'native_type' => 'DOUBLE',
5905+
'pdo_type' => PDO::PARAM_STR,
5906+
'flags' => array(),
5907+
'table' => 't',
5908+
'name' => 'score',
5909+
//'len' => 22,
5910+
'len' => -1,
5911+
//'precision' => 31,
5912+
'precision' => 0,
5913+
'sqlite:decl_type' => 'REAL',
5914+
),
5915+
$column_info[2]
5916+
);
5917+
5918+
$this->assertSame(
5919+
array(
5920+
'native_type' => 'BLOB',
5921+
'pdo_type' => PDO::PARAM_STR,
5922+
'flags' => array( 'blob' ),
5923+
'table' => 't',
5924+
'name' => 'data',
5925+
//'len' => 65535,
5926+
'len' => -1,
5927+
'precision' => 0,
5928+
'sqlite:decl_type' => 'BLOB',
5929+
),
5930+
$column_info[3]
5931+
);
5932+
}
58625933
}

wp-includes/sqlite-ast/class-wp-sqlite-driver.php

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,13 @@ class WP_SQLite_Driver {
378378
*/
379379
private $last_return_value;
380380

381+
/**
382+
* Statement object that carries column metadata for the last emulated query.
383+
*
384+
* @var PDOStatement|null
385+
*/
386+
private $last_column_meta_statement;
387+
381388
/**
382389
* Number of rows found by the last SQL_CALC_FOUND_ROW query.
383390
*
@@ -718,6 +725,74 @@ public function get_last_return_value() {
718725
return $this->last_return_value;
719726
}
720727

728+
/**
729+
* Get the number of columns returned by the last emulated query.
730+
*
731+
* @return int
732+
*/
733+
public function get_last_column_count(): int {
734+
if ( null === $this->last_column_meta_statement ) {
735+
return 0;
736+
}
737+
return $this->last_column_meta_statement->columnCount();
738+
}
739+
740+
/**
741+
* Get column metadata for results of the last emulated query.
742+
*
743+
* @return array
744+
*/
745+
public function get_last_column_meta(): array {
746+
if ( null === $this->last_column_meta_statement ) {
747+
return array();
748+
}
749+
750+
// Map of SQLite column types to native PHP types.
751+
$native_types = array(
752+
'NULL' => 'NULL',
753+
'INTEGER' => 'LONG',
754+
'TEXT' => 'BLOB',
755+
'REAL' => 'DOUBLE',
756+
'BLOB' => 'BLOB',
757+
);
758+
759+
// Map of SQLite column types to PDO parameter types.
760+
$pdo_types = array(
761+
'NULL' => PDO::PARAM_NULL,
762+
'INTEGER' => PDO::PARAM_INT,
763+
'TEXT' => PDO::PARAM_STR,
764+
'REAL' => PDO::PARAM_STR,
765+
'BLOB' => PDO::PARAM_STR,
766+
);
767+
768+
// Build the column metadata as per "PDOStatement::getColumnMeta()".
769+
$column_meta = array();
770+
for ( $i = 0; $i < $this->last_column_meta_statement->columnCount(); $i++ ) {
771+
$meta = $this->last_column_meta_statement->getColumnMeta( $i );
772+
773+
$sqlite_type = $meta['sqlite:decl_type'];
774+
$native_type = $native_types[ $sqlite_type ] ?? null;
775+
$pdo_type = $pdo_types[ $sqlite_type ] ?? PDO::PARAM_NULL;
776+
777+
$flags = array();
778+
if ( 'BLOB' === $native_type ) {
779+
$flags[] = 'blob';
780+
}
781+
782+
$column_meta[] = array(
783+
'native_type' => $native_type,
784+
'pdo_type' => $pdo_type,
785+
'flags' => $flags,
786+
'table' => $meta['table'],
787+
'name' => $meta['name'],
788+
'len' => $meta['len'],
789+
'precision' => $meta['precision'],
790+
'sqlite:decl_type' => $meta['sqlite:decl_type'],
791+
);
792+
}
793+
return $column_meta;
794+
}
795+
721796
/**
722797
* Execute a query in SQLite.
723798
*
@@ -1037,6 +1112,7 @@ private function execute_select_statement( WP_Parser_Node $node ): void {
10371112
$this->set_results_from_fetched_data(
10381113
$stmt->fetchAll( $this->pdo_fetch_mode )
10391114
);
1115+
$this->last_column_meta_statement = $stmt;
10401116
}
10411117

10421118
/**
@@ -3887,11 +3963,12 @@ private function quote_mysql_utf8_string_literal( string $utf8_literal ): string
38873963
* Clear the state of the driver.
38883964
*/
38893965
private function flush(): void {
3890-
$this->last_mysql_query = '';
3891-
$this->last_sqlite_queries = array();
3892-
$this->last_result = null;
3893-
$this->last_return_value = null;
3894-
$this->is_readonly = false;
3966+
$this->last_mysql_query = '';
3967+
$this->last_sqlite_queries = array();
3968+
$this->last_result = null;
3969+
$this->last_return_value = null;
3970+
$this->last_column_meta_statements = array();
3971+
$this->is_readonly = false;
38953972
}
38963973

38973974
/**

0 commit comments

Comments
 (0)