From 8ab0b2bffd500e4e16be949aa53b519f90a5abc7 Mon Sep 17 00:00:00 2001 From: Tony Murray Date: Wed, 6 Dec 2017 16:44:23 -0600 Subject: [PATCH] refactor: Replace custom queries with dbDeleteOrphans(). (#7862) * Replace custom queries with dbDeleteOrphans(). Generalize dbDeleteOrphans() a bit more. Allow for multiple tables and custom key pairs. * fix whitespace --- includes/dbFacile.php | 38 +++++++++++++++---- includes/discovery/applications.inc.php | 4 +- includes/discovery/arp-table.inc.php | 5 +-- .../discovery/discovery-protocols.inc.php | 4 +- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/includes/dbFacile.php b/includes/dbFacile.php index 1d4e44d423..5d8626b836 100644 --- a/includes/dbFacile.php +++ b/includes/dbFacile.php @@ -298,22 +298,44 @@ function dbDelete($table, $where = null, $parameters = array()) /** * Delete orphaned entries from a table that no longer have a parent in parent_table + * Format of parents array is as follows table.table_key_column<.target_key_column> * - * @param string $parent_table - * @param string $child_table - * @param string $id_column + * @param string $target_table The table to delete entries from + * @param array $parents an array of parent tables to check. * @return bool|int */ -function dbDeleteOrphans($parent_table, $child_table, $id_column) +function dbDeleteOrphans($target_table, $parents) { global $database_link; $time_start = microtime(true); - $sql = "DELETE C FROM `$child_table` C"; - $sql .= " LEFT JOIN `$parent_table` P USING (`$id_column`)"; - $sql .= " WHERE P.`$id_column` IS NULL"; + if (empty($parents)) { + // don't delete all entries if parents is missing + return false; + } - $result = dbQuery($sql, array()); + $target_table = mres($target_table); + $sql = "DELETE T FROM `$target_table` T"; + $where = array(); + + foreach ((array)$parents as $parent) { + $parent_parts = explode('.', mres($parent)); + if (count($parent_parts) == 2) { + list($parent_table, $parent_column) = $parent_parts; + $target_column = $parent_column; + } elseif (count($parent_parts) == 3) { + list($parent_table, $parent_column, $target_column) = $parent_parts; + } else { + // invalid input + return false; + } + + $sql .= " LEFT JOIN `$parent_table` ON `$parent_table`.`$parent_column` = T.`$target_column`"; + $where[] = " `$parent_table`.`$parent_column` IS NULL"; + } + + $query = "$sql WHERE" . implode(' AND', $where); + $result = dbQuery($query, array()); recordDbStatistic('delete', $time_start); if ($result) { diff --git a/includes/discovery/applications.inc.php b/includes/discovery/applications.inc.php index 7dfaf73e03..0b19a8ea9b 100644 --- a/includes/discovery/applications.inc.php +++ b/includes/discovery/applications.inc.php @@ -97,7 +97,7 @@ if ($num > 0) { array_unshift($vars, $device['device_id']); dbDelete( 'applications', - '`device_id`=? AND `app_type` IN (' . implode(',', array_fill(0, $num, '?')) . ')', + '`device_id`=? AND `app_type` IN ' . dbGenPlaceholders($num), $vars ); foreach ($apps_to_remove as $app) { @@ -106,7 +106,7 @@ if ($num > 0) { } // clean application_metrics -dbDeleteOrphans('applications', 'application_metrics', 'app_id'); +dbDeleteOrphans('application_metrics', array('applications.app_id')); echo PHP_EOL; diff --git a/includes/discovery/arp-table.inc.php b/includes/discovery/arp-table.inc.php index 239b49fadc..675a5a247b 100644 --- a/includes/discovery/arp-table.inc.php +++ b/includes/discovery/arp-table.inc.php @@ -117,10 +117,7 @@ foreach ($vrfs_lite_cisco as $vrf) { } // remove entries that no longer have an owner - dbQuery('DELETE `ipv4_mac` FROM `ipv4_mac` - LEFT JOIN `ports` ON `ipv4_mac`.`port_id` = `ports`.`port_id` - LEFT JOIN `devices` ON `ipv4_mac`.`device_id` = `devices`.`device_id` - WHERE `ports`.`port_id` IS NULL OR `devices`.`device_id` IS NULL'); + dbDeleteOrphans('ipv4_mac', array('ports.port_id', 'devices.device_id')); echo PHP_EOL; unset( diff --git a/includes/discovery/discovery-protocols.inc.php b/includes/discovery/discovery-protocols.inc.php index 82c865a021..38ea8a35a2 100644 --- a/includes/discovery/discovery-protocols.inc.php +++ b/includes/discovery/discovery-protocols.inc.php @@ -243,8 +243,7 @@ foreach (dbFetchRows($sql, array($device['device_id'])) as $test) { } // remove orphaned links -$del_result = dbQuery('DELETE `l` FROM `links` `l` LEFT JOIN `devices` `d` ON `d`.`device_id` = `l`.`local_device_id` WHERE `d`.`device_id` IS NULL'); -$deleted = mysqli_affected_rows($del_result); +$deleted = (int)dbDeleteOrphans('links', array('devices.device_id.local_device_id')); echo str_repeat('-', $deleted); d_echo(" $deleted orphaned links deleted\n"); @@ -254,6 +253,5 @@ unset( $fdp_array, $cdp_array, $lldp_array, - $del_result, $deleted );