results('SHOW CREATE TABLE ' . Db::ident($table), ARRAY_N); $sql = (string) ($rows[0][1] ?? ''); $head = 'CREATE TABLE ' . Db::ident($table); if (strpos($sql, $head) !== 0) { /* translators: %s: table name */ throw new RelayError('db.show_create_failed', esc_html(sprintf(__('Could not read the structure of table %s.', 'siterelay'), $table))); } $sql = 'CREATE TABLE ' . Db::ident($as) . substr($sql, strlen($head)); return self::split_constraints($sql, $final); } // Ported from WP Migrate 2.7.11 (GPL) Table::process_sql_constraint, simplified to line filtering. /** @return array{create: string, constraints: ?string} */ public static function split_constraints(string $create, string $final): array { if (!preg_match('/\bCONSTRAINT\b|\bFOREIGN\s+KEY\b/i', $create)) { return ['create' => $create, 'constraints' => null]; } $keep = []; $adds = []; foreach (explode("\n", $create) as $line) { if (preg_match('/^\s*(CONSTRAINT|FOREIGN\s+KEY)\b/i', $line)) { $adds[] = 'ADD ' . rtrim(trim($line), ','); } else { $keep[] = $line; } } if ($adds === []) { return ['create' => $create, 'constraints' => null]; } for ($i = count($keep) - 1; $i > 0; $i--) { if (strpos(ltrim($keep[$i]), ')') === 0) { $keep[$i - 1] = rtrim($keep[$i - 1], ','); break; } } return [ 'create' => implode("\n", $keep), 'constraints' => 'ALTER TABLE ' . Db::ident($final) . ' ' . implode(', ', $adds), ]; } /** @return string[] names of FOREIGN KEY constraints added by an ALTER statement */ public static function constraint_names(string $alter): array { preg_match_all('/ADD CONSTRAINT `((?:[^`]|``)+)` FOREIGN KEY/i', $alter, $m); return array_map(fn ($n) => str_replace('``', '`', $n), $m[1]); } }