Copy DBRepair.sh's new 98=quit and 99=exit

Also remove the temporary deflate code and other minor refactoring.
This commit is contained in:
danrahn 2025-06-01 12:33:53 -07:00
parent 65f4e5d33d
commit a3ba41b668
3 changed files with 67 additions and 55 deletions

View File

@ -12,7 +12,7 @@ setlocal enabledelayedexpansion
echo. echo.
echo NOTE: This script is being replaced with the PowerShell script DBRepair-Windows.ps1, echo NOTE: This script is being replaced with the PowerShell script DBRepair-Windows.ps1,
echo which aims to better emulate DBRepair.sh (more options, interative mode, etc). echo which aims to better emulate DBRepair.sh (more options, interactive mode, etc).
echo Consider moving over to the new script. echo Consider moving over to the new script.
echo. echo.
@ -135,8 +135,8 @@ del "%TmpFile%"
echo %time% -- Main DB verification check is: %Result% echo %time% -- Main DB verification check is: %Result%
echo %time% -- Main DB verification check is: %Result% >> "%PlexData%\DBRepair.log" echo %time% -- Main DB verification check is: %Result% >> "%PlexData%\DBRepair.log"
if not "%Result%" == "ok" ( if not "%Result%" == "ok" (
echo %time% -- ERROR: Main DB verificaion failed. Exiting. echo %time% -- ERROR: Main DB verification failed. Exiting.
echo %time% -- ERROR: Main DB verificaion failed. Exiting. >> "%PlexData%\DBRepair.log" echo %time% -- ERROR: Main DB verification failed. Exiting. >> "%PlexData%\DBRepair.log"
exit /B 4 exit /B 4
) )
echo %time% -- Main DB verification successful. echo %time% -- Main DB verification successful.
@ -161,8 +161,8 @@ del "%TmpFile%"
echo %time% -- Blobs DB verification check is: %Result% echo %time% -- Blobs DB verification check is: %Result%
echo %time% -- Blobs DB verification check is: %Result% >> "%PlexData%\DBRepair.log" echo %time% -- Blobs DB verification check is: %Result% >> "%PlexData%\DBRepair.log"
if not "%Result%" == "ok" ( if not "%Result%" == "ok" (
echo %time% -- ERROR: Blobs DB verificaion failed. Exiting. echo %time% -- ERROR: Blobs DB verification failed. Exiting.
echo %time% -- ERROR: Blobs DB verificaion failed. Exiting. >> "%PlexData%\DBRepair.log" echo %time% -- ERROR: Blobs DB verification failed. Exiting. >> "%PlexData%\DBRepair.log"
exit /B 6 exit /B 6
) )
echo %time% -- Blobs DB verification successful. echo %time% -- Blobs DB verification successful.

View File

@ -3,7 +3,7 @@
# # # #
######################################################################### #########################################################################
$DBRepairVersion = 'v1.01.01' $DBRepairVersion = 'v1.01.02'
class DBRepair { class DBRepair {
[DBRepairOptions] $Options [DBRepairOptions] $Options
@ -14,7 +14,10 @@ class DBRepair {
[string] $Timestamp # Timestamp used for temporary database files [string] $Timestamp # Timestamp used for temporary database files
[string] $LogFile # Path of our log file [string] $LogFile # Path of our log file
[string] $Version # Current script version [string] $Version # Current script version
[string] $Stage # Current stage of the script (e.g. "Auto", "Prune", etc.)
[bool] $IsError # Whether we're currently in an error state [bool] $IsError # Whether we're currently in an error state
[string] $MainDB = "com.plexapp.plugins.library.db"
[string] $BlobsDB = "com.plexapp.plugins.library.blobs.db"
DBRepair($Arguments, $Version) { DBRepair($Arguments, $Version) {
$this.Options = [DBRepairOptions]::new() $this.Options = [DBRepairOptions]::new()
@ -85,8 +88,8 @@ class DBRepair {
Write-Host " 42 - 'ignore' - Ignore duplicate/constraint errors." Write-Host " 42 - 'ignore' - Ignore duplicate/constraint errors."
} }
Write-Host Write-Host
Write-Host " 99 - 'quit' - Quit immediately. Keep all temporary files." Write-Host " 98 - 'quit' - Quit immediately. Keep all temporary files."
Write-Host " 'exit' - Exit with cleanup options." Write-Host " 99 'exit' - Exit with cleanup options."
Write-Host Write-Host
Write-Host " 'menu x' - Show this menu in interactive mode, where x is on/off/yes/no" Write-Host " 'menu x' - Show this menu in interactive mode, where x is on/off/yes/no"
} }
@ -190,10 +193,14 @@ class DBRepair {
switch -Regex ($Choice) { switch -Regex ($Choice) {
"^(1|stop)$" { $this.DoStop() } "^(1|stop)$" { $this.DoStop() }
"^(2|autom?a?t?i?c?)$" { "^(2|autom?a?t?i?c?)$" {
$this.SetStage("Auto")
$this.IsError = !$this.RunAutomaticDatabaseMaintenance() $this.IsError = !$this.RunAutomaticDatabaseMaintenance()
} }
"^(7|start?)$" { $this.StartPMS() } "^(7|start?)$" { $this.StartPMS() }
"^(21|(prune?|remov?e?))$" { $this.PrunePhotoTranscoderCache() } "^(21|(prune?|remov?e?))$" {
$this.SetStage("Prune")
$this.PrunePhotoTranscoderCache()
}
"^(42|ignor?e?|honor?)$" { "^(42|ignor?e?|honor?)$" {
if (($this.Options.IgnoreErrors -and ($Choice[0] -eq 'i')) -or (!$this.Options.IgnoreErrors -and ($Choice[0] -eq 'h'))) { if (($this.Options.IgnoreErrors -and ($Choice[0] -eq 'i')) -or (!$this.Options.IgnoreErrors -and ($Choice[0] -eq 'h'))) {
Write-Host "Honor/Ignore setting unchanged." Write-Host "Honor/Ignore setting unchanged."
@ -204,13 +211,13 @@ class DBRepair {
$msg = if ($this.Options.IgnoreErrors) { "Ignoring database errors." } else { "Honoring database errors." } $msg = if ($this.Options.IgnoreErrors) { "Ignoring database errors." } else { "Honoring database errors." }
$this.WriteOutputLog($msg) $this.WriteOutputLog($msg)
} }
"^(99|quit)$" { "^(98|quit)$" {
$this.Output("Retaining all remporary work files.") $this.Output("Retaining all temporary work files.")
$this.WriteLog("Exit - Retain temp files.") $this.WriteLog("Exit - Retain temp files.")
$this.WriteEnd() $this.WriteEnd()
return return
} }
"^exit$" { "^(99|exit)$" {
if ($EOFExit) { if ($EOFExit) {
$this.Output("Unexpected exit command. Keeping all temporary work files.") $this.Output("Unexpected exit command. Keeping all temporary work files.")
$this.WriteLog("EOFExit - Retain temp files.") $this.WriteLog("EOFExit - Retain temp files.")
@ -307,10 +314,10 @@ class DBRepair {
# All-in-one database utility - Repair/Check/Reindex # All-in-one database utility - Repair/Check/Reindex
[bool] RunAutomaticDatabaseMaintenance() { [bool] RunAutomaticDatabaseMaintenance() {
$this.Output("Automatic Check,Repair,Index started.") $this.Output("Automatic Check,Repair,Index started.")
$this.WriteLog("Auto - START") $this.WriteLog($this.StageLog("START"))
if ($this.PMSRunning()) { if ($this.PMSRunning()) {
$this.WriteLog("Auto - FAIL - PMS running") $this.WriteLog($this.StageLog("FAIL - PMS running"))
$this.OutputWarn("Unable to run automatic sequence. PMS is running. Please stop PlexMediaServer.") $this.OutputWarn("Unable to run automatic sequence. PMS is running. Please stop PlexMediaServer.")
return $false return $false
} }
@ -326,48 +333,38 @@ class DBRepair {
} }
} }
$MainDBName = "com.plexapp.plugins.library.db"
$MainDB = Join-Path $this.PlexDBDir -ChildPath $MainDBName
# Temporary DB actions
$this.WriteOutputLog("Performing DB cleanup tasks.")
$ignoreErrorsSaved = $this.Options.IgnoreErrors # This isn't a critical task, allow it to fail without stopping the script
$this.Options.IgnoreErrors = $true
$this.RunSqlCommand("""$MainDB"" ""DELETE from statistics_bandwidth WHERE account_id IS NULL;""", "Failed to clean up statistics_bandwidth table.")
$this.Options.IgnoreErrors = $ignoreErrorsSaved
$this.Output("Exporting Main DB") $this.Output("Exporting Main DB")
$MainDBPath = Join-Path $this.PlexDBDir -ChildPath $this.MainDB
$MainDBSQL = Join-Path $DBTemp -ChildPath "library.sql_$($this.TimeStamp)" $MainDBSQL = Join-Path $DBTemp -ChildPath "library.sql_$($this.TimeStamp)"
if (!$this.FileExists($MainDB)) { if (!$this.FileExists($MainDBPath)) {
$this.ExitDBMaintenance("Could not find $MainDBName in database directory", $false) $this.ExitDBMaintenance("Could not find $($this.MainDB) in database directory", $false)
return $false return $false
} }
if (!$this.ExportPlexDB($MainDB, $MainDBSQL)) { return $false } if (!$this.ExportPlexDB($MainDBPath, $MainDBSQL)) { return $false }
$this.Output("Exporting Blobs DB") $this.Output("Exporting Blobs DB")
$BlobsDBName = "com.plexapp.plugins.library.blobs.db" $BlobsDBPath = Join-Path $this.PlexDBDir -ChildPath $this.BlobsDB
$BlobsDB = Join-Path $this.PlexDBDir -ChildPath $BlobsDBName
$BlobsDBSQL = Join-Path $DBTemp -ChildPath "blobs.sql_$($this.Timestamp)" $BlobsDBSQL = Join-Path $DBTemp -ChildPath "blobs.sql_$($this.Timestamp)"
if (!$this.FileExists($BlobsDB)) { if (!$this.FileExists($BlobsDBPath)) {
$this.ExitDBMaintenance("Could not find $BlobsDBName in database directory", $false) $this.ExitDBMaintenance("Could not find $($this.BlobsDB) in database directory", $false)
return $false return $false
} }
if (!$this.ExportPlexDB($BlobsDB, $BlobsDBSQL)) { return $false } if (!$this.ExportPlexDB($BlobsDBPath, $BlobsDBSQL)) { return $false }
$this.Output("Successfully exported the main and blobs databases. Proceeding to import into new database.") $this.Output("Successfully exported the main and blobs databases. Proceeding to import into new database.")
$this.WriteLog("Repair - Export databases - PASS") $this.WriteLog("Repair - Export databases - PASS")
# Make sure Plex hasn't been started while we were exporting # Make sure Plex hasn't been started while we were exporting
if (!$this.CheckPMS("Auto ", "export")) { return $false } if (!$this.CheckPMS("export")) { return $false }
$this.Output("Importing Main DB.") $this.Output("Importing Main DB.")
$MainDBImport = Join-Path $this.PlexDBDir -ChildPath "${MainDBName}_$($this.Timestamp)" $MainDBImport = Join-Path $this.PlexDBDir -ChildPath "$($this.MainDB)_$($this.Timestamp)"
if (!$this.ImportPlexDB($MainDBSQL, $MainDBImport)) { return $false } if (!$this.ImportPlexDB($MainDBSQL, $MainDBImport)) { return $false }
$this.Output("Importing Blobs DB.") $this.Output("Importing Blobs DB.")
$BlobsDBImport = Join-Path $this.PlexDBDir -ChildPath "${BlobsDBName}_$($this.Timestamp)" $BlobsDBImport = Join-Path $this.PlexDBDir -ChildPath "$($this.BlobsDB)_$($this.Timestamp)"
if (!$this.ImportPlexDB($BlobsDBSQL, $BlobsDBImport)) { return $false } if (!$this.ImportPlexDB($BlobsDBSQL, $BlobsDBImport)) { return $false }
$this.Output("Successfully imported databases.") $this.Output("Successfully imported databases.")
@ -383,7 +380,7 @@ class DBRepair {
$this.Output("Verification complete. PMS blobs database is OK.") $this.Output("Verification complete. PMS blobs database is OK.")
$this.WriteLog("Repair - Verify blobs database - PASS") $this.WriteLog("Repair - Verify blobs database - PASS")
if (!$this.CheckPMS("Auto ", "import")) { return $false } if (!$this.CheckPMS("import")) { return $false }
# Import complete, now reindex # Import complete, now reindex
$this.WriteOutputLog("Reindexing Main DB") $this.WriteOutputLog("Reindexing Main DB")
@ -393,14 +390,14 @@ class DBRepair {
$this.WriteOutputLog("Reindexing complete.") $this.WriteOutputLog("Reindexing complete.")
$this.WriteOutputLog("Moving current DBs to DBTMP and making new databases active") $this.WriteOutputLog("Moving current DBs to DBTMP and making new databases active")
if (!$this.CheckPMS("Auto ", "new database copy")) { return $false } if (!$this.CheckPMS("new database copy")) { return $false }
try { try {
$this.MoveDatabase($MainDB, (Join-Path $DBTemp -ChildPath "${MainDBName}_$($this.Timestamp)"), "move Main DB to DBTMP") $this.MoveDatabase($MainDBPath, (Join-Path $DBTemp -ChildPath "$($this.MainDB)_$($this.Timestamp)"), "move Main DB to DBTMP")
$this.MoveDatabase($MainDBImport, $MainDB, "replace Main DB with rebuilt DB") $this.MoveDatabase($MainDBImport, $MainDBPath, "replace Main DB with rebuilt DB")
$this.MoveDatabase($BlobsDB, (Join-Path $DBTemp -ChildPath "${BlobsDBName}_$($this.Timestamp)"), "move Blobs DB to DBTMP") $this.MoveDatabase($BlobsDBPath, (Join-Path $DBTemp -ChildPath "$($this.BlobsDB)_$($this.Timestamp)"), "move Blobs DB to DBTMP")
$this.MoveDatabase($BlobsDBImport, $BlobsDB, "replace Blobs DB with rebuilt DB") $this.MoveDatabase($BlobsDBImport, $BlobsDBPath, "replace Blobs DB with rebuilt DB")
} catch { } catch {
$Error.Clear() $Error.Clear()
return $false return $false
@ -411,11 +408,11 @@ class DBRepair {
} }
# Return whether we can continue DB repair (i.e. whether PMS is running) at the given stage in the process. # Return whether we can continue DB repair (i.e. whether PMS is running) at the given stage in the process.
[bool] CheckPMS([string] $Stage, [string] $SubStage) { [bool] CheckPMS([string] $SubStage) {
if ($this.PMSRunning()) { if ($this.PMSRunning()) {
$SubMessage = if ($SubStage) { "during $SubStage" } else { "" } $SubMessage = if ($SubStage) { "during $SubStage" } else { "" }
$this.WriteLog("$Stage - FAIL - PMS running $SubMessage") $this.WriteLog($this.StageLog("FAIL - PMS running $SubMessage"))
$this.OutputWarn("Unable to run $Stage. PMS is running. Please stop PlexMediaServer.") $this.OutputWarn("Unable to run $($this.Stage.TrimEnd()). PMS is running. Please stop PlexMediaServer.")
return $false return $false
} }
@ -435,10 +432,10 @@ class DBRepair {
# Attempts to prune PhotoTranscoder images that are older than the specified date cutoff (30 days by default) # Attempts to prune PhotoTranscoder images that are older than the specified date cutoff (30 days by default)
[void] PrunePhotoTranscoderCache() { [void] PrunePhotoTranscoderCache() {
$this.WriteLog("Prune - START") $this.WriteLog($this.StageLog("START"))
if ($this.PMSRunning()) { if ($this.PMSRunning()) {
$this.OutputWarn("Unable to prune Phototranscoder cache. PMS is running.") $this.OutputWarn("Unable to prune Phototranscoder cache. PMS is running.")
$this.WriteLog("Prune - FAIL - PMS running") $this.WriteLog($this.StageLog("FAIL - PMS running"))
return return
} }
@ -452,7 +449,7 @@ class DBRepair {
if ($Prunable -eq 0) { if ($Prunable -eq 0) {
$this.Output("No files found to prune.") $this.Output("No files found to prune.")
$this.WriteLog("Prune - PASS (no files found to prune)") $this.WriteLog($this.StageLog("PASS (no files found to prune)"))
return return
} }
@ -465,13 +462,13 @@ class DBRepair {
$Pruned = $PruneResult.PrunableFiles $Pruned = $PruneResult.PrunableFiles
$Total = $PruneResult.TotalFiles $Total = $PruneResult.TotalFiles
$Saved = $PruneResult.SpaceSavings $Saved = $PruneResult.SpaceSavings
$this.WriteOutputLog("Prune - Removed $Pruned files over $Cutoff days old ($Saved), out of $Total total files") $this.WriteOutputLog($this.StageLog("Removed $Pruned files over $Cutoff days old ($Saved), out of $Total total files"))
$this.Output("Pruning completed.") $this.Output("Pruning completed.")
} else { } else {
$this.WriteOutputLog("Prune - Prune cancelled by user") $this.WriteOutputLog($this.StageLog("Prune cancelled by user"))
} }
$this.WriteLog("Prune - PASS") $this.WriteLog($this.StageLog("PASS"))
} }
# Traverses PhotoTranscoder cache to find and delete files older than the specified max age. # Traverses PhotoTranscoder cache to find and delete files older than the specified max age.
@ -544,6 +541,16 @@ class DBRepair {
$this.WriteLog("============================================================") $this.WriteLog("============================================================")
} }
# Set the current stage (with the right amount of padding)
[void] SetStage([string] $Stage) {
$this.Stage = $Stage + (" " * [math]::Max(0, 8 - $Stage.Length))
}
# Prepend the current stage to the given text
[string] StageLog([string] $text) {
return "$($this.Stage) - $text"
}
### File Helpers ### ### File Helpers ###
# Check whether the given directory exists (and is a directory) # Check whether the given directory exists (and is a directory)
@ -566,7 +573,7 @@ class DBRepair {
### Setup Helpers ### ### Setup Helpers ###
# Retrieve Plex's data directory, exiting the script on falure # Retrieve Plex's data directory, exiting the script on failure
[string] GetAppDataDir() { [string] GetAppDataDir() {
$PMSRegistry = $this.GetHKCU() $PMSRegistry = $this.GetHKCU()
$PlexAppData = $PMSRegistry.LocalAppDataPath $PlexAppData = $PMSRegistry.LocalAppDataPath
@ -681,11 +688,11 @@ class DBRepair {
[void] ExitDBMaintenance([string] $Message, [boolean] $Success) { [void] ExitDBMaintenance([string] $Message, [boolean] $Success) {
if ($Success) { if ($Success) {
$this.Output("Automatic Check,Repair,Index succeeded.") $this.Output("Automatic Check,Repair,Index succeeded.")
$this.WriteLog("Auto - PASS") $this.WriteLog($this.StageLog("PASS"))
} else { } else {
$this.OutputWarn("Automatic maintenance failed - $Message") $this.OutputWarn("Database maintenance failed - $Message")
$this.WriteLog("Auto - $Message, cannot continue.") $this.WriteLog($this.StageLog("$Message, cannot continue."))
$this.WriteLog("Auto - FAIL") $this.WriteLog($this.StageLog("FAIL"))
} }
} }

View File

@ -4,6 +4,11 @@ Release notes for the Windows counterpart to DBRepair.sh (DBRepair-Windows.ps1)
# Release Info # Release Info
v1.01.02
- Remove `statistics_bandwidth` pruning, as it's now part of PMS 1.41.8
- Change `quit` to 98 and `exit` to 99
- Minor logging refactoring
v1.01.01 v1.01.01
- Add `staticstics_bandwidth` pruning during automatic repair. - Add `staticstics_bandwidth` pruning during automatic repair.