From 3fa094570272bc864d2c4c3b387e8fe0d9999311 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Wed, 21 Jun 2023 17:59:23 -0700 Subject: [PATCH 1/4] Remove SQLite module. --- modules/database/sqlite/activate.php | 179 -- modules/database/sqlite/admin.php | 89 - modules/database/sqlite/can-load.php | 37 - modules/database/sqlite/constants.php | 50 - modules/database/sqlite/db.copy.php | 28 - modules/database/sqlite/deactivate.php | 59 - modules/database/sqlite/load.php | 24 - modules/database/sqlite/site-health.php | 68 - .../class-perflab-sqlite-alter-query.php | 611 ------- .../class-perflab-sqlite-create-query.php | 497 ------ .../sqlite/class-perflab-sqlite-db.php | 330 ---- .../class-perflab-sqlite-object-array.php | 35 - .../class-perflab-sqlite-pdo-driver.php | 793 --------- .../class-perflab-sqlite-pdo-engine.php | 1527 ----------------- ...flab-sqlite-pdo-user-defined-functions.php | 781 --------- .../database/sqlite/wp-includes/sqlite/db.php | 54 - .../wp-includes/sqlite/install-functions.php | 212 --- phpcs.xml.dist | 2 - 18 files changed, 5376 deletions(-) delete mode 100644 modules/database/sqlite/activate.php delete mode 100644 modules/database/sqlite/admin.php delete mode 100644 modules/database/sqlite/can-load.php delete mode 100644 modules/database/sqlite/constants.php delete mode 100644 modules/database/sqlite/db.copy.php delete mode 100644 modules/database/sqlite/deactivate.php delete mode 100644 modules/database/sqlite/load.php delete mode 100644 modules/database/sqlite/site-health.php delete mode 100644 modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-alter-query.php delete mode 100644 modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-create-query.php delete mode 100644 modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-db.php delete mode 100644 modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-object-array.php delete mode 100644 modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-pdo-driver.php delete mode 100644 modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-pdo-engine.php delete mode 100644 modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-pdo-user-defined-functions.php delete mode 100644 modules/database/sqlite/wp-includes/sqlite/db.php delete mode 100644 modules/database/sqlite/wp-includes/sqlite/install-functions.php diff --git a/modules/database/sqlite/activate.php b/modules/database/sqlite/activate.php deleted file mode 100644 index 3a2e57e53e..0000000000 --- a/modules/database/sqlite/activate.php +++ /dev/null @@ -1,179 +0,0 @@ -touch( $destination ) ) { - - // Get the db.copy.php file contents, replace placeholders and write it to the destination. - $file_contents = str_replace( - '{SQLITE_IMPLEMENTATION_FOLDER_PATH}', - __DIR__, - file_get_contents( __DIR__ . '/db.copy.php' ) - ); - - $wp_filesystem->put_contents( $destination, $file_contents ); - } - } - - // Do not automatically set up SQLite DB on a multisite as that is notably - // more complex. Potentially it can be added in the future. - if ( is_multisite() ) { - return; - } - - // As an extra safety check, bail if the current user cannot update - // (or install) WordPress core. - if ( ! current_user_can( 'update_core' ) ) { - return; - } - - // Otherwise install WordPress in the SQLite database before the redirect, - // so that the user does not end up on the WordPress installation screen - // but rather remains in the Performance Lab modules screen. - add_filter( - 'wp_redirect', - static function( $redirect_location ) { - if ( ! defined( 'DATABASE_TYPE' ) ) { - define( 'DATABASE_TYPE', 'sqlite' ); - } - require_once __DIR__ . '/constants.php'; - - // If the SQLite DB already exists, simply ensure the module is - // active there. - if ( file_exists( FQDB ) ) { - require_once __DIR__ . '/wp-includes/sqlite/db.php'; - wp_set_wpdb_vars(); - global $wpdb; - $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", PERFLAB_MODULES_SETTING ) ); - if ( is_object( $row ) ) { - $value = maybe_unserialize( $row->option_value ); - if ( is_array( $value ) && ( ! isset( $value['database/sqlite'] ) || ! $value['database/sqlite']['enabled'] ) ) { - $value['database/sqlite'] = array( 'enabled' => true ); - $wpdb->update( $wpdb->options, array( 'option_value' => maybe_serialize( $value ) ), array( 'option_name' => PERFLAB_MODULES_SETTING ) ); - } - } - return $redirect_location; - } - - // Get current basic setup data to install WordPress in the new DB. - $blog_title = get_bloginfo( 'name' ); - $is_public = (bool) get_option( 'blog_public' ); - $language = get_option( 'WPLANG' ); - $admin_email = get_option( 'admin_email' ); - $admin_user = get_user_by( 'email', $admin_email ); - if ( ! $admin_user ) { - $admin_user = wp_get_current_user(); - } - - // Look up the data for the current user (in case they're not the - // admin email user). Additionally, attempt to keep them - // logged-in by retaining their current session. Depending on the - // site configuration, this is not 100% reliable as sites may store - // session tokens outside of user meta. However that does not lead - // to any problem, the user would simply be required to sign in - // again. - $current_user = wp_get_current_user(); - $current_user_sessions = get_user_meta( $current_user->ID, 'session_tokens', true ); - - // Get current data to keep the Performance Lab plugin and relevant - // modules active in the new DB. - $active_plugins_option = array( plugin_basename( PERFLAB_MAIN_FILE ) ); - $active_modules_option = get_option( PERFLAB_MODULES_SETTING, array() ); - - // Load and set up SQLite database. - require_once __DIR__ . '/wp-includes/sqlite/db.php'; - wp_set_wpdb_vars(); - - // Load WordPress installation API functions. - require_once ABSPATH . 'wp-admin/includes/upgrade.php'; - - // Install WordPress in the SQLite database with the same base - // configuration as the MySQL database. - // Since $admin_user->user_pass is already hashed, add a filter to - // ensure it is inserted into the database like that, instead of - // being re-hashed. - $unhash_user_pass = static function( $data, $update, $user_id, $userdata ) use ( $admin_user, $current_user ) { - // Double check this is actually the already hashed password, - // to prevent any chance of accidentally putting another - // password into the database which would then be plain text. - if ( - ! empty( $userdata['user_pass'] ) - && ( - $userdata['user_pass'] === $admin_user->user_pass - || $userdata['user_pass'] === $current_user->user_pass - ) - ) { - $data['user_pass'] = $userdata['user_pass']; - } - return $data; - }; - add_filter( 'wp_pre_insert_user_data', $unhash_user_pass, 10, 4 ); - wp_install( $blog_title, $admin_user->user_login, $admin_user->user_email, $is_public, '', $admin_user->user_pass, $language ); - // If the current user is not the admin user, create an account for that user too. - if ( $current_user->user_login !== $admin_user->user_login ) { - wp_create_user( $current_user->user_login, $current_user->user_pass, $current_user->user_email ); - } - remove_filter( 'wp_pre_insert_user_data', $unhash_user_pass ); - - // If the admin email was originally not attached to any user - // (e.g. when the original admin email user was deleted), reset - // the option to the original admin email again (by default - // `wp_install()` will set it to the same email as the initial - // admin user email). - if ( 0 !== strcasecmp( $admin_user->user_email, $admin_email ) ) { - update_option( 'admin_email', $admin_email ); - } - - // If user sessions are found, migrate them over so that the - // current user remains logged in. - if ( $current_user_sessions ) { - $session_user = get_user_by( 'login', $current_user->user_login ); - if ( $session_user ) { - update_user_meta( $session_user->ID, 'session_tokens', $current_user_sessions ); - } - } - - // Activate the Performance Lab plugin and its modules. - // Use direct database query for Performance Lab modules to - // prevent module activation logic from firing again. - update_option( 'active_plugins', $active_plugins_option ); - global $wpdb; - $wpdb->insert( - $wpdb->options, - array( - 'option_name' => PERFLAB_MODULES_SETTING, - 'option_value' => maybe_serialize( $active_modules_option ), - 'autoload' => 'yes', - ) - ); - - return $redirect_location; - } - ); -}; diff --git a/modules/database/sqlite/admin.php b/modules/database/sqlite/admin.php deleted file mode 100644 index c5c4a1253e..0000000000 --- a/modules/database/sqlite/admin.php +++ /dev/null @@ -1,89 +0,0 @@ -

%s

', - sprintf( - /* translators: 1: PERFLAB_SQLITE_DB_DROPIN_VERSION constant, 2: db.php drop-in path */ - __( 'The SQLite Integration module is active, but the %1$s constant is missing. It appears you already have another %2$s file present on your site. ', 'performance-lab' ), - 'PERFLAB_SQLITE_DB_DROPIN_VERSION', - '' . esc_html( basename( WP_CONTENT_DIR ) ) . '/db.php' - ) - ); - - return; - } - - // The dropin db.php is missing. - printf( - '

%s

', - sprintf( - /* translators: 1: db.php drop-in path, 2: Admin URL to deactivate the module */ - __( 'The SQLite Integration module is active, but the %1$s file is missing. Please deactivate the module and re-activate it to try again.', 'performance-lab' ), - '' . esc_html( basename( WP_CONTENT_DIR ) ) . '/db.php', - esc_url( admin_url( 'options-general.php?page=' . PERFLAB_MODULES_SCREEN ) ) - ) - ); -} -add_action( 'admin_notices', 'perflab_sqlite_plugin_admin_notice' ); // Add the admin notices. - -/** - * Adds a link to the admin bar. - * - * @since 2.0.0 - * - * @global wpdb $wpdb WordPress database abstraction object. - * - * @param WP_Admin_Bar $admin_bar The admin bar object. - */ -function perflab_sqlite_plugin_adminbar_item( $admin_bar ) { - global $wpdb; - - if ( defined( 'PERFLAB_SQLITE_DB_DROPIN_VERSION' ) && defined( 'DATABASE_TYPE' ) && 'sqlite' === DATABASE_TYPE ) { - $title = '' . __( 'Database: SQLite', 'performance-lab' ) . ''; - } elseif ( stripos( $wpdb->db_server_info(), 'maria' ) !== false ) { - $title = '' . __( 'Database: MariaDB', 'performance-lab' ) . ''; - } else { - $title = '' . __( 'Database: MySQL', 'performance-lab' ) . ''; - } - - $args = array( - 'id' => 'performance-lab-sqlite', - 'parent' => 'top-secondary', - 'title' => $title, - 'href' => esc_url( admin_url( 'options-general.php?page=' . PERFLAB_MODULES_SCREEN ) ), - 'meta' => false, - ); - $admin_bar->add_node( $args ); -} -add_action( 'admin_bar_menu', 'perflab_sqlite_plugin_adminbar_item', 999 ); diff --git a/modules/database/sqlite/can-load.php b/modules/database/sqlite/can-load.php deleted file mode 100644 index 2664120e40..0000000000 --- a/modules/database/sqlite/can-load.php +++ /dev/null @@ -1,37 +0,0 @@ -delete( WP_CONTENT_DIR . '/db.php' ); - } - } - - // Run an action on `shutdown`, to deactivate the option in the MySQL database. - add_action( - 'shutdown', - static function() { - global $table_prefix; - - // Get credentials for the MySQL database. - $dbuser = defined( 'DB_USER' ) ? DB_USER : ''; - $dbpassword = defined( 'DB_PASSWORD' ) ? DB_PASSWORD : ''; - $dbname = defined( 'DB_NAME' ) ? DB_NAME : ''; - $dbhost = defined( 'DB_HOST' ) ? DB_HOST : ''; - - // Init a connection to the MySQL database. - $wpdb_mysql = new wpdb( $dbuser, $dbpassword, $dbname, $dbhost ); - $wpdb_mysql->set_prefix( $table_prefix ); - - // Get the perflab options, remove the database/sqlite module and update the option. - $row = $wpdb_mysql->get_row( $wpdb_mysql->prepare( "SELECT option_value FROM $wpdb_mysql->options WHERE option_name = %s LIMIT 1", PERFLAB_MODULES_SETTING ) ); - if ( is_object( $row ) ) { - $value = maybe_unserialize( $row->option_value ); - if ( is_array( $value ) && isset( $value['database/sqlite'] ) ) { - unset( $value['database/sqlite'] ); - $wpdb_mysql->update( $wpdb_mysql->options, array( 'option_value' => maybe_serialize( $value ) ), array( 'option_name' => PERFLAB_MODULES_SETTING ) ); - } - } - } - ); -}; diff --git a/modules/database/sqlite/load.php b/modules/database/sqlite/load.php deleted file mode 100644 index 1bbd069fe2..0000000000 --- a/modules/database/sqlite/load.php +++ /dev/null @@ -1,24 +0,0 @@ - 'DATABASE_TYPE', - 'value' => ( defined( 'DATABASE_TYPE' ) ? DATABASE_TYPE : __( 'Undefined', 'performance-lab' ) ), - 'debug' => ( defined( 'DATABASE_TYPE' ) ? DATABASE_TYPE : 'undefined' ), - ); - - $info['wp-database']['fields']['database_type'] = array( - 'label' => __( 'Database type', 'performance-lab' ), - 'value' => 'sqlite' === $database_type ? 'SQLite' : 'MySQL/MariaDB', - ); - - if ( 'sqlite' === $database_type ) { - $info['wp-database']['fields']['database_version'] = array( - 'label' => __( 'SQLite version', 'performance-lab' ), - 'value' => class_exists( 'SQLite3' ) ? SQLite3::version()['versionString'] : null, - ); - - $info['wp-database']['fields']['database_file'] = array( - 'label' => __( 'Database file', 'performance-lab' ), - 'value' => FQDB, - 'private' => true, - ); - - $info['wp-database']['fields']['database_size'] = array( - 'label' => __( 'Database size', 'performance-lab' ), - 'value' => size_format( filesize( FQDB ) ), - ); - - unset( $info['wp-database']['fields']['extension'] ); - unset( $info['wp-database']['fields']['server_version'] ); - unset( $info['wp-database']['fields']['client_version'] ); - unset( $info['wp-database']['fields']['database_host'] ); - unset( $info['wp-database']['fields']['database_user'] ); - unset( $info['wp-database']['fields']['database_name'] ); - unset( $info['wp-database']['fields']['database_charset'] ); - unset( $info['wp-database']['fields']['database_collate'] ); - unset( $info['wp-database']['fields']['max_allowed_packet'] ); - unset( $info['wp-database']['fields']['max_connections'] ); - } - - return $info; -} -add_filter( 'debug_information', 'perflab_sqlite_plugin_filter_debug_data' ); // Filter debug data in site-health screen. diff --git a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-alter-query.php b/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-alter-query.php deleted file mode 100644 index d9909732fa..0000000000 --- a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-alter-query.php +++ /dev/null @@ -1,611 +0,0 @@ -_query = 'SELECT 1=1'; - return $this->_query; - } - - $tmp_query = array(); - $re_command = ''; - $command = str_ireplace( $match[0], '', $query ); - $tmp_tokens['query_type'] = trim( $match[1] ); - $tmp_tokens['table_name'] = trim( $match[2] ); - $command_array = explode( ',', $command ); - - $single_command = array_shift( $command_array ); - if ( ! empty( $command_array ) ) { - $re_command = "ALTER TABLE {$tmp_tokens['table_name']} "; - $re_command .= implode( ',', $command_array ); - } - $command_tokens = $this->command_tokenizer( $single_command ); - if ( empty( $command_tokens ) ) { - $this->_query = 'SELECT 1=1'; - return $this->_query; - } - $tokens = array_merge( $tmp_tokens, $command_tokens ); - $command_name = strtolower( $tokens['command'] ); - switch ( $command_name ) { - case 'add column': - case 'rename to': - case 'add index': - case 'drop index': - $tmp_query = $this->handle_single_command( $tokens ); - break; - - case 'add primary key': - $tmp_query = $this->handle_add_primary_key( $tokens ); - break; - - case 'drop primary key': - $tmp_query = $this->handle_drop_primary_key( $tokens ); - break; - - case 'modify column': - $tmp_query = $this->handle_modify_command( $tokens ); - break; - - case 'change column': - $tmp_query = $this->handle_change_command( $tokens ); - break; - - case 'alter column': - $tmp_query = $this->handle_alter_command( $tokens ); - break; - - default: - break; - } - if ( ! is_array( $tmp_query ) ) { - $this->_query[] = $tmp_query; - } else { - $this->_query = $tmp_query; - } - if ( '' !== $re_command ) { - $this->_query = array_merge( $this->_query, array( 'recursion' => $re_command ) ); - } - - return $this->_query; - } - - /** - * Function to analyze ALTER TABLE command and sets the data to an array. - * - * @param string $command The command string. - * - * @return array - * @access private - */ - private function command_tokenizer( $command ) { - $tokens = array(); - $pattern = '/^(ADD|DROP|RENAME|MODIFY|CHANGE|ALTER)\\s*(\\w+)?\\s*(\\w+(\(.+\)|))?\\s*/ims'; - if ( preg_match( $pattern, $command, $match ) ) { - $the_rest = str_ireplace( $match[0], '', $command ); - $match_1 = trim( $match[1] ); - $match_2 = trim( $match[2] ); - $match_3 = isset( $match[3] ) ? trim( $match[3] ) : ''; - switch ( strtolower( $match_1 ) ) { - case 'add': - if ( in_array( strtolower( $match_2 ), array( 'fulltext', 'constraint', 'foreign' ), true ) ) { - break; - } - - if ( stripos( 'column', $match_2 ) !== false ) { - $tokens['command'] = $match_1 . ' ' . $match_2; - $tokens['column_name'] = $match_3; - $tokens['column_def'] = trim( $the_rest ); - } elseif ( stripos( 'primary', $match_2 ) !== false ) { - $tokens['command'] = $match_1 . ' ' . $match_2 . ' ' . $match_3; - $tokens['column_name'] = $the_rest; - } elseif ( stripos( 'unique', $match_2 ) !== false ) { - list($index_name, $col_name) = preg_split( '/[\(\)]/s', trim( $the_rest ), -1, PREG_SPLIT_DELIM_CAPTURE ); - $tokens['unique'] = true; - $tokens['command'] = $match_1 . ' ' . $match_3; - $tokens['index_name'] = trim( $index_name ); - $tokens['column_name'] = '(' . trim( $col_name ) . ')'; - } elseif ( in_array( strtolower( $match_2 ), array( 'index', 'key' ), true ) ) { - $tokens['command'] = $match_1 . ' ' . $match_2; - $tokens['index_name'] = $match_3; - if ( '' === $match_3 ) { - $tokens['index_name'] = str_replace( array( '(', ')' ), '', $the_rest ); - } - $tokens['column_name'] = trim( $the_rest ); - } else { - $tokens['command'] = $match_1 . ' COLUMN'; - $tokens['column_name'] = $match_2; - $tokens['column_def'] = $match_3 . ' ' . $the_rest; - } - break; - - case 'drop': - if ( stripos( 'column', $match_2 ) !== false ) { - $tokens['command'] = $match_1 . ' ' . $match_2; - $tokens['column_name'] = trim( $match_3 ); - } elseif ( stripos( 'primary', $match_2 ) !== false ) { - $tokens['command'] = $match_1 . ' ' . $match_2 . ' ' . $match_3; - } elseif ( in_array( strtolower( $match_2 ), array( 'index', 'key' ), true ) ) { - $tokens['command'] = $match_1 . ' ' . $match_2; - $tokens['index_name'] = $match_3; - } elseif ( stripos( 'primary', $match_2 ) !== false ) { - $tokens['command'] = $match_1 . ' ' . $match_2 . ' ' . $match_3; - } else { - $tokens['command'] = $match_1 . ' COLUMN'; - $tokens['column_name'] = $match_2; - } - break; - - case 'rename': - if ( stripos( 'to', $match_2 ) !== false ) { - $tokens['command'] = $match_1 . ' ' . $match_2; - $tokens['column_name'] = $match_3; - } else { - $tokens['command'] = $match_1 . ' TO'; - $tokens['column_name'] = $match_2; - } - break; - - case 'modify': - if ( stripos( 'column', $match_2 ) !== false ) { - $tokens['command'] = $match_1 . ' ' . $match_2; - $tokens['column_name'] = $match_3; - $tokens['column_def'] = trim( $the_rest ); - } else { - $tokens['command'] = $match_1 . ' COLUMN'; - $tokens['column_name'] = $match_2; - $tokens['column_def'] = $match_3 . ' ' . trim( $the_rest ); - } - break; - - case 'change': - $the_rest = trim( $the_rest ); - if ( stripos( 'column', $match_2 ) !== false ) { - $tokens['command'] = $match_1 . ' ' . $match_2; - $tokens['old_column'] = $match_3; - list($new_col) = explode( ' ', $the_rest ); - $tmp_col = preg_replace( '/\(.+?\)/im', '', $new_col ); - if ( array_key_exists( strtolower( $tmp_col ), $this->array_types ) ) { - $tokens['column_def'] = $the_rest; - } else { - $tokens['new_column'] = $new_col; - $col_def = str_replace( $new_col, '', $the_rest ); - $tokens['column_def'] = trim( $col_def ); - } - } else { - $tokens['command'] = $match_1 . ' column'; - $tokens['old_column'] = $match_2; - $tmp_col = preg_replace( '/\(.+?\)/im', '', $match_3 ); - if ( array_key_exists( strtolower( $tmp_col ), $this->array_types ) ) { - $tokens['column_def'] = $match_3 . ' ' . $the_rest; - } else { - $tokens['new_column'] = $match_3; - $tokens['column_def'] = $the_rest; - } - } - break; - - case 'alter': - $tokens['default_command'] = 'DROP DEFAULT'; - if ( stripos( 'column', $match_2 ) !== false ) { - $tokens['command'] = $match_1 . ' ' . $match_2; - $tokens['column_name'] = $match_3; - list($set_or_drop) = explode( ' ', $the_rest ); - if ( stripos( 'set', $set_or_drop ) !== false ) { - $tokens['default_command'] = 'SET DEFAULT'; - $default_value = str_ireplace( 'set default', '', $the_rest ); - $tokens['default_value'] = trim( $default_value ); - } - } else { - $tokens['command'] = $match_1 . ' COLUMN'; - $tokens['column_name'] = $match_2; - if ( stripos( 'set', $match_3 ) !== false ) { - $tokens['default_command'] = 'SET DEFAULT'; - $default_value = str_ireplace( 'default', '', $the_rest ); - $tokens['default_value'] = trim( $default_value ); - } - } - break; - - default: - break; - } - } - return $tokens; - } - - /** - * Function to handle single command. - * - * @access private - * - * @param array $queries An array of string queries. - * - * @return string - */ - private function handle_single_command( $queries ) { - $tokenized_query = $queries; - - // Command is "add column". - if ( stripos( $tokenized_query['command'], 'add column' ) !== false ) { - $column_def = $this->convert_field_types( $tokenized_query['column_name'], $tokenized_query['column_def'] ); - return "ALTER TABLE {$tokenized_query['table_name']} ADD COLUMN {$tokenized_query['column_name']} $column_def"; - } - - // Command is "rename". - if ( stripos( $tokenized_query['command'], 'rename' ) !== false ) { - return "ALTER TABLE {$tokenized_query['table_name']} RENAME TO {$tokenized_query['column_name']}"; - } - - // Command is "add index". - if ( stripos( $tokenized_query['command'], 'add index' ) !== false ) { - $unique = isset( $tokenized_query['unique'] ) ? 'UNIQUE' : ''; - return "CREATE $unique INDEX IF NOT EXISTS {$tokenized_query['index_name']} ON {$tokenized_query['table_name']} {$tokenized_query['column_name']}"; - } - - // Command is "drop index". - if ( stripos( $tokenized_query['command'], 'drop index' ) !== false ) { - return "DROP INDEX IF EXISTS {$tokenized_query['index_name']}"; - } - - // Fallback. - return 'SELECT 1=1'; - } - - /** - * Function to handle ADD PRIMARY KEY. - * - * @access private - * - * @param array $queries An array of string queries. - * - * @return array - */ - private function handle_add_primary_key( $queries ) { - $tokenized_query = $queries; - $tbl_name = $tokenized_query['table_name']; - $temp_table = 'temp_' . $tokenized_query['table_name']; - $query_obj = ( new Perflab_SQLite_DB() )->get_results( "SELECT sql FROM sqlite_master WHERE tbl_name='$tbl_name'" ); - for ( $i = 0; $i < count( $query_obj ); $i++ ) { - $index_queries[ $i ] = $query_obj[ $i ]->sql; - } - $table_query = ", PRIMARY KEY {$tokenized_query['column_name']}"; - $query = array( - $table_query, - "INSERT INTO $temp_table SELECT * FROM {$tokenized_query['table_name']}", - "DROP TABLE IF EXISTS {$tokenized_query['table_name']}", - "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}", - ); - - foreach ( $index_queries as $index ) { - $query[] = $index; - } - - return $query; - } - - /** - * Function to handle DROP PRIMARY KEY. - * - * @access private - * - * @param array $queries An of string $queries. - * - * @return array - */ - private function handle_drop_primary_key( $queries ) { - $tokenized_query = $queries; - $temp_table = 'temp_' . $tokenized_query['table_name']; - $query_obj = ( new Perflab_SQLite_DB() )->get_results( "SELECT sql FROM sqlite_master WHERE tbl_name='{$tokenized_query['table_name']}'" ); - for ( $i = 0; $i < count( $query_obj ); $i++ ) { - $index_queries[ $i ] = $query_obj[ $i ]->sql; - } - $table_query = array_shift( $index_queries ); - $pattern1 = '/^\\s*PRIMARY\\s*KEY\\s*\(.*\)/im'; - $pattern2 = '/^\\s*.*(PRIMARY\\s*KEY\\s*(:?AUTOINCREMENT|))\\s*(?!\()/im'; - if ( preg_match( $pattern1, $table_query, $match ) ) { - $table_query = str_replace( $match[0], '', $table_query ); - } elseif ( preg_match( $pattern2, $table_query, $match ) ) { - $table_query = str_replace( $match[1], '', $table_query ); - } - $table_query = str_replace( $tokenized_query['table_name'], $temp_table, $table_query ); - $query = array( - $table_query, - "INSERT INTO $temp_table SELECT * FROM {$tokenized_query['table_name']}", - "DROP TABLE IF EXISTS {$tokenized_query['table_name']}", - "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}", - ); - foreach ( $index_queries as $index ) { - $query[] = $index; - } - - return $query; - } - - /** - * Function to handle MODIFY COLUMN. - * - * @access private - * - * @param array $queries An array of string queries. - * - * @return string|array - */ - private function handle_modify_command( $queries ) { - $tokenized_query = $queries; - $temp_table = 'temp_' . $tokenized_query['table_name']; - $column_def = $this->convert_field_types( $tokenized_query['column_name'], $tokenized_query['column_def'] ); - $query_obj = ( new Perflab_SQLite_DB() )->get_results( "SELECT sql FROM sqlite_master WHERE tbl_name='{$tokenized_query['table_name']}'" ); - for ( $i = 0; $i < count( $query_obj ); $i++ ) { - $index_queries[ $i ] = $query_obj[ $i ]->sql; - } - $create_query = array_shift( $index_queries ); - if ( stripos( $create_query, $tokenized_query['column_name'] ) === false ) { - return 'SELECT 1=1'; - } - $pattern = "/{$tokenized_query['column_name']}\\s*{$column_def}\\s*[,)]/i"; - if ( preg_match( $pattern, $create_query ) ) { - return 'SELECT 1=1'; - } - $pattern_1 = "/{$tokenized_query['table_name']}/i"; - $pattern_2 = "/\\b{$tokenized_query['column_name']}\\s*.*(?=,)/ims"; - $pattern_3 = "/\\b{$tokenized_query['column_name']}\\s*.*(?=\))/ims"; - - $create_query = preg_replace( $pattern_1, $temp_table, $create_query ); - if ( preg_match( $pattern_2, $create_query ) ) { - $create_query = preg_replace( $pattern_2, "{$tokenized_query['column_name']} {$column_def}", $create_query ); - } elseif ( preg_match( $pattern_3, $create_query ) ) { - $create_query = preg_replace( $pattern_3, "{$tokenized_query['column_name']} {$column_def}", $create_query ); - } - $query = array( - $create_query, - "INSERT INTO $temp_table SELECT * FROM {$tokenized_query['table_name']}", - "DROP TABLE IF EXISTS {$tokenized_query['table_name']}", - "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}", - ); - foreach ( $index_queries as $index ) { - $query[] = $index; - } - - return $query; - } - - /** - * Function to handle CHANGE COLUMN. - * - * @access private - * - * @param array $queries An array of string queries. - * - * @return string|array - */ - private function handle_change_command( $queries ) { - $col_check = false; - $old_fields = ''; - $tokenized_query = $queries; - $temp_table = 'temp_' . $tokenized_query['table_name']; - $column_name = $tokenized_query['old_column']; - if ( isset( $tokenized_query['new_column'] ) ) { - $column_name = $tokenized_query['new_column']; - } - $column_def = $this->convert_field_types( $column_name, $tokenized_query['column_def'] ); - $col_obj = ( new Perflab_SQLite_DB() )->get_results( "SHOW COLUMNS FROM {$tokenized_query['table_name']}" ); - foreach ( $col_obj as $col ) { - if ( stripos( $col->Field, $tokenized_query['old_column'] ) !== false ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase - $col_check = true; - } - $old_fields .= $col->Field . ','; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase - } - if ( false === $col_check ) { - return 'SELECT 1=1'; - } - $old_fields = rtrim( $old_fields, ',' ); - $new_fields = str_ireplace( $tokenized_query['old_column'], $column_name, $old_fields ); - $query_obj = ( new Perflab_SQLite_DB() )->get_results( "SELECT sql FROM sqlite_master WHERE tbl_name='{$tokenized_query['table_name']}'" ); - for ( $i = 0; $i < count( $query_obj ); $i++ ) { - $index_queries[ $i ] = $query_obj[ $i ]->sql; - } - $create_query = array_shift( $index_queries ); - $create_query = preg_replace( "/{$tokenized_query['table_name']}/i", $temp_table, $create_query ); - - $pattern_1 = "/\\b{$tokenized_query['old_column']}\\s*(.+?)(?=,)/ims"; - $pattern_2 = "/\\b{$tokenized_query['old_column']}\\s*(.+?)(?=\))/ims"; - if ( preg_match( $pattern_1, $create_query, $match ) ) { - if ( stripos( trim( $match[1] ), $column_def ) !== false ) { - return 'SELECT 1=1'; - } - $pattern = "/\\b{$tokenized_query['old_column']}\\s*.+?(?=,)/ims"; - $create_query = preg_replace( $pattern, "{$column_name} {$column_def}", $create_query, 1 ); - } elseif ( preg_match( $pattern_2, $create_query, $match ) ) { - if ( stripos( trim( $match[1] ), $column_def ) !== false ) { - return 'SELECT 1=1'; - } - $pattern = "/\\b{$tokenized_query['old_column']}\\s*.*(?=\))/ims"; - $create_query = preg_replace( $pattern, "{$column_name} {$column_def}", $create_query, 1 ); - } - $query = array( - $create_query, - "INSERT INTO $temp_table ($new_fields) SELECT $old_fields FROM {$tokenized_query['table_name']}", - "DROP TABLE IF EXISTS {$tokenized_query['table_name']}", - "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}", - ); - foreach ( $index_queries as $index ) { - $query[] = $index; - } - - return $query; - } - - /** - * Function to handle ALTER COLUMN. - * - * @access private - * - * @param array $queries An array of string queries. - * - * @return string|array - */ - private function handle_alter_command( $queries ) { - $tokenized_query = $queries; - $temp_table = 'temp_' . $tokenized_query['table_name']; - $def_value = null; - if ( isset( $tokenized_query['default_value'] ) ) { - $def_value = $this->convert_field_types( $tokenized_query['column_name'], $tokenized_query['default_value'] ); - $def_value = 'DEFAULT ' . $def_value; - } - $query_obj = ( new Perflab_SQLite_DB() )->get_results( "SELECT sql FROM sqlite_master WHERE tbl_name='{$tokenized_query['table_name']}'" ); - for ( $i = 0; $i < count( $query_obj ); $i++ ) { - $index_queries[ $i ] = $query_obj[ $i ]->sql; - } - $create_query = array_shift( $index_queries ); - if ( stripos( $create_query, $tokenized_query['column_name'] ) === false ) { - return 'SELECT 1=1'; - } - $pattern_1 = "/\\s*({$tokenized_query['column_name']})\\s*(.*)?(DEFAULT\\s*.*)[,)]/im"; - $pattern_2 = "/\\s*({$tokenized_query['column_name']})\\s*(.*)?[,)]/im"; - if ( preg_match( $pattern_1, $create_query, $match ) ) { - $col_name = trim( $match[1] ); - $col_def = trim( $match[2] ); - $col_def_esc = str_replace( array( '(', ')' ), array( '\(', '\)' ), $col_def ); - $checked_col_def = $this->convert_field_types( $col_name, $col_def ); - $old_default = trim( $match[3] ); - $replacement = $col_name . ' ' . $checked_col_def; - if ( ! is_null( $def_value ) ) { - $replacement .= ' ' . $def_value; - } - $pattern = "/$col_name\\s*$col_def_esc\\s*$old_default/im"; - $create_query = preg_replace( $pattern, $replacement, $create_query ); - $create_query = str_ireplace( $tokenized_query['table_name'], $temp_table, $create_query ); - } elseif ( preg_match( $pattern_2, $create_query, $match ) ) { - $col_name = trim( $match[1] ); - $col_def = trim( $match[2] ); - $col_def_esc = str_replace( array( '(', ')' ), array( '\(', '\)' ), $col_def ); - $checked_col_def = $this->convert_field_types( $col_name, $col_def ); - $replacement = $col_name . ' ' . $checked_col_def; - if ( ! is_null( $def_value ) ) { - $replacement .= ' ' . $def_value; - } - $pattern = "/$col_name\\s*$col_def_esc/im"; - $create_query = preg_replace( $pattern, $replacement, $create_query ); - $create_query = str_ireplace( $tokenized_query['table_name'], $temp_table, $create_query ); - } else { - return 'SELECT 1=1'; - } - $query = array( - $create_query, - "INSERT INTO $temp_table SELECT * FROM {$tokenized_query['table_name']}", - "DROP TABLE IF EXISTS {$tokenized_query['table_name']}", - "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}", - ); - foreach ( $index_queries as $index ) { - $query[] = $index; - } - - return $query; - } - - /** - * Function to change the field definition to SQLite compatible data type. - * - * @access private - * - * @param string $col_name Column name. - * @param string $col_def Column definition. - * - * @return string - */ - private function convert_field_types( $col_name, $col_def ) { - $array_curtime = array( 'current_timestamp', 'current_time', 'current_date' ); - $array_reptime = array( "'0000-00-00 00:00:00'", "'0000-00-00 00:00:00'", "'0000-00-00'" ); - $def_string = str_replace( '`', '', $col_def ); - foreach ( $this->array_types as $o => $r ) { - $pattern = "/\\b$o\\s*(\([^\)]*\)*)?\\s*/ims"; - if ( preg_match( $pattern, $def_string ) ) { - $def_string = preg_replace( $pattern, "$r ", $def_string ); - break; - } - } - $def_string = preg_replace( '/unsigned/im', '', $def_string ); - $def_string = preg_replace( '/auto_increment/im', 'PRIMARY KEY AUTOINCREMENT', $def_string ); - // When you use ALTER TABLE ADD, you can't use current_*. so we replace. - $def_string = str_ireplace( $array_curtime, $array_reptime, $def_string ); - // This is enum. - $pattern_enum = '/enum\((.*?)\)([^,\)]*)/ims'; - if ( preg_match( $pattern_enum, $col_def, $matches ) ) { - $def_string = 'TEXT' . $matches[2] . ' CHECK (' . $col_name . ' IN (' . $matches[1] . '))'; - } - - return $def_string; - } - - /** - * Variable to store the data definition table. - * - * @access private - * @var associative array - */ - private $array_types = array( - 'bit' => 'INTEGER', - 'bool' => 'INTEGER', - 'boolean' => 'INTEGER', - 'tinyint' => 'INTEGER', - 'smallint' => 'INTEGER', - 'mediumint' => 'INTEGER', - 'bigint' => 'INTEGER', - 'integer' => 'INTEGER', - 'int' => 'INTEGER', - 'float' => 'REAL', - 'double' => 'REAL', - 'decimal' => 'REAL', - 'dec' => 'REAL', - 'numeric' => 'REAL', - 'fixed' => 'REAL', - 'datetime' => 'TEXT', - 'date' => 'TEXT', - 'timestamp' => 'TEXT', - 'time' => 'TEXT', - 'year' => 'TEXT', - 'varchar' => 'TEXT', - 'char' => 'TEXT', - 'varbinary' => 'BLOB', - 'binary' => 'BLOB', - 'tinyblob' => 'BLOB', - 'mediumblob' => 'BLOB', - 'longblob' => 'BLOB', - 'blob' => 'BLOB', - 'tinytext' => 'TEXT', - 'mediumtext' => 'TEXT', - 'longtext' => 'TEXT', - 'text' => 'TEXT', - ); -} diff --git a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-create-query.php b/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-create-query.php deleted file mode 100644 index c9823d655f..0000000000 --- a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-create-query.php +++ /dev/null @@ -1,497 +0,0 @@ -_query = $query; - $this->_errors [] = ''; - if ( preg_match( '/^CREATE\\s*(UNIQUE|FULLTEXT|)\\s*INDEX/ims', $this->_query, $match ) ) { - // We manipulate CREATE INDEX query in the Perflab_SQLite_PDO_Engine class. - // FULLTEXT index creation is simply ignored. - if ( isset( $match[1] ) && stripos( $match[1], 'fulltext' ) !== false ) { - return 'SELECT 1=1'; - } - return $this->_query; - } - if ( preg_match( '/^CREATE\\s*(TEMP|TEMPORARY|)\\s*TRIGGER\\s*/im', $this->_query ) ) { - // If WordPress comes to use foreign key constraint, trigger will be needed. - // We don't use it for now. - return $this->_query; - } - $this->strip_backticks(); - $this->quote_illegal_field(); - $this->get_table_name(); - $this->rewrite_comments(); - $this->rewrite_field_types(); - $this->rewrite_character_set(); - $this->rewrite_engine_info(); - $this->rewrite_unsigned(); - $this->rewrite_autoincrement(); - $this->rewrite_primary_key(); - $this->rewrite_foreign_key(); - $this->rewrite_unique_key(); - $this->rewrite_enum(); - $this->rewrite_set(); - $this->rewrite_key(); - $this->add_if_not_exists(); - - return $this->post_process(); - } - - /** - * Method to get table name from the query string. - * - * 'IF NOT EXISTS' clause is removed for the easy regular expression usage. - * It will be added at the end of the process. - * - * @access private - */ - private function get_table_name() { - // $pattern = '/^\\s*CREATE\\s*(TEMP|TEMPORARY)?\\s*TABLE\\s*(IF NOT EXISTS)?\\s*([^\(]*)/imsx'; - $pattern = '/^\\s*CREATE\\s*(?:TEMP|TEMPORARY)?\\s*TABLE\\s*(?:IF\\s*NOT\\s*EXISTS)?\\s*([^\(]*)/imsx'; - if ( preg_match( $pattern, $this->_query, $matches ) ) { - $this->table_name = trim( $matches[1] ); - } - } - - /** - * Method to change the MySQL field types to SQLite compatible types. - * - * If column name is the same as the key value, e.g. "date" or "timestamp", - * and the column is on the top of the line, we add a single quote and avoid - * to be replaced. But this doesn't work if that column name is in the middle - * of the line. - * Order of the key value is important. Don't change it. - * - * @access private - */ - private function rewrite_field_types() { - $array_types = array( - 'bit' => 'integer', - 'bool' => 'integer', - 'boolean' => 'integer', - 'tinyint' => 'integer', - 'smallint' => 'integer', - 'mediumint' => 'integer', - 'int' => 'integer', - 'integer' => 'integer', - 'bigint' => 'integer', - 'float' => 'real', - 'double' => 'real', - 'decimal' => 'real', - 'dec' => 'real', - 'numeric' => 'real', - 'fixed' => 'real', - 'date' => 'text', - 'datetime' => 'text', - 'timestamp' => 'text', - 'time' => 'text', - 'year' => 'text', - 'char' => 'text', - 'varchar' => 'text', - 'binary' => 'integer', - 'varbinary' => 'blob', - 'tinyblob' => 'blob', - 'tinytext' => 'text', - 'blob' => 'blob', - 'text' => 'text', - 'mediumblob' => 'blob', - 'mediumtext' => 'text', - 'longblob' => 'blob', - 'longtext' => 'text', - ); - foreach ( $array_types as $o => $r ) { - if ( preg_match( "/^\\s*(?_query, $match ) ) { - $ptrn = "/$match[1]/im"; - $replaced = str_ireplace( $ptrn, '#placeholder#', $this->_query ); - $replaced = str_ireplace( $o, "'{$o}'", $replaced ); - $this->_query = str_replace( '#placeholder#', $ptrn, $replaced ); - } - $pattern = "/\\b(?_query ) ) { - // ; - } else { - $this->_query = preg_replace( $pattern, " $r ", $this->_query ); - } - } - } - - /** - * Method for stripping the comments from the SQL statement. - * - * @access private - */ - private function rewrite_comments() { - $this->_query = preg_replace( - '/# --------------------------------------------------------/', - '-- ******************************************************', - $this->_query - ); - $this->_query = preg_replace( '/#/', '--', $this->_query ); - } - - /** - * Method for stripping the engine and other stuffs. - * - * TYPE, ENGINE and AUTO_INCREMENT are removed here. - * - * @access private - */ - private function rewrite_engine_info() { - $this->_query = preg_replace( '/\\s*(TYPE|ENGINE)\\s*=\\s*.*(?_query ); - $this->_query = preg_replace( '/ AUTO_INCREMENT\\s*=\\s*[0-9]*/ims', '', $this->_query ); - } - - /** - * Method for stripping unsigned. - * - * SQLite doesn't have unsigned int data type. So UNSIGNED INT(EGER) is converted - * to INTEGER here. - * - * @access private - */ - private function rewrite_unsigned() { - $this->_query = preg_replace( '/\\bunsigned\\b/ims', ' ', $this->_query ); - } - - /** - * Method for rewriting primary key auto_increment. - * - * If the field type is 'INTEGER PRIMARY KEY', it is automatically autoincremented - * by SQLite. There's a little difference between PRIMARY KEY and AUTOINCREMENT, so - * we may well convert to PRIMARY KEY only. - * - * @access private - */ - private function rewrite_autoincrement() { - $this->_query = preg_replace( - '/\\bauto_increment\\s*primary\\s*key\\s*(,)?/ims', - ' PRIMARY KEY AUTOINCREMENT \\1', - $this->_query, - -1, - $count - ); - $this->_query = preg_replace( - '/\\bauto_increment\\b\\s*(,)?/ims', - ' PRIMARY KEY AUTOINCREMENT $1', - $this->_query, - -1, - $count - ); - if ( $count > 0 ) { - $this->has_primary_key = true; - } - } - - /** - * Method for rewriting primary key. - * - * @access private - */ - private function rewrite_primary_key() { - if ( $this->has_primary_key ) { - $this->_query = preg_replace( '/\\s*primary key\\s*.*?\([^\)]*\)\\s*(,|)/i', ' ', $this->_query ); - } else { - // If primary key has an index name, we remove that name. - $this->_query = preg_replace( '/\\bprimary\\s*key\\s*.*?\\s*(\(.*?\))/im', 'PRIMARY KEY \\1', $this->_query ); - } - } - - /** - * Method for rewriting foreign key. - * - * @access private - */ - private function rewrite_foreign_key() { - $pattern = '/\\s*foreign\\s*key\\s*(|.*?)\([^\)]+?\)\\s*references\\s*.*/i'; - if ( preg_match_all( $pattern, $this->_query, $match ) ) { - if ( isset( $match[1] ) ) { - $this->_query = str_ireplace( $match[1], '', $this->_query ); - } - } - } - - /** - * Method for rewriting unique key. - * - * @access private - */ - private function rewrite_unique_key() { - $this->_query = preg_replace_callback( - '/\\bunique key\\b([^\(]*)(\(.*\))/im', - array( $this, '_rewrite_unique_key' ), - $this->_query - ); - } - - /** - * Callback method for rewrite_unique_key. - * - * @access private - * - * @param array $matches An array of matches from the Regex. - * @return string - */ - private function _rewrite_unique_key( $matches ) { - $index_name = trim( $matches[1] ); - $col_name = trim( $matches[2] ); - $tbl_name = $this->table_name; - if ( preg_match( '/\(\\d+?\)/', $col_name ) ) { - $col_name = preg_replace( '/\(\\d+?\)/', '', $col_name ); - } - $_wpdb = new Perflab_SQLite_DB(); - $results = $_wpdb->get_results( "SELECT name FROM sqlite_master WHERE type='index'" ); - $_wpdb = null; - if ( $results ) { - foreach ( $results as $result ) { - if ( $result->name === $index_name ) { - $r = rand( 0, 50 ); - $index_name = $index_name . "_$r"; - break; - } - } - } - $index_name = str_replace( ' ', '', $index_name ); - $this->index_queries[] = "CREATE UNIQUE INDEX $index_name ON " . $tbl_name . $col_name; - - return ''; - } - - /** - * Method for handling ENUM fields. - * - * SQLite doesn't support enum, so we change it to check constraint. - * - * @access private - */ - private function rewrite_enum() { - $pattern = '/(,|\))([^,]*)enum\((.*?)\)([^,\)]*)/ims'; - $this->_query = preg_replace_callback( $pattern, array( $this, '_rewrite_enum' ), $this->_query ); - } - - /** - * Call back method for rewrite_enum() and rewrite_set(). - * - * @access private - * - * @param array $matches An array of matches from the Regex. - * - * @return string - */ - private function _rewrite_enum( $matches ) { - $output = $matches[1] . ' ' . $matches[2] . ' TEXT ' . $matches[4] . ' CHECK (' . $matches[2] . ' IN (' . $matches[3] . ')) '; - - return $output; - } - - /** - * Method for rewriting usage of set. - * - * It is similar but not identical to enum. SQLite does not support either. - * - * @access private - */ - private function rewrite_set() { - $pattern = '/\b(\w)*\bset\\s*\((.*?)\)\\s*(.*?)(,)*/ims'; - $this->_query = preg_replace_callback( $pattern, array( $this, '_rewrite_enum' ), $this->_query ); - } - - /** - * Method for rewriting usage of key to create an index. - * - * SQLite cannot create non-unique indices as part of the create query, - * so we need to create an index by hand and append it to the create query. - * - * @access private - */ - private function rewrite_key() { - $this->_query = preg_replace_callback( - '/,\\s*(KEY|INDEX)\\s*(\\w+)?\\s*(\(.+\))/im', - array( $this, '_rewrite_key' ), - $this->_query - ); - } - - /** - * Callback method for rewrite_key. - * - * @param array $matches an array of matches from the Regex. - * - * @access private - * @return string - */ - private function _rewrite_key( $matches ) { - $index_name = trim( $matches[2] ); - $col_name = trim( $matches[3] ); - if ( preg_match( '/\([0-9]+?\)/', $col_name, $match ) ) { - $col_name = preg_replace_callback( '/\([0-9]+?\)/', array( $this, '_remove_length' ), $col_name ); - } - $tbl_name = $this->table_name; - $_wpdb = new Perflab_SQLite_DB(); - $results = $_wpdb->get_results( "SELECT name FROM sqlite_master WHERE type='index'" ); - $_wpdb = null; - if ( $results ) { - foreach ( $results as $result ) { - if ( $result->name === $index_name ) { - $r = rand( 0, 50 ); - $index_name = $index_name . "_$r"; - break; - } - } - } - $this->index_queries[] = 'CREATE INDEX ' . $index_name . ' ON ' . $tbl_name . $col_name; - - return ''; - } - - /** - * Call back method to remove unnecessary string. - * - * This method is deprecated. - * - * @param string $match The string to be removed. Not used. - * - * @return string whose length is zero - * @access private - */ - private function _remove_length( $match ) { - return ''; - } - - /** - * Method to assemble the main query and index queries into an array. - * - * It return the array of the queries to be executed separately. - * - * @return array - * @access private - */ - private function post_process() { - $mainquery = $this->_query; - do { - $count = 0; - $mainquery = preg_replace( '/,\\s*\)/imsx', ')', $mainquery, -1, $count ); - } while ( $count > 0 ); - do { - $count = 0; - $mainquery = preg_replace( '/\(\\s*?,/imsx', '(', $mainquery, -1, $count ); - } while ( $count > 0 ); - $return_val[] = $mainquery; - $return_val = array_merge( $return_val, $this->index_queries ); - - return $return_val; - } - - /** - * Method to add IF NOT EXISTS to query string. - * - * This adds IF NOT EXISTS to every query string, which prevent the exception - * from being thrown. - * - * @access private - */ - private function add_if_not_exists() { - $pattern_table = '/^\\s*CREATE\\s*(TEMP|TEMPORARY)?\\s*TABLE\\s*(IF NOT EXISTS)?\\s*/ims'; - $this->_query = preg_replace( $pattern_table, 'CREATE $1 TABLE IF NOT EXISTS ', $this->_query ); - $pattern_index = '/^\\s*CREATE\\s*(UNIQUE)?\\s*INDEX\\s*(IF NOT EXISTS)?\\s*/ims'; - for ( $i = 0; $i < count( $this->index_queries ); $i++ ) { - $this->index_queries[ $i ] = preg_replace( - $pattern_index, - 'CREATE $1 INDEX IF NOT EXISTS ', - $this->index_queries[ $i ] - ); - } - } - - /** - * Method to strip back quotes. - * - * @access private - */ - private function strip_backticks() { - $this->_query = str_replace( '`', '', $this->_query ); - foreach ( $this->index_queries as &$query ) { - $query = str_replace( '`', '', $query ); - } - } - - /** - * Method to remove the character set information from within mysql queries. - * - * This removes DEFAULT CHAR(ACTER) SET and COLLATE, which is meaningless for - * SQLite. - * - * @access private - */ - private function rewrite_character_set() { - $pattern_charset = '/\\b(default\\s*character\\s*set|default\\s*charset|character\\s*set)\\s*(?_query = preg_replace( $patterns, '', $this->_query ); - } - - /** - * Method to quote illegal field name for SQLite - * - * @access private - */ - private function quote_illegal_field() { - $this->_query = preg_replace( "/^\\s*(?_query ); - } -} diff --git a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-db.php b/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-db.php deleted file mode 100644 index bee6b09285..0000000000 --- a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-db.php +++ /dev/null @@ -1,330 +0,0 @@ -ready = true; - } - - /** - * Method to escape characters. - * - * This overrides wpdb::_real_escape() to avoid using mysql_real_escape_string(). - * - * @see wpdb::_real_escape() - * - * @param string $str The string to escape. - * - * @return string escaped - */ - function _real_escape( $str ) { - return addslashes( $str ); - } - - /** - * Method to dummy out wpdb::esc_like() function. - * - * WordPress 4.0.0 introduced esc_like() function that adds backslashes to %, - * underscore and backslash, which is not interpreted as escape character - * by SQLite. So we override it and dummy out this function. - * - * @param string $text The raw text to be escaped. The input typed by the user should have no - * extra or deleted slashes. - * - * @return string Text in the form of a LIKE phrase. The output is not SQL safe. Call $wpdb::prepare() - * or real_escape next. - */ - public function esc_like( $text ) { - return $text; - } - - /** - * Method to put out the error message. - * - * This overrides wpdb::print_error(), for we can't use the parent class method. - * - * @see wpdb::print_error() - * - * @global array $EZSQL_ERROR Stores error information of query and error string. - * - * @param string $str The error to display. - * - * @return bool|void False if the showing of errors is disabled. - */ - public function print_error( $str = '' ) { - global $EZSQL_ERROR; - - if ( ! $str ) { - $err = $this->dbh->get_error_message() ? $this->dbh->get_error_message() : ''; - $str = empty( $err ) ? '' : $err[2]; - } - $EZSQL_ERROR[] = array( - 'query' => $this->last_query, - 'error_str' => $str, - ); - - if ( $this->suppress_errors ) { - return false; - } - - wp_load_translations_early(); - - $caller = $this->get_caller(); - $caller = $caller ? $caller : __( '(unknown)', 'performance-lab' ); - - $error_str = sprintf( - /* translators: 1: Database error message, 2: SQL query, 3: Caller. */ - __( 'WordPress database error %1$s for query %2$s made by %3$s', 'performance-lab' ), - $str, - $this->last_query, - $caller - ); - - error_log( $error_str ); - - if ( ! $this->show_errors ) { - return false; - } - - if ( is_multisite() ) { - $msg = "WordPress database error: [$str]\n{$this->last_query}\n"; - if ( defined( 'ERRORLOGFILE' ) ) { - error_log( $msg, 3, ERRORLOGFILE ); - } - if ( defined( 'DIEONDBERROR' ) ) { - wp_die( $msg ); - } - } else { - $str = htmlspecialchars( $str, ENT_QUOTES ); - $query = htmlspecialchars( $this->last_query, ENT_QUOTES ); - - printf( - /* translators: 1: Database error message, 2: SQL query. */ - '

' . __( 'WordPress database error: [%1$s] %2$s', 'performance-lab' ) . '

', - $str, - '' . $query . '' - ); - } - } - - /** - * Method to flush cached data. - * - * This overrides wpdb::flush(). This is not necessarily overridden, because - * $result will never be resource. - * - * @see wpdb::flush - */ - public function flush() { - $this->last_result = array(); - $this->col_info = null; - $this->last_query = null; - $this->rows_affected = 0; - $this->num_rows = 0; - $this->last_error = ''; - $this->result = null; - } - - /** - * Method to do the database connection. - * - * This overrides wpdb::db_connect() to avoid using MySQL function. - * - * @see wpdb::db_connect() - * - * @param bool $allow_bail Not used. - * @return void - */ - public function db_connect( $allow_bail = true ) { - $this->init_charset(); - $this->dbh = new Perflab_SQLite_PDO_Engine(); - $this->ready = true; - } - - /** - * Method to dummy out wpdb::check_connection() - * - * @param bool $allow_bail Not used. - * - * @return bool - */ - public function check_connection( $allow_bail = true ) { - return true; - } - - /** - * Method to execute the query. - * - * This overrides wpdb::query(). In fact, this method does all the database - * access jobs. - * - * @see wpdb::query() - * - * @param string $query Database query. - * - * @return int|false Number of rows affected/selected or false on error - */ - public function query( $query ) { - if ( ! $this->ready ) { - return false; - } - - $query = apply_filters( 'query', $query ); - - $this->flush(); - - $this->func_call = "\$db->query(\"$query\")"; - $this->last_query = $query; - - if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) { - $this->timer_start(); - } - - $this->result = $this->dbh->query( $query ); - $this->num_queries++; - - if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) { - $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() ); - } - - $this->last_error = $this->dbh->get_error_message(); - if ( $this->last_error && ( ! defined( 'WP_INSTALLING' ) || ! WP_INSTALLING ) ) { - $this->print_error( $this->last_error ); - return false; - } - - if ( preg_match( '/^\\s*(create|alter|truncate|drop|optimize)\\s*/i', $query ) ) { - return $this->dbh->get_return_value(); - } - - if ( preg_match( '/^\\s*(insert|delete|update|replace)\s/i', $query ) ) { - $this->rows_affected = $this->dbh->get_affected_rows(); - if ( preg_match( '/^\s*(insert|replace)\s/i', $query ) ) { - $this->insert_id = $this->dbh->get_insert_id(); - } - return $this->rows_affected; - } - - $this->last_result = $this->dbh->get_query_results(); - $this->num_rows = $this->dbh->get_num_rows(); - return $this->num_rows; - } - - /** - * Method to set the class variable $col_info. - * - * This overrides wpdb::load_col_info(), which uses a mysql function. - * - * @see wpdb::load_col_info() - * @access protected - */ - protected function load_col_info() { - if ( $this->col_info ) { - return; - } - $this->col_info = $this->dbh->get_columns(); - } - - /** - * Method to return what the database can do. - * - * This overrides wpdb::has_cap() to avoid using MySQL functions. - * SQLite supports subqueries, but not support collation, group_concat and set_charset. - * - * @see wpdb::has_cap() - * - * @param string $db_cap The feature to check for. Accepts 'collation', - * 'group_concat', 'subqueries', 'set_charset', - * 'utf8mb4', or 'utf8mb4_520'. - * - * @return bool Whether the database feature is supported, false otherwise. - */ - public function has_cap( $db_cap ) { - return 'subqueries' === strtolower( $db_cap ); - } - - /** - * Method to return database version number. - * - * This overrides wpdb::db_version() to avoid using MySQL function. - * It returns mysql version number, but it means nothing for SQLite. - * So it return the newest mysql version. - * - * @see wpdb::db_version() - */ - public function db_version() { - return '5.5'; - } - - /** - * Retrieves full database server information. - * - * @return string|false Server info on success, false on failure. - */ - public function db_server_info() { - return SQLite3::version()['versionString']; - } -} diff --git a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-object-array.php b/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-object-array.php deleted file mode 100644 index d09c81bdd1..0000000000 --- a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-object-array.php +++ /dev/null @@ -1,35 +0,0 @@ - $value ) { - if ( ! $node ) { - $node =& $this; - } - if ( is_array( $value ) ) { - $node->$key = new stdClass(); - self::__construct( $value, $node->$key ); - } else { - $node->$key = $value; - } - } - } -} diff --git a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-pdo-driver.php b/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-pdo-driver.php deleted file mode 100644 index 8b9678931e..0000000000 --- a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-pdo-driver.php +++ /dev/null @@ -1,793 +0,0 @@ -query_type = $query_type; - $this->_query = $query; - $this->parse_query(); - switch ( $this->query_type ) { - case 'truncate': - $this->handle_truncate_query(); - break; - - case 'alter': - $this->handle_alter_query(); - break; - - case 'create': - $this->handle_create_query(); - break; - - case 'describe': - case 'desc': - $this->handle_describe_query(); - break; - - case 'show': - $this->handle_show_query(); - break; - - case 'showcolumns': - $this->handle_show_columns_query(); - break; - - case 'showindex': - $this->handle_show_index(); - break; - - case 'select': - // $this->strip_backticks(); - $this->handle_sql_count(); - $this->rewrite_date_sub(); - $this->delete_index_hints(); - $this->rewrite_regexp(); - // $this->rewrite_boolean(); - $this->fix_date_quoting(); - $this->rewrite_between(); - $this->handle_orderby_field(); - break; - - case 'insert': - // $this->safe_strip_backticks(); - $this->execute_duplicate_key_update(); - $this->rewrite_insert_ignore(); - $this->rewrite_regexp(); - $this->fix_date_quoting(); - break; - - case 'update': - // $this->safe_strip_backticks(); - $this->rewrite_update_ignore(); - // $this->_rewrite_date_sub(); - $this->rewrite_limit_usage(); - $this->rewrite_order_by_usage(); - $this->rewrite_regexp(); - $this->rewrite_between(); - break; - - case 'delete': - // $this->strip_backticks(); - $this->rewrite_limit_usage(); - $this->rewrite_order_by_usage(); - $this->rewrite_date_sub(); - $this->rewrite_regexp(); - $this->delete_workaround(); - break; - - case 'replace': - // $this->safe_strip_backticks(); - $this->rewrite_date_sub(); - $this->rewrite_regexp(); - break; - - case 'optimize': - $this->rewrite_optimize(); - break; - - case 'pragma': - break; - - default: - if ( defined( WP_DEBUG ) && WP_DEBUG ) { - break; - } - $this->return_true(); - break; - } - - return $this->_query; - } - - /** - * Method to parse query string and determine which operation is needed. - * - * Remove backticks and change true/false values into 1/0. And determines - * if rewriting CALC_FOUND_ROWS or ON DUPLICATE KEY UPDATE etc is needed. - * - * @access private - */ - private function parse_query() { - $tokens = preg_split( "/(\\\'|''|')/s", $this->_query, -1, PREG_SPLIT_DELIM_CAPTURE ); - $literal = false; - $query_string = ''; - foreach ( $tokens as $token ) { - if ( "'" === $token ) { - $literal = ! $literal; - } else { - if ( false === $literal ) { - if ( strpos( $token, '`' ) !== false ) { - $token = str_replace( '`', '', $token ); - } - if ( preg_match( '/\\bTRUE\\b/i', $token ) ) { - $token = str_ireplace( 'TRUE', '1', $token ); - } - if ( preg_match( '/\\bFALSE\\b/i', $token ) ) { - $token = str_ireplace( 'FALSE', '0', $token ); - } - if ( stripos( $token, 'SQL_CALC_FOUND_ROWS' ) !== false ) { - $this->rewrite_calc_found = true; - } - if ( stripos( $token, 'ON DUPLICATE KEY UPDATE' ) !== false ) { - $this->rewrite_duplicate_key = true; - } - if ( stripos( $token, 'USE INDEX' ) !== false ) { - $this->rewrite_index_hint = true; - } - if ( stripos( $token, 'IGNORE INDEX' ) !== false ) { - $this->rewrite_index_hint = true; - } - if ( stripos( $token, 'FORCE INDEX' ) !== false ) { - $this->rewrite_index_hint = true; - } - if ( stripos( $token, 'BETWEEN' ) !== false ) { - $this->rewrite_between = true; - $this->num_of_rewrite_between++; - } - if ( stripos( $token, 'ORDER BY FIELD' ) !== false ) { - $this->orderby_field = true; - } - } - } - $query_string .= $token; - } - $this->_query = $query_string; - } - - /** - * Method to handle SHOW TABLES query. - * - * @access private - */ - private function handle_show_query() { - $this->_query = str_ireplace( ' FULL', '', $this->_query ); - $table_name = ''; - $pattern = '/^\\s*SHOW\\s*TABLES\\s*.*?(LIKE\\s*(.*))$/im'; - if ( preg_match( $pattern, $this->_query, $matches ) ) { - $table_name = str_replace( array( "'", ';' ), '', $matches[2] ); - } - $suffix = empty( $table_name ) ? '' : ' AND name LIKE ' . "'" . $table_name . "'"; - $this->_query = "SELECT name FROM sqlite_master WHERE type='table'" . $suffix . ' ORDER BY name DESC'; - } - - /** - * Method to emulate the SQL_CALC_FOUND_ROWS placeholder for MySQL. - * - * This is a kind of tricky play. - * 1. remove SQL_CALC_FOUND_ROWS option, and give it to the pdo engine - * 2. make another $wpdb instance, and execute the rewritten query - * 3. give the returned value (integer: number of the rows) to the original instance variable without LIMIT - * - * We no longer use SELECT COUNT query, because it returns the inexact values when used with WP_Meta_Query(). - * - * This kind of statement is required for WordPress to calculate the paging information. - * see also WP_Query class in wp-includes/query.php - */ - private function handle_sql_count() { - if ( ! $this->rewrite_calc_found ) { - return; - } - global $wpdb; - // First strip the code. this is the end of rewriting process. - $this->_query = str_ireplace( 'SQL_CALC_FOUND_ROWS', '', $this->_query ); - // We make the data for next SELECE FOUND_ROWS() statement. - $unlimited_query = preg_replace( '/\\bLIMIT\\s*.*/imsx', '', $this->_query ); - $_wpdb = new Perflab_SQLite_DB(); - $result = $_wpdb->query( $unlimited_query ); - $wpdb->dbh->found_rows_result = $result; - $_wpdb = null; - } - - /** - * Method to rewrite INSERT IGNORE to INSERT OR IGNORE. - * - * @access private - */ - private function rewrite_insert_ignore() { - $this->_query = str_ireplace( 'INSERT IGNORE', 'INSERT OR IGNORE ', $this->_query ); - } - - /** - * Method to rewrite UPDATE IGNORE to UPDATE OR IGNORE. - * - * @access private - */ - private function rewrite_update_ignore() { - $this->_query = str_ireplace( 'UPDATE IGNORE', 'UPDATE OR IGNORE ', $this->_query ); - } - - /** - * Method to rewrite DATE_ADD() function. - * - * DATE_ADD has a parameter PHP function can't parse, so we quote the list and - * pass it to the user defined function. - * - * @access private - */ - private function rewrite_date_add() { - // (date,interval expression unit) - $pattern = '/\\s*date_add\\s*\(([^,]*),([^\)]*)\)/imsx'; - if ( preg_match( $pattern, $this->_query, $matches ) ) { - $expression = "'" . trim( $matches[2] ) . "'"; - $this->_query = preg_replace( $pattern, " date_add($matches[1], $expression) ", $this->_query ); - } - } - - /** - * Method to rewrite DATE_SUB() function. - * - * DATE_SUB has a parameter PHP function can't parse, so we quote the list and - * pass it to the user defined function. - * - * @access private - */ - private function rewrite_date_sub() { - // (date,interval expression unit) - $pattern = '/\\s*date_sub\\s*\(([^,]*),([^\)]*)\)/imsx'; - if ( preg_match( $pattern, $this->_query, $matches ) ) { - $expression = "'" . trim( $matches[2] ) . "'"; - $this->_query = preg_replace( $pattern, " date_sub($matches[1], $expression) ", $this->_query ); - } - } - - /** - * Method to handle CREATE query. - * - * If the query is CREATE query, it will be passed to the query_create.class.php. - * So this method can't be used. It's here for safety. - * - * @access private - */ - private function handle_create_query() { - $engine = new Perflab_SQLite_Create_Query(); - $this->_query = $engine->rewrite_query( $this->_query ); - $engine = null; - } - - /** - * Method to handle ALTER query. - * - * If the query is ALTER query, it will be passed ot the query_alter.class.php. - * So this method can't be used. It is here for safety. - * - * @access private - */ - private function handle_alter_query() { - $engine = new Perflab_SQLite_Alter_Query(); - $this->_query = $engine->rewrite_query( $this->_query, 'alter' ); - $engine = null; - } - - /** - * Method to handle DESCRIBE or DESC query. - * - * DESCRIBE is required for WordPress installation process. DESC is - * an alias for DESCRIBE, but it is not used in core WordPress. - * - * @access private - */ - private function handle_describe_query() { - $pattern = '/^\\s*(DESCRIBE|DESC)\\s*(.*)/i'; - if ( preg_match( $pattern, $this->_query, $match ) ) { - $tablename = preg_replace( '/[\';]/', '', $match[2] ); - $this->_query = "PRAGMA table_info($tablename)"; - } - } - - /** - * Method to remove LIMIT clause from DELETE or UPDATE query. - * - * The author of the original 'PDO for WordPress' says update method of wpdb - * insists on adding LIMIT. But the newest version of WordPress doesn't do that. - * Nevertheless some plugins use DELETE with LIMIT, UPDATE with LIMIT. - * We need to exclude sub query's LIMIT. And if SQLite is compiled with - * ENABLE_UPDATE_DELETE_LIMIT option, we don't remove it. - * - * @access private - */ - private function rewrite_limit_usage() { - $_wpdb = new Perflab_SQLite_DB(); - $options = $_wpdb->get_results( 'PRAGMA compile_options' ); - foreach ( $options as $opt ) { - if ( isset( $opt->compile_option ) && stripos( $opt->compile_option, 'ENABLE_UPDATE_DELETE_LIMIT' ) !== false ) { - return; - } - } - if ( stripos( $this->_query, '(select' ) === false ) { - $this->_query = preg_replace( '/\\s*LIMIT\\s*[0-9]$/i', '', $this->_query ); - } - } - - /** - * Method to remove ORDER BY clause from DELETE or UPDATE query. - * - * SQLite compiled without SQLITE_ENABLE_UPDATE_DELETE_LIMIT option can't - * execute UPDATE with ORDER BY, DELETE with GROUP BY. - * We need to exclude sub query's GROUP BY. - * - * @access private - */ - private function rewrite_order_by_usage() { - $_wpdb = new Perflab_SQLite_DB(); - $options = $_wpdb->get_results( 'PRAGMA compile_options' ); - foreach ( $options as $opt ) { - if ( isset( $opt->compile_option ) && stripos( $opt->compile_option, 'ENABLE_UPDATE_DELETE_LIMIT' ) !== false ) { - return; - } - } - if ( stripos( $this->_query, '(select' ) === false ) { - $this->_query = preg_replace( '/\\s+ORDER\\s+BY\\s*.*$/i', '', $this->_query ); - } - } - - /** - * Method to handle TRUNCATE query. - * - * @access private - */ - private function handle_truncate_query() { - $pattern = '/TRUNCATE TABLE (.*)/im'; - $this->_query = preg_replace( $pattern, 'DELETE FROM $1', $this->_query ); - } - - /** - * Method to handle OPTIMIZE query. - * - * Original query has the table names, but they are simply ignored. - * Table names are meaningless in SQLite. - * - * @access private - */ - private function rewrite_optimize() { - $this->_query = 'VACUUM'; - } - - /** - * Method to rewrite day. - * - * Jusitn Adie says: some wp UI interfaces (notably the post interface) - * badly composes the day part of the date leading to problems in sqlite - * sort ordering etc. - * - * I don't understand that... - * - * @access private - */ - private function rewrite_badly_formed_dates() { - $pattern = '/([12]\d{3,}-\d{2}-)(\d )/ims'; - $this->_query = preg_replace( $pattern, '${1}0$2', $this->_query ); - } - - /** - * Method to remove INDEX HINT. - * - * @access private - */ - private function delete_index_hints() { - $pattern = '/\\s*(use|ignore|force)\\s+index\\s*\(.*?\)/i'; - $this->_query = preg_replace( $pattern, '', $this->_query ); - } - - /** - * Method to fix the date string and quoting. - * - * This is required for the calendar widget. - * - * WHERE month(fieldname)=08 is converted to month(fieldname)='8' - * WHERE month(fieldname)='08' is converted to month(fieldname)='8' - * - * I use preg_replace_callback instead of 'e' option because of security reason. - * cf. PHP manual (regular expression) - * - * @access private - */ - private function fix_date_quoting() { - $pattern = '/(month|year|second|day|minute|hour|dayofmonth)\\s*\((.*?)\)\\s*=\\s*["\']?(\d{1,4})[\'"]?\\s*/im'; - $this->_query = preg_replace_callback( $pattern, array( $this, '_fix_date_quoting' ), $this->_query ); - } - - /** - * Call back method to rewrite date string. - * - * @param string $match The match from preg_replace_callback. - * - * @return string - * @access private - */ - private function _fix_date_quoting( $match ) { - return "{$match[1]}({$match[2]})='" . intval( $match[3] ) . "' "; - } - - /** - * Method to rewrite REGEXP() function. - * - * This method changes function name to regexpp() and pass it to the user defined - * function. - * - * @access private - */ - private function rewrite_regexp() { - $pattern = '/\s([^\s]*)\s*regexp\s*(\'.*?\')/im'; - $this->_query = preg_replace( $pattern, ' regexpp(\1, \2)', $this->_query ); - } - - /** - * Method to handle SHOW COLUMN query. - * - * @access private - */ - private function handle_show_columns_query() { - $this->_query = str_ireplace( ' FULL', '', $this->_query ); - $pattern_like = '/^\\s*SHOW\\s*(COLUMNS|FIELDS)\\s*FROM\\s*(.*)?\\s*LIKE\\s*(.*)?/i'; - $pattern = '/^\\s*SHOW\\s*(COLUMNS|FIELDS)\\s*FROM\\s*(.*)?/i'; - if ( preg_match( $pattern_like, $this->_query, $matches ) ) { - $table_name = str_replace( "'", '', trim( $matches[2] ) ); - $column_name = str_replace( "'", '', trim( $matches[3] ) ); - $query_string = "SELECT sql FROM sqlite_master WHERE tbl_name='$table_name' AND sql LIKE '%$column_name%'"; - $this->_query = $query_string; - } elseif ( preg_match( $pattern, $this->_query, $matches ) ) { - $table_name = $matches[2]; - $query_string = preg_replace( $pattern, "PRAGMA table_info($table_name)", $this->_query ); - $this->_query = $query_string; - } - } - - /** - * Method to handle SHOW INDEX query. - * - * Moved the WHERE clause manipulation to pdoengin.class.php (ver 1.3.1) - * - * @access private - */ - private function handle_show_index() { - $pattern = '/^\\s*SHOW\\s*(?:INDEX|INDEXES|KEYS)\\s*FROM\\s*(\\w+)?/im'; - if ( preg_match( $pattern, $this->_query, $match ) ) { - $table_name = preg_replace( "/[\';]/", '', $match[1] ); - $table_name = trim( $table_name ); - $this->_query = "SELECT * FROM sqlite_master WHERE tbl_name='$table_name'"; - } - } - - /** - * Method to handle ON DUPLICATE KEY UPDATE statement. - * - * First we use SELECT query and check if INSERT is allowed or not. - * Rewriting procedure looks like a detour, but I've got no other ways. - * - * Added the literal check since the version 1.5.1. - * - * @access private - */ - private function execute_duplicate_key_update() { - if ( ! $this->rewrite_duplicate_key ) { - return; - } - $unique_keys_for_cond = array(); - $unique_keys_for_check = array(); - $pattern = '/^\\s*INSERT\\s*INTO\\s*(\\w+)?\\s*(.*)\\s*ON\\s*DUPLICATE\\s*KEY\\s*UPDATE\\s*(.*)$/ims'; - if ( preg_match( $pattern, $this->_query, $match_0 ) ) { - $table_name = trim( $match_0[1] ); - $insert_data = trim( $match_0[2] ); - $update_data = trim( $match_0[3] ); - // Prepare two unique key data for the table. - // 1. array('col1', 'col2, col3', etc) 2. array('col1', 'col2', 'col3', etc). - $_wpdb = new Perflab_SQLite_DB(); - $indexes = $_wpdb->get_results( "SHOW INDEX FROM {$table_name}" ); - if ( ! empty( $indexes ) ) { - foreach ( $indexes as $index ) { - if ( 0 === $index->Non_unique ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase - $unique_keys_for_cond[] = $index->Column_name; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase - if ( strpos( $index->Column_name, ',' ) !== false ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase - $unique_keys_for_check = array_merge( - $unique_keys_for_check, - explode( ',', $index->Column_name ) // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase - ); - } else { - $unique_keys_for_check[] = $index->Column_name; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase - } - } - } - $unique_keys_for_check = array_map( 'trim', $unique_keys_for_check ); - } else { - // Without unique key or primary key, UPDATE statement will affect all the rows! - $query = "INSERT INTO $table_name $insert_data"; - $this->_query = $query; - $_wpdb = null; - - return; - } - // Data check. - if ( preg_match( '/^\((.*)\)\\s*VALUES\\s*\((.*)\)$/ims', $insert_data, $match_1 ) ) { - $col_array = explode( ',', $match_1[1] ); - $ins_data_array = explode( ',', $match_1[2] ); - foreach ( $col_array as $col ) { - $val = trim( array_shift( $ins_data_array ) ); - $ins_data_assoc[ trim( $col ) ] = $val; - } - $condition = ''; - foreach ( $unique_keys_for_cond as $unique_key ) { - if ( strpos( $unique_key, ',' ) !== false ) { - $unique_key_array = explode( ',', $unique_key ); - $counter = count( $unique_key_array ); - for ( $i = 0; $i < $counter; ++$i ) { - $col = trim( $unique_key_array[ $i ] ); - if ( isset( $ins_data_assoc[ $col ] ) && $i === $counter - 1 ) { - $condition .= $col . '=' . $ins_data_assoc[ $col ] . ' OR '; - } elseif ( isset( $ins_data_assoc[ $col ] ) ) { - $condition .= $col . '=' . $ins_data_assoc[ $col ] . ' AND '; - } else { - continue; - } - } - } else { - $col = trim( $unique_key ); - if ( ! isset( $ins_data_assoc[ $col ] ) ) { - continue; - } - $condition .= $col . '=' . $ins_data_assoc[ $col ] . ' OR '; - } - } - $condition = rtrim( $condition, ' OR ' ); - $test_query = "SELECT * FROM {$table_name} WHERE {$condition}"; - $results = $_wpdb->query( $test_query ); - $_wpdb = null; - if ( 0 == $results ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison - $this->_query = "INSERT INTO $table_name $insert_data"; - return; - } - - $ins_array_assoc = array(); - - if ( preg_match( '/^\((.*)\)\\s*VALUES\\s*\((.*)\)$/im', $insert_data, $match_2 ) ) { - $col_array = explode( ',', $match_2[1] ); - $ins_array = explode( ',', $match_2[2] ); - $count = count( $col_array ); - for ( $i = 0; $i < $count; $i++ ) { - $col = trim( $col_array[ $i ] ); - $val = trim( $ins_array[ $i ] ); - $ins_array_assoc[ $col ] = $val; - } - } - $update_data = rtrim( $update_data, ';' ); - $tmp_array = explode( ',', $update_data ); - foreach ( $tmp_array as $pair ) { - list($col, $value) = explode( '=', $pair ); - $col = trim( $col ); - $value = trim( $value ); - $update_array_assoc[ $col ] = $value; - } - foreach ( $update_array_assoc as $key => &$value ) { - if ( preg_match( '/^VALUES\\s*\((.*)\)$/im', $value, $match_3 ) ) { - $col = trim( $match_3[1] ); - $value = $ins_array_assoc[ $col ]; - } - } - foreach ( $ins_array_assoc as $key => $val ) { - if ( in_array( $key, $unique_keys_for_check, true ) ) { - $where_array[] = $key . '=' . $val; - } - } - $update_strings = ''; - foreach ( $update_array_assoc as $key => $val ) { - if ( in_array( $key, $unique_keys_for_check, true ) ) { - $where_array[] = $key . '=' . $val; - } else { - $update_strings .= $key . '=' . $val . ','; - } - } - $update_strings = rtrim( $update_strings, ',' ); - $unique_where = array_unique( $where_array, SORT_REGULAR ); - $where_string = ' WHERE ' . implode( ' AND ', $unique_where ); - $update_query = 'UPDATE ' . $table_name . ' SET ' . $update_strings . $where_string; - $this->_query = $update_query; - } - } - } - - /** - * Method to rewrite BETWEEN A AND B clause. - * - * This clause is the same form as natural language, so we have to check if it is - * in the data or SQL statement. - * - * @access private - */ - private function rewrite_between() { - if ( ! $this->rewrite_between ) { - return; - } - $pattern = '/\\s*(CAST\([^\)]+?\)|[^\\s\(]*)?\\s*BETWEEN\\s*([^\\s]*)?\\s*AND\\s*([^\\s\)]*)?\\s*/ims'; - do { - if ( preg_match( $pattern, $this->_query, $match ) ) { - $column_name = trim( $match[1] ); - $min_value = trim( $match[2] ); - $max_value = trim( $match[3] ); - $max_value = rtrim( $max_value ); - $replacement = " ($column_name >= $min_value AND $column_name <= $max_value)"; - $this->_query = str_ireplace( $match[0], $replacement, $this->_query ); - } - $this->num_of_rewrite_between--; - } while ( $this->num_of_rewrite_between > 0 ); - } - - /** - * Method to handle ORDER BY FIELD() clause. - * - * When FIELD() function has column name to compare, we can't rewrite it with - * use defined functions. When this function detect column name in the argument, - * it creates another instance, does the query withuot ORDER BY clause and gives - * the result array sorted to the main instance. - * - * If FIELD() function doesn't have column name, it will use the user defined - * function. usort() function closure function to compare the items. - * - * @access private - */ - private function handle_orderby_field() { - if ( ! $this->orderby_field ) { - return; - } - global $wpdb; - $pattern = '/\\s+ORDER\\s+BY\\s+FIELD\\s*\(\\s*([^\)]+?)\\s*\)/i'; - if ( preg_match( $pattern, $this->_query, $match ) ) { - $params = explode( ',', $match[1] ); - $params = array_map( 'trim', $params ); - $tbl_col = array_shift( $params ); - $flipped = array_flip( $params ); - $tbl_name = substr( $tbl_col, 0, strpos( $tbl_col, '.' ) ); - $tbl_name = str_replace( $wpdb->prefix, '', $tbl_name ); - - if ( $tbl_name && in_array( $tbl_name, $wpdb->tables, true ) ) { - $query = str_replace( $match[0], '', $this->_query ); - $_wpdb = new Perflab_SQLite_DB(); - $results = $_wpdb->get_results( $query ); - $_wpdb = null; - usort( - $results, - static function ( $a, $b ) use ( $flipped ) { - return $flipped[ $a->ID ] - $flipped[ $b->ID ]; - } - ); - } - $wpdb->dbh->pre_ordered_results = $results; - } - } - - /** - * Method to avoid DELETE with JOIN statement. - * - * The wp-admin/includes/upgrade.php contains a 'DELETE ... JOIN' statement. - * This query can't be replaced with regular expression or udf, so we - * replace all the statement with another. But this query was used in - * the very old version of WordPress when it was upgraded. So we won't - * have no chance that this method should be used. - * - * @access private - */ - private function delete_workaround() { - global $wpdb; - $pattern = "DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2"; - $pattern2 = "DELETE a, b FROM $wpdb->sitemeta AS a, $wpdb->sitemeta AS b"; - $rewritten = "DELETE FROM $wpdb->options WHERE option_id IN (SELECT MIN(option_id) FROM $wpdb->options GROUP BY option_name HAVING COUNT(*) > 1)"; - if ( stripos( $this->_query, $pattern ) !== false ) { - $this->_query = $rewritten; - } elseif ( stripos( $this->_query, $pattern2 ) !== false ) { - $time = time(); - $prep_query = "SELECT a.meta_id AS aid, b.meta_id AS bid FROM $wpdb->sitemeta AS a INNER JOIN $wpdb->sitemeta AS b ON a.meta_key='_site_transient_timeout_'||substr(b.meta_key, 17) WHERE b.meta_key='_site_transient_'||substr(a.meta_key, 25) AND a.meta_value < $time"; - $_wpdb = new Perflab_SQLite_DB(); - $ids = $_wpdb->get_results( $prep_query ); - foreach ( $ids as $id ) { - $ids_to_delete[] = $id->aid; - $ids_to_delete[] = $id->bid; - } - $rewritten = "DELETE FROM $wpdb->sitemeta WHERE meta_id IN (" . implode( ',', $ids_to_delete ) . ')'; - $this->_query = $rewritten; - } - } - - /** - * Method to suppress errors. - * - * When the query string is the one that this class can't manipulate, - * the query string is replaced with the one that always returns true - * and does nothing. - * - * @access private - */ - private function return_true() { - $this->_query = 'SELECT 1=1'; - } -} diff --git a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-pdo-engine.php b/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-pdo-engine.php deleted file mode 100644 index e72b5d27b4..0000000000 --- a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-pdo-engine.php +++ /dev/null @@ -1,1527 +0,0 @@ -client_info = SQLite3::version()['versionString']; - - register_shutdown_function( array( $this, '__destruct' ) ); - if ( ! is_file( FQDB ) ) { - $this->prepare_directory(); - } - $dsn = 'sqlite:' . FQDB; - if ( isset( $GLOBALS['@pdo'] ) ) { - $this->pdo = $GLOBALS['@pdo']; - $this->init(); - return; - } - - $locked = false; - $status = 0; - $err_message = ''; - do { - try { - $this->pdo = new PDO( $dsn, null, null, array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ) ); // phpcs:ignore WordPress.DB.RestrictedClasses - new Perflab_SQLite_PDO_User_Defined_Functions( $this->pdo ); - $GLOBALS['@pdo'] = $this->pdo; - } catch ( PDOException $ex ) { - $status = $ex->getCode(); - if ( 5 === $status || 6 === $status ) { - $locked = true; - } else { - $err_message = $ex->getMessage(); - } - } - } while ( $locked ); - - if ( $status > 0 ) { - $message = sprintf( - '

%s

%s

%s

', - __( 'Database initialization error!', 'performance-lab' ), - /* translators: %d: error code */ - sprintf( __( 'Code: %d', 'performance-lab' ), $status ), - /* translators: %s: error message */ - sprintf( __( 'Error Message: %s', 'performance-lab' ), $err_message ) - ); - $this->set_error( __LINE__, __FILE__, $message ); - - return false; - } - $this->init(); - } - - /** - * Destructor - * - * If SQLITE_MEM_DEBUG constant is defined, append information about - * memory usage into database/mem_debug.txt. - * - * This definition is changed since version 1.7. - * - * @return boolean - */ - function __destruct() { - if ( defined( 'SQLITE_MEM_DEBUG' ) && SQLITE_MEM_DEBUG ) { - $max = ini_get( 'memory_limit' ); - if ( is_null( $max ) ) { - $message = sprintf( - '[%s] Memory_limit is not set in php.ini file.', - gmdate( 'Y-m-d H:i:s', $_SERVER['REQUEST_TIME'] ) - ); - error_log( $message ); - return true; - } - if ( stripos( $max, 'M' ) !== false ) { - $max = (int) $max * MB_IN_BYTES; - } - $peak = memory_get_peak_usage( true ); - $used = round( (int) $peak / (int) $max * 100, 2 ); - if ( $used > 90 ) { - $message = sprintf( - "[%s] Memory peak usage warning: %s %% used. (max: %sM, now: %sM)\n", - gmdate( 'Y-m-d H:i:s', $_SERVER['REQUEST_TIME'] ), - $used, - $max, - $peak - ); - error_log( $message ); - } - } - - return true; - } - - /** - * Method to initialize database, executed in the constructor. - * - * It checks if WordPress is in the installing process and does the required - * jobs. SQLite library version specific settings are also in this function. - * - * Some developers use WP_INSTALLING constant for other purposes, if so, this - * function will do no harms. - */ - private function init() { - if ( version_compare( SQLite3::version()['versionString'], '3.7.11', '>=' ) ) { - $this->can_insert_multiple_rows = true; - } - $statement = $this->pdo->query( 'PRAGMA foreign_keys' ); - if ( $statement->fetchColumn( 0 ) == '0' ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison - $this->pdo->query( 'PRAGMA foreign_keys = ON' ); - } - } - - /** - * This method makes database directory and .htaccess file. - * - * It is executed only once when the installation begins. - */ - private function prepare_directory() { - global $wpdb; - $u = umask( 0000 ); - if ( ! is_dir( FQDBDIR ) ) { - if ( ! @mkdir( FQDBDIR, 0704, true ) ) { - umask( $u ); - $message = __( 'Unable to create the required directory! Please check your server settings.', 'performance-lab' ); - wp_die( $message, 'Error!' ); - } - } - if ( ! is_writable( FQDBDIR ) ) { - umask( $u ); - $message = __( 'Unable to create a file in the directory! Please check your server settings.', 'performance-lab' ); - wp_die( $message, 'Error!' ); - } - if ( ! is_file( FQDBDIR . '.htaccess' ) ) { - $fh = fopen( FQDBDIR . '.htaccess', 'w' ); - if ( ! $fh ) { - umask( $u ); - $message = __( 'Unable to create a file in the directory! Please check your server settings.', 'performance-lab' ); - echo $message; - - return false; - } - fwrite( $fh, 'DENY FROM ALL' ); - fclose( $fh ); - } - if ( ! is_file( FQDBDIR . 'index.php' ) ) { - $fh = fopen( FQDBDIR . 'index.php', 'w' ); - if ( ! $fh ) { - umask( $u ); - $message = __( 'Unable to create a file in the directory! Please check your server settings.', 'performance-lab' ); - echo $message; - - return false; - } - fwrite( $fh, '' ); - fclose( $fh ); - } - umask( $u ); - - return true; - } - - /** - * Method to execute query(). - * - * Divide the query types into seven different ones. That is to say: - * - * 1. SELECT SQL_CALC_FOUND_ROWS - * 2. INSERT - * 3. CREATE TABLE(INDEX) - * 4. ALTER TABLE - * 5. SHOW VARIABLES - * 6. DROP INDEX - * 7. THE OTHERS - * - * #1 is just a tricky play. See the private function handle_sql_count() in query.class.php. - * From #2 through #5 call different functions respectively. - * #6 call the ALTER TABLE query. - * #7 is a normal process: sequentially call prepare_query() and execute_query(). - * - * #1 process has been changed since version 1.5.1. - * - * @param string $statement Full SQL statement string. - * @param int $mode Not used. - * @param array ...$fetch_mode_args Not used. - * - * @return mixed according to the query type - * @see PDO::query() - */ - public function query( $statement, $mode = PDO::ATTR_DEFAULT_FETCH_MODE, ...$fetch_mode_args ) { // phpcs:ignore WordPress.DB.RestrictedClasses - $this->flush(); - - $this->queries[] = "Raw query:\n$statement"; - $res = $this->determine_query_type( $statement ); - if ( ! $res && defined( 'PDO_DEBUG' ) && PDO_DEBUG ) { - $bailout_string = sprintf( - /* translators: %s: SQL statement */ - '

' . __( 'Unknown query type', 'performance-lab' ) . '

' . __( 'Sorry, we cannot determine the type of query that is requested (%s).', 'performance-lab' ) . '

', - $statement - ); - $this->set_error( __LINE__, __FUNCTION__, $bailout_string ); - } - switch ( strtolower( $this->query_type ) ) { - case 'set': - $this->return_value = false; - break; - - case 'foundrows': - $_column = array( 'FOUND_ROWS()' => '' ); - $column = array(); - if ( ! is_null( $this->found_rows_result ) ) { - $this->num_rows = $this->found_rows_result; - $_column['FOUND_ROWS()'] = $this->num_rows; - $column[] = new Perflab_SQLite_Object_Array( $_column ); - $this->results = $column; - $this->found_rows_result = null; - } - break; - - case 'insert': - if ( $this->can_insert_multiple_rows ) { - $this->execute_insert_query_new( $statement ); - break; - } - $this->execute_insert_query( $statement ); - break; - - case 'create': - $this->return_value = $this->execute_create_query( $statement ); - break; - - case 'alter': - $this->return_value = $this->execute_alter_query( $statement ); - break; - - case 'show_variables': - $this->return_value = $this->show_variables_workaround( $statement ); - break; - - case 'showstatus': - $this->return_value = $this->show_status_workaround( $statement ); - break; - - case 'drop_index': - $this->return_value = false; - if ( preg_match( '/^\\s*(DROP\\s*INDEX\\s*.*?)\\s*ON\\s*(.*)/im', $statement, $match ) ) { - $this->query_type = 'alter'; - $this->return_value = $this->execute_alter_query( 'ALTER TABLE ' . trim( $match[2] ) . ' ' . trim( $match[1] ) ); - } - break; - - default: - $engine = $this->prepare_engine( $this->query_type ); - $this->rewritten_query = $engine->rewrite_query( $statement, $this->query_type ); - if ( ! is_null( $this->pre_ordered_results ) ) { - $this->results = $this->pre_ordered_results; - $this->num_rows = count( $this->results ); - $this->return_value = $this->num_rows; - $this->pre_ordered_results = null; - break; - } - $this->queries[] = "Rewritten:\n$this->rewritten_query"; - $this->extract_variables(); - $prepared_query = $this->prepare_query(); - $this->execute_query( $prepared_query ); - if ( ! $this->is_error ) { - $this->process_results( $engine ); - } - break; - } - $debug_string = $this->get_debug_info(); - if ( defined( 'PDO_DEBUG' ) && PDO_DEBUG === true && $debug_string ) { - error_log( $debug_string ); - } - - return $this->return_value; - } - - /** - * Method to return inserted row id. - */ - public function get_insert_id() { - return $this->last_insert_id; - } - - /** - * Method to return the number of rows affected. - */ - public function get_affected_rows() { - return $this->affected_rows; - } - - /** - * Method to return the queried column names. - * - * These data are meaningless for SQLite. So they are dummy emulating - * MySQL columns data. - * - * @return array of the object - */ - public function get_columns() { - if ( ! empty( $this->results ) ) { - $primary_key = array( - 'meta_id', - 'comment_ID', - 'link_ID', - 'option_id', - 'blog_id', - 'option_name', - 'ID', - 'term_id', - 'object_id', - 'term_taxonomy_id', - 'umeta_id', - 'id', - ); - $unique_key = array( 'term_id', 'taxonomy', 'slug' ); - $data = array( - 'name' => '', // Column name. - 'table' => '', // Table name. - 'max_length' => 0, // Max length of the column. - 'not_null' => 1, // 1 if not null. - 'primary_key' => 0, // 1 if column has primary key. - 'unique_key' => 0, // 1 if column has unique key. - 'multiple_key' => 0, // 1 if column doesn't have unique key. - 'numeric' => 0, // 1 if column has numeric value. - 'blob' => 0, // 1 if column is blob. - 'type' => '', // Type of the column. - 'unsigned' => 0, // 1 if column is unsigned integer. - 'zerofill' => 0, // 1 if column is zero-filled. - ); - $table_name = ''; - if ( preg_match( '/\s*FROM\s*(.*)?\s*/i', $this->rewritten_query, $match ) ) { - $table_name = trim( $match[1] ); - } - foreach ( $this->results[0] as $key => $value ) { - $data['name'] = $key; - $data['table'] = $table_name; - if ( in_array( $key, $primary_key, true ) ) { - $data['primary_key'] = 1; - } elseif ( in_array( $key, $unique_key, true ) ) { - $data['unique_key'] = 1; - } else { - $data['multiple_key'] = 1; - } - $this->column_data[] = new Perflab_SQLite_Object_Array( $data ); - - // Reset data for next iteration. - $data['name'] = ''; - $data['table'] = ''; - $data['primary_key'] = 0; - $data['unique_key'] = 0; - $data['multiple_key'] = 0; - } - - return $this->column_data; - } - return null; - } - - /** - * Method to return the queried result data. - * - * @return mixed - */ - public function get_query_results() { - return $this->results; - } - - /** - * Method to return the number of rows from the queried result. - */ - public function get_num_rows() { - return $this->num_rows; - } - - /** - * Method to return the queried results according to the query types. - * - * @return mixed - */ - public function get_return_value() { - return $this->return_value; - } - - /** - * Method to return error messages. - * - * @return string - */ - public function get_error_message() { - if ( count( $this->error_messages ) === 0 ) { - $this->is_error = false; - $this->error_messages = array(); - return ''; - } - - if ( false === $this->is_error ) { - return ''; - } - - $output = '
 
'; - $output .= '
'; - $output .= '

' . __( 'Queries made or created this session were:', 'performance-lab' ) . '

'; - $output .= '
    '; - foreach ( $this->queries as $q ) { - $output .= '
  1. ' . $q . '
  2. '; - } - $output .= '
'; - $output .= '
'; - foreach ( $this->error_messages as $num => $m ) { - $output .= '
'; - $output .= sprintf( - /* translators: %1$d: line number, %2$s: function name, %3$s: error message */ - __( 'Error occurred at line %1$d in Function %2$s. Error message was: %3$s.', 'performance-lab' ), - (int) $this->errors[ $num ]['line'], - '' . esc_html( $this->errors[ $num ]['function'] ) . '', - $m - ); - $output .= '
'; - } - - ob_start(); - debug_print_backtrace(); - $output .= '
' . ob_get_contents() . '
'; - ob_end_clean(); - - return $output; - } - - /** - * Method to return information about query string for debugging. - * - * @return string - */ - private function get_debug_info() { - $output = ''; - foreach ( $this->queries as $q ) { - $output .= $q . "\n"; - } - - return $output; - } - - /** - * Method to clear previous data. - */ - private function flush() { - $this->rewritten_query = ''; - $this->query_type = ''; - $this->results = null; - $this->_results = null; - $this->last_insert_id = null; - $this->affected_rows = null; - $this->column_data = array(); - $this->num_rows = null; - $this->return_value = null; - $this->extracted_variables = array(); - $this->error_messages = array(); - $this->is_error = false; - $this->queries = array(); - $this->param_num = 0; - } - - /** - * Method to include the apropreate class files. - * - * It is not a good habit to change the include files programmatically. - * Needs to be fixed some other way. - * - * @param string $query_type The query type (create, alter, etc). - * - * @return object reference to apropreate driver - */ - private function prepare_engine( $query_type = null ) { - if ( stripos( $query_type, 'create' ) !== false ) { - return new Perflab_SQLite_Create_Query(); - } - if ( stripos( $query_type, 'alter' ) !== false ) { - return new Perflab_SQLite_Alter_Query(); - } - return new Perflab_SQLite_PDO_Driver(); - } - - /** - * Method to create a PDO statement object from the query string. - * - * @return PDOStatement - */ - private function prepare_query() { - $this->queries[] = "Prepare:\n" . $this->prepared_query; - $reason = 0; - $message = ''; - $statement = null; - do { - try { - $statement = $this->pdo->prepare( $this->prepared_query ); - } catch ( PDOException $err ) { - $reason = $err->getCode(); - $message = $err->getMessage(); - } - } while ( 5 === $reason || 6 === $reason ); - - if ( $reason > 0 ) { - $err_message = sprintf( 'Problem preparing the PDO SQL Statement. Error was: %s', $message ); - $this->set_error( __LINE__, __FUNCTION__, $err_message ); - } - - return $statement; - } - - /** - * Method to execute PDO statement object. - * - * This function executes query and sets the variables to give back to WordPress. - * The variables are class fields. So if success, no return value. If failure, it - * returns void and stops. - * - * @param object $statement The PDO statement. - * - * @return boolean|void - */ - private function execute_query( $statement ) { - $reason = 0; - $message = ''; - if ( ! is_object( $statement ) ) { - return false; - } - if ( count( $this->extracted_variables ) > 0 ) { - $this->queries[] = "Executing:\n" . var_export( $this->extracted_variables, true ); - do { - if ( 'update' === $this->query_type || 'replace' === $this->query_type ) { - try { - $this->beginTransaction(); - $statement->execute( $this->extracted_variables ); - $this->commit(); - } catch ( PDOException $err ) { - $reason = $err->getCode(); - $message = $err->getMessage(); - $this->rollBack(); - } - } else { - try { - $statement->execute( $this->extracted_variables ); - } catch ( PDOException $err ) { - $reason = $err->getCode(); - $message = $err->getMessage(); - } - } - } while ( 5 == $reason || 6 == $reason ); // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison - } else { - $this->queries[] = 'Executing: (no parameters)'; - do { - if ( 'update' === $this->query_type || 'replace' === $this->query_type ) { - try { - $this->beginTransaction(); - $statement->execute(); - $this->commit(); - } catch ( PDOException $err ) { - $reason = $err->getCode(); - $message = $err->getMessage(); - $this->rollBack(); - } - } else { - try { - $statement->execute(); - } catch ( PDOException $err ) { - $reason = $err->getCode(); - $message = $err->getMessage(); - } - } - } while ( 5 == $reason || 6 == $reason ); // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison - } - if ( $reason > 0 ) { - $err_message = sprintf( 'Error while executing query! Error message was: %s', $message ); - $this->set_error( __LINE__, __FUNCTION__, $err_message ); - return false; - } - $this->_results = $statement->fetchAll( PDO::FETCH_OBJ ); // phpcs:ignore WordPress.DB.RestrictedClasses - - // Generate the results that $wpdb will want to see. - switch ( $this->query_type ) { - case 'insert': - case 'update': - case 'replace': - $this->last_insert_id = $this->pdo->lastInsertId(); - $this->affected_rows = $statement->rowCount(); - $this->return_value = $this->affected_rows; - break; - - case 'select': - case 'show': - case 'showcolumns': - case 'showindex': - case 'describe': - case 'desc': - case 'check': - case 'analyze': - $this->num_rows = count( $this->_results ); - $this->return_value = $this->num_rows; - break; - - case 'delete': - $this->affected_rows = $statement->rowCount(); - $this->return_value = $this->affected_rows; - break; - - case 'alter': - case 'drop': - case 'create': - case 'optimize': - case 'truncate': - $this->return_value = true; - if ( $this->is_error ) { - $this->return_value = false; - } - break; - } - } - - /** - * Method to extract field data to an array and prepare the query statement. - * - * If original SQL statement is CREATE query, this function does nothing. - */ - private function extract_variables() { - if ( 'create' === $this->query_type ) { - $this->prepared_query = $this->rewritten_query; - return; - } - - // Long queries can really kill this. - $pattern = '/(? 10000000 ) { - $query = preg_replace_callback( - $pattern, - array( $this, 'replace_variables_with_placeholders' ), - $this->rewritten_query - ); - } else { - do { - if ( $limit > 10000000 ) { - $this->set_error( __LINE__, __FUNCTION__, 'The query is too big to parse properly' ); - break; // No point in continuing execution, would get into a loop. - } - ini_set( 'pcre.backtrack_limit', $limit ); - $query = preg_replace_callback( - $pattern, - array( $this, 'replace_variables_with_placeholders' ), - $this->rewritten_query - ); - $limit = $limit * 10; - } while ( is_null( $query ) ); - - // Reset the pcre.backtrack_limit. - ini_set( 'pcre.backtrack_limit', $_limit ); - } - - if ( isset( $query ) ) { - $this->queries[] = "With Placeholders:\n" . $query; - $this->prepared_query = $query; - } - } - - /** - * Call back function to replace field data with PDO parameter. - * - * @param string $matches Matched string. - * - * @return string - */ - private function replace_variables_with_placeholders( $matches ) { - // Remove the WordPress escaping mechanism. - $param = stripslashes( $matches[0] ); - - // Remove trailing spaces. - $param = trim( $param ); - - // Remove the quotes at the end and the beginning. - if ( in_array( $param[ strlen( $param ) - 1 ], array( "'", '"' ), true ) ) { - $param = substr( $param, 0, -1 ); // End. - } - if ( in_array( $param[0], array( "'", '"' ), true ) ) { - $param = substr( $param, 1 ); // Start. - } - $key = ':param_' . $this->param_num++; - $this->extracted_variables[] = $param; - // Return the placeholder. - return ' ' . $key . ' '; - } - - /** - * Method to determine which query type the argument is. - * - * It takes the query string ,determines the type and returns the type string. - * If the query is the type that SQLite Integration can't executes, returns false. - * - * @param string $query The query string. - * - * @return boolean - */ - private function determine_query_type( $query ) { - $result = preg_match( - '/^\\s*(SET|EXPLAIN|PRAGMA|SELECT\\s*FOUND_ROWS|SELECT|INSERT|UPDATE|REPLACE|DELETE|ALTER|CREATE|DROP\\s*INDEX|DROP|SHOW\\s*\\w+\\s*\\w+\\s*|DESCRIBE|DESC|TRUNCATE|OPTIMIZE|CHECK|ANALYZE)/i', - $query, - $match - ); - - if ( ! $result ) { - return false; - } - $this->query_type = strtolower( $match[1] ); - if ( stripos( $this->query_type, 'found' ) !== false ) { - $this->query_type = 'foundrows'; - } - if ( stripos( $this->query_type, 'show' ) !== false ) { - if ( stripos( $this->query_type, 'show table status' ) !== false ) { - $this->query_type = 'showstatus'; - } elseif ( - stripos( $this->query_type, 'show tables' ) !== false || - stripos( $this->query_type, 'show full tables' ) !== false - ) { - $this->query_type = 'show'; - } elseif ( - stripos( $this->query_type, 'show columns' ) !== false || - stripos( $this->query_type, 'show fields' ) !== false || - stripos( $this->query_type, 'show full columns' ) !== false - ) { - $this->query_type = 'showcolumns'; - } elseif ( - stripos( $this->query_type, 'show index' ) !== false || - stripos( $this->query_type, 'show indexes' ) !== false || - stripos( $this->query_type, 'show keys' ) !== false - ) { - $this->query_type = 'showindex'; - } elseif ( - stripos( $this->query_type, 'show variables' ) !== false || - stripos( $this->query_type, 'show global variables' ) !== false || - stripos( $this->query_type, 'show session variables' ) !== false - ) { - $this->query_type = 'show_variables'; - } else { - return false; - } - } - if ( stripos( $this->query_type, 'drop index' ) !== false ) { - $this->query_type = 'drop_index'; - } - - return true; - } - - /** - * Method to execute INSERT query for SQLite version 3.7.11 or later. - * - * SQLite version 3.7.11 began to support multiple rows insert with values - * clause. This is for that version or later. - * - * @param string $query The query string. - */ - private function execute_insert_query_new( $query ) { - $engine = $this->prepare_engine( $this->query_type ); - $this->rewritten_query = $engine->rewrite_query( $query, $this->query_type ); - $this->queries[] = "Rewritten:\n" . $this->rewritten_query; - $this->extract_variables(); - $statement = $this->prepare_query(); - $this->execute_query( $statement ); - } - - /** - * Method to execute INSERT query for SQLite version 3.7.10 or lesser. - * - * It executes the INSERT query for SQLite version 3.7.10 or lesser. It is - * necessary to rewrite multiple row values. - * - * @param string $query The query string. - */ - private function execute_insert_query( $query ) { - global $wpdb; - $multi_insert = false; - $statement = null; - $engine = $this->prepare_engine( $this->query_type ); - if ( preg_match( '/(INSERT.*?VALUES\\s*)(\(.*\))/imsx', $query, $matched ) ) { - $query_prefix = $matched[1]; - $values_data = $matched[2]; - if ( stripos( $values_data, 'ON DUPLICATE KEY' ) !== false ) { - $exploded_parts = $values_data; - } elseif ( stripos( $query_prefix, "INSERT INTO $wpdb->comments" ) !== false ) { - $exploded_parts = $values_data; - } else { - $exploded_parts = $this->parse_multiple_inserts( $values_data ); - } - $count = count( $exploded_parts ); - if ( $count > 1 ) { - $multi_insert = true; - } - } - if ( $multi_insert ) { - $first = true; - foreach ( $exploded_parts as $value ) { - $suffix = ( substr( $value, -1, 1 ) === ')' ) ? '' : ')'; - - $query_string = $query_prefix . ' ' . $value . $suffix; - $this->rewritten_query = $engine->rewrite_query( $query_string, $this->query_type ); - $this->queries[] = "Rewritten:\n" . $this->rewritten_query; - $this->extracted_variables = array(); - $this->extract_variables(); - if ( $first ) { - $statement = $this->prepare_query(); - $this->execute_query( $statement ); - $first = false; - } else { - $this->execute_query( $statement ); - } - } - } else { - $this->rewritten_query = $engine->rewrite_query( $query, $this->query_type ); - $this->queries[] = "Rewritten:\n" . $this->rewritten_query; - $this->extract_variables(); - $statement = $this->prepare_query(); - $this->execute_query( $statement ); - } - } - - /** - * Method to help rewriting multiple row values insert query. - * - * It splits the values clause into an array to execute separately. - * - * @param string $values The values to be split. - * - * @return array - */ - private function parse_multiple_inserts( $values ) { - $tokens = preg_split( "/(''|(?prepare_engine( $this->query_type ); - $rewritten_query = $engine->rewrite_query( $query ); - $reason = 0; - $message = ''; - - try { - $this->beginTransaction(); - foreach ( (array) $rewritten_query as $single_query ) { - $this->queries[] = "Executing:\n" . $single_query; - $single_query = trim( $single_query ); - if ( empty( $single_query ) ) { - continue; - } - $this->pdo->exec( $single_query ); - } - $this->commit(); - } catch ( PDOException $err ) { - $reason = $err->getCode(); - $message = $err->getMessage(); - if ( 5 == $reason || 6 == $reason ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison - $this->commit(); - } else { - $this->rollBack(); - } - } - if ( $reason > 0 ) { - $err_message = sprintf( 'Problem in creating table or index. Error was: %s', $message ); - $this->set_error( __LINE__, __FUNCTION__, $err_message ); - - return false; - } - - return true; - } - - /** - * Method to execute ALTER TABLE query. - * - * @param string $query The query to execute. - * - * @return boolean - */ - private function execute_alter_query( $query ) { - $engine = $this->prepare_engine( $this->query_type ); - $reason = 0; - $message = ''; - $re_query = ''; - $rewritten_query = $engine->rewrite_query( $query, $this->query_type ); - if ( is_array( $rewritten_query ) && array_key_exists( 'recursion', $rewritten_query ) ) { - $re_query = $rewritten_query['recursion']; - unset( $rewritten_query['recursion'] ); - } - try { - $this->beginTransaction(); - if ( is_array( $rewritten_query ) ) { - foreach ( $rewritten_query as $single_query ) { - $this->queries[] = "Executing:\n" . $single_query; - $single_query = trim( $single_query ); - if ( empty( $single_query ) ) { - continue; - } - $this->pdo->exec( $single_query ); - } - } else { - $this->queries[] = "Executing:\n" . $rewritten_query; - $rewritten_query = trim( $rewritten_query ); - $this->pdo->exec( $rewritten_query ); - } - $this->commit(); - } catch ( PDOException $err ) { - $reason = $err->getCode(); - $message = $err->getMessage(); - if ( 5 == $reason || 6 == $reason ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison - $this->commit(); - usleep( 10000 ); - } else { - $this->rollBack(); - } - } - if ( '' !== $re_query ) { - $this->query( $re_query ); - } - if ( $reason > 0 ) { - $err_message = sprintf( 'Problem in executing alter query. Error was: %s', $message ); - $this->set_error( __LINE__, __FUNCTION__, $err_message ); - - return false; - } - - return true; - } - - /** - * Method to execute SHOW VARIABLES query - * - * This query is meaningless for SQLite. This function returns null data with some - * exceptions and only avoids the error message. - * - * @param string $query The query to execute. - * - * @return bool - */ - private function show_variables_workaround( $query ) { - $dummy_data = array( - 'Variable_name' => '', - 'Value' => null, - ); - $pattern = '/SHOW\\s*VARIABLES\\s*LIKE\\s*(.*)?$/im'; - if ( preg_match( $pattern, $query, $match ) ) { - $value = str_replace( "'", '', $match[1] ); - $dummy_data['Variable_name'] = trim( $value ); - // This is set for Wordfence Security Plugin. - $dummy_data['Value'] = ''; - if ( 'max_allowed_packet' === $value ) { - $dummy_data['Value'] = 1047552; - } - } - $_results[] = new Perflab_SQLite_Object_Array( $dummy_data ); - $this->results = $_results; - $this->num_rows = count( $this->results ); - $this->return_value = $this->num_rows; - - return true; - } - - /** - * Method to execute SHOW TABLE STATUS query. - * - * This query is meaningless for SQLite. This function returns dummy data. - * - * @param string $query The query to execute. - * - * @return bool - */ - private function show_status_workaround( $query ) { - $pattern = '/^SHOW\\s*TABLE\\s*STATUS\\s*LIKE\\s*(.*?)$/im'; - $table_name = ''; - if ( preg_match( $pattern, $query, $match ) ) { - $table_name = str_replace( "'", '', $match[1] ); - } - $dummy_data = array( - 'Name' => $table_name, - 'Engine' => '', - 'Version' => '', - 'Row_format' => '', - 'Rows' => 0, - 'Avg_row_length' => 0, - 'Data_length' => 0, - 'Max_data_length' => 0, - 'Index_length' => 0, - 'Data_free' => 0, - 'Auto_increment' => 0, - 'Create_time' => '', - 'Update_time' => '', - 'Check_time' => '', - 'Collation' => '', - 'Checksum' => '', - 'Create_options' => '', - 'Comment' => '', - ); - $_results[] = new Perflab_SQLite_Object_Array( $dummy_data ); - $this->results = $_results; - $this->num_rows = count( $this->results ); - $this->return_value = $this->num_rows; - - return true; - } - - /** - * Method to format the queried data to that of MySQL. - * - * @param string $engine Not used. - */ - private function process_results( $engine ) { - if ( in_array( $this->query_type, array( 'describe', 'desc', 'showcolumns' ), true ) ) { - $this->convert_to_columns_object(); - } elseif ( 'showindex' === $this->query_type ) { - $this->convert_to_index_object(); - } elseif ( in_array( $this->query_type, array( 'check', 'analyze' ), true ) ) { - $this->convert_result_check_or_analyze(); - } else { - $this->results = $this->_results; - } - } - - /** - * Method to format the error messages and put out to the file. - * - * When $wpdb::suppress_errors is set to true or $wpdb::show_errors is set to false, - * the error messages are ignored. - * - * @param string $line Where the error occurred. - * @param string $function Indicate the function name where the error occurred. - * @param string $message The message. - * - * @return boolean|void - */ - private function set_error( $line, $function, $message ) { - global $wpdb; - $this->errors[] = array( - 'line' => $line, - 'function' => $function, - ); - $this->error_messages[] = $message; - $this->is_error = true; - if ( $wpdb->suppress_errors || ! $wpdb->show_errors ) { - return false; - } - error_log( "Line $line, Function: $function, Message: $message" ); - } - - /** - * Method to change the queried data to PHP object format. - * - * It takes the associative array of query results and creates a numeric - * array of anonymous objects - * - * @access private - */ - private function convert_to_object() { - $_results = array(); - if ( count( $this->results ) === 0 ) { - echo $this->get_error_message(); - } else { - foreach ( $this->results as $row ) { - $_results[] = new Perflab_SQLite_Object_Array( $row ); - } - } - $this->results = $_results; - } - - /** - * Method to convert the SHOW COLUMNS query data to an object. - * - * It rewrites pragma results to mysql compatible array - * when query_type is describe, we use sqlite pragma function. - * - * @access private - */ - private function convert_to_columns_object() { - $_results = array(); - $_columns = array( // Field names MySQL SHOW COLUMNS returns. - 'Field' => '', - 'Type' => '', - 'Null' => '', - 'Key' => '', - 'Default' => '', - 'Extra' => '', - ); - if ( empty( $this->_results ) ) { - echo $this->get_error_message(); - } else { - foreach ( $this->_results as $row ) { - if ( ! is_object( $row ) ) { - continue; - } - if ( property_exists( $row, 'name' ) ) { - $_columns['Field'] = $row->name; - } - if ( property_exists( $row, 'type' ) ) { - $_columns['Type'] = $row->type; - } - if ( property_exists( $row, 'notnull' ) ) { - $_columns['Null'] = $row->notnull ? 'NO' : 'YES'; - } - if ( property_exists( $row, 'pk' ) ) { - $_columns['Key'] = $row->pk ? 'PRI' : ''; - } - if ( property_exists( $row, 'dflt_value' ) ) { - $_columns['Default'] = $row->dflt_value; - } - $_results[] = new Perflab_SQLite_Object_Array( $_columns ); - } - } - $this->results = $_results; - } - - /** - * Method to convert SHOW INDEX query data to PHP object. - * - * It rewrites the result of SHOW INDEX to the Object compatible with MySQL - * added the WHERE clause manipulation (ver 1.3.1) - * - * @access private - */ - private function convert_to_index_object() { - $_results = array(); - $_columns = array( - 'Table' => '', - 'Non_unique' => '', // Unique -> 0, not unique -> 1. - 'Key_name' => '', // The name of the index. - 'Seq_in_index' => '', // Column sequence number in the index. begins at 1. - 'Column_name' => '', - 'Collation' => '', // A(scend) or NULL. - 'Cardinality' => '', - 'Sub_part' => '', // Set to NULL. - 'Packed' => '', // How to pack key or else NULL. - 'Null' => '', // If column contains null, YES. If not, NO. - 'Index_type' => '', // BTREE, FULLTEXT, HASH, RTREE. - 'Comment' => '', - ); - if ( 0 === count( $this->_results ) ) { - echo $this->get_error_message(); - } else { - foreach ( $this->_results as $row ) { - if ( 'table' === $row->type && ! stripos( $row->sql, 'primary' ) ) { - continue; - } - if ( 'index' === $row->type && stripos( $row->name, 'sqlite_autoindex' ) !== false ) { - continue; - } - switch ( $row->type ) { - case 'table': - $pattern1 = '/^\\s*PRIMARY.*\((.*)\)/im'; - $pattern2 = '/^\\s*(\\w+)?\\s*.*PRIMARY.*(?!\()/im'; - if ( preg_match( $pattern1, $row->sql, $match ) ) { - $col_name = trim( $match[1] ); - $_columns['Key_name'] = 'PRIMARY'; - $_columns['Non_unique'] = 0; - $_columns['Column_name'] = $col_name; - } elseif ( preg_match( $pattern2, $row->sql, $match ) ) { - $col_name = trim( $match[1] ); - $_columns['Key_name'] = 'PRIMARY'; - $_columns['Non_unique'] = 0; - $_columns['Column_name'] = $col_name; - } - break; - - case 'index': - $_columns['Non_unique'] = 1; - if ( stripos( $row->sql, 'unique' ) !== false ) { - $_columns['Non_unique'] = 0; - } - if ( preg_match( '/^.*\((.*)\)/i', $row->sql, $match ) ) { - $col_name = str_replace( "'", '', $match[1] ); - $_columns['Column_name'] = trim( $col_name ); - } - $_columns['Key_name'] = $row->name; - break; - - } - $_columns['Table'] = $row->tbl_name; - $_columns['Collation'] = null; - $_columns['Cardinality'] = 0; - $_columns['Sub_part'] = null; - $_columns['Packed'] = null; - $_columns['Null'] = 'NO'; - $_columns['Index_type'] = 'BTREE'; - $_columns['Comment'] = ''; - $_results[] = new Perflab_SQLite_Object_Array( $_columns ); - } - if ( stripos( $this->queries[0], 'WHERE' ) !== false ) { - preg_match( '/WHERE\\s*(.*)$/im', $this->queries[0], $match ); - list($key, $value) = explode( '=', $match[1] ); - $key = trim( $key ); - $value = trim( preg_replace( "/[\';]/", '', $value ) ); - foreach ( $_results as $result ) { - if ( ! empty( $result->$key ) && is_scalar( $result->$key ) && stripos( $value, $result->$key ) !== false ) { - unset( $_results ); - $_results[] = $result; - break; - } - } - } - } - - $this->results = $_results; - } - - /** - * Method to the CHECK query data to an object. - * - * @access private - */ - private function convert_result_check_or_analyze() { - $is_check = 'check' === $this->query_type; - $_results[] = new Perflab_SQLite_Object_Array( - array( - 'Table' => '', - 'Op' => $is_check ? 'check' : 'analyze', - 'Msg_type' => 'status', - 'Msg_text' => $is_check ? __( 'OK', 'performance-lab' ) : __( 'Table is already up to date', 'performance-lab' ), - ) - ); - $this->results = $_results; - } - - /** - * Method to check SQLite library version. - * - * This is used for checking if SQLite can execute multiple rows insert. - * - * @return version number string or 0 - * @access private - */ - private function get_sqlite_version() { - try { - $statement = $this->pdo->prepare( 'SELECT sqlite_version()' ); - $statement->execute(); - $result = $statement->fetch( PDO::FETCH_NUM ); // phpcs:ignore WordPress.DB.RestrictedClasses - - return $result[0]; - } catch ( PDOException $err ) { - return '0'; - } - } - - /** - * Method to call PDO::beginTransaction(). - * - * @see PDO::beginTransaction() - * @return boolean - */ - public function beginTransaction() { - if ( $this->has_active_transaction ) { - return false; - } - $this->has_active_transaction = $this->pdo->beginTransaction(); - return $this->has_active_transaction; - } - - /** - * Method to call PDO::commit(). - * - * @see PDO::commit() - * @return void - */ - public function commit() { - $this->pdo->commit(); - $this->has_active_transaction = false; - } - - /** - * Method to call PDO::rollBack(). - * - * @see PDO::rollBack() - * @return void - */ - public function rollBack() { - $this->pdo->rollBack(); - $this->has_active_transaction = false; - } -} diff --git a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-pdo-user-defined-functions.php b/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-pdo-user-defined-functions.php deleted file mode 100644 index d1f4421c14..0000000000 --- a/modules/database/sqlite/wp-includes/sqlite/class-perflab-sqlite-pdo-user-defined-functions.php +++ /dev/null @@ -1,781 +0,0 @@ - - * new Perflab_SQLite_PDO_User_Defined_Functions(ref_to_pdo_obj); - * - * - * This automatically enables ref_to_pdo_obj to replace the function in the SQL statement - * to the ones defined here. - */ -class Perflab_SQLite_PDO_User_Defined_Functions { - - /** - * The class constructor - * - * Initializes the use defined functions to PDO object with PDO::sqliteCreateFunction(). - * - * @param PDO $pdo The PDO object. - */ - public function __construct( $pdo ) { - if ( ! $pdo ) { - wp_die( 'Database is not initialized.', 'Database Error' ); - } - foreach ( $this->functions as $f => $t ) { - $pdo->sqliteCreateFunction( $f, array( $this, $t ) ); - } - } - - /** - * Array to define MySQL function => function defined with PHP. - * - * Replaced functions must be public. - * - * @var array - */ - private $functions = array( - 'month' => 'month', - 'year' => 'year', - 'day' => 'day', - 'unix_timestamp' => 'unix_timestamp', - 'now' => 'now', - 'char_length' => 'char_length', - 'md5' => 'md5', - 'curdate' => 'curdate', - 'rand' => 'rand', - 'substring' => 'substring', - 'dayofmonth' => 'day', - 'second' => 'second', - 'minute' => 'minute', - 'hour' => 'hour', - 'date_format' => 'dateformat', - 'from_unixtime' => 'from_unixtime', - 'date_add' => 'date_add', - 'date_sub' => 'date_sub', - 'adddate' => 'date_add', - 'subdate' => 'date_sub', - 'localtime' => 'now', - 'localtimestamp' => 'now', - 'isnull' => 'isnull', - 'if' => '_if', - 'regexpp' => 'regexp', - 'concat' => 'concat', - 'field' => 'field', - 'log' => 'log', - 'least' => 'least', - 'greatest' => 'greatest', - 'get_lock' => 'get_lock', - 'release_lock' => 'release_lock', - 'ucase' => 'ucase', - 'lcase' => 'lcase', - 'inet_ntoa' => 'inet_ntoa', - 'inet_aton' => 'inet_aton', - 'datediff' => 'datediff', - 'locate' => 'locate', - 'utc_date' => 'utc_date', - 'utc_time' => 'utc_time', - 'utc_timestamp' => 'utc_timestamp', - 'version' => 'version', - ); - - /** - * Method to extract the month value from the date. - * - * @param string $field representing the date formatted as 0000-00-00. - * - * @return string representing the number of the month between 1 and 12. - */ - public function month( $field ) { - return gmdate( 'n', strtotime( $field ) ); - } - - /** - * Method to extract the year value from the date. - * - * @param string $field representing the date formatted as 0000-00-00. - * - * @return string representing the number of the year. - */ - public function year( $field ) { - return gmdate( 'Y', strtotime( $field ) ); - } - - /** - * Method to extract the day value from the date. - * - * @param string $field Representing the date formatted as 0000-00-00. - * - * @return string representing the number of the day of the month from 1 and 31. - */ - public function day( $field ) { - return gmdate( 'j', strtotime( $field ) ); - } - - /** - * Method to return the unix timestamp. - * - * Used without an argument, it returns PHP time() function (total seconds passed - * from '1970-01-01 00:00:00' GMT). Used with the argument, it changes the value - * to the timestamp. - * - * @param string $field Representing the date formatted as '0000-00-00 00:00:00'. - * - * @return number of unsigned integer - */ - public function unix_timestamp( $field = null ) { - return is_null( $field ) ? time() : strtotime( $field ); - } - - /** - * Method to emulate MySQL SECOND() function. - * - * @param string $field Representing the time formatted as '00:00:00'. - * - * @return number of unsigned integer - */ - public function second( $field ) { - return intval( gmdate( 's', strtotime( $field ) ) ); - } - - /** - * Method to emulate MySQL MINUTE() function. - * - * @param string $field Representing the time formatted as '00:00:00'. - * - * @return number of unsigned integer - */ - public function minute( $field ) { - return intval( gmdate( 'i', strtotime( $field ) ) ); - } - - /** - * Method to emulate MySQL HOUR() function. - * - * @param string $time Representing the time formatted as '00:00:00'. - * - * @return number - */ - public function hour( $time ) { - list($hours) = explode( ':', $time ); - - return intval( $hours ); - } - - /** - * Method to emulate MySQL FROM_UNIXTIME() function. - * - * @param integer $field The unix timestamp. - * @param string $format Indicate the way of formatting(optional). - * - * @return string formatted as '0000-00-00 00:00:00'. - */ - public function from_unixtime( $field, $format = null ) { - // Convert to ISO time. - $date = gmdate( 'Y-m-d H:i:s', $field ); - - return is_null( $format ) ? $date : $this->dateformat( $date, $format ); - } - - /** - * Method to emulate MySQL NOW() function. - * - * @return string representing current time formatted as '0000-00-00 00:00:00'. - */ - public function now() { - return gmdate( 'Y-m-d H:i:s' ); - } - - /** - * Method to emulate MySQL CURDATE() function. - * - * @return string representing current time formatted as '0000-00-00'. - */ - public function curdate() { - return gmdate( 'Y-m-d' ); - } - - /** - * Method to emulate MySQL CHAR_LENGTH() function. - * - * @param string $field The string to be measured. - * - * @return int unsigned integer for the length of the argument. - */ - public function char_length( $field ) { - return strlen( $field ); - } - - /** - * Method to emulate MySQL MD5() function. - * - * @param string $field The string to be hashed. - * - * @return string of the md5 hash value of the argument. - */ - public function md5( $field ) { - return md5( $field ); - } - - /** - * Method to emulate MySQL RAND() function. - * - * SQLite does have a random generator, but it is called RANDOM() and returns random - * number between -9223372036854775808 and +9223372036854775807. So we substitute it - * with PHP random generator. - * - * This function uses mt_rand() which is four times faster than rand() and returns - * the random number between 0 and 1. - * - * @return int - */ - public function rand() { - return mt_rand( 0, 1 ); - } - - /** - * Method to emulate MySQL SUBSTRING() function. - * - * This function rewrites the function name to SQLite compatible substr(), - * which can manipulate UTF-8 characters. - * - * @param string $text The text to be processed. - * @param integer $pos Representing the start point. - * @param integer $len Representing the length of the substring(optional). - * - * @return string - */ - public function substring( $text, $pos, $len = null ) { - return "substr($text, $pos, $len)"; - } - - /** - * Method to emulate MySQL DATEFORMAT() function. - * - * @param string $date Formatted as '0000-00-00' or datetime as '0000-00-00 00:00:00'. - * @param string $format The string format. - * - * @return string formatted according to $format - */ - public function dateformat( $date, $format ) { - $mysql_php_date_formats = array( - '%a' => 'D', - '%b' => 'M', - '%c' => 'n', - '%D' => 'jS', - '%d' => 'd', - '%e' => 'j', - '%H' => 'H', - '%h' => 'h', - '%I' => 'h', - '%i' => 'i', - '%j' => 'z', - '%k' => 'G', - '%l' => 'g', - '%M' => 'F', - '%m' => 'm', - '%p' => 'A', - '%r' => 'h:i:s A', - '%S' => 's', - '%s' => 's', - '%T' => 'H:i:s', - '%U' => 'W', - '%u' => 'W', - '%V' => 'W', - '%v' => 'W', - '%W' => 'l', - '%w' => 'w', - '%X' => 'Y', - '%x' => 'o', - '%Y' => 'Y', - '%y' => 'y', - ); - - $time = strtotime( $date ); - $format = strtr( $format, $mysql_php_date_formats ); - - return gmdate( $format, $time ); - } - - /** - * Method to emulate MySQL DATE_ADD() function. - * - * This function adds the time value of $interval expression to $date. - * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). - * It is calculated in the private function derive_interval(). - * - * @param string $date representing the start date. - * @param string $interval representing the expression of the time to add. - * - * @return string date formatted as '0000-00-00 00:00:00'. - */ - public function date_add( $date, $interval ) { - $interval = $this->derive_interval( $interval ); - switch ( strtolower( $date ) ) { - case 'curdate()': - $date_object = new DateTime( $this->curdate() ); - $date_object->add( new DateInterval( $interval ) ); - return $date_object->format( 'Y-m-d' ); - - case 'now()': - $date_object = new DateTime( $this->now() ); - $date_object->add( new DateInterval( $interval ) ); - return $date_object->format( 'Y-m-d H:i:s' ); - - default: - $date_object = new DateTime( $date ); - $date_object->add( new DateInterval( $interval ) ); - return $date_object->format( 'Y-m-d H:i:s' ); - } - } - - /** - * Method to emulate MySQL DATE_SUB() function. - * - * This function subtracts the time value of $interval expression from $date. - * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). - * It is calculated in the private function derive_interval(). - * - * @param string $date representing the start date. - * @param string $interval representing the expression of the time to subtract. - * - * @return string date formatted as '0000-00-00 00:00:00'. - */ - public function date_sub( $date, $interval ) { - $interval = $this->derive_interval( $interval ); - switch ( strtolower( $date ) ) { - case 'curdate()': - $date_object = new DateTime( $this->curdate() ); - $date_object->sub( new DateInterval( $interval ) ); - return $date_object->format( 'Y-m-d' ); - - case 'now()': - $date_object = new DateTime( $this->now() ); - $date_object->sub( new DateInterval( $interval ) ); - return $date_object->format( 'Y-m-d H:i:s' ); - - default: - $date_object = new DateTime( $date ); - $date_object->sub( new DateInterval( $interval ) ); - return $date_object->format( 'Y-m-d H:i:s' ); - } - } - - /** - * Method to calculate the interval time between two dates value. - * - * @access private - * - * @param string $interval white space separated expression. - * - * @return string representing the time to add or substract. - */ - private function derive_interval( $interval ) { - $interval = trim( substr( trim( $interval ), 8 ) ); - $parts = explode( ' ', $interval ); - foreach ( $parts as $part ) { - if ( ! empty( $part ) ) { - $_parts[] = $part; - } - } - $type = strtolower( end( $_parts ) ); - switch ( $type ) { - case 'second': - return 'PT' . $_parts[0] . 'S'; - - case 'minute': - return 'PT' . $_parts[0] . 'M'; - - case 'hour': - return 'PT' . $_parts[0] . 'H'; - - case 'day': - return 'P' . $_parts[0] . 'D'; - - case 'week': - return 'P' . $_parts[0] . 'W'; - - case 'month': - return 'P' . $_parts[0] . 'M'; - - case 'year': - return 'P' . $_parts[0] . 'Y'; - - case 'minute_second': - list($minutes, $seconds) = explode( ':', $_parts[0] ); - return 'PT' . $minutes . 'M' . $seconds . 'S'; - - case 'hour_second': - list($hours, $minutes, $seconds) = explode( ':', $_parts[0] ); - return 'PT' . $hours . 'H' . $minutes . 'M' . $seconds . 'S'; - - case 'hour_minute': - list($hours, $minutes) = explode( ':', $_parts[0] ); - return 'PT' . $hours . 'H' . $minutes . 'M'; - - case 'day_second': - $days = intval( $_parts[0] ); - list($hours, $minutes, $seconds) = explode( ':', $_parts[1] ); - return 'P' . $days . 'D' . 'T' . $hours . 'H' . $minutes . 'M' . $seconds . 'S'; - - case 'day_minute': - $days = intval( $_parts[0] ); - list($hours, $minutes) = explode( ':', $parts[1] ); - return 'P' . $days . 'D' . 'T' . $hours . 'H' . $minutes . 'M'; - - case 'day_hour': - $days = intval( $_parts[0] ); - $hours = intval( $_parts[1] ); - return 'P' . $days . 'D' . 'T' . $hours . 'H'; - - case 'year_month': - list($years, $months) = explode( '-', $_parts[0] ); - return 'P' . $years . 'Y' . $months . 'M'; - } - return ''; - } - - /** - * Method to emulate MySQL DATE() function. - * - * @param string $date formatted as unix time. - * - * @return string formatted as '0000-00-00'. - */ - public function date( $date ) { - return gmdate( 'Y-m-d', strtotime( $date ) ); - } - - /** - * Method to emulate MySQL ISNULL() function. - * - * This function returns true if the argument is null, and true if not. - * - * @param mixed $field The field to be tested. - * - * @return boolean - */ - public function isnull( $field ) { - return is_null( $field ); - } - - /** - * Method to emulate MySQL IF() function. - * - * As 'IF' is a reserved word for PHP, function name must be changed. - * - * @param unknonw $expression the statement to be evaluated as true or false. - * @param unknown $true statement or value returned if $expression is true. - * @param unknown $false statement or value returned if $expression is false. - * - * @return unknown - */ - public function _if( $expression, $true, $false ) { - return ( true === $expression ) ? $true : $false; - } - - /** - * Method to emulate MySQL REGEXP() function. - * - * @param string $field Haystack. - * @param string $pattern Regular expression to match. - * - * @return integer 1 if matched, 0 if not matched. - */ - public function regexp( $field, $pattern ) { - $pattern = str_replace( '/', '\/', $pattern ); - $pattern = '/' . $pattern . '/i'; - - return preg_match( $pattern, $field ); - } - - /** - * Method to emulate MySQL CONCAT() function. - * - * SQLite does have CONCAT() function, but it has a different syntax from MySQL. - * So this function must be manipulated here. - * - * @return null|string Return null if the argument is null, or a concatenated string if the argument is given. - */ - public function concat() { - $return_value = ''; - $args_num = func_num_args(); - $args_list = func_get_args(); - for ( $i = 0; $i < $args_num; $i++ ) { - if ( is_null( $args_list[ $i ] ) ) { - return null; - } - $return_value .= $args_list[ $i ]; - } - - return $return_value; - } - - /** - * Method to emulate MySQL FIELD() function. - * - * This function gets the list argument and compares the first item to all the others. - * If the same value is found, it returns the position of that value. If not, it - * returns 0. - * - * @return int - */ - public function field() { - global $wpdb; - $num_args = func_num_args(); - if ( $num_args < 2 || is_null( func_get_arg( 0 ) ) ) { - return 0; - } - $arg_list = func_get_args(); - $search_string = array_shift( $arg_list ); - $str_to_check = substr( $search_string, 0, strpos( $search_string, '.' ) ); - $str_to_check = str_replace( $wpdb->prefix, '', $str_to_check ); - if ( $str_to_check && in_array( trim( $str_to_check ), $wpdb->tables, true ) ) { - return 0; - } - for ( $i = 0; $i < $num_args - 1; $i++ ) { - if ( strtolower( $arg_list[ $i ] ) === $search_string ) { - return $i + 1; - } - } - - return 0; - } - - /** - * Method to emulate MySQL LOG() function. - * - * Used with one argument, it returns the natural logarithm of X. - * - * LOG(X) - * - * Used with two arguments, it returns the natural logarithm of X base B. - * - * LOG(B, X) - * - * In this case, it returns the value of log(X) / log(B). - * - * Used without an argument, it returns false. This returned value will be - * rewritten to 0, because SQLite doesn't understand true/false value. - * - * @return double|null - */ - public function log() { - $num_args = func_num_args(); - if ( 1 === $num_args ) { - $arg1 = func_get_arg( 0 ); - - return log( $arg1 ); - } - if ( 2 === $num_args ) { - $arg1 = func_get_arg( 0 ); - $arg2 = func_get_arg( 1 ); - - return log( $arg1 ) / log( $arg2 ); - } - return null; - } - - /** - * Method to emulate MySQL LEAST() function. - * - * This function rewrites the function name to SQLite compatible function name. - * - * @return mixed - */ - public function least() { - $arg_list = func_get_args(); - - return "min($arg_list)"; - } - - /** - * Method to emulate MySQL GREATEST() function. - * - * This function rewrites the function name to SQLite compatible function name. - * - * @return mixed - */ - public function greatest() { - $arg_list = func_get_args(); - - return "max($arg_list)"; - } - - /** - * Method to dummy out MySQL GET_LOCK() function. - * - * This function is meaningless in SQLite, so we do nothing. - * - * @param string $name Not used. - * @param integer $timeout Not used. - * - * @return string - */ - public function get_lock( $name, $timeout ) { - return '1=1'; - } - - /** - * Method to dummy out MySQL RELEASE_LOCK() function. - * - * This function is meaningless in SQLite, so we do nothing. - * - * @param string $name Not used. - * - * @return string - */ - public function release_lock( $name ) { - return '1=1'; - } - - /** - * Method to emulate MySQL UCASE() function. - * - * This is MySQL alias for upper() function. This function rewrites it - * to SQLite compatible name upper(). - * - * @param string $content String to be converted to uppercase. - * - * @return string SQLite compatible function name. - */ - public function ucase( $content ) { - return "upper($content)"; - } - - /** - * Method to emulate MySQL LCASE() function. - * - * This is MySQL alias for lower() function. This function rewrites it - * to SQLite compatible name lower(). - * - * @param string $content String to be converted to lowercase. - * - * @return string SQLite compatible function name. - */ - public function lcase( $content ) { - return "lower($content)"; - } - - /** - * Method to emulate MySQL INET_NTOA() function. - * - * This function gets 4 or 8 bytes integer and turn it into the network address. - * - * @param integer $num Long integer. - * - * @return string - */ - public function inet_ntoa( $num ) { - return long2ip( $num ); - } - - /** - * Method to emulate MySQL INET_ATON() function. - * - * This function gets the network address and turns it into integer. - * - * @param string $addr Network address. - * - * @return int long integer - */ - public function inet_aton( $addr ) { - return absint( ip2long( $addr ) ); - } - - /** - * Method to emulate MySQL DATEDIFF() function. - * - * This function compares two dates value and returns the difference. - * - * @param string $start Start date. - * @param string $end End date. - * - * @return string - */ - public function datediff( $start, $end ) { - $start_date = new DateTime( $start ); - $end_date = new DateTime( $end ); - $interval = $end_date->diff( $start_date, false ); - - return $interval->format( '%r%a' ); - } - - /** - * Method to emulate MySQL LOCATE() function. - * - * This function returns the position if $substr is found in $str. If not, - * it returns 0. If mbstring extension is loaded, mb_strpos() function is - * used. - * - * @param string $substr Needle. - * @param string $str Haystack. - * @param integer $pos Position. - * - * @return integer - */ - public function locate( $substr, $str, $pos = 0 ) { - if ( ! extension_loaded( 'mbstring' ) ) { - $val = strpos( $str, $substr, $pos ); - if ( false !== $val ) { - return $val + 1; - } - return 0; - } - $val = mb_strpos( $str, $substr, $pos ); - if ( false !== $val ) { - return $val + 1; - } - return 0; - } - - /** - * Method to return GMT date in the string format. - * - * @return string formatted GMT date 'dddd-mm-dd' - */ - public function utc_date() { - return gmdate( 'Y-m-d', time() ); - } - - /** - * Method to return GMT time in the string format. - * - * @return string formatted GMT time '00:00:00' - */ - public function utc_time() { - return gmdate( 'H:i:s', time() ); - } - - /** - * Method to return GMT time stamp in the string format. - * - * @return string formatted GMT timestamp 'yyyy-mm-dd 00:00:00' - */ - public function utc_timestamp() { - return gmdate( 'Y-m-d H:i:s', time() ); - } - - /** - * Method to return MySQL version. - * - * This function only returns the current newest version number of MySQL, - * because it is meaningless for SQLite database. - * - * @return string representing the version number: major_version.minor_version - */ - public function version() { - return '5.5'; - } -} diff --git a/modules/database/sqlite/wp-includes/sqlite/db.php b/modules/database/sqlite/wp-includes/sqlite/db.php deleted file mode 100644 index 4480b9155a..0000000000 --- a/modules/database/sqlite/wp-includes/sqlite/db.php +++ /dev/null @@ -1,54 +0,0 @@ -%1$s

%2$s

', - 'PHP PDO Extension is not loaded', - 'Your PHP installation appears to be missing the PDO extension which is required for this version of WordPress and the type of database you have specified.' - ) - ), - 'PHP PDO Extension is not loaded.' - ); -} - -if ( ! extension_loaded( 'pdo_sqlite' ) ) { - wp_die( - new WP_Error( - 'pdo_driver_not_loaded', - sprintf( - '

%1$s

%2$s

', - 'PDO Driver for SQLite is missing', - 'Your PHP installation appears not to have the right PDO drivers loaded. These are required for this version of WordPress and the type of database you have specified.' - ) - ), - 'PDO Driver for SQLite is missing.' - ); -} - -require_once __DIR__ . '/class-perflab-sqlite-pdo-user-defined-functions.php'; -require_once __DIR__ . '/class-perflab-sqlite-pdo-engine.php'; -require_once __DIR__ . '/class-perflab-sqlite-object-array.php'; -require_once __DIR__ . '/class-perflab-sqlite-db.php'; -require_once __DIR__ . '/class-perflab-sqlite-pdo-driver.php'; -require_once __DIR__ . '/class-perflab-sqlite-create-query.php'; -require_once __DIR__ . '/class-perflab-sqlite-alter-query.php'; -require_once __DIR__ . '/install-functions.php'; - -$GLOBALS['wpdb'] = new Perflab_SQLite_DB(); diff --git a/modules/database/sqlite/wp-includes/sqlite/install-functions.php b/modules/database/sqlite/wp-includes/sqlite/install-functions.php deleted file mode 100644 index e7442ffab4..0000000000 --- a/modules/database/sqlite/wp-includes/sqlite/install-functions.php +++ /dev/null @@ -1,212 +0,0 @@ - PDO::ERRMODE_EXCEPTION ) ); // phpcs:ignore WordPress.DB.RestrictedClasses - } catch ( PDOException $err ) { - $err_data = $err->errorInfo; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase - $message = 'Database connection error!
'; - $message .= sprintf( 'Error message is: %s', $err_data[2] ); - wp_die( $message, 'Database Error!' ); - } - - try { - $pdo->beginTransaction(); - foreach ( $queries as $query ) { - $query = trim( $query ); - if ( empty( $query ) ) { - continue; - } - $rewritten_query = $query_parser->rewrite_query( $query ); - if ( is_array( $rewritten_query ) ) { - $table_query = array_shift( $rewritten_query ); - $index_queries = $rewritten_query; - $table_query = trim( $table_query ); - $pdo->exec( $table_query ); - } else { - $rewritten_query = trim( $rewritten_query ); - $pdo->exec( $rewritten_query ); - } - } - $pdo->commit(); - if ( $index_queries ) { - // $query_parser rewrites KEY to INDEX, so we don't need KEY pattern. - $pattern = '/CREATE\\s*(UNIQUE\\s*INDEX|INDEX)\\s*IF\\s*NOT\\s*EXISTS\\s*(\\w+)?\\s*.*/im'; - $pdo->beginTransaction(); - foreach ( $index_queries as $index_query ) { - preg_match( $pattern, $index_query, $match ); - $index_name = trim( $match[2] ); - if ( in_array( $index_name, $index_array, true ) ) { - $r = rand( 0, 50 ); - $replacement = $index_name . "_$r"; - $index_query = str_ireplace( - 'EXISTS ' . $index_name, - 'EXISTS ' . $replacement, - $index_query - ); - } else { - $index_array[] = $index_name; - } - $pdo->exec( $index_query ); - } - $pdo->commit(); - } - } catch ( PDOException $err ) { - $err_data = $err->errorInfo; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase - $err_code = $err_data[1]; - if ( 5 == $err_code || 6 == $err_code ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison - // If the database is locked, commit again. - $pdo->commit(); - } else { - $pdo->rollBack(); - $message = sprintf( - 'Error occurred while creating tables or indexes...
Query was: %s
', - var_export( $rewritten_query, true ) - ); - $message .= sprintf( 'Error message is: %s', $err_data[2] ); - wp_die( $message, 'Database Error!' ); - } - } - - $query_parser = null; - $pdo = null; - - return true; -} - -/** - * Installs the site. - * - * Runs the required functions to set up and populate the database, - * including primary admin user and initial options. - * - * @since 1.8.0 - * - * @param string $blog_title Site title. - * @param string $user_name User's username. - * @param string $user_email User's email. - * @param bool $is_public Whether the site is public. - * @param string $deprecated Optional. Not used. - * @param string $user_password Optional. User's chosen password. Default empty (random password). - * @param string $language Optional. Language chosen. Default empty. - * @return array { - * Data for the newly installed site. - * - * @type string $url The URL of the site. - * @type int $user_id The ID of the site owner. - * @type string $password The password of the site owner, if their user account didn't already exist. - * @type string $password_message The explanatory message regarding the password. - * } - */ -function wp_install( $blog_title, $user_name, $user_email, $is_public, $deprecated = '', $user_password = '', $language = '' ) { - if ( ! empty( $deprecated ) ) { - _deprecated_argument( __FUNCTION__, '2.6.0' ); - } - - wp_check_mysql_version(); - wp_cache_flush(); - /* SQLite changes: Replace the call to make_db_current_silent() with perflab_sqlite_make_db_sqlite(). */ - perflab_sqlite_make_db_sqlite(); - populate_options(); - populate_roles(); - - update_option( 'blogname', $blog_title ); - update_option( 'admin_email', $user_email ); - update_option( 'blog_public', $is_public ); - - // Freshness of site - in the future, this could get more specific about actions taken, perhaps. - update_option( 'fresh_site', 1 ); - - if ( $language ) { - update_option( 'WPLANG', $language ); - } - - $guessurl = wp_guess_url(); - - update_option( 'siteurl', $guessurl ); - - // If not a public site, don't ping. - if ( ! $is_public ) { - update_option( 'default_pingback_flag', 0 ); - } - - /* - * Create default user. If the user already exists, the user tables are - * being shared among sites. Just set the role in that case. - */ - $user_id = username_exists( $user_name ); - $user_password = trim( $user_password ); - $email_password = false; - $user_created = false; - - if ( ! $user_id && empty( $user_password ) ) { - $user_password = wp_generate_password( 12, false ); - $message = __( 'Note that password carefully! It is a random password that was generated just for you.', 'performance-lab' ); - $user_id = wp_create_user( $user_name, $user_password, $user_email ); - update_user_meta( $user_id, 'default_password_nag', true ); - $email_password = true; - $user_created = true; - } elseif ( ! $user_id ) { - // Password has been provided. - $message = '' . __( 'Your chosen password.', 'performance-lab' ) . ''; - $user_id = wp_create_user( $user_name, $user_password, $user_email ); - $user_created = true; - } else { - $message = __( 'User already exists. Password inherited.', 'performance-lab' ); - } - - $user = new WP_User( $user_id ); - $user->set_role( 'administrator' ); - - if ( $user_created ) { - $user->user_url = $guessurl; - wp_update_user( $user ); - } - - wp_install_defaults( $user_id ); - - wp_install_maybe_enable_pretty_permalinks(); - - flush_rewrite_rules(); - - wp_new_blog_notification( $blog_title, $guessurl, $user_id, ( $email_password ? $user_password : __( 'The password you chose during installation.', 'performance-lab' ) ) ); - - wp_cache_flush(); - - /** - * Fires after a site is fully installed. - * - * @since 3.9.0 - * - * @param WP_User $user The site owner. - */ - do_action( 'wp_install', $user ); - - return array( - 'url' => $guessurl, - 'user_id' => $user_id, - 'password' => $user_password, - 'password_message' => $message, - ); -} diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 62d3e8035b..3557d76a95 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -8,8 +8,6 @@ tests/* - - modules/database/sqlite/* From 35cf3d477a0accf1aa80b82262e6bf8d743339af Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Wed, 21 Jun 2023 18:00:08 -0700 Subject: [PATCH 2/4] Remove SQLite module migration routine and special notices. --- admin/load.php | 222 +------------------------------------------------ load.php | 1 - 2 files changed, 2 insertions(+), 221 deletions(-) diff --git a/admin/load.php b/admin/load.php index 722da0af3f..b2bd3b2a79 100644 --- a/admin/load.php +++ b/admin/load.php @@ -163,20 +163,6 @@ function perflab_render_modules_page_field( $module_slug, $module_data, $module_ ' . esc_html( basename( WP_CONTENT_DIR ) ) . '/db.php' - ); - } elseif ( 'database/sqlite' === $module_slug && ! wp_is_writable( WP_CONTENT_DIR ) ) { - printf( - /* translators: %s: db.php drop-in path */ - esc_html__( 'The SQLite module cannot be activated because the %s directory is not writable.', 'performance-lab' ), - '' . esc_html( basename( WP_CONTENT_DIR ) ) . '' - ); - } elseif ( 'database/sqlite' === $module_slug && ! class_exists( 'SQLite3' ) ) { - esc_html_e( 'The SQLite module cannot be activated because the SQLite extension is not loaded.', 'performance-lab' ); } else { printf( /* translators: %s: module name */ @@ -190,24 +176,6 @@ function perflab_render_modules_page_field( $module_slug, $module_data, $module_

" class="description">

- - - - -

- -

- - - -

- - - - -

- - ' . __( 'Settings > Performance', 'performance-lab' ) . '' - ); - perflab_render_pointer( - 'perflab-sqlite-module-removal-pointer', - array( - 'heading' => __( 'Action required', 'performance-lab' ), - 'content' => $content, - ) - ); - } - ); - return; - } - if ( in_array( 'perflab-admin-pointer', $dismissed, true ) ) { return; } @@ -565,155 +492,10 @@ function perflab_plugin_action_links_add_settings( $links ) { * @see perflab_render_modules_pointer() */ function perflab_dismiss_wp_pointer_wrapper() { - if ( isset( $_POST['pointer'] ) && 'perflab-admin-pointer' !== $_POST['pointer'] && 'perflab-sqlite-module-removal-pointer' !== $_POST['pointer'] ) { + if ( isset( $_POST['pointer'] ) && 'perflab-admin-pointer' !== $_POST['pointer'] ) { // Another plugin's pointer, do nothing. return; } check_ajax_referer( 'dismiss_pointer' ); } add_action( 'wp_ajax_dismiss-wp-pointer', 'perflab_dismiss_wp_pointer_wrapper', 0 ); - -/* - * Temporary code to inform about SQLite module removal. Since it will be - * removed again when the module is removed from the plugin, it uses a closure - * instead of a regular function. - */ -add_action( - 'admin_notices', - static function() { - global $hook_suffix; - - // Only show in the WordPress dashboard and Performance Lab admin screen. - if ( ! in_array( $hook_suffix, array( 'index.php', 'settings_page_' . PERFLAB_MODULES_SCREEN ), true ) ) { - return; - } - - // Only show if the SQLite module is active. - if ( ! defined( 'SQLITE_VERSION' ) || ! str_starts_with( SQLITE_VERSION, 'Performance Lab ' ) ) { - return; - } - - // Only show if the user can manage plugins. - if ( ! current_user_can( 'activate_plugins' ) ) { - return; - } - - $wp_kses_options = array( - 'span' => array( - 'style' => array(), - ), - 'strong' => array(), - 'a' => array( - 'href' => array(), - ), - ); - - $todo_before = ''; - $todo_after = ''; - $done_before = ''; - $done_after = ' ✅'; - - if ( file_exists( WP_PLUGIN_DIR . '/sqlite-database-integration/load.php' ) ) { - $step1_before = $done_before; - $step1_after = $done_after; - $step1_placeholder = 'SQLite Database Integration'; - } else { - $step1_before = $todo_before; - $step1_after = $todo_after; - $step1_placeholder = 'SQLite Database Integration'; - } - if ( defined( 'SQLITE_MAIN_FILE' ) ) { - $step2_before = $done_before; - $step2_after = $done_after; - } else { - $step2_before = $todo_before; - $step2_after = $todo_after; - if ( file_exists( WP_PLUGIN_DIR . '/sqlite-database-integration/load.php' ) ) { - $activate_url = wp_nonce_url( - add_query_arg( - array( - 'action' => 'activate', - 'plugin' => 'sqlite-database-integration/load.php', - ), - admin_url( 'plugins.php' ) - ), - 'activate-plugin_sqlite-database-integration/load.php' - ); - - $step2_before .= ''; - $step2_after = '' . $step2_after; - } - } - $step3_before = $todo_before; - $step3_after = $todo_after; - $step3_placeholder = 'SQLite'; - if ( 'index.php' === $hook_suffix && defined( 'SQLITE_MAIN_FILE' ) ) { - // Link to Performance Lab settings. - $screen_url = add_query_arg( - 'page', - PERFLAB_MODULES_SCREEN, - admin_url( 'options-general.php' ) - ); - - $step3_before .= ''; - $step3_after = '' . $step3_after; - } - - /* - * The first two translation strings below are reused in the SQLite - * module admin pointer to keep new temporary translation strings at a - * small number. - */ - ?> -
-

-

- - -

-
    -
  1. - -
  2. -
  3. - -
  4. -
  5. - -
  6. -
-
- 'DOMINANT_COLOR_IMAGES_VERSION', 'images/fetchpriority' => 'FETCHPRIORITY_VERSION', 'images/webp-uploads' => 'WEBP_UPLOADS_VERSION', - 'database/sqlite' => 'SQLITE_MAIN_FILE', ); } From a841b863454db3e856ce65d38aa77f27187e1b87 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Wed, 21 Jun 2023 18:01:18 -0700 Subject: [PATCH 3/4] Add upgrade notice for PL 2.5.0 to readme to inform about SQLite module removal (as last resort following the migration routine in 2.4.0). --- readme.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/readme.txt b/readme.txt index 8748719bdc..69be049190 100644 --- a/readme.txt +++ b/readme.txt @@ -386,3 +386,9 @@ By default, the WebP Uploads module will only generate WebP versions of the imag * Infrastructure: Add contribution documentation. ([47](https://github.com/WordPress/performance/pull/47)) * Infrastructure: Add release documentation. ([138](https://github.com/WordPress/performance/pull/138)) * Infrastructure: Define module specification in documentation. ([26](https://github.com/WordPress/performance/pull/26)) + +== Upgrade Notice == + += 2.5.0 = + +The SQLite module has been removed as part of this Performance Lab release. If you are using it, please install and activate the SQLite integration plugin before updating Performance Lab. From ea9bba9f1928cbe285b0d6d1e5d03190a9404a47 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Wed, 21 Jun 2023 19:54:10 -0700 Subject: [PATCH 4/4] Reword upgrade notice according to issue. --- readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index 69be049190..fc2b85821c 100644 --- a/readme.txt +++ b/readme.txt @@ -391,4 +391,4 @@ By default, the WebP Uploads module will only generate WebP versions of the imag = 2.5.0 = -The SQLite module has been removed as part of this Performance Lab release. If you are using it, please install and activate the SQLite integration plugin before updating Performance Lab. +The SQLite module is no longer present starting with this release. If you still use it, please migrate to the standalone plugin before updating.