fix(2meet-data-optimizer): do not recreate a deleted entity's flat row
- Deleting a post / user / term / comment drops its flat row in the adapter delete hook, then WordPress deletes each meta row; sync_from_native upserted NULL for each and brought the row back (512 orphan rows on dev36). With no native value it now only clears the column on an existing row - Verify: tests/live/run.php resync (25/25, entity deletes in dual_write and shadow_read leave no flat row); mut.php T8 flat_row NO-ROW; integration 516 - PR: PR-057b
This commit is contained in:
@@ -201,7 +201,8 @@ final class TMDO_Hook_Bus {
|
||||
* (NULL when native has no row). Runs in dual_write / shadow_read only,
|
||||
* after WP wrote native, so flat always ends up equal to native — also
|
||||
* when WP skipped or refused the write, and when an earlier direct SQL
|
||||
* write had left flat stale.
|
||||
* write had left flat stale. A NULL never creates a row: deleting an
|
||||
* entity drops its flat row before WP deletes the meta rows one by one.
|
||||
*
|
||||
* @param string $type Entity type.
|
||||
* @param int $object_id Entity ID.
|
||||
@@ -222,7 +223,9 @@ final class TMDO_Hook_Bus {
|
||||
|
||||
$before = self::maybe_read_before_value( $type, $object_id, $meta_key, $field_def, $op );
|
||||
$native = self::native_first_value( $type, $object_id, $meta_key );
|
||||
$result = self::perform_upsert( $type, $object_id, $meta_key, null === $native ? null : maybe_unserialize( $native ), $field_def );
|
||||
$result = null === $native
|
||||
? self::clear_column( $type, $object_id, $meta_key, $field_def )
|
||||
: self::perform_upsert( $type, $object_id, $meta_key, maybe_unserialize( $native ), $field_def );
|
||||
|
||||
if ( 'delete' === $op ) {
|
||||
do_action( 'wpdo_after_delete', $type, $object_id, $meta_key, $meta_value, $result, $delete_all, $before );
|
||||
@@ -522,6 +525,34 @@ final class TMDO_Hook_Bus {
|
||||
return 'flat';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a flat column to NULL on the entity's existing row; never insert one.
|
||||
*
|
||||
* @param string $type Entity type.
|
||||
* @param int $entity_id Entity ID.
|
||||
* @param string $meta_key Meta key.
|
||||
* @param array<string, mixed> $field_def Registered field.
|
||||
* @return bool|null Null when there is no adapter or table.
|
||||
*/
|
||||
private static function clear_column( string $type, int $entity_id, string $meta_key, array $field_def ): ?bool {
|
||||
global $wpdb;
|
||||
|
||||
$adapter = TMDO_Entity_Registry::get_adapter( $type );
|
||||
$table = TMDO_Schema_Manager::get_table_name( $type, $field_def['group'] );
|
||||
if ( ! $adapter || ! TMDO_Schema_Manager::table_exists( $table ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$col = TMDO_Schema_Manager::sanitize_column_name( $meta_key );
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
$result = $wpdb->update( $table, array( $col => null ), array( $adapter->get_entity_id_column() => $entity_id ) );
|
||||
|
||||
TMDO_Cache_Orchestrator::invalidate( $type, $entity_id, $field_def['group'] );
|
||||
self::touch_posts_last_changed( $type );
|
||||
|
||||
return false !== $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 執行 Upsert 操作
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user