Add migrations for operational data table.
This commit is contained in:
parent
6cc34e8616
commit
786561d6fd
|
@ -39,10 +39,12 @@ class MetaToCustomTableMigrator {
|
|||
* @var string[]
|
||||
*/
|
||||
private $wpdb_placeholder_for_type = array(
|
||||
'int' => '%d',
|
||||
'decimal' => '%f',
|
||||
'string' => '%s',
|
||||
'date' => '%s',
|
||||
'int' => '%d',
|
||||
'decimal' => '%f',
|
||||
'string' => '%s',
|
||||
'date' => '%s',
|
||||
'date_epoch' => '%s',
|
||||
'bool' => '%d',
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -181,18 +183,18 @@ class MetaToCustomTableMigrator {
|
|||
// TODO: Add code to validate params.
|
||||
$entity_table_query = $this->build_entity_table_query( $where_clause, $batch_size, $order_by );
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Output of $this->build_entity_table_query is already prepared.
|
||||
$entity_data = $wpdb->get_results( $entity_table_query );
|
||||
$entity_data = $wpdb->get_results( $entity_table_query );
|
||||
if ( empty( $entity_data ) ) {
|
||||
return array(
|
||||
'data' => array(),
|
||||
'data' => array(),
|
||||
'errors' => array(),
|
||||
);
|
||||
}
|
||||
$entity_ids = array_column( $entity_data, 'entity_rel_column' );
|
||||
$entity_ids = array_column( $entity_data, 'entity_rel_column' );
|
||||
|
||||
$meta_table_query = $this->build_meta_data_query( $entity_ids );
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Output of $this->build_meta_data_query is already prepared.
|
||||
$meta_data = $wpdb->get_results( $meta_table_query );
|
||||
$meta_data = $wpdb->get_results( $meta_table_query );
|
||||
|
||||
return $this->process_and_sanitize_data( $entity_data, $meta_data );
|
||||
}
|
||||
|
@ -208,10 +210,10 @@ class MetaToCustomTableMigrator {
|
|||
*/
|
||||
private function build_entity_table_query( $where_clause, $batch_size, $order_by ) {
|
||||
global $wpdb;
|
||||
$entity_table = $this->escape_backtick( $this->schema_config['entity_schema']['table_name'] );
|
||||
$primary_id_column = $this->escape_backtick( $this->schema_config['entity_schema']['primary_id'] );
|
||||
$entity_table = $this->escape_backtick( $this->schema_config['entity_schema']['table_name'] );
|
||||
$primary_id_column = $this->escape_backtick( $this->schema_config['entity_schema']['primary_id'] );
|
||||
$entity_rel_column = $this->escape_backtick( $this->schema_config['entity_meta_relation']['entity_rel_column'] );
|
||||
$entity_keys = array();
|
||||
$entity_keys = array();
|
||||
foreach ( $this->core_column_mapping as $column_name => $column_schema ) {
|
||||
if ( isset( $column_schema['select_clause'] ) ) {
|
||||
$select_clause = $column_schema['select_clause'];
|
||||
|
@ -222,7 +224,7 @@ class MetaToCustomTableMigrator {
|
|||
}
|
||||
$entity_column_string = implode( ', ', $entity_keys );
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $entity_table, $primary_id_column and $entity_column_string is escaped for backticks. $where clause and $order_by should already be escaped.
|
||||
$query = $wpdb->prepare(
|
||||
$query = $wpdb->prepare(
|
||||
"
|
||||
SELECT `$primary_id_column` as primary_key_id, `$entity_rel_column` AS entity_rel_column, $entity_column_string FROM $entity_table WHERE $where_clause ORDER BY $order_by LIMIT %d;
|
||||
",
|
||||
|
@ -230,6 +232,7 @@ SELECT `$primary_id_column` as primary_key_id, `$entity_rel_column` AS entity_re
|
|||
$batch_size,
|
||||
)
|
||||
);
|
||||
|
||||
// phpcs:enable
|
||||
|
||||
return $query;
|
||||
|
@ -279,6 +282,7 @@ WHERE
|
|||
$meta_keys
|
||||
)
|
||||
);
|
||||
|
||||
// phpcs:enable
|
||||
|
||||
return $query;
|
||||
|
@ -304,7 +308,7 @@ WHERE
|
|||
$this->processs_and_sanitize_meta_data( $sanitized_entity_data, $error_records, $meta_data );
|
||||
|
||||
return array(
|
||||
'data' => $sanitized_entity_data,
|
||||
'data' => $sanitized_entity_data,
|
||||
'errors' => $error_records,
|
||||
);
|
||||
}
|
||||
|
@ -345,7 +349,7 @@ WHERE
|
|||
$column_schema = $this->meta_column_mapping[ $datum->meta_key ];
|
||||
$value = $this->validate_data( $datum->meta_value, $column_schema['type'] );
|
||||
if ( is_wp_error( $value ) ) {
|
||||
$error_records[ $datum->entity_id ][ $column_schema['destination'] ] = $value->get_error_message();
|
||||
$error_records[ $datum->entity_id ][ $column_schema['destination'] ] = "{$value->get_error_code()}: {$value->get_error_message()}";
|
||||
} else {
|
||||
$sanitized_entity_data[ $datum->entity_id ][ $column_schema['destination'] ] = $value;
|
||||
}
|
||||
|
@ -368,10 +372,28 @@ WHERE
|
|||
case 'int':
|
||||
$value = (int) $value;
|
||||
break;
|
||||
case 'bool':
|
||||
$value = wc_string_to_bool( $value );
|
||||
break;
|
||||
case 'date':
|
||||
// TODO: Test this validation in unit tests.
|
||||
try {
|
||||
$value = ( new \DateTime( $value ) )->format( 'Y-m-d H:i:s' );
|
||||
if ( '' === $value ) {
|
||||
$value = null;
|
||||
} else {
|
||||
$value = ( new \DateTime( $value ) )->format( 'Y-m-d H:i:s' );
|
||||
}
|
||||
} catch ( \Exception $e ) {
|
||||
return new \WP_Error( $e->getMessage() );
|
||||
}
|
||||
break;
|
||||
case 'date_epoch':
|
||||
try {
|
||||
if ( '' === $value ) {
|
||||
$value = null;
|
||||
} else {
|
||||
$value = ( new \DateTime( "@$value" ) )->format( 'Y-m-d H:i:s' );
|
||||
}
|
||||
} catch ( \Exception $e ) {
|
||||
return new \WP_Error( $e->getMessage() );
|
||||
}
|
||||
|
|
|
@ -42,6 +42,13 @@ class WPPostToCOTMigrator {
|
|||
*/
|
||||
private $shipping_address_table_migrator;
|
||||
|
||||
/**
|
||||
* Migrator instance to migrate operational data.
|
||||
*
|
||||
* @var MetaToCustomTableMigrator
|
||||
*/
|
||||
private $operation_data_table_migrator;
|
||||
|
||||
/**
|
||||
* Names of different order tables.
|
||||
*
|
||||
|
@ -62,13 +69,17 @@ class WPPostToCOTMigrator {
|
|||
'op_data' => $wpdb->prefix . 'wc_order_operational_data',
|
||||
);
|
||||
|
||||
$order_config = $this->get_config_for_order_table();
|
||||
$billing_address_config = $this->get_config_for_address_table_billing();
|
||||
$shipping_address_config = $this->get_config_for_address_table_shipping();
|
||||
$order_config = $this->get_config_for_order_table();
|
||||
$billing_address_config = $this->get_config_for_address_table_billing();
|
||||
$shipping_address_config = $this->get_config_for_address_table_shipping();
|
||||
$operation_data_config = $this->get_config_for_operational_data_table();
|
||||
|
||||
$this->order_table_migrator = new MetaToCustomTableMigrator( $order_config['schema'], $order_config['meta'], $order_config['core'] );
|
||||
$this->billing_address_table_migrator = new MetaToCustomTableMigrator( $billing_address_config['schema'], $billing_address_config['meta'], $billing_address_config['core'] );
|
||||
$this->shipping_address_table_migrator = new MetaToCustomTableMigrator( $shipping_address_config['schema'], $shipping_address_config['meta'], $shipping_address_config['core'] );
|
||||
$this->error_logger = new MigrationErrorLogger();
|
||||
$this->operation_data_table_migrator = new MetaToCustomTableMigrator( $operation_data_config['schema'], $operation_data_config['meta'], $operation_data_config['core'] );
|
||||
|
||||
$this->error_logger = new MigrationErrorLogger();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,7 +87,7 @@ class WPPostToCOTMigrator {
|
|||
*
|
||||
* @return array Config for order table.
|
||||
*/
|
||||
public function get_config_for_order_table() {
|
||||
private function get_config_for_order_table() {
|
||||
global $wpdb;
|
||||
$order_table_schema_config = array(
|
||||
'entity_schema' => array(
|
||||
|
@ -170,7 +181,7 @@ class WPPostToCOTMigrator {
|
|||
*
|
||||
* @return array Billing address migration config.
|
||||
*/
|
||||
public function get_config_for_address_table_billing() {
|
||||
private function get_config_for_address_table_billing() {
|
||||
return $this->get_config_for_address_table( 'billing' );
|
||||
}
|
||||
|
||||
|
@ -179,7 +190,7 @@ class WPPostToCOTMigrator {
|
|||
*
|
||||
* @return array Shipping address migration config.
|
||||
*/
|
||||
public function get_config_for_address_table_shipping() {
|
||||
private function get_config_for_address_table_shipping() {
|
||||
return $this->get_config_for_address_table( 'shipping' );
|
||||
}
|
||||
|
||||
|
@ -277,6 +288,108 @@ class WPPostToCOTMigrator {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate config for operational data.
|
||||
*
|
||||
* @return array Config for operational data table.
|
||||
*/
|
||||
private function get_config_for_operational_data_table() {
|
||||
global $wpdb;
|
||||
|
||||
$schema_config = array(
|
||||
'entity_schema' => array(
|
||||
'primary_id' => 'post_id',
|
||||
'table_name' => $this->table_names['orders'],
|
||||
),
|
||||
'entity_meta_schema' => array(
|
||||
'meta_key_column' => 'meta_key',
|
||||
'meta_value_column' => 'meta_value',
|
||||
'table_name' => $wpdb->postmeta,
|
||||
),
|
||||
'destination_table' => $this->table_names['op_data'],
|
||||
'entity_meta_relation' => array(
|
||||
'entity_rel_column' => 'post_id',
|
||||
'meta_rel_column' => 'post_id',
|
||||
),
|
||||
);
|
||||
|
||||
$core_config = array(
|
||||
'id' => array(
|
||||
'type' => 'int',
|
||||
'destination' => 'order_id',
|
||||
),
|
||||
);
|
||||
|
||||
$meta_config = array(
|
||||
'_created_via' => array(
|
||||
'type' => 'string',
|
||||
'destination' => 'created_via',
|
||||
),
|
||||
'_order_version' => array(
|
||||
'type' => 'string',
|
||||
'destination' => 'woocommerce_version',
|
||||
),
|
||||
'_prices_include_tax' => array(
|
||||
'type' => 'bool',
|
||||
'destination' => 'prices_include_tax',
|
||||
),
|
||||
'_recorded_coupon_usage_counts' => array(
|
||||
'type' => 'bool',
|
||||
'destination' => 'coupon_usages_are_counted',
|
||||
),
|
||||
'_download_permissions_granted' => array(
|
||||
'type' => 'bool',
|
||||
'destination' => 'download_permissions_granted',
|
||||
),
|
||||
'_cart_hash' => array(
|
||||
'type' => 'string',
|
||||
'destination' => 'cart_hash',
|
||||
),
|
||||
'_new_order_email_sent' => array(
|
||||
'type' => 'bool',
|
||||
'destination' => 'new_order_email_sent',
|
||||
),
|
||||
'_order_key' => array(
|
||||
'type' => 'string',
|
||||
'destination' => 'order_key',
|
||||
),
|
||||
'_order_stock_reduced' => array(
|
||||
'type' => 'bool',
|
||||
'destination' => 'order_stock_reduced',
|
||||
),
|
||||
'_date_paid' => array(
|
||||
'type' => 'date_epoch',
|
||||
'destination' => 'date_paid_gmt',
|
||||
),
|
||||
'_date_completed' => array(
|
||||
'type' => 'date_epoch',
|
||||
'destination' => 'date_completed_gmt',
|
||||
),
|
||||
'_order_shipping_tax' => array(
|
||||
'type' => 'decimal',
|
||||
'destination' => 'shipping_tax_amount',
|
||||
),
|
||||
'_order_shipping' => array(
|
||||
'type' => 'decimal',
|
||||
'destination' => 'shipping_total_amount',
|
||||
),
|
||||
'_cart_discount_tax' => array(
|
||||
'type' => 'decimal',
|
||||
'destination' => 'discount_tax_amount',
|
||||
),
|
||||
'_cart_discount' => array(
|
||||
'type' => 'decimal',
|
||||
'destination' => 'discount_total_amount',
|
||||
),
|
||||
);
|
||||
|
||||
return array(
|
||||
'schema' => $schema_config,
|
||||
'core' => $core_config,
|
||||
'meta' => $meta_config,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process next migration batch, uses option `wc_cot_migration` to checkpoints of what have been processed so far.
|
||||
*
|
||||
|
@ -307,8 +420,9 @@ class WPPostToCOTMigrator {
|
|||
}
|
||||
|
||||
$order_post_ids = array_column( $order_data['data'], 'post_id' );
|
||||
$this->process_next_address_batch( $this->billing_address_table_migrator, $order_post_ids, $order_by );
|
||||
$this->process_next_address_batch( $this->shipping_address_table_migrator, $order_post_ids, $order_by );
|
||||
$this->process_next_migrator_batch( $this->billing_address_table_migrator, $order_post_ids, $order_by );
|
||||
$this->process_next_migrator_batch( $this->shipping_address_table_migrator, $order_post_ids, $order_by );
|
||||
$this->process_next_migrator_batch( $this->operation_data_table_migrator, $order_post_ids, $order_by );
|
||||
|
||||
$last_post_migrated = max( array_keys( $order_data['data'] ) );
|
||||
$this->update_checkpoint( $last_post_migrated );
|
||||
|
@ -323,17 +437,18 @@ class WPPostToCOTMigrator {
|
|||
* @param array $order_post_ids Array of post IDs for orders.
|
||||
* @param string $order_by Order by clause.
|
||||
*/
|
||||
private function process_next_address_batch( $migrator, $order_post_ids, $order_by ) {
|
||||
private function process_next_migrator_batch( $migrator, $order_post_ids, $order_by ) {
|
||||
global $wpdb;
|
||||
$post_ids_where_clause = $this->get_where_id_clause( $order_post_ids, 'post_id' );
|
||||
$batch_size = count( $order_post_ids );
|
||||
$address_data = $migrator->fetch_data_for_migration( $post_ids_where_clause, $batch_size, $order_by );
|
||||
foreach ( $address_data['errors'] as $order_id => $error ) {
|
||||
$this->error_logger->log( 'info', "Error in importing address data for Order ID $order_id: " . print_r( $error, true ) );
|
||||
$data = $migrator->fetch_data_for_migration( $post_ids_where_clause, $batch_size, $order_by );
|
||||
foreach ( $data['errors'] as $order_id => $error ) {
|
||||
// TODO: Add name of the migrator in error message.
|
||||
$this->error_logger->log( 'info', "Error in importing data for Order ID $order_id: " . print_r( $error, true ) );
|
||||
}
|
||||
$address_queries = $migrator->generate_insert_sql_for_batch( $address_data['data'], 'insert' );
|
||||
$result = $wpdb->query( $address_queries ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Insert statements should already be escaped.
|
||||
if ( count( $address_data['data'] ) !== $result ) {
|
||||
$queries = $migrator->generate_insert_sql_for_batch( $data['data'], 'insert' );
|
||||
$result = $wpdb->query( $queries ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Insert statements should already be escaped.
|
||||
if ( count( $data['data'] ) !== $result ) {
|
||||
// Some rows were not inserted.
|
||||
// TODO: Find and log the entity ids that were not inserted.
|
||||
echo 'error';
|
||||
|
|
|
@ -234,7 +234,7 @@ CREATE TABLE $operational_data_table_name (
|
|||
woocommerce_version varchar(20) NULL,
|
||||
prices_include_tax tinyint(1) NULL,
|
||||
coupon_usages_are_counted tinyint(1) NULL,
|
||||
download_permissionis_granted tinyint(1) NULL,
|
||||
download_permission_granted tinyint(1) NULL,
|
||||
cart_hash varchar(100) NULL,
|
||||
new_order_email_sent tinyint(1) NULL,
|
||||
order_key varchar(100) NULL,
|
||||
|
@ -242,7 +242,7 @@ CREATE TABLE $operational_data_table_name (
|
|||
date_paid_gmt datetime NULL,
|
||||
date_completed_gmt datetime NULL,
|
||||
shipping_tax_amount decimal(26, 8) NULL,
|
||||
shopping_total_amount decimal(26, 8) NULL,
|
||||
shipping_total_amount decimal(26, 8) NULL,
|
||||
discount_tax_amount decimal(26, 8) NULL,
|
||||
discount_total_amount decimal(26, 8) NULL,
|
||||
KEY order_id (order_id),
|
||||
|
|
Loading…
Reference in New Issue