f72a315986
- Add tests/live: a `wp eval-file` runner (PASS/FAIL/XFAIL/XPASS/SKIP) with fixtures that override entity modes in process (pre_option) and read native / flat values with plain SQL, so WP core meta flows run for real - shadow_write suite reproduces the dev36 finding: in shadow_read, update_*_meta returns false and native meta is never written (3 XFAIL marked for PR-056); the dual_write control passes - Move the dev36 integration harness into tests/live/tools; outputs go to cwd / $TMDO_LIVE_OUT, site URL and path are env-configurable - Verify: wp --path=<dev36> eval-file tests/live/run.php shadow_write → 1 passed, 3 xfail; unit 658 OK, integration 480 OK, phpcs (phpcs.xml) 0, stan OK - PR: PR-052
47 lines
2.9 KiB
PHP
47 lines
2.9 KiB
PHP
<?php
|
|
/**
|
|
* Independent native-meta vs flat-table consistency checker (does not use TMDO read paths).
|
|
* Usage: wp eval-file checker.php [entity]
|
|
* Per registered group/key: native rows, flat non-null, missing-in-flat, value mismatches, extra-in-flat.
|
|
*/
|
|
global $wpdb;
|
|
$only = $args[0] ?? '';
|
|
$ids = array( 'post' => 'post_id', 'user' => 'user_id', 'term' => 'term_id', 'comment' => 'comment_id' );
|
|
$metas = array( 'post' => $wpdb->postmeta, 'user' => $wpdb->usermeta, 'term' => $wpdb->termmeta, 'comment' => $wpdb->commentmeta );
|
|
$tot = array( 'miss' => 0, 'diff' => 0, 'extra' => 0 );
|
|
|
|
printf( "%-8s %-24s %-28s %8s %8s %6s %6s %6s\n", 'entity', 'group', 'key', 'native', 'flat', 'miss', 'diff', 'extra' );
|
|
foreach ( $ids as $e => $idcol ) {
|
|
if ( $only && $only !== $e ) { continue; }
|
|
$mt = $metas[ $e ];
|
|
$mid = ( 'user' === $e ) ? 'umeta_id' : 'meta_id';
|
|
foreach ( TMDO_Entity_Registry::get_groups_for_type( $e ) as $g ) {
|
|
$table = $wpdb->prefix . 'wpdo_' . $e . '_' . $g;
|
|
if ( ! $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) ) ) { continue; }
|
|
$scope = ( 'post' === $e ) ? TMDO_Entity_Registry::get_group_post_types( $e, $g ) : array();
|
|
$scope_sql = $scope ? " AND m.post_id IN (SELECT ID FROM {$wpdb->posts} WHERE post_type IN ('" . implode( "','", array_map( 'esc_sql', $scope ) ) . "'))" : '';
|
|
foreach ( TMDO_Entity_Registry::get_group_keys( $e, $g ) as $key ) {
|
|
$col = preg_replace( '/[^a-zA-Z0-9_]/', '', $key );
|
|
// Latest native value per entity.
|
|
$nat = $wpdb->prepare( "SELECT m.$idcol AS eid, m.meta_value AS v FROM $mt m JOIN (SELECT $idcol, MAX($mid) mid FROM $mt WHERE meta_key=%s GROUP BY $idcol) x ON x.mid=m.$mid WHERE 1=1 $scope_sql", $key );
|
|
$n_native = (int) $wpdb->get_var( "SELECT COUNT(*) FROM ($nat) n" );
|
|
$n_flat = (int) $wpdb->get_var( "SELECT COUNT(*) FROM $table WHERE `$col` IS NOT NULL" );
|
|
$miss = (int) $wpdb->get_var( "SELECT COUNT(*) FROM ($nat) n LEFT JOIN $table f ON f.$idcol=n.eid WHERE f.$idcol IS NULL OR (f.`$col` IS NULL AND n.v <> '')" );
|
|
// Value diff: numeric-aware loose compare.
|
|
$diff = (int) $wpdb->get_var( "SELECT COUNT(*) FROM ($nat) n JOIN $table f ON f.$idcol=n.eid WHERE f.`$col` IS NOT NULL AND NOT (
|
|
CAST(f.`$col` AS CHAR) = n.v
|
|
OR (n.v REGEXP '^-?[0-9]+(\\\\.[0-9]+)?$' AND CAST(f.`$col` AS DECIMAL(30,6)) = CAST(n.v AS DECIMAL(30,6)))
|
|
OR (n.v='' AND CAST(f.`$col` AS CHAR) IN ('','0'))
|
|
)" );
|
|
$extra = (int) $wpdb->get_var( "SELECT COUNT(*) FROM $table f WHERE f.`$col` IS NOT NULL AND NOT EXISTS (SELECT 1 FROM $mt m WHERE m.$idcol=f.$idcol AND m.meta_key='" . esc_sql( $key ) . "')" );
|
|
if ( $n_native || $n_flat ) {
|
|
printf( "%-8s %-24s %-28s %8d %8d %6d %6d %6d\n", $e, $g, $key, $n_native, $n_flat, $miss, $diff, $extra );
|
|
}
|
|
$tot['miss'] += $miss;
|
|
$tot['diff'] += $diff;
|
|
$tot['extra'] += $extra;
|
|
}
|
|
}
|
|
}
|
|
printf( "TOTAL miss=%d diff=%d extra=%d\n", $tot['miss'], $tot['diff'], $tot['extra'] );
|