Skip to content

Commit

Permalink
1.5.7 <=> Database Corruption Mitigation reworked for newer Plex vers…
Browse files Browse the repository at this point in the history
…ions
  • Loading branch information
mynttt committed Jul 16, 2021
1 parent 5343089 commit 6498322
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 37 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.5.7
- Database corruption mitigation reworked in order to support newer plex versions
- Added some library processing details for easier debugging of potential future issues

## 1.5.6b
- bugfix regarding support for 16 char TVDB v3 keys

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.5.6b
1.5.7
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
id 'com.github.spotbugs' version '2.0.1'
}

version = '1.5.6b'
version = '1.5.7'
sourceCompatibility = '11'

new File(projectDir, "VERSION").text = version;
Expand Down
72 changes: 38 additions & 34 deletions src/main/java/updatetool/imdb/ImdbDatabaseSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -164,53 +165,43 @@ public void requestBatchUpdateOf(List<ImdbMetadataResult> items) throws SQLiteEx
}
}

private static final String ICU_MIG_1 = "fts4_metadata_titles_after_update_icu";
private static final String ICU_MIG_2 = "fts4_metadata_titles_before_update_icu";
private static final String ICU_MIG_1_SQL = "CREATE TRIGGER fts4_metadata_titles_after_update_icu AFTER UPDATE ON metadata_items BEGIN INSERT INTO fts4_metadata_titles_icu(docid, title, title_sort, original_title) VALUES(new.rowid, new.title, new.title_sort, new.original_title); END";
private static final String ICU_MIG_2_SQL = "CREATE TRIGGER fts4_metadata_titles_before_update_icu BEFORE UPDATE ON metadata_items BEGIN DELETE FROM fts4_metadata_titles_icu WHERE docid=old.rowid; END";

@SuppressFBWarnings({"DM_EXIT", "REC_CATCH_EXCEPTION", "OBL_UNSATISFIED_OBLIGATION", "DE_MIGHT_IGNORE"})
private void internalBatchUpdate(List<ImdbMetadataResult> items, boolean isNewAgent) {
boolean success = true;
boolean mitigationIcuNeeded, mitigationIcuTriggersDisabled = false;
List<AutoCloseable> close = new ArrayList<>();
Map<String, String> disabledTriggers = new LinkedHashMap<>();

try {

// Mitigation
var mitigationIcu = provider.connection.createStatement();
close.add(mitigationIcu);
var rs = mitigationIcu.executeQuery("SELECT name, sql FROM sqlite_master WHERE type = 'trigger' AND name = '" + ICU_MIG_1 + "' OR name = '" + ICU_MIG_2 + "';");
var rs = mitigationIcu.executeQuery("SELECT name, sql FROM sqlite_master WHERE type = 'trigger' AND sql LIKE \"%ON metadata_items%\";");
Map<String, String> storedSql = new HashMap<>();
while(rs.next()) {
storedSql.put(rs.getString(1), rs.getString(2));
}
rs.close();

int count = storedSql.size();
if(!(count == 2 || count == 0)) {
throw new UnsupportedOperationException("@@!!! INCONSISTENT TRIGGER COUNT STATE !!!@@ - Parameters for ICU SQLite3 Mitigation have changed! Contact the author of this tool immediatly and create a github issue here and include the output of '.schema metadata_items' on your SQLite3 PlexDB: https://github.com/mynttt/UpdateTool/issues");
}

mitigationIcuNeeded = count == 2;
mitigationIcuNeeded = storedSql.size() > 0;
Logger.info("PlexDB ICU Mitigation enabled: {}", mitigationIcuNeeded);

if(mitigationIcuNeeded) {
if(!Objects.equals(ICU_MIG_1_SQL, storedSql.get(ICU_MIG_1)) || !Objects.equals(ICU_MIG_2_SQL, storedSql.get(ICU_MIG_2))) {
Logger.error("IS : {}",storedSql.get(ICU_MIG_1));
Logger.error("MUST: {}",ICU_MIG_1_SQL);
Logger.error("IS : {}",storedSql.get(ICU_MIG_2));
Logger.error("MUST: {}",ICU_MIG_2_SQL);
throw new UnsupportedOperationException("@@!!! INCONSISTENT TRIGGER STATE !!!@@ - Parameters for ICU SQLite3 Mitigation have changed! Contact the author of this tool immediatly and create a github issue here and include the output of '.schema metadata_items' on your SQLite3 PlexDB: https://github.com/mynttt/UpdateTool/issues");
Logger.info("=== DATABASE CORRUPTION MITIGATION ===");
Logger.info("Disabling the following metadata_items triggers temporarily:");

for(var s : storedSql.entrySet()) {
Logger.info("{} => {}", s.getKey(), s.getValue());
var stmt = provider.connection.createStatement();
close.add(stmt);
stmt.executeUpdate(String.format("DROP TRIGGER %s;", s.getKey()));
disabledTriggers.put(s.getKey(), s.getValue());
Logger.info("Disabled Trigger: {}", s.getKey());
}

var s1 = provider.connection.createStatement();
close.add(s1);
s1.executeUpdate("DROP TRIGGER fts4_metadata_titles_before_update_icu;");
var s2 = provider.connection.createStatement();
close.add(s2);
s2.executeUpdate("DROP TRIGGER fts4_metadata_titles_after_update_icu;");
mitigationIcuTriggersDisabled = true;
Logger.info("=== ALL metadata_items TRIGGERS DISABLED :: PROCEED UPDATE ===");
}

try(var s = provider.connection.prepareStatement(isNewAgent ? "UPDATE metadata_items SET audience_rating = ?, extra_data = ?, rating = NULL WHERE id = ?"
Expand Down Expand Up @@ -262,23 +253,36 @@ private void internalBatchUpdate(List<ImdbMetadataResult> items, boolean isNewAg
close.clear();

if(mitigationIcuTriggersDisabled) {
Map<String, String> uncompleted = new LinkedHashMap<>(disabledTriggers);
try {
var s1 = provider.connection.createStatement();
close.add(s1);
s1.executeUpdate(ICU_MIG_1_SQL);
var s2 = provider.connection.createStatement();
close.add(s2);
s2.executeUpdate(ICU_MIG_2_SQL);
Logger.info("=== RESTORING metadata_items TRIGGERS AFTER UPDATE ===");
for(var s : disabledTriggers.entrySet()) {
var stmt = provider.connection.createStatement();
close.add(stmt);
stmt.executeUpdate(s.getValue());
Logger.info("Restored Trigger: {}", s.getKey());
uncompleted.remove(s.getKey());
}
Logger.info("=== DATABASE CORRUPTION MITIGATION COMPLETED :: TRIGGERS RESTORED ===");
} catch (SQLException ex) {

if(uncompleted.isEmpty()) {
Logger.error(ex);
Logger.error("Unknown error encountered. Please contact the author of this tool.");
System.exit(-1);
}

Logger.error(ex);
Logger.error("======================================");
Logger.error("WARNING!!! COULD NOT RESTORE DISABLED TRIGGERS IN ICU MITIGATION!!!");
Logger.error("RUN THE QUERIES BELOW ON YOUR PLEX DATABASE TO RESTORE TRIGGERS!");
Logger.error("RUN THE TRIGGER CREATION QUERIES BELOW ON YOUR PLEX DATABASE MANUALLY TO RESTORE THE DISABLED TRIGGERS!");
Logger.error("======================================");
Logger.error(ICU_MIG_1_SQL);
Logger.error(ICU_MIG_2_SQL);
for(var s : uncompleted.entrySet()) {
Logger.error(s.getValue());
}
Logger.error("======================================");
Logger.error("TOOL WILL EXIT NOW! DON'T USE BEVORE HAVING EXECUTED THESE COMMANDS!");
Logger.error("TOOL WILL EXIT NOW! DON'T USE BEFORE HAVING EXECUTED THESE COMMANDS!");
Logger.error("CONTACT THE AUTHOR OF THIS TOOL IF YOU DON'T KNOW WHAT TO DO NOW!");
System.exit(-1);
} finally {
for(AutoCloseable a : close) {
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/updatetool/imdb/ImdbDockerImplementation.java
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,15 @@ public void run() {
libraries.addAll(support.requestMovieLibraries(capabilities));
if(!capabilities.contains(Capabilities.NO_TV))
libraries.addAll(support.requestSeriesLibraries(capabilities));

if(libraries.isEmpty()) {
Logger.error("FATAL ERROR :: NO LIBRARIES EXIST IN DATABASE. EXITING NOW.");
System.exit(-1);
}

Logger.info("LIBRARIES => PRE LIBRARY FILTERING");
libraries.forEach(l -> Logger.info("Found library {} (ID={}) with agent: {} and {} item(s).", l.name, l.id, l.agent, l.items));

libraries.removeIf(l -> IGNORE_LIBRARIES.contains(l.id));
libraries.removeIf(l -> {
if(!l.agent.equals("tv.plex.agents.series"))
Expand All @@ -221,6 +230,9 @@ public void run() {
}
return false;
});

Logger.info("LIBRARIES => POST LIBRARY FILTERING");
libraries.forEach(l -> Logger.info("Will process library {} (ID={}) with agent: {} and {} item(s).", l.name, l.id, l.agent, l.items));
metadata = ImdbLibraryMetadata.fetchAll(libraries, new ImdbDatabaseSupport(connection, caches.get("new-agent-mapping")), config);
} catch(Exception e) {
Logger.error(e.getClass().getSimpleName() + " exception encountered...");
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.5.6b
1.5.7

0 comments on commit 6498322

Please sign in to comment.