Skip to content

Commit b1e4db9

Browse files
committed
Set up MySQL proxy package, improve class naming and organization
1 parent b322e3b commit b1e4db9

File tree

10 files changed

+934
-112
lines changed

10 files changed

+934
-112
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "wordpress/wp-mysql-proxy",
3+
"type": "library",
4+
"scripts": {
5+
"test": "phpunit"
6+
},
7+
"require-dev": {
8+
"phpunit/phpunit": "^8.5",
9+
"symfony/process": "^5.4"
10+
},
11+
"autoload": {
12+
"classmap": [
13+
"src/"
14+
],
15+
"files": [
16+
"../../php-polyfills.php"
17+
]
18+
}
19+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php declare( strict_types = 1 );
2+
3+
namespace WP_MySQL_Proxy\Adapter;
4+
5+
use WP_MySQL_Proxy\MySQL_Result;
6+
7+
interface Adapter {
8+
public function handle_query( string $query ): MySQL_Result;
9+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?php declare( strict_types = 1 );
2+
3+
namespace WP_MySQL_Proxy\Adapter;
4+
5+
use Throwable;
6+
use WP_MySQL_Proxy\MySQL_Result;
7+
use WP_SQLite_Connection;
8+
use WP_SQLite_Driver;
9+
use WP_SQLite_Driver_Exception;
10+
use WP_MySQL_Proxy\MySQL_Protocol;
11+
12+
define( 'SQLITE_DRIVER_PATH', __DIR__ . '/../../../..' );
13+
14+
require_once SQLITE_DRIVER_PATH . '/version.php';
15+
require_once SQLITE_DRIVER_PATH . '/wp-includes/parser/class-wp-parser-grammar.php';
16+
require_once SQLITE_DRIVER_PATH . '/wp-includes/parser/class-wp-parser.php';
17+
require_once SQLITE_DRIVER_PATH . '/wp-includes/parser/class-wp-parser-node.php';
18+
require_once SQLITE_DRIVER_PATH . '/wp-includes/parser/class-wp-parser-token.php';
19+
require_once SQLITE_DRIVER_PATH . '/wp-includes/mysql/class-wp-mysql-token.php';
20+
require_once SQLITE_DRIVER_PATH . '/wp-includes/mysql/class-wp-mysql-lexer.php';
21+
require_once SQLITE_DRIVER_PATH . '/wp-includes/mysql/class-wp-mysql-parser.php';
22+
require_once SQLITE_DRIVER_PATH . '/wp-includes/sqlite/class-wp-sqlite-pdo-user-defined-functions.php';
23+
require_once SQLITE_DRIVER_PATH . '/wp-includes/sqlite-ast/class-wp-sqlite-connection.php';
24+
require_once SQLITE_DRIVER_PATH . '/wp-includes/sqlite-ast/class-wp-sqlite-configurator.php';
25+
require_once SQLITE_DRIVER_PATH . '/wp-includes/sqlite-ast/class-wp-sqlite-driver.php';
26+
require_once SQLITE_DRIVER_PATH . '/wp-includes/sqlite-ast/class-wp-sqlite-driver-exception.php';
27+
require_once SQLITE_DRIVER_PATH . '/wp-includes/sqlite-ast/class-wp-sqlite-information-schema-builder.php';
28+
require_once SQLITE_DRIVER_PATH . '/wp-includes/sqlite-ast/class-wp-sqlite-information-schema-exception.php';
29+
require_once SQLITE_DRIVER_PATH . '/wp-includes/sqlite-ast/class-wp-sqlite-information-schema-reconstructor.php';
30+
31+
class SQLite_Adapter implements Adapter {
32+
/** @var WP_SQLite_Driver */
33+
private $sqlite_driver;
34+
35+
public function __construct( $sqlite_database_path ) {
36+
define( 'FQDB', $sqlite_database_path );
37+
define( 'FQDBDIR', dirname( FQDB ) . '/' );
38+
39+
$this->sqlite_driver = new WP_SQLite_Driver(
40+
new WP_SQLite_Connection( array( 'path' => $sqlite_database_path ) ),
41+
'sqlite_database'
42+
);
43+
}
44+
45+
public function handle_query( string $query ): MySQL_Result {
46+
$affected_rows = 0;
47+
$last_insert_id = null;
48+
$columns = array();
49+
$rows = array();
50+
51+
try {
52+
$return_value = $this->sqlite_driver->query( $query );
53+
$last_insert_id = $this->sqlite_driver->get_insert_id() ?? null;
54+
if ( is_numeric( $return_value ) ) {
55+
$affected_rows = (int) $return_value;
56+
} elseif ( is_array( $return_value ) ) {
57+
$rows = $return_value;
58+
}
59+
if ( $this->sqlite_driver->get_last_column_count() > 0 ) {
60+
$columns = $this->computeColumnInfo();
61+
}
62+
return MySQL_Result::from_data( $affected_rows, $last_insert_id, $columns, $rows ?? array() );
63+
} catch ( Throwable $e ) {
64+
if ( $e instanceof WP_SQLite_Driver_Exception ) {
65+
$error_info = $e->errorInfo; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
66+
return MySQL_Result::from_error( $error_info[0], $error_info[1], $error_info[2] );
67+
}
68+
return MySQL_Result::from_error( 'HY000', 1105, $e->getMessage() );
69+
}
70+
}
71+
72+
public function computeColumnInfo() {
73+
$columns = array();
74+
75+
$column_meta = $this->sqlite_driver->get_last_column_meta();
76+
77+
$types = array(
78+
'DECIMAL' => MySQL_Protocol::FIELD_TYPE_DECIMAL,
79+
'TINY' => MySQL_Protocol::FIELD_TYPE_TINY,
80+
'SHORT' => MySQL_Protocol::FIELD_TYPE_SHORT,
81+
'LONG' => MySQL_Protocol::FIELD_TYPE_LONG,
82+
'FLOAT' => MySQL_Protocol::FIELD_TYPE_FLOAT,
83+
'DOUBLE' => MySQL_Protocol::FIELD_TYPE_DOUBLE,
84+
'NULL' => MySQL_Protocol::FIELD_TYPE_NULL,
85+
'TIMESTAMP' => MySQL_Protocol::FIELD_TYPE_TIMESTAMP,
86+
'LONGLONG' => MySQL_Protocol::FIELD_TYPE_LONGLONG,
87+
'INT24' => MySQL_Protocol::FIELD_TYPE_INT24,
88+
'DATE' => MySQL_Protocol::FIELD_TYPE_DATE,
89+
'TIME' => MySQL_Protocol::FIELD_TYPE_TIME,
90+
'DATETIME' => MySQL_Protocol::FIELD_TYPE_DATETIME,
91+
'YEAR' => MySQL_Protocol::FIELD_TYPE_YEAR,
92+
'NEWDATE' => MySQL_Protocol::FIELD_TYPE_NEWDATE,
93+
'VARCHAR' => MySQL_Protocol::FIELD_TYPE_VARCHAR,
94+
'BIT' => MySQL_Protocol::FIELD_TYPE_BIT,
95+
'NEWDECIMAL' => MySQL_Protocol::FIELD_TYPE_NEWDECIMAL,
96+
'ENUM' => MySQL_Protocol::FIELD_TYPE_ENUM,
97+
'SET' => MySQL_Protocol::FIELD_TYPE_SET,
98+
'TINY_BLOB' => MySQL_Protocol::FIELD_TYPE_TINY_BLOB,
99+
'MEDIUM_BLOB' => MySQL_Protocol::FIELD_TYPE_MEDIUM_BLOB,
100+
'LONG_BLOB' => MySQL_Protocol::FIELD_TYPE_LONG_BLOB,
101+
'BLOB' => MySQL_Protocol::FIELD_TYPE_BLOB,
102+
'VAR_STRING' => MySQL_Protocol::FIELD_TYPE_VAR_STRING,
103+
'STRING' => MySQL_Protocol::FIELD_TYPE_STRING,
104+
'GEOMETRY' => MySQL_Protocol::FIELD_TYPE_GEOMETRY,
105+
);
106+
107+
foreach ( $column_meta as $column ) {
108+
$type = $types[ $column['native_type'] ] ?? null;
109+
if ( null === $type ) {
110+
throw new Exception( 'Unknown column type: ' . $column['native_type'] );
111+
}
112+
$columns[] = array(
113+
'name' => $column['name'],
114+
'length' => $column['len'],
115+
'type' => $type,
116+
'flags' => 129,
117+
'decimals' => $column['precision'],
118+
);
119+
}
120+
return $columns;
121+
}
122+
}

0 commit comments

Comments
 (0)