Skip to content

Commit

Permalink
#2065 Increase match report column size in database (#2067)
Browse files Browse the repository at this point in the history
* #1797 create beta (#2052)

* Fix build (#2054)

* #1797 create beta

* #1797 fix build

* #2055 fix slow opening of team analyzer panel (#2056)

* update release_notes.md

* #2055 remove unused info label

* #2055 remove unused info label (code analysis results)

* #2055 release_notes.md

* #2055 release_notes.md

* Use SwingWorker to properly fix hanging UI. (#2057)

* Update dependencies, in particular OkHttp to fix CVE. (#2058)

This fixes CVE-2023-3635, cf. https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-3635

* #2059 fix currency error in team analyzer's total salary column (#2060)

* #2065 truncate match report if string is too long for database column

* #2065 set maximum match report size to 40000 characters

* #2065 new column "nullable" in sql editor table

* #2065 rename AbstractTable.truncateString

---------

Co-authored-by: Sébastien Le Callonnec <sebastien@weblogism.com>
  • Loading branch information
wsbrenk and tychobrailleur committed May 10, 2024
1 parent 3bcb696 commit 1cb63b5
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 82 deletions.
11 changes: 11 additions & 0 deletions src/main/java/core/db/AbstractTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ public AbstractTable(String tableName, ConnectionManager connectionManager) {
initColumns();
}

/**
* Truncate string to maximum length
* @param s String is truncated if its length exceeds given limit
* @param maxLength Length limit
* @return Truncated string
*/
static String truncateString(String s, int maxLength) {
if (s != null && s.length() > maxLength) return s.substring(0, maxLength);
return s;
}

protected String getTableType() {
return "CACHED";
}
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/core/db/DBUpdater.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ void updateDB(int DBVersion) {
updateDBv500(DBVersion);
updateDBv800(DBVersion);
case 800:
updateDBv900(DBVersion);
case 900:
}

} catch (Exception e) {
Expand All @@ -83,6 +85,12 @@ void updateDB(int DBVersion) {
}
}

private void updateDBv900(int dbVersion) throws SQLException {
var matchDetailsTable = dbManager.getTable(MatchDetailsTable.TABLENAME);
matchDetailsTable.tryChangeColumn("Matchreport", "VARCHAR(40000)");
updateDBVersion(dbVersion, 900);
}

private void updateDBv800(int dbVersion) throws SQLException {
assert dbManager.getConnectionManager() != null;
dbManager.getConnectionManager().executeUpdate("DROP TABLE IF EXISTS SPIELERSKILLUP");
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/core/db/MatchDetailsTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ protected void initColumns() {
ColumnDescriptor.Builder.newInstance().setColumnName("MatchID").setGetter((o) -> ((Matchdetails) o).getMatchID()).setSetter((o, v) -> ((Matchdetails) o).setMatchID((int) v)).setType(Types.INTEGER).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("MatchTyp").setGetter((o) -> ((Matchdetails) o).getMatchType().getId()).setSetter((o, v) -> ((Matchdetails) o).setMatchType(MatchType.getById((int) v))).setType(Types.INTEGER).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("ArenaId").setGetter((o) -> ((Matchdetails) o).getArenaID()).setSetter((o, v) -> ((Matchdetails) o).setArenaID((int) v)).setType(Types.INTEGER).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("ArenaName").setGetter((o) -> ((Matchdetails) o).getArenaName()).setSetter((o, v) -> ((Matchdetails) o).setArenaName((String) v)).setType(Types.VARCHAR).setLength(256).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("ArenaName").setGetter((o) -> truncateString(((Matchdetails) o).getArenaName(), 256)).setSetter((o, v) -> ((Matchdetails) o).setArenaName((String) v)).setType(Types.VARCHAR).setLength(256).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("Fetchdatum").setGetter((o) -> ((Matchdetails) o).getFetchDatum().toDbTimestamp()).setSetter((o, v) -> ((Matchdetails) o).setFetchDatum((HODateTime) v)).setType(Types.TIMESTAMP).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("GastName").setGetter((o) -> ((Matchdetails) o).getGuestTeamName()).setSetter((o, v) -> ((Matchdetails) o).setGastName((String) v)).setType(Types.VARCHAR).setLength(256).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("GastName").setGetter((o) -> truncateString(((Matchdetails) o).getGuestTeamName(), 256)).setSetter((o, v) -> ((Matchdetails) o).setGastName((String) v)).setType(Types.VARCHAR).setLength(256).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("GastID").setGetter((o) -> ((Matchdetails) o).getGuestTeamId()).setSetter((o, v) -> ((Matchdetails) o).setGastId((int) v)).setType(Types.INTEGER).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("GastEinstellung").setGetter((o) -> ((Matchdetails) o).getGuestEinstellung()).setSetter((o, v) -> ((Matchdetails) o).setGuestEinstellung((int) v)).setType(Types.INTEGER).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("GastTore").setGetter((o) -> ((Matchdetails) o).getGuestGoals()).setSetter((o, v) -> ((Matchdetails) o).setGuestGoals((int) v)).setType(Types.INTEGER).isNullable(false).build(),
Expand All @@ -42,7 +42,7 @@ protected void initColumns() {
ColumnDescriptor.Builder.newInstance().setColumnName("GastTacticSkill").setGetter((o) -> ((Matchdetails) o).getGuestTacticSkill()).setSetter((o, v) -> ((Matchdetails) o).setGuestTacticSkill((int) v)).setType(Types.INTEGER).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("GastTacticType").setGetter((o) -> ((Matchdetails) o).getGuestTacticType()).setSetter((o, v) -> ((Matchdetails) o).setGuestTacticType((int) v)).setType(Types.INTEGER).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("GASTHATSTATS").setGetter((o) -> ((Matchdetails) o).getGuestHatStats()).setSetter((o, v) -> ((Matchdetails) o).setGuestHatStats((int) v)).setType(Types.INTEGER).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("HeimName").setGetter((o) -> ((Matchdetails) o).getHomeTeamName()).setSetter((o, v) -> ((Matchdetails) o).setHeimName((String) v)).setType(Types.VARCHAR).setLength(256).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("HeimName").setGetter((o) -> truncateString(((Matchdetails) o).getHomeTeamName(), 256)).setSetter((o, v) -> ((Matchdetails) o).setHeimName((String) v)).setType(Types.VARCHAR).setLength(256).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("HeimId").setGetter((o) -> ((Matchdetails) o).getHomeTeamId()).setSetter((o, v) -> ((Matchdetails) o).setHeimId((int) v)).setType(Types.INTEGER).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("HeimEinstellung").setGetter((o) -> ((Matchdetails) o).getHomeEinstellung()).setSetter((o, v) -> ((Matchdetails) o).setHomeEinstellung((int) v)).setType(Types.INTEGER).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("HeimTore").setGetter((o) -> ((Matchdetails) o).getHomeGoals()).setSetter((o, v) -> ((Matchdetails) o).setHomeGoals((int) v)).setType(Types.INTEGER).isNullable(false).build(),
Expand All @@ -59,7 +59,7 @@ protected void initColumns() {
ColumnDescriptor.Builder.newInstance().setColumnName("SpielDatum").setGetter((o) -> ((Matchdetails) o).getMatchDate().toDbTimestamp()).setSetter((o, v) -> ((Matchdetails) o).setSpielDatum((HODateTime) v)).setType(Types.TIMESTAMP).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("WetterId").setGetter((o) -> ((Matchdetails) o).getWetterId()).setSetter((o, v) -> ((Matchdetails) o).setWetterId((int) v)).setType(Types.INTEGER).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("Zuschauer").setGetter((o) -> ((Matchdetails) o).getZuschauer()).setSetter((o, v) -> ((Matchdetails) o).setZuschauer((int) v)).setType(Types.INTEGER).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("Matchreport").setGetter((o) -> ((Matchdetails) o).getMatchreport()).setSetter((o, v) -> ((Matchdetails) o).setMatchreport((String) v)).setType(Types.VARCHAR).setLength(20000).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("Matchreport").setGetter((o) -> truncateString(((Matchdetails) o).getMatchreport(), 40000)).setSetter((o, v) -> ((Matchdetails) o).setMatchreport((String) v)).setType(Types.VARCHAR).setLength(40000).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("RegionID").setGetter((o) -> ((Matchdetails) o).getRegionId()).setSetter((o, v) -> ((Matchdetails) o).setRegionId((Integer) v)).setType(Types.INTEGER).isNullable(true).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("soldTerraces").setGetter((o) -> ((Matchdetails) o).getSoldTerraces()).setSetter((o, v) -> ((Matchdetails) o).setSoldTerraces((int) v)).setType(Types.INTEGER).isNullable(false).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("soldBasic").setGetter((o) -> ((Matchdetails) o).getSoldBasic()).setSetter((o, v) -> ((Matchdetails) o).setSoldBasic((int) v)).setType(Types.INTEGER).isNullable(false).build(),
Expand All @@ -77,8 +77,8 @@ protected void initColumns() {
ColumnDescriptor.Builder.newInstance().setColumnName("GuestGoal2").setGetter((o) -> ((Matchdetails) o).getGuestGoalsInPart(MatchEvent.MatchPartId.SECOND_HALF)).setSetter((o, v) -> ((Matchdetails) o).setGuestGoalsInPart(MatchEvent.MatchPartId.SECOND_HALF, (Integer) v)).setType(Types.INTEGER).isNullable(true).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("GuestGoal3").setGetter((o) -> ((Matchdetails) o).getGuestGoalsInPart(MatchEvent.MatchPartId.OVERTIME)).setSetter((o, v) -> ((Matchdetails) o).setGuestGoalsInPart(MatchEvent.MatchPartId.OVERTIME, (Integer) v)).setType(Types.INTEGER).isNullable(true).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("GuestGoal4").setGetter((o) -> ((Matchdetails) o).getGuestGoalsInPart(MatchEvent.MatchPartId.PENALTY_CONTEST)).setSetter((o, v) -> ((Matchdetails) o).setGuestGoalsInPart(MatchEvent.MatchPartId.PENALTY_CONTEST, (Integer) v)).setType(Types.INTEGER).isNullable(true).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("HomeFormation").setGetter((o) -> ((Matchdetails) o).getFormation(true)).setSetter((o, v) -> ((Matchdetails) o).setHomeFormation((String) v)).setType(Types.VARCHAR).setLength(5).isNullable(true).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("AwayFormation").setGetter((o) -> ((Matchdetails) o).getFormation(false)).setSetter((o, v) -> ((Matchdetails) o).setAwayFormation((String) v)).setType(Types.VARCHAR).setLength(5).isNullable(true).build()
ColumnDescriptor.Builder.newInstance().setColumnName("HomeFormation").setGetter((o) -> truncateString(((Matchdetails) o).getFormation(true), 5)).setSetter((o, v) -> ((Matchdetails) o).setHomeFormation((String) v)).setType(Types.VARCHAR).setLength(5).isNullable(true).build(),
ColumnDescriptor.Builder.newInstance().setColumnName("AwayFormation").setGetter((o) -> truncateString(((Matchdetails) o).getFormation(false), 5)).setSetter((o, v) -> ((Matchdetails) o).setAwayFormation((String) v)).setType(Types.VARCHAR).setLength(5).isNullable(true).build()
};
}

Expand Down
33 changes: 15 additions & 18 deletions src/main/java/core/db/frontend/TablesDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.awt.GraphicsEnvironment;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.Serial;
import java.sql.ResultSet;

import javax.swing.JDialog;
Expand All @@ -15,14 +16,13 @@
import javax.swing.JTable;
import javax.swing.JTextPane;



final class TablesDialog extends JDialog implements MouseListener {
private static final long serialVersionUID = -1584823279333655850L;
private JList tablelist;
@Serial
private static final long serialVersionUID = -1584823279333655850L;
private JList<String> tablelist;
private JTable tableColumns;

protected TablesDialog(SQLDialog owner) {
TablesDialog(SQLDialog owner) {
super(owner, "Tables");
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
initialize();
Expand All @@ -39,20 +39,18 @@ private void initialize() {
}

private JScrollPane getMiddlePanel() {
JScrollPane scrollPane = new JScrollPane(getList());
return scrollPane;
return new JScrollPane(getList());
}

private JScrollPane getTablePanel() {
JScrollPane scrollPane = new JScrollPane(getTable());
return scrollPane;
return new JScrollPane(getTable());
}

private JList getList()
private JList<String> getList()
{
if(tablelist == null)
{
tablelist = new JList(DBManager.instance().getConnectionManager().getAllTableNames());
tablelist = new JList<>(DBManager.instance().getConnectionManager().getAllTableNames());
tablelist.addMouseListener(this);
}
return tablelist;
Expand All @@ -73,12 +71,13 @@ private Object[][] setTable(String tablename)
{
ResultSet rs = DBManager.instance().getConnectionManager().executeQuery("SELECT * FROM " + tablename + " where 1 = 2");
int columns = rs.getMetaData().getColumnCount();
Object columnData[][] = new Object[columns][4];
var columnData = new Object[columns][4];
for(int i = 0; i < columns; i++)
{
columnData[i][0] = rs.getMetaData().getColumnName(i + 1);
columnData[i][1] = rs.getMetaData().getColumnTypeName(i + 1);
columnData[i][2] = rs.getMetaData().getColumnDisplaySize(i + 1);
columnData[i][3] = rs.getMetaData().isNullable(i + 1)==0?"false":"true";
}

rs.close();
Expand Down Expand Up @@ -113,12 +112,12 @@ public void mouseExited(MouseEvent mouseevent)
{
}

protected void refresh()
private void refresh()
{
String tableName = getList().getSelectedValue().toString();
try
{
DummyTableModel model1 = new DummyTableModel(setTable(tableName), COLUMNNAMES);
DummyTableModel model1 = new DummyTableModel(setTable(tableName), COLUMN_NAMES);
tableColumns.setModel(model1);
}
catch(Exception e)
Expand All @@ -127,9 +126,7 @@ protected void refresh()
}
}

private static final String COLUMNNAMES[] = {
"NAME", "TYP", "SIZE"
private static final String[] COLUMN_NAMES = {
"NAME", "TYP", "SIZE", "Nullable"
};


}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import core.model.HOVerwaltung;
import core.model.enums.MatchType;
import core.model.match.Matchdetails;
import core.util.CurrencyUtils;
import core.util.Helper;
import module.teamAnalyzer.SystemManager;
import module.teamAnalyzer.report.TeamReport;
Expand Down Expand Up @@ -220,7 +221,7 @@ public IHOTableEntry getTableEntry(TeamLineup lineup) {
new RecapUserColumn("ls.team.sumsalary", 50) {
@Override
public IHOTableEntry getTableEntry(TeamLineup lineup) {
return createIntegerTableEntry(lineup.getSalarySum(), MatchesColumnModel.getColor4Matchtyp(lineup.getMatchType()), true);
return createIntegerTableEntry(CurrencyUtils.convertCurrency(lineup.getSalarySum()), MatchesColumnModel.getColor4Matchtyp(lineup.getMatchType()), true);
}
},
new RecapUserColumn("ls.team.numhomegrown", 50) {
Expand Down
63 changes: 6 additions & 57 deletions src/main/resources/release_notes.md
Original file line number Diff line number Diff line change
@@ -1,92 +1,41 @@


## Highlights
* Calculate stamina sub skill value (using Schum's formula)
* Refactoring rating prediction (implement Schum rating)
* Refactoring of the transfer module. Calculation of transfer fee income.
* Refactoring of the database prepared statement caching.
* Improve training planning
* New color editor in options dialog

## [Detailed Changelog](https://github.com/ho-dev/HattrickOrganizer/issues?q=milestone%3A8.0)

## [Detailed Changelog](https://github.com/ho-dev/HattrickOrganizer/issues?q=milestone%3A9.0)

### Database
* Fix `unexpected token` issue with Transfer table query (#1965)
* Fix potential NPE when using a prepared statement (#1941)
* Improve Database Cleanup tool by adding additional match types (#1587)
* Repairing a failed V5 database upgrade (#1941)
* Increase match report column size (#2065)

### Squad
* Fix length of owner notes in players' database table (#1816)
* player avatar image can be reloaded (#1815)
* Fix error player download nickname null pointer exception (#1938)
* Fix initial sorting by player group (#1909)
* Show stamina sub skill (#383)
* fix error on player details display after initial download (#2044)

### Team Analyzer
* Restore size of match prediction dialog box (#1898)
* Improve layout of Team Analyzer a bit, add option to hide Special Events, and add info about selected team (#2020)
* Fix Home/Away setup in Simulator panel (#1885)

### Rating
* Implement schum rating prediction (#1782)

### Matches
* Fix bug loading matches with no region id (#1975)
* Fix NPE when selecting match with red card (#2034)

### Lineup
* Fix missing player id column in lineup assistant's player table (#1930)

### Special events
* Refactoring special events table layout (#816)

### Transfer
* Refactoring of the transfer module. Calculation of transfer fee income. (#245)
* Fix transfer scout's copy and paste of own players (#1897)
* Calculation of player's total cost of ownership (#741)

### Training
* Fix scrolling of training table (#1936)
* Improve training planning. Each skill training can be prioritized (#1886)
* Change subskill recalculation dialog display (#1556)
* Tuning subskill recalculation (#1870)

### League

### Youth
* Increase effect of youth friendly match training (#1950, #1994)
* Modify youth module layout (#1449)
* Set initial youth module view layout (#1558)
* Display specialty icons in youth player tables (#1999)
* Display future player development (potential) and take allrounder skill into account (#2045)

### Option setting
* new color editor in option settings (#1242)

### Misc
* Add a Linux-friendly default theme, called “Gnome.”
* Add Kotlin support to codebase
* Reset progress bar when action is finished (#1955)
* Upgrade Gradle to version 8.5
* Fix issue with startup post-installation (#2002)
* Fix NPE when saving preferences on un-managed HO install (#1992)
HO now downloads the update in the browser when HO install is un-managed.
* Enable standard custom popup menu in oauth dialog's text fields (#1471)
* Move previous series download checkbox to the check box tree of download dialog (#1434)

## Translations

Reports by Contributors - September 24, 2023 - April 28, 2024
Reports by Contributors - April 28, 2024 - May 06, 2024

* wsbrenk 355
* Lidegand 178
* Sebastien 156
* Achilles 70
* \_KOHb\_ 22
* Georgi 10
* Moorhuhninho 3
* sich 3
* wsbrenk 0

Total 797
Total 0

0 comments on commit 1cb63b5

Please sign in to comment.