aaemnnosttv/wp-sqlite-db

To make wordpress 6.1 work with this project

Closed this issue ยท 9 comments

To make wordpress 6.1 it work with sqlite:

Change wp-admin/includes/upgrade.php:47: function wp_install

        /* begin wp-sqlite-db changes */
        // make_db_current_silent();
        WP_SQLite_DB\make_db_sqlite();
        /* end wp-sqlite-db changes */

Replace/update wp-includes/load.php function require_wp_db()

function require_wp_db() {
	global $wpdb;

	require_once ABSPATH . WPINC . '/wp-db.php';
	if ( file_exists( WP_CONTENT_DIR . '/db.php' ) ) {
		require_once WP_CONTENT_DIR . '/db.php';
	}

	/* begin wp-sqlite-db changes */
	if(!($wpdb instanceof  WP_SQLite_DB\wpsqlitedb)) {
		$wpdb = new WP_SQLite_DB\wpsqlitedb();
	}
	/* end wp-sqlite-db changes */

	if ( isset( $wpdb ) ) {
		return;
	}
	$dbuser     = defined( 'DB_USER' ) ? DB_USER : '';
	$dbpassword = defined( 'DB_PASSWORD' ) ? DB_PASSWORD : '';
	$dbname     = defined( 'DB_NAME' ) ? DB_NAME : '';
	$dbhost     = defined( 'DB_HOST' ) ? DB_HOST : '';

	$wpdb = new wpdb( $dbuser, $dbpassword, $dbname, $dbhost );
}

After going through it with xdebug I did some small fixes to allow install some new themes that also import demo content without errors:

--- wp-sqlite-db/src/db.php
+++ wordpress/wp-content/db.php
@@ -2978,6 +2978,11 @@
          *
          * @access private
          */
+        private function quote_illegal_field_backticked($qry)
+        {
+            return preg_replace("/`(default|values|group)`/im", "[\\1]", $qry);
+        }
+        
         private function parse_query()
         {
             $tokens = preg_split("/(\\\'|''|')/s", $this->_query, -1, PREG_SPLIT_DELIM_CAPTURE);
@@ -2993,6 +2998,7 @@
                 } else {
                     if ($literal === false) {
                         if (strpos($token, '`') !== false) {
+                            $token = $this->quote_illegal_field_backticked($token);
                             $token = str_replace('`', '', $token);
                         }
                         if (preg_match('/\\bTRUE\\b/i', $token)) {
@@ -3467,7 +3473,7 @@
                     } else {
                         $ins_array_assoc = [];
 
-                        if (preg_match('/^\((.*)\)\\s*VALUES\\s*\((.*)\)$/im', $insert_data, $match_2)) {
+                        if (preg_match('/^\((.*)\)\\s*VALUES\\s*\((.*)\)$/ims', $insert_data, $match_2)) {
                             $col_array = explode(',', $match_2[1]);
                             $ins_array = explode(',', $match_2[2]);
                             $count = count($col_array);

Do you mean 6.1 requires changes to core in order for wpsqlitedb to work at all?

Well for me to get it working with some extensions and even wordpress alone I needed those changes, instead of trying to emulate every weird mysql query in db.php with regex rewrite it's easier and cleaner change the original query in some places.

Here is my changes to wordpress itself to get it somehow working:

--- wordpress-6.1/wp-admin/includes/class-wp-debug-data.php
+++ wordpress-6.1-dad/wp-admin/includes/class-wp-debug-data.php
@@ -854,7 +854,9 @@
 
 		$server = $wpdb->get_var( 'SELECT VERSION()' );
 
-		if ( isset( $wpdb->use_mysqli ) && $wpdb->use_mysqli ) {
+		if($wpdb  instanceof  WP_SQLite_DB\wpsqlitedb) {
+			$client_version = 'Sqlite3';
+		} else if ( isset( $wpdb->use_mysqli ) && $wpdb->use_mysqli ) {
 			$client_version = $wpdb->dbh->client_info;
 		} else {
 			// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_client_info,PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
--- wordpress-6.1/wp-admin/includes/class-wp-site-health.php
+++ wordpress-6.1-dad/wp-admin/includes/class-wp-site-health.php
@@ -205,7 +205,9 @@
 	private function prepare_sql_data() {
 		global $wpdb;
 
-		if ( $wpdb->use_mysqli ) {
+		if($wpdb  instanceof  WP_SQLite_DB\wpsqlitedb) {
+			$mysql_server_type = 'Sqlite3';
+		} else if ( $wpdb->use_mysqli ) {
 			// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_server_info
 			$mysql_server_type = mysqli_get_server_info( $wpdb->dbh );
 		} else {
@@ -1321,7 +1323,9 @@
 			}
 		}
 
-		if ( $wpdb->use_mysqli ) {
+		if($wpdb  instanceof  WP_SQLite_DB\wpsqlitedb) {
+			$mysql_client_version = 'Sqlite3';
+		} else if ( $wpdb->use_mysqli ) {
 			// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_client_info
 			$mysql_client_version = mysqli_get_client_info();
 		} else {
--- wordpress-6.1/wp-admin/includes/template.php
+++ wordpress-6.1-dad/wp-admin/includes/template.php
@@ -701,7 +701,7 @@
 				"SELECT DISTINCT meta_key
 				FROM $wpdb->postmeta
 				WHERE meta_key NOT BETWEEN '_' AND '_z'
-				HAVING meta_key NOT LIKE %s
+				AND meta_key NOT LIKE %s
 				ORDER BY meta_key
 				LIMIT %d",
 				$wpdb->esc_like( '_' ) . '%',
--- wordpress-6.1/wp-admin/includes/upgrade.php
+++ wordpress-6.1-dad/wp-admin/includes/upgrade.php
@@ -51,7 +51,10 @@
 
 		wp_check_mysql_version();
 		wp_cache_flush();
-		make_db_current_silent();
+        	/* begin wp-sqlite-db changes */
+        	// make_db_current_silent();
+        	WP_SQLite_DB\make_db_sqlite();
+        	/* end wp-sqlite-db changes */
 		populate_options();
 		populate_roles();
 
--- wordpress-6.1/wp-includes/load.php
+++ wordpress-6.1-dad/wp-includes/load.php
@@ -548,6 +548,12 @@
 	if ( file_exists( WP_CONTENT_DIR . '/db.php' ) ) {
 		require_once WP_CONTENT_DIR . '/db.php';
 	}
+
+	/* begin wp-sqlite-db changes */
+	if(!($wpdb instanceof  WP_SQLite_DB\wpsqlitedb)) {
+		$wpdb = new WP_SQLite_DB\wpsqlitedb();
+	}
+	/* end wp-sqlite-db changes */
 
 	if ( isset( $wpdb ) ) {
 		return;
--- wordpress-6.1/wp-includes/option.php
+++ wordpress-6.1-dad/wp-includes/option.php
@@ -636,11 +636,24 @@
 	 * @param mixed  $value  Value of the option.
 	 */
 	do_action( 'add_option', $option, $value );
-
-	$result = $wpdb->query( $wpdb->prepare( "INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)", $option, $serialized_value, $autoload ) );
-	if ( ! $result ) {
+        $sql_prepared = null;
+        $result = null;
+
+        if($wpdb  instanceof  WP_SQLite_DB\wpsqlitedb) {
+            //$sql_prepared = $wpdb->prepare( "INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s) ON CONFLICT(option_name) DO UPDATE SET option_value = excluded.option_value, autoload = excluded.autoload", $option, $serialized_value, $autoload );            
+            $sql_prepared = $wpdb->prepare( "UPDATE `$wpdb->options` SET `option_value` = %s, `autoload` = %s WHERE `option_name` = %s", $serialized_value, $autoload, $option );
+            $result = $wpdb->query( $sql_prepared );
+            if ( ! $result ) {
+                $sql_prepared = $wpdb->prepare( "INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s)", $option, $serialized_value, $autoload );
+                $result = $wpdb->query( $sql_prepared );        
+            }
+        }
+        else {
+            $sql_prepared = $wpdb->prepare( "INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)", $option, $serialized_value, $autoload );
+            $result = $wpdb->query( $sql_prepared );
+        }
+	if ( ! $result )
 		return false;
-	}
 
 	if ( ! wp_installing() ) {
 		if ( 'yes' === $autoload ) {
@@ -1023,7 +1036,7 @@
 			"DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b
 			WHERE a.option_name LIKE %s
 			AND a.option_name NOT LIKE %s
-			AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
+			AND b.option_name = '_transient_timeout_' || SUBSTRING( a.option_name, 12 )
 			AND b.option_value < %d",
 			$wpdb->esc_like( '_transient_' ) . '%',
 			$wpdb->esc_like( '_transient_timeout_' ) . '%',
@@ -1038,7 +1051,7 @@
 				"DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b
 				WHERE a.option_name LIKE %s
 				AND a.option_name NOT LIKE %s
-				AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )
+				AND b.option_name = '_site_transient_timeout_' || SUBSTRING( a.option_name, 17 )
 				AND b.option_value < %d",
 				$wpdb->esc_like( '_site_transient_' ) . '%',
 				$wpdb->esc_like( '_site_transient_timeout_' ) . '%',
@@ -1052,7 +1065,7 @@
 				"DELETE a, b FROM {$wpdb->sitemeta} a, {$wpdb->sitemeta} b
 				WHERE a.meta_key LIKE %s
 				AND a.meta_key NOT LIKE %s
-				AND b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, 17 ) )
+				AND b.meta_key = '_site_transient_timeout_' || SUBSTRING( a.meta_key, 17 )
 				AND b.meta_value < %d",
 				$wpdb->esc_like( '_site_transient_' ) . '%',
 				$wpdb->esc_like( '_site_transient_timeout_' ) . '%',
--- wordpress-6.1/wp-includes/taxonomy.php
+++ wordpress-6.1-dad/wp-includes/taxonomy.php
@@ -2841,7 +2841,16 @@
 		}
 
 		if ( $values ) {
-			if ( false === $wpdb->query( "INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id, term_order) VALUES " . implode( ',', $values ) . ' ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)' ) ) {
+                        $result = false;
+                        if($wpdb  instanceof  WP_SQLite_DB\wpsqlitedb) {
+                            //$result = $wpdb->query( "INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id, term_order) VALUES " . implode( ',', $values ) . " ON CONFLICT(object_id,term_taxonomy_id) UPDATE term_order = excluded.term_order" );
+                            $result = $wpdb->query( "UPDATE $wpdb->term_relationships SET term_taxonomy_id = $values[1], term_order = $values[2] WHERE object_id = $values[0]");
+                            if(!$result)
+                                $result = $wpdb->query( "INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id, term_order) VALUES " . implode( ',', $values ) );
+			} else {
+				$result = $wpdb->query( "INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id, term_order) VALUES " . implode( ',', $values ) . ' ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)' );
+			}
+			if ( false === $result ) {
 				return new WP_Error( 'db_insert_error', __( 'Could not insert term relationship into the database.' ), $wpdb->last_error );
 			}
 		}

for me to get it working with some extensions and even wordpress alone I needed those changes

Can you be more specific as to what changes are necessary for wp-sqlite-db to continue working with WordPress core? Changes to WordPress core itself are obviously out of scope here ๐Ÿ˜„

Why don't you try by yourself run wordpress 6.1 with sqlite3 ans see it ?

The latest release of Wordpress is 6.0.2 as of today, and I am not able to get the plugin running, just copying the file.
Anyone succeeded with this version ?

I gave it a test and everything seemed to work fine for me. Maybe I'm missing something?

Assuming you have wp-cli and a compatible version of PHP installed, this script should work for you too using the very latest bleeding edge version of WordPress.

cd /tmp
mkdir test
cd test
wp core download --version=trunk
cd wp-content
wget https://raw.githubusercontent.com/aaemnnosttv/wp-sqlite-db/master/src/db.php
cd ..
wp config create --dbname=foo --dbuser=bar --skip-check
wp core install --url=http://localhost --title=Test --admin_user=admin --admin_email=admin@localhost.test --skip-email
wp server

Then open http://localhost:8080

image

php -r 'print_r(SQLite3::version());'
Array
(
    [versionString] => 3.38.3
    [versionNumber] => 3038003
)

This is a bare install of only WordPress core but it works as intended. There could be other plugins and configurations that are not compatible but that's not the same as saying this project does not work with WP 6.1 ๐Ÿ˜‰

I gave it a test and everything seemed to work fine for me. Maybe I'm missing something?

Assuming you have wp-cli and a compatible version of PHP installed, this script should work for you too using the very latest bleeding edge version of WordPress.

cd /tmp
mkdir test
cd test
wp core download --version=trunk
cd wp-content
wget https://raw.githubusercontent.com/aaemnnosttv/wp-sqlite-db/master/src/db.php
cd ..
wp config create --dbname=foo --dbuser=bar --skip-check
wp core install --url=http://localhost --title=Test --admin_user=admin --admin_email=admin@localhost.test --skip-email
wp server

Then open http://localhost:8080

image
php -r 'print_r(SQLite3::version());'
Array
(
    [versionString] => 3.38.3
    [versionNumber] => 3038003
)

This is a bare install of only WordPress core but it works as intended. There could be other plugins and configurations that are not compatible but that's not the same as saying this project does not work with WP 6.1 ๐Ÿ˜‰

Thank you very much for your detailed explanation, now it works. I was making an error generating the wp-config.php file, that's why the installation process was requiring the connection to MySQL database.