- using the next available sequence * number for that year. Entries are ordered by id within each year so the * numbering is deterministic and roughly chronological. * * Safe to re-run: only updates identifiers that are already mismatched. */ defined('APP_ROOT') || define('APP_ROOT', dirname(__DIR__, 2)); defined('STORAGE_ROOT') || define('STORAGE_ROOT', APP_ROOT . '/storage'); // Accept optional DB path from command line (used by run.php runner) $dbPath = $argv[1] ?? (APP_ROOT . '/storage/xamxam.db'); if (!file_exists($dbPath)) { echo "ERROR: database not found at $dbPath\n"; exit(1); } $pdo = new PDO('sqlite:' . $dbPath); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $pdo->exec('PRAGMA foreign_keys = ON'); // ── 1. Identify mismatched rows ────────────────────────────────────────── $stmt = $pdo->query( "SELECT id, year, identifier FROM theses WHERE deleted_at IS NULL AND CAST(SUBSTR(identifier, 1, 4) AS INTEGER) != year" ); $mismatched = $stmt->fetchAll(); if (empty($mismatched)) { echo "No mismatched identifiers found. Nothing to fix.\n"; exit(0); } echo "Found " . count($mismatched) . " thesis(es) with mismatched identifiers.\n"; // Group by year, ordered by id within each year (deterministic renumbering) $byYear = []; foreach ($mismatched as $row) { $year = (int)$row['year']; $byYear[$year][] = $row; } $fixed = 0; foreach ($byYear as $year => $rows) { // Sort by id for deterministic sequencing usort($rows, fn($a, $b) => (int)$a['id'] <=> (int)$b['id']); // Find the max existing sequence for CORRECT identifiers of this year $stmt = $pdo->prepare( "SELECT COALESCE(MAX(CAST(SUBSTR(identifier, 6) AS INTEGER)), 0) FROM theses WHERE year = ? AND deleted_at IS NULL AND CAST(SUBSTR(identifier, 1, 4) AS INTEGER) = ?" ); $stmt->execute([$year, $year]); $maxSeq = (int)$stmt->fetchColumn(); foreach ($rows as $row) { $maxSeq++; $newIdentifier = sprintf('%d-%03d', $year, $maxSeq); echo " Thesis {$row['id']}: {$row['identifier']} → {$newIdentifier} (year={$year})\n"; $pdo->prepare("UPDATE theses SET identifier = ? WHERE id = ?") ->execute([$newIdentifier, $row['id']]); $fixed++; } } echo "\nFixed $fixed identifier(s).\n"; echo "Migration 038 complete.\n";