Skip to content

Commit 8ed692a

Browse files
committed
WIP Implement column metadata
1 parent 14fc4ed commit 8ed692a

2 files changed

Lines changed: 149 additions & 5 deletions

File tree

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: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,18 @@ class WP_SQLite_Driver {
378378
*/
379379
private $last_return_value;
380380

381+
/**
382+
* Statement objects that carry column metadata for the last emulated query.
383+
*
384+
* In most cases, this will store a single statement representing the main
385+
* SQLite query that was executed. However, it can also be list of multiple
386+
* statements in some cases when a single MySQL query needs multiple SQLite
387+
* queries to be executed separately.
388+
*
389+
* @var PDOStatement[]
390+
*/
391+
private $last_column_meta_statements = array();
392+
381393
/**
382394
* Number of rows found by the last SQL_CALC_FOUND_ROW query.
383395
*
@@ -718,6 +730,65 @@ public function get_last_return_value() {
718730
return $this->last_return_value;
719731
}
720732

733+
public function get_last_column_count(): int {
734+
$count = 0;
735+
foreach ( $this->last_column_meta_statements as $stmt ) {
736+
$count += $stmt->columnCount();
737+
}
738+
return $count;
739+
}
740+
741+
/**
742+
* Get column information of the last emulated query.
743+
*
744+
* @return array
745+
*/
746+
public function get_last_column_meta(): array {
747+
$native_types = array(
748+
'NULL' => 'NULL',
749+
'INTEGER' => 'LONG',
750+
'TEXT' => 'BLOB',
751+
'REAL' => 'DOUBLE',
752+
'BLOB' => 'BLOB',
753+
);
754+
755+
$pdo_types = array(
756+
'NULL' => PDO::PARAM_NULL,
757+
'INTEGER' => PDO::PARAM_INT,
758+
'TEXT' => PDO::PARAM_STR,
759+
'REAL' => PDO::PARAM_STR,
760+
'BLOB' => PDO::PARAM_STR,
761+
);
762+
763+
$column_meta = array();
764+
foreach ( $this->last_column_meta_statements as $stmt ) {
765+
for ( $i = 0; $i < $stmt->columnCount(); $i++ ) {
766+
$meta = $stmt->getColumnMeta( $i );
767+
768+
$sqlite_type = $meta['sqlite:decl_type'];
769+
$native_type = $native_types[ $sqlite_type ] ?? null;
770+
$pdo_type = $pdo_types[ $sqlite_type ] ?? PDO::PARAM_NULL;
771+
772+
$flags = array();
773+
if ( 'BLOB' === $native_type ) {
774+
$flags[] = 'blob';
775+
}
776+
777+
$column_meta[] = array(
778+
'native_type' => $native_type,
779+
'pdo_type' => $pdo_type,
780+
'flags' => $flags,
781+
'table' => $meta['table'],
782+
'name' => $meta['name'],
783+
'len' => $meta['len'],
784+
'precision' => $meta['precision'],
785+
'sqlite:decl_type' => $meta['sqlite:decl_type'],
786+
);
787+
}
788+
}
789+
return $column_meta;
790+
}
791+
721792
/**
722793
* Execute a query in SQLite.
723794
*
@@ -1037,6 +1108,7 @@ private function execute_select_statement( WP_Parser_Node $node ): void {
10371108
$this->set_results_from_fetched_data(
10381109
$stmt->fetchAll( $this->pdo_fetch_mode )
10391110
);
1111+
$this->last_column_meta_statements[] = $stmt;
10401112
}
10411113

10421114
/**
@@ -3887,11 +3959,12 @@ private function quote_mysql_utf8_string_literal( string $utf8_literal ): string
38873959
* Clear the state of the driver.
38883960
*/
38893961
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;
3962+
$this->last_mysql_query = '';
3963+
$this->last_sqlite_queries = array();
3964+
$this->last_result = null;
3965+
$this->last_return_value = null;
3966+
$this->last_column_meta_statements = array();
3967+
$this->is_readonly = false;
38953968
}
38963969

38973970
/**

0 commit comments

Comments
 (0)