diff --git a/plugins/woocommerce/src/Database/Migrations/CustomOrderTable/MetaToMetaTableMigrator.php b/plugins/woocommerce/src/Database/Migrations/CustomOrderTable/MetaToMetaTableMigrator.php index 92b14c4512b..00d7a62ed1a 100644 --- a/plugins/woocommerce/src/Database/Migrations/CustomOrderTable/MetaToMetaTableMigrator.php +++ b/plugins/woocommerce/src/Database/Migrations/CustomOrderTable/MetaToMetaTableMigrator.php @@ -30,13 +30,52 @@ abstract class MetaToMetaTableMigrator { */ protected $errors; - public abstract function get_meta_config(); + /** + * Returns config for the migration. + * + * @return array Meta config, must be in following format: + * array( + * 'source' => array( + * 'meta' => array( + * 'table_name' => source_meta_table_name, + * 'entity_id_column' => entity_id column name in source meta table, + * 'meta_key_column' => meta_key column', + * 'meta_value_column' => meta_value column', + * ), + * 'entity' => array( + * 'table_name' => entity table name for the meta table, + * 'source_id_column' => column name in entity table which maps to meta table, + * 'id_column' => id column in entity table, + * ), + * 'excluded_keys' => array of keys to exclude, + * ), + * 'destination' => array( + * 'meta' => array( + * 'table_name' => destination meta table name, + * 'entity_id_column' => entity_id column in meta table, + * 'meta_key_column' => meta key column, + * 'meta_value_column' => meta_value column, + * 'entity_id_type' => data type of entity id, + * 'meta_id_column' => id column in meta table, + * ), + * ), + * ) + */ + abstract public function get_meta_config(); + /** + * MetaToMetaTableMigrator constructor. + */ public function __construct() { $this->schema_config = $this->get_meta_config(); $this->errors = array(); } + /** + * Process migration for provided entity ids. + * + * @param array $entity_ids Entity IDs to process migration for. + */ public function process_migration_batch_for_ids( $entity_ids ) { global $wpdb; $to_migrate = $this->fetch_data_for_migration_for_ids( $entity_ids ); @@ -50,20 +89,26 @@ abstract class MetaToMetaTableMigrator { // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $insert_queries should already be escaped in the generating function. $result = $wpdb->query( $insert_queries ); $wpdb->query( 'COMMIT;' ); - if ( count( $to_insert ) !== $result ) { - // TODO: Find and log entity ids that were not inserted. - } + // TODO: Find and log entity ids that were not inserted. } if ( empty( $to_update ) ) { return; } $update_queries = $this->generate_update_sql_for_batch( $to_update ); - $result = $wpdb->query( $update_queries ); + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- update queries are autogenerated and should already be prepared. + $result = $wpdb->query( $update_queries ); $wpdb->query( 'COMMIT;' ); // TODO: Find and log error updates. } + /** + * Generate update SQL for given batch. + * + * @param array $batch List of data to generate update SQL for. Should be in same format as output of $this->fetch_data_for_migration_for_ids. + * + * @return string Query to update batch records. + */ public function generate_update_sql_for_batch( $batch ) { global $wpdb; @@ -80,7 +125,9 @@ abstract class MetaToMetaTableMigrator { $values = array(); foreach ( $batch as $entity_id => $rows ) { foreach ( $rows as $meta_key => $meta_details ) { + $values[] = $wpdb->prepare( + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Placeholder string is already being prepared. "( $placeholder_string )", array( $meta_details['id'], $entity_id, $meta_key, $meta_details['meta_value'] ) ); @@ -97,9 +144,8 @@ abstract class MetaToMetaTableMigrator { * Generate insert sql queries for batches. * * @param array $batch Data to generate queries for. - * @param string $insert_switch Insert switch to use. * - * @return string + * @return string Insert SQL query. */ public function generate_insert_sql_for_batch( $batch ) { global $wpdb; @@ -119,7 +165,7 @@ abstract class MetaToMetaTableMigrator { $query_params = array( $entity_id, $meta_key, - $meta_value + $meta_value, ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $placeholder_string is hardcoded. $value_sql = $wpdb->prepare( "$placeholder_string", $query_params ); @@ -145,7 +191,6 @@ abstract class MetaToMetaTableMigrator { * ..., * ), * 'errors' => array( - * 'id_1' => array( 'column1' => error1, 'column2' => value2, ...), * ..., * ) */ @@ -187,6 +232,13 @@ abstract class MetaToMetaTableMigrator { ); } + /** + * Helper method to get already migrated records. Will be used to find prevent migration of already migrated records. + * + * @param array $entity_ids List of entity ids to check for. + * + * @return array Already migrated records. + */ private function get_already_migrated_records( $entity_ids ) { global $wpdb; @@ -199,6 +251,7 @@ abstract class MetaToMetaTableMigrator { $entity_id_type_placeholder = MigrationHelper::get_wpdb_placeholder_for_type( $this->schema_config['destination']['meta']['entity_id_type'] ); $entity_ids_placeholder = implode( ',', array_fill( 0, count( $entity_ids ), $entity_id_type_placeholder ) ); + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- All columns are hardcoded. $data_already_migrated = $wpdb->get_results( $wpdb->prepare( " @@ -213,6 +266,7 @@ WHERE destination.$destination_entity_id_column in ( $entity_ids_placeholder ) O $entity_ids ) ); + // phpcs:enable $already_migrated = array(); @@ -227,12 +281,21 @@ WHERE destination.$destination_entity_id_column in ( $entity_ids_placeholder ) O $already_migrated[ $migrate_row->entity_id ][ $migrate_row->meta_key ][] = array( 'id' => $migrate_row->meta_id, - 'meta_value' => $migrate_row->meta_value + 'meta_value' => $migrate_row->meta_value, ); } + return $already_migrated; } + /** + * Classify each record on whether to migrate or update. + * + * @param array $to_migrate Records to migrate. + * @param array $already_migrated Records already migrated. + * + * @return array[] Returns two arrays, first for records to migrate, and second for records to upgrade. + */ private function classify_update_insert_records( $to_migrate, $already_migrated ) { $to_update = array(); $to_insert = array(); @@ -254,7 +317,7 @@ WHERE destination.$destination_entity_id_column in ( $entity_ids_placeholder ) O } $to_update[ $entity_id ][ $meta_key ] = array( 'id' => $already_migrated[ $entity_id ][ $meta_key ][0]['id'], - 'meta_value' => $meta_values[0] + 'meta_value' => $meta_values[0], ); continue; }