Skip to content

Commit e0e0b5d

Browse files
committed
fixed purge command
1 parent f25edeb commit e0e0b5d

1 file changed

Lines changed: 53 additions & 1 deletion

File tree

src/commands/PurgeCommand.php

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,55 @@ public function execute() {
8080

8181
$io->boldGreen("Successfully purged {$rowCount} old records from apm_requests table", true);
8282

83+
// Clean up any orphaned child records in case foreign keys were disabled in the past
84+
$childTables = [
85+
'apm_routes',
86+
'apm_middleware',
87+
'apm_views',
88+
'apm_db_connections',
89+
'apm_db_queries',
90+
'apm_errors',
91+
'apm_cache',
92+
'apm_custom_events',
93+
'apm_custom_event_data',
94+
'apm_raw_metrics'
95+
];
96+
97+
$orphanedCount = 0;
98+
foreach ($childTables as $table) {
99+
try {
100+
$io->info("Scanning {$table} for orphaned records...", true);
101+
$orphansDeleted = $db->exec("DELETE FROM {$table} WHERE NOT EXISTS (SELECT 1 FROM apm_requests WHERE id = {$table}.request_id)");
102+
if ($orphansDeleted > 0) {
103+
$orphanedCount += (int)$orphansDeleted;
104+
$io->boldGreen("Purged {$orphansDeleted} orphaned records from {$table}", true);
105+
}
106+
} catch (PDOException $e) {
107+
// Table might not exist in an older schema version, continue
108+
}
109+
}
110+
111+
if ($orphanedCount > 0) {
112+
$io->boldGreen("Successfully cleaned up a total of {$orphanedCount} orphaned child records", true);
113+
}
114+
115+
// Clean up JSON buffer tables if they exist using JSON extraction
116+
try {
117+
$cutoffUnix = strtotime("-{$daysToKeep} days");
118+
$jsonExtractFunc = $storageType === 'mysql' ? 'JSON_EXTRACT' : 'json_extract';
119+
120+
$stmt = $db->prepare("DELETE FROM apm_metrics_log WHERE {$jsonExtractFunc}(metrics_json, '$.start_time') < :cutoff_unix");
121+
$stmt->bindParam(':cutoff_unix', $cutoffUnix);
122+
if ($stmt->execute()) {
123+
$logCount = $stmt->rowCount();
124+
if ($logCount > 0) {
125+
$io->info("Purged {$logCount} old records from apm_metrics_log table by JSON timestamp", true);
126+
}
127+
}
128+
} catch (PDOException $e) {
129+
// Table might not exist, continue smoothly
130+
}
131+
83132
// If SQLite, vacuum the database to reclaim space
84133
if ($storageType === 'sqlite') {
85134
$db->exec('VACUUM');
@@ -105,11 +154,14 @@ protected function getDatabaseConnection(array $config): PDO {
105154
switch ($storageType) {
106155
case 'sqlite':
107156
$dsn = $config['dest_db_dsn'];
108-
return new PDO($dsn, null, null, [
157+
$pdo = new PDO($dsn, null, null, [
109158
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
110159
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
111160
PDO::ATTR_EMULATE_PREPARES => false,
112161
]);
162+
// Enable foreign keys explicitly so CASCADE works correctly
163+
$pdo->exec('PRAGMA foreign_keys = ON;');
164+
return $pdo;
113165

114166
case 'mysql':
115167
$dsn = $config['dest_db_dsn'];

0 commit comments

Comments
 (0)