Skip to content

Commit 403e055

Browse files
committed
- add helper tool to optimize history db. Especially older converted histories may contain duplicate data which might sloe down processing.
1 parent fecd883 commit 403e055

File tree

4 files changed

+105
-2
lines changed

4 files changed

+105
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
- **FEATURE:** Dialog "Filminformation" kann nun vollständig vergrößert oder verkleinert werden.
4242
- **FEATURE:** Die Filter werden nun über einen eigenen Button umbenannt und nicht mehr durch Eingabe in der ComboBox.
4343
- **FEATURE:** Bei der Lucene-Suche dürfen Wildcards nun auch am Anfang des Suchtexts verwendet werden.
44+
- **FEATURE:** Die Datenbank der gesehenen Filme kann nun über das Menü *"Hilfe/Hilfsmittel/History-Datenbank optimieren..."* von eventuell vorhandenen Duplikaten befreit werden. Dies kann die Performance des Programms bei einer großen (und älteren) Datenbank positiv beeinflussen.
4445
- Network Timeout wurde auf 10 Sekunden erhöht. Dies sollte bei schlechten Netzwerkverbindungen etwas Abhilfe schaffen.
4546

4647

src/main/java/mediathek/controller/history/SeenHistoryController.kt

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import java.nio.file.Files
1212
import java.nio.file.Path
1313
import java.sql.*
1414
import kotlin.system.exitProcess
15+
import kotlin.use
1516

1617
/**
1718
* Database based seen history controller.
@@ -126,8 +127,7 @@ class SeenHistoryController : AutoCloseable {
126127
it.executeUpdate("REINDEX seen_history")
127128
it.executeUpdate("VACUUM")
128129
}
129-
}
130-
catch (e: SQLException) {
130+
} catch (e: SQLException) {
131131
logger.error("Failed to execute maintenance script", e)
132132
}
133133
logger.trace("Finished maintenance")
@@ -271,6 +271,49 @@ class SeenHistoryController : AutoCloseable {
271271
Runtime.getRuntime().addShutdownHook(shutdownThread)
272272
}
273273

274+
@JvmRecord
275+
data class DuplicateSearchResult(val total: Long, val distinct: Long)
276+
277+
@Throws(SQLException::class)
278+
fun removeDuplicates() {
279+
val prevAutoCommitState = connection!!.autoCommit
280+
connection!!.autoCommit = false
281+
try {
282+
connection!!.createStatement().use { statement ->
283+
statement.executeUpdate("CREATE TABLE temp_history AS SELECT DISTINCT datum,thema,titel,url FROM seen_history ORDER BY datum")
284+
statement.executeUpdate("DELETE FROM seen_history")
285+
statement.executeUpdate("INSERT INTO seen_history(datum,thema,titel,url) SELECT datum,thema,titel,url FROM temp_history")
286+
statement.executeUpdate("DROP TABLE temp_history")
287+
}
288+
connection!!.commit()
289+
}
290+
catch (e: SQLException) {
291+
connection!!.rollback()
292+
throw e
293+
}
294+
connection!!.autoCommit = prevAutoCommitState
295+
}
296+
297+
@Throws(SQLException::class)
298+
fun checkDuplicates(): DuplicateSearchResult {
299+
var total: Long = 0
300+
var distinct: Long = 0
301+
302+
connection!!.createStatement().use { statement ->
303+
statement!!.executeQuery("SELECT COUNT(*) FROM seen_history").use {
304+
it.next()
305+
total = it.getLong(1)
306+
}
307+
}
308+
connection!!.createStatement().use { statement ->
309+
statement.executeQuery("SELECT COUNT(*) FROM (SELECT DISTINCT datum,thema,titel,url FROM seen_history)").use {
310+
it.next()
311+
distinct = it.getLong(1)
312+
}
313+
}
314+
return DuplicateSearchResult(total, distinct)
315+
}
316+
274317
init {
275318
try {
276319
if (!Files.exists(SqlDatabaseConfig.historyDbPath)) {
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package mediathek.gui.actions;
2+
3+
import mediathek.config.Konstanten;
4+
import mediathek.controller.history.SeenHistoryController;
5+
import mediathek.mainwindow.MediathekGui;
6+
import org.apache.logging.log4j.LogManager;
7+
import org.apache.logging.log4j.Logger;
8+
9+
import javax.swing.*;
10+
import java.awt.event.ActionEvent;
11+
import java.sql.SQLException;
12+
13+
public class OptimizeHistoryDbAction extends AbstractAction {
14+
private final MediathekGui mediathekGui;
15+
private static final Logger logger = LogManager.getLogger();
16+
17+
public OptimizeHistoryDbAction(MediathekGui mediathekGui) {
18+
this.mediathekGui = mediathekGui;
19+
putValue(NAME, "History-Datenbank optimieren...");
20+
}
21+
22+
@Override
23+
public void actionPerformed(ActionEvent e) {
24+
try (SeenHistoryController controller = new SeenHistoryController()) {
25+
var dupes = controller.checkDuplicates();
26+
var numDuplicates = dupes.total() - dupes.distinct();
27+
logger.trace("{} duplicates found in history", numDuplicates);
28+
if (numDuplicates == 0) {
29+
//no duplicates
30+
var msg = "Es sind keine Duplikate vorhanden.\nEine Optimierung ist nicht notwendig.";
31+
JOptionPane.showMessageDialog(mediathekGui, msg, Konstanten.PROGRAMMNAME, JOptionPane.INFORMATION_MESSAGE);
32+
}
33+
else {
34+
var msg = String.format("Es wurden %d Duplikate gefunden.\nMöchten Sie diese bereinigen?", numDuplicates);
35+
var answer = JOptionPane.showOptionDialog(mediathekGui, msg, Konstanten.PROGRAMMNAME,
36+
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
37+
if (answer == JOptionPane.YES_OPTION) {
38+
controller.removeDuplicates();
39+
dupes = controller.checkDuplicates();
40+
numDuplicates = dupes.total() - dupes.distinct();
41+
logger.trace("{} duplicates found in history after cleanup", numDuplicates);
42+
msg = String.format("Datenbank wurde bereinigt.\n%d Duplikate blieben übrig.", numDuplicates);
43+
JOptionPane.showMessageDialog(mediathekGui, msg, Konstanten.PROGRAMMNAME, JOptionPane.INFORMATION_MESSAGE);
44+
}
45+
}
46+
} catch (SQLException ex) {
47+
JOptionPane.showMessageDialog(mediathekGui, ex.getMessage(), Konstanten.PROGRAMMNAME, JOptionPane.ERROR_MESSAGE);
48+
}
49+
}
50+
}

src/main/java/mediathek/mainwindow/MediathekGui.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,12 @@ private void handleFilmlistWriteStopEvent(FilmListWriteStopEvent e) {
992992
SwingUtilities.invokeLater(() -> loadFilmListAction.setEnabled(true));
993993
}
994994

995+
private void createHelperToolsEntries() {
996+
var menu = new JMenu("Hilfsmittel");
997+
menu.add(new OptimizeHistoryDbAction(this));
998+
jMenuHilfe.add(menu);
999+
}
1000+
9951001
private void createHelpMenu() {
9961002
jMenuHilfe.add(new ShowOnlineHelpAction());
9971003
jMenuHilfe.add(new ShowOnlineFaqAction(this));
@@ -1003,6 +1009,9 @@ private void createHelpMenu() {
10031009
jMenuHilfe.addSeparator();
10041010
jMenuHilfe.add(new ResetFilterDialogPosition(this));
10051011
jMenuHilfe.addSeparator();
1012+
createHelperToolsEntries();
1013+
jMenuHilfe.addSeparator();
1014+
10061015
//do not show menu entry if we have external update support
10071016
if (GuiFunktionen.isNotUsingExternalUpdater()) {
10081017
jMenuHilfe.add(searchProgramUpdateAction);

0 commit comments

Comments
 (0)