diff --git a/code/cron/src/com/turning_leaf_technologies/cron/DatabaseCleanup.java b/code/cron/src/com/turning_leaf_technologies/cron/DatabaseCleanup.java index c267fe0bac..04427b7f54 100644 --- a/code/cron/src/com/turning_leaf_technologies/cron/DatabaseCleanup.java +++ b/code/cron/src/com/turning_leaf_technologies/cron/DatabaseCleanup.java @@ -27,6 +27,7 @@ public void doCronProcess(String servername, Ini configIni, Section processSetti removeOldCachedObjects(dbConn, logger, processLog); removeOldIndexingData(dbConn, logger, processLog); removeOldExternalRequests(dbConn, logger, processLog); + removeOldLastListUsed(dbConn, logger, processLog); optimizeSearchTable(dbConn, logger, processLog); optimizeSessionsTable(dbConn, logger, processLog); @@ -420,7 +421,7 @@ private void removeOldSearches(Connection dbConn, Logger logger, CronProcessLogE //Remove old searches try { int rowsRemoved = 0; - ResultSet numSearchesRS = dbConn.prepareStatement("SELECT count(id) from search where created < (CURDATE() - INTERVAL 2 DAY) and saved = 0").executeQuery(); + ResultSet numSearchesRS = dbConn.prepareStatement("SELECT count(id) from search where saved = 0").executeQuery(); numSearchesRS.next(); long numSearches = numSearchesRS.getLong(1); long batchSize = 100000; @@ -428,7 +429,7 @@ private void removeOldSearches(Connection dbConn, Logger logger, CronProcessLogE processLog.addNote("Found " + numSearches + " expired searches that need to be removed. Will process in " + numBatches + " batches"); processLog.saveResults(); for (int i = 0; i < numBatches; i++){ - PreparedStatement searchesToRemove = dbConn.prepareStatement("SELECT id from search where created < (CURDATE() - INTERVAL 2 DAY) and saved = 0 LIMIT 0, " + batchSize, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + PreparedStatement searchesToRemove = dbConn.prepareStatement("SELECT id from search where saved = 0 LIMIT 0, " + batchSize, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); PreparedStatement removeSearchStmt = dbConn.prepareStatement("DELETE from search where id = ?"); ResultSet searchesToRemoveRs = searchesToRemove.executeQuery(); @@ -447,4 +448,56 @@ private void removeOldSearches(Connection dbConn, Logger logger, CronProcessLogE } } + private void removeOldLastListUsed(Connection dbConn, Logger logger, CronProcessLogEntry processLog) { + //Remove old last list used + try { + //Get list of libraries that want last used list cleared + PreparedStatement librariesListStmt = dbConn.prepareStatement("SELECT libraryId, deleteOldLastListUsedEntries from library where deleteOldLastListUsedEntries > 0"); + PreparedStatement libraryLocationsStmt = dbConn.prepareStatement("SELECT locationId from location where libraryId = ?"); + PreparedStatement deleteLastListUsedStmt = dbConn.prepareStatement("DELETE from user where lastListUsed = ?"); + + ResultSet librariesListRS = librariesListStmt.executeQuery(); + + long numDeletions = 0; + while (librariesListRS.next()) { + long libraryId = librariesListRS.getLong("libraryId"); + long daysToPreserve = librariesListRS.getLong("deleteLastUsedListEntries"); + + libraryLocationsStmt.setLong(1, libraryId); + + ResultSet libraryLocationsRS = libraryLocationsStmt.executeQuery(); + StringBuilder libraryLocations = new StringBuilder(); + + while (libraryLocationsRS.next()) { + if (libraryLocations.length() > 0) { + libraryLocations.append(", "); + } + libraryLocations.append(libraryLocationsRS.getString("locationId")); + } + if (libraryLocations.length() > 0) { + long now = new Date().getTime() /1000; + + long earliestDateToPreserve = now - (14 * 24 * 60 * 60); + + PreparedStatement lastListUsedEntriesToDeleteStmt = dbConn.prepareStatement("SELECT lastListUsed from user where user.homeLocationId IN (" + libraryLocations + ") and lastListused < ?"); + lastListUsedEntriesToDeleteStmt.setLong(1, earliestDateToPreserve); + + ResultSet lastListUsedEntriesToDeleteRS = lastListUsedEntriesToDeleteStmt.executeQuery(); + while (lastListUsedEntriesToDeleteRS.next()) { + deleteLastListUsedStmt.setLong(1, lastListUsedEntriesToDeleteRS.getLong(1)); + int numUpdates = deleteLastListUsedStmt.executeUpdate(); + processLog.addUpdates(numUpdates); + numDeletions += numUpdates; + } + lastListUsedEntriesToDeleteRS.close(); + lastListUsedEntriesToDeleteStmt.close(); + } + } + librariesListRS.close(); + librariesListStmt.close(); + processLog.addNote("Removed " + numDeletions + " expired last list used entries"); + } catch (SQLException e) { + processLog.incErrors("Unable to remove expired last used list entries.", e); + } + } } diff --git a/code/web/release_notes/24.06.00.MD b/code/web/release_notes/24.06.00.MD index 26a52db63a..6475118fc7 100644 --- a/code/web/release_notes/24.06.00.MD +++ b/code/web/release_notes/24.06.00.MD @@ -52,6 +52,14 @@ - Added new Documentation links to several settings pages (*MKD*) - Updates to default user roles: removed testing roles and a couple uncommonly used roles; updated role titles (*MKD*) +//alexander +### New Settings +- Added option to delete stored information for lastListUsed after 14 days. Primary Configuration > Library Systems. + +### Database Cleanup Script Updates +- Update DatabaseCleanup.java to delete unsaved searches each time the cron runs. +- Add function to remove last list used after 14 days for libraries who have selected this option. + ## This release includes code contributions from - ByWater Solutions - Mark Noble (MDN) @@ -59,3 +67,6 @@ - Kodi Lein (KL) - Liz Rea (LR) - Morgan Daigneault (MKD) + +- PTFS Europe + - Alexander Blanchard (AB) \ No newline at end of file diff --git a/code/web/sys/DBMaintenance/version_updates/24.06.00.php b/code/web/sys/DBMaintenance/version_updates/24.06.00.php index 429e2dcd65..f1c9df984d 100644 --- a/code/web/sys/DBMaintenance/version_updates/24.06.00.php +++ b/code/web/sys/DBMaintenance/version_updates/24.06.00.php @@ -64,6 +64,15 @@ function getUpdates24_06_00(): array { ], ], //full_text_limiter + //alexander - PTFS Europe + 'library_delete_last_list_used_entries' => [ + 'title' => 'Library delete last list used history', + 'description' => 'Add an option to delete lastListUsed', + 'continueOnError' => true, + 'sql' => [ + 'ALTER TABLE library ADD COLUMN deleteLastListUsedEntries TINYINT(1) DEFAULT 0', + ], + ], //other diff --git a/code/web/sys/LibraryLocation/Library.php b/code/web/sys/LibraryLocation/Library.php index d55b451d3d..889eade7a3 100644 --- a/code/web/sys/LibraryLocation/Library.php +++ b/code/web/sys/LibraryLocation/Library.php @@ -113,6 +113,7 @@ class Library extends DataObject { public $showUserContactInformation; public $inSystemPickupsOnly; public $validPickupSystems; + public $deleteLastListUsedEntries; /** @noinspection PhpUnused */ public $pTypes; //This is used as part of the indexing process public $facetLabel; @@ -2837,6 +2838,14 @@ static function getObjectStructure($context = ''): array { 'forcesListReindex' => true, 'default' => 4, ], + 'deleteLastListUsedEntries' => [ + 'property' => 'deleteLastListUsedEntries', + 'type' => 'checkbox', + 'label' => 'Delete Last Used List After 14 Days', + 'description' => 'Whether to delete the last used list information for users after 14 days', + 'hideInLists' => true, + 'default' => 0, + ], 'allowAutomaticSearchReplacements' => [ 'property' => 'allowAutomaticSearchReplacements', 'type' => 'checkbox',