Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft/POC for SQLite support in Core #3220

Draft
wants to merge 47 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
1651902
copy & tweak the SQLite implementation
aristath Sep 2, 2022
d738213
CS fixes
aristath Sep 5, 2022
ba59589
more CS fixes
aristath Sep 5, 2022
84c1827
some coding improvements
aristath Sep 5, 2022
7618507
change constant to DATABASE_TYPE
aristath Sep 7, 2022
4af4ab2
update system status info
aristath Sep 9, 2022
faf217e
add debug info for constant
aristath Sep 9, 2022
9528095
change wording
aristath Sep 9, 2022
24a8d0a
debug tweak
aristath Sep 9, 2022
3cc5da5
minor coding tweaks
aristath Sep 13, 2022
e71dba7
site-health improvements
aristath Sep 13, 2022
b5b14d9
Fix PHP Warning by adding a db_server_info() method
aristath Sep 13, 2022
1d18604
Update implementation
aristath Feb 23, 2023
7b72595
backport more changes
aristath Feb 23, 2023
886508a
Force SQLite so that tests run in this PR using the new db
aristath Feb 23, 2023
605846a
compatibility fixes for PHP < 7
aristath Feb 23, 2023
e8f8b7c
backport latest changes from the plugin
aristath Feb 28, 2023
fa4a2bc
Remove type declarations (PHP Compatibility)
aristath Mar 1, 2023
55fd8ff
overzealous check
aristath Mar 1, 2023
adedea2
strict_types not necessary
aristath Mar 1, 2023
383acb6
backport installation function changes
aristath Mar 3, 2023
562520e
Proof of concept for db-type selection during the installation
aristath Mar 3, 2023
f178291
Use a select input instead of radios
aristath Mar 3, 2023
d93deff
remove console.log, it was just for debugging
aristath Mar 3, 2023
a48ec94
check if SQLite3 exists
aristath Mar 3, 2023
0501699
Simplify installation when the server supports SQLite and not MySQL
aristath Mar 10, 2023
da0eb68
Rename DATABASE_TYPE to DB_ENGINE for consistency with other constants
aristath Mar 13, 2023
3f2729f
Backport changes
aristath Mar 28, 2023
b8bdadd
minor tweaks
aristath Jul 20, 2023
1828212
CS fix after rebase
aristath Aug 30, 2023
18790ca
Update SQLite implementation
aristath Dec 28, 2023
f21e20c
Add PHPCS exclusion
aristath Dec 28, 2023
5efd2e2
fix typo
aristath Jan 9, 2024
92a383c
Merge branch 'trunk' into sqlite
aristath Apr 18, 2024
d367e65
Sync SQLite classes with the plugin
aristath Apr 18, 2024
3f6aabe
CS fixes
aristath Apr 18, 2024
e1dab1d
Merge branch 'trunk' into sqlite
aristath May 9, 2024
982a1c6
Merge branch 'trunk' into sqlite
aristath May 15, 2024
4ebb830
Merge branch 'trunk' into sqlite
aristath May 16, 2024
0a33a6e
Merge branch 'trunk' into sqlite
aristath Jun 19, 2024
6f79c14
Merge branch 'trunk' into sqlite
aristath Jun 19, 2024
1c2f880
Merge branch 'trunk' into sqlite
aristath Jun 20, 2024
47342f9
Update the SQLite translator class
aristath Jun 20, 2024
41097ce
Merge branch 'trunk' into sqlite
aristath Jun 24, 2024
1ef5ad6
Merge branch 'trunk' into sqlite
aristath Jun 25, 2024
3c26161
Merge branch 'trunk' into sqlite
aristath Jun 27, 2024
b37c4dc
Merge branch 'trunk' into sqlite
aristath Jul 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,7 @@ wp-tests-config.php

# Visual regression test diffs
tests/visual-regression/specs/__snapshots__

src/wp-content/database/.ht.sqlite

src/wp-content/database/
6 changes: 5 additions & 1 deletion phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@
#############################################################################
SELECTIVE EXCLUSIONS
Exclude specific files for specific sniffs and/or exclude sub-groups in sniffs.

These exclusions are listed ordered by alphabetic sniff name.
#############################################################################
-->
Expand Down Expand Up @@ -295,6 +295,10 @@
<exclude-pattern>/tests/phpunit/tests/db/charset\.php</exclude-pattern>
</rule>

<rule ref="WordPress.DB.RestrictedClasses">
<exclude-pattern>/src/wp-includes/sqlite/*\.php</exclude-pattern>
</rule>

<!-- Allow the WP DB related tests for issues with prepared SQL placeholders
(as the handling of those are being tested). -->
<rule ref="WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare">
Expand Down
133 changes: 82 additions & 51 deletions src/wp-admin/includes/class-wp-debug-data.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,11 @@ public static function debug_data() {
'label' => 'WP_MAX_MEMORY_LIMIT',
'value' => WP_MAX_MEMORY_LIMIT,
),
'DB_ENGINE' => array(
'label' => 'DB_ENGINE',
'value' => ( defined( 'DB_ENGINE' ) ? DB_ENGINE : __( 'Undefined' ) ),
'debug' => ( defined( 'DB_ENGINE' ) ? DB_ENGINE : 'undefined' ),
),
'WP_DEBUG' => array(
'label' => 'WP_DEBUG',
'value' => WP_DEBUG ? __( 'Enabled' ) : __( 'Disabled' ),
Expand Down Expand Up @@ -879,79 +884,105 @@ public static function debug_data() {
'value' => wp_date( 'c', $_SERVER['REQUEST_TIME'] ),
);

// Populate the database debug fields.
if ( is_object( $wpdb->dbh ) ) {
// mysqli or PDO.
$extension = get_class( $wpdb->dbh );
} else {
// Unknown sql extension.
$extension = null;
$db_engine = defined( 'DB_ENGINE' ) && 'sqlite' === DB_ENGINE ? 'sqlite' : 'mysql';
$extension = null;
if ( 'mysql' === $db_engine ) {
// Populate the database debug fields.
if ( is_object( $wpdb->dbh ) ) {
// mysqli or PDO.
$extension = get_class( $wpdb->dbh );
}
}

$server = $wpdb->get_var( 'SELECT VERSION()' );

$client_version = $wpdb->dbh->client_info;

$info['wp-database']['fields']['extension'] = array(
'label' => __( 'Extension' ),
'value' => $extension,
$info['wp-database']['fields']['db_engine'] = array(
'label' => __( 'Database engine' ),
'value' => 'sqlite' === $db_engine ? 'SQLite' : 'MySQL/MariaDB',
);

$info['wp-database']['fields']['server_version'] = array(
'label' => __( 'Server version' ),
'value' => $server,
);
if ( 'mysql' === $db_engine ) {
$info['wp-database']['fields']['extension'] = array(
'label' => __( 'Extension' ),
'value' => $extension,
);

$info['wp-database']['fields']['client_version'] = array(
'label' => __( 'Client version' ),
'value' => $client_version,
);
$info['wp-database']['fields']['server_version'] = array(
'label' => __( 'Server version' ),
'value' => $server,
);

$info['wp-database']['fields']['database_user'] = array(
'label' => __( 'Database username' ),
'value' => $wpdb->dbuser,
'private' => true,
);
$info['wp-database']['fields']['client_version'] = array(
'label' => __( 'Client version' ),
'value' => $client_version,
);

$info['wp-database']['fields']['database_host'] = array(
'label' => __( 'Database host' ),
'value' => $wpdb->dbhost,
'private' => true,
);
$info['wp-database']['fields']['database_user'] = array(
'label' => __( 'Database username' ),
'value' => $wpdb->dbuser,
'private' => true,
);

$info['wp-database']['fields']['database_name'] = array(
'label' => __( 'Database name' ),
'value' => $wpdb->dbname,
'private' => true,
);
$info['wp-database']['fields']['database_host'] = array(
'label' => __( 'Database host' ),
'value' => $wpdb->dbhost,
'private' => true,
);

$info['wp-database']['fields']['database_name'] = array(
'label' => __( 'Database name' ),
'value' => $wpdb->dbname,
'private' => true,
);
} elseif ( 'sqlite' === $db_engine ) {
$info['wp-database']['fields']['database_version'] = array(
'label' => __( 'SQLite version' ),
'value' => class_exists( 'SQLite3' ) ? SQLite3::version()['versionString'] : null,
);

$info['wp-database']['fields']['database_file'] = array(
'label' => __( 'Database file' ),
'value' => FQDB,
'private' => true,
);

$info['wp-database']['fields']['database_size'] = array(
'label' => __( 'Database size' ),
'value' => size_format( filesize( FQDB ) ),
);
}

$info['wp-database']['fields']['database_prefix'] = array(
'label' => __( 'Table prefix' ),
'value' => $wpdb->prefix,
'private' => true,
);

$info['wp-database']['fields']['database_charset'] = array(
'label' => __( 'Database charset' ),
'value' => $wpdb->charset,
'private' => true,
);
if ( 'mysql' === $db_engine ) {
$info['wp-database']['fields']['database_charset'] = array(
'label' => __( 'Database charset' ),
'value' => $wpdb->charset,
'private' => true,
);

$info['wp-database']['fields']['database_collate'] = array(
'label' => __( 'Database collation' ),
'value' => $wpdb->collate,
'private' => true,
);
$info['wp-database']['fields']['database_collate'] = array(
'label' => __( 'Database collation' ),
'value' => $wpdb->collate,
'private' => true,
);

$info['wp-database']['fields']['max_allowed_packet'] = array(
'label' => __( 'Max allowed packet size' ),
'value' => self::get_mysql_var( 'max_allowed_packet' ),
);
$info['wp-database']['fields']['max_allowed_packet'] = array(
'label' => __( 'Max allowed packet size' ),
'value' => self::get_mysql_var( 'max_allowed_packet' ),
);

$info['wp-database']['fields']['max_connections'] = array(
'label' => __( 'Max connections number' ),
'value' => self::get_mysql_var( 'max_connections' ),
);
$info['wp-database']['fields']['max_connections'] = array(
'label' => __( 'Max connections number' ),
'value' => self::get_mysql_var( 'max_connections' ),
);
}

// List must use plugins if there are any.
$mu_plugins = get_mu_plugins();
Expand Down
6 changes: 4 additions & 2 deletions src/wp-admin/includes/class-wp-site-health.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class WP_Site_Health {
private $is_recommended_mysql_version;

public $is_mariadb = false;
public $is_sqlite = false;
private $mysql_server_version = '';
private $mysql_required_version = '5.5';
private $mysql_recommended_version = '8.0';
Expand Down Expand Up @@ -208,6 +209,7 @@ private function prepare_sql_data() {
global $wpdb;

$mysql_server_type = $wpdb->db_server_info();
$this->is_sqlite = defined( 'DB_ENGINE' ) && 'sqlite' === DB_ENGINE ? 'sqlite' : 'mysql';

$this->mysql_server_version = $wpdb->get_var( 'SELECT VERSION()' );

Expand Down Expand Up @@ -1230,7 +1232,7 @@ public function get_test_sql_server() {

$db_dropin = file_exists( WP_CONTENT_DIR . '/db.php' );

if ( ! $this->is_recommended_mysql_version ) {
if ( ! $this->is_sqlite && ! $this->is_recommended_mysql_version ) {
$result['status'] = 'recommended';

$result['label'] = __( 'Outdated SQL server' );
Expand All @@ -1246,7 +1248,7 @@ public function get_test_sql_server() {
);
}

if ( ! $this->is_acceptable_mysql_version ) {
if ( ! $this->is_sqlite && ! $this->is_acceptable_mysql_version ) {
$result['status'] = 'critical';

$result['label'] = __( 'Severely outdated SQL server' );
Expand Down
58 changes: 57 additions & 1 deletion src/wp-admin/includes/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ function wp_install( $blog_title, $user_name, $user_email, $is_public, $deprecat

wp_check_mysql_version();
wp_cache_flush();
make_db_current_silent();

if ( defined( 'DB_ENGINE' ) && 'sqlite' === DB_ENGINE ) {
sqlite_make_db_sqlite(); // phpcs:ignore PHPCompatibility.Extensions.RemovedExtensions.sqliteRemoved
} else {
make_db_current_silent();
}

/*
* Ensure update checks are delayed after installation.
Expand Down Expand Up @@ -3279,6 +3284,57 @@ function make_db_current_silent( $tables = 'all' ) {
dbDelta( $tables );
}


/**
* Function to create tables according to the schemas of WordPress.
*
* This is executed only once while installation.
*
* @since 1.0.0
*
* @return boolean
*/
function sqlite_make_db_sqlite() {
include_once ABSPATH . 'wp-admin/includes/schema.php';

$table_schemas = wp_get_db_schema();
$queries = explode( ';', $table_schemas );
try {
$pdo = new PDO( 'sqlite:' . FQDB, null, null, array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ) ); // phpcs:ignore WordPress.DB.RestrictedClasses
} catch ( PDOException $err ) {
$err_data = $err->errorInfo; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
wp_die( $err_data[2], 'Database Error!' );
}

$translator = new WP_SQLite_Translator( $pdo, $GLOBALS['table_prefix'] );
$query = null;

try {
$translator->begin_transaction();
foreach ( $queries as $query ) {
$query = trim( $query );
if ( empty( $query ) ) {
continue;
}

$result = $translator->query( $query );
if ( false === $result ) {
throw new PDOException( $translator->get_error_message() );
}
}
$translator->commit();
} catch ( PDOException $err ) {
$err_data = $err->errorInfo; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
$err_code = $err_data[1];
$translator->rollback();
wp_die( $err_data[2], 'Database Error!' );
}

$pdo = null;

return true;
}

/**
* Creates a site theme from an existing theme.
*
Expand Down
Loading
Loading