Skip to content

Commit

Permalink
Merge pull request #53 from AlexanderBlanchardAC/gdpr_cleanup_script
Browse files Browse the repository at this point in the history
feat: alter unsaved search deletion and add option for last used lists
  • Loading branch information
AlexanderBlanchardAC authored May 21, 2024
2 parents 063e933 + 62c6be2 commit f55beb0
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -420,15 +421,15 @@ 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;
long numBatches = (numSearches / batchSize) + 1;
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();
Expand All @@ -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);
}
}
}
11 changes: 11 additions & 0 deletions code/web/release_notes/24.06.00.MD
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,21 @@
- 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)
- Kirstin Kroeger (KK)
- Kodi Lein (KL)
- Liz Rea (LR)
- Morgan Daigneault (MKD)

- PTFS Europe
- Alexander Blanchard (AB)
9 changes: 9 additions & 0 deletions code/web/sys/DBMaintenance/version_updates/24.06.00.php
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
9 changes: 9 additions & 0 deletions code/web/sys/LibraryLocation/Library.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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',
Expand Down

0 comments on commit f55beb0

Please sign in to comment.