You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
4.2 KiB
126 lines
4.2 KiB
/* © SRSoftware 2025 */ |
|
package de.srsoftware.umbrella.message; |
|
|
|
import de.srsoftware.umbrella.core.UmbrellaException; |
|
import de.srsoftware.umbrella.user.model.UmbrellaUser; |
|
import de.srsoftware.umbrella.message.model.Settings; |
|
|
|
import java.sql.Connection; |
|
import java.sql.ResultSet; |
|
import java.sql.SQLException; |
|
import java.util.HashSet; |
|
import java.util.stream.Collectors; |
|
|
|
import static de.srsoftware.tools.jdbc.Condition.equal; |
|
import static de.srsoftware.tools.jdbc.Query.*; |
|
import static de.srsoftware.umbrella.core.Constants.*; |
|
import static de.srsoftware.umbrella.message.model.Settings.Times; |
|
import static java.lang.System.Logger.Level.ERROR; |
|
import static java.lang.System.Logger.Level.WARNING; |
|
import static java.text.MessageFormat.format; |
|
|
|
public class SqliteDb implements MessageDb{ |
|
private static final System.Logger LOG = System.getLogger(SqliteDb.class.getSimpleName()); |
|
private final Connection db; |
|
private static final String DB_VERSION = "message_db_version"; |
|
private static final int INITIAL_DB_VERSION = 1; |
|
private static final String TABLE_SUBMISSIONS = "message_submission"; |
|
|
|
public SqliteDb(Connection conn){ |
|
db = conn; |
|
init(); |
|
} |
|
|
|
private void createSubmissionTable() { |
|
var createTable = """ |
|
CREATE TABLE IF NOT EXISTS {0} ( {1} Integer PRIMARY KEY, {2} VARCHAR(255) NOT NULL); |
|
"""; |
|
try { |
|
var stmt = db.prepareStatement(format(createTable,TABLE_SUBMISSIONS, USER_ID, VALUE)); |
|
stmt.execute(); |
|
stmt.close(); |
|
} catch (SQLException e) { |
|
LOG.log(ERROR,ERROR_FAILED_CREATE_TABLE,TABLE_SUBMISSIONS,e); |
|
throw new RuntimeException(e); |
|
} |
|
} |
|
|
|
|
|
private int createSettingsTable() { |
|
var createTable = """ |
|
CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255) NOT NULL); |
|
"""; |
|
try { |
|
var stmt = db.prepareStatement(format(createTable,TABLE_SETTINGS, KEY, VALUE)); |
|
stmt.execute(); |
|
stmt.close(); |
|
} catch (SQLException e) { |
|
LOG.log(ERROR,ERROR_FAILED_CREATE_TABLE,TABLE_SETTINGS,e); |
|
throw new RuntimeException(e); |
|
} |
|
|
|
Integer version = null; |
|
try { |
|
var rs = select(VALUE).from(TABLE_SETTINGS).where(KEY, equal(DB_VERSION)).exec(db); |
|
if (rs.next()) version = rs.getInt(VALUE); |
|
rs.close(); |
|
if (version == null) { |
|
version = INITIAL_DB_VERSION; |
|
insertInto(TABLE_SETTINGS, KEY, VALUE).values(DB_VERSION,version).execute(db).close(); |
|
} |
|
|
|
return version; |
|
} catch (SQLException e) { |
|
LOG.log(ERROR,ERROR_FAILED_CREATE_TABLE,DB_VERSION,TABLE_SETTINGS,e); |
|
throw new RuntimeException(e); |
|
} |
|
} |
|
|
|
private int createTables() { |
|
createSubmissionTable(); |
|
return createSettingsTable(); |
|
} |
|
|
|
@Override |
|
public Settings getSettings(UmbrellaUser user) throws UmbrellaException { |
|
try { |
|
Settings settings = null; |
|
var rs = select(VALUE).from(TABLE_SUBMISSIONS).where(USER_ID,equal(user.id())).exec(db); |
|
if (rs.next()) settings = toSettings(rs); |
|
rs.close(); |
|
if (settings != null) return settings; |
|
throw new UmbrellaException(500,"No submission settings stored for {0}",user); |
|
} catch (SQLException e) { |
|
LOG.log(ERROR,"Failed to read settings for {0} from {1} table",user,TABLE_SUBMISSIONS,e); |
|
throw new UmbrellaException(500,"Failed to read settings for {0} from {1} table",user,TABLE_SUBMISSIONS).causedBy(e); |
|
} |
|
} |
|
|
|
private void init() { |
|
var version = createTables(); |
|
} |
|
|
|
private Settings toSettings(ResultSet rs) throws SQLException { |
|
var submission = rs.getString(VALUE); |
|
var parts = submission.split(","); |
|
var times = new HashSet<Times>(); |
|
for (var part : parts) try { |
|
times.add(Times.valueOf(part)); |
|
} catch (IllegalArgumentException e) { |
|
LOG.log(WARNING,"encountered {0}, which is not a valid Times enumeration value!",part); |
|
} |
|
return new Settings(times); |
|
} |
|
|
|
@Override |
|
public Settings update(UmbrellaUser user, Settings settings) throws UmbrellaException { |
|
var times = settings.times().stream().map(Times::toString).collect(Collectors.joining(",")); |
|
try { |
|
replaceInto(TABLE_SUBMISSIONS, USER_ID, VALUE).values(user.id(),times).execute(db).close(); |
|
return settings; |
|
} catch (SQLException e) { |
|
LOG.log(WARNING,"Failed to store submission data for {0}!",user.name(),e); |
|
throw new UmbrellaException(500,"Failed to store submission data for {0}!",user.name()).causedBy(e); |
|
} |
|
} |
|
}
|
|
|