implemented storing of messages in db

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2026-01-25 23:43:20 +01:00
parent 50fa610837
commit fc1c735036
4 changed files with 112 additions and 58 deletions

View File

@@ -84,7 +84,9 @@ public class Field {
public static final String LOCATION_ID = "location_id";
public static final String LOCATIONS = "locations";
public static final String LOGIN = "login";
public static final String MEMBERS = "members";
public static final String MESSAGE_ID = "message_id";
public static final String MIME = "mime";
public static final String MODULE = "module";
@@ -124,17 +126,18 @@ public class Field {
public static final String RENDERED = "rendered";
public static final String REQUIRED_TASKS_IDS = "required_tasks_ids";
public static final String SENDER = "sender";
public static final String SETTINGS = "settings";
public static final String SHOW_CLOSED = "show_closed";
public static final String SILENT = "silent";
public static final String SOURCE = "source";
public static final String START_DATE = "start_date";
public static final String START_TIME = "start_time";
public static final String STATE = "state";
public static final String STATUS = "status";
public static final String STATUS_CODE = "code";
public static final String SUBJECT = "subject";
public static final String SENDER = "sender";
public static final String SENDER_USER_ID = "sender_user_id";
public static final String SETTINGS = "settings";
public static final String SHOW_CLOSED = "show_closed";
public static final String SILENT = "silent";
public static final String SOURCE = "source";
public static final String START_DATE = "start_date";
public static final String START_TIME = "start_time";
public static final String STATE = "state";
public static final String STATUS = "status";
public static final String STATUS_CODE = "code";
public static final String SUBJECT = "subject";
public static final String TABLE = "table";
public static final String TAGS = "tags";

View File

@@ -12,12 +12,13 @@ public class Constants {
public static final String DEBUG_ADDREESS = "umbrella.modules.message.debug_address";
public static final String ENVELOPE_FROM = "mail.smtp.from";
public static final String FIELD_MESSAGES = "messages";
public static final String FIELD_HOST = "host";
public static final String FIELD_PORT = "port";
public static final String HOST = "mail.smtp.host";
public static final String PORT = "mail.smtp.port";
public static final String SSL = "mail.smtp.ssl.enable";
public static final String SUBMISSION = "submission";
public static final String TABLE_ATTACHMENTS = "attachments";
public static final String TABLE_MESSAGES = "messages";
public static final String TABLE_RECEIVERS = "receivers";
public static final String TABLE_SUBMISSIONS = "message_submission";
}

View File

@@ -84,8 +84,9 @@ public class MessageSystem extends BaseHandler implements PostBox, EventListener
public MessageSystem(Configuration config) throws UmbrellaException {
var dbFile = config.get(CONFIG_DB).orElseThrow(() -> missingConfig(CONFIG_DB));
db = new SqliteMessageDb(connect(dbFile));
queue = new InMemoryQueue();
var sqlite = new SqliteMessageDb(connect(dbFile));
db = sqlite;
queue = sqlite;
debugAddress = config.get(DEBUG_ADDREESS).map(Object::toString).orElse(null);
port = config.get(CONFIG_SMTP_PORT,587);

View File

@@ -9,9 +9,14 @@ import static de.srsoftware.umbrella.core.constants.Constants.TABLE_SETTINGS;
import static de.srsoftware.umbrella.core.constants.Field.*;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
import static de.srsoftware.umbrella.core.model.Translatable.t;
import static de.srsoftware.umbrella.message.Constants.*;
import static de.srsoftware.umbrella.message.model.Schedule.schedule;
import static java.text.MessageFormat.format;
import static java.time.ZoneOffset.UTC;
import de.srsoftware.tools.jdbc.Query;
import de.srsoftware.umbrella.core.BaseDb;
import de.srsoftware.umbrella.core.constants.Field;
import de.srsoftware.umbrella.core.constants.Text;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.core.model.Envelope;
@@ -22,28 +27,73 @@ import de.srsoftware.umbrella.message.model.Instantly;
import de.srsoftware.umbrella.message.model.Settings;
import de.srsoftware.umbrella.message.model.Silent;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
public class SqliteMessageDb implements MessageDb, MessageQueue<TranslatedMessage> {
public class SqliteMessageDb extends BaseDb implements MessageDb, MessageQueue<TranslatedMessage> {
private static final System.Logger LOG = System.getLogger(SqliteMessageDb.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 SqliteMessageDb(Connection conn){
db = conn;
init();
super(conn);
}
private void createMessageTables() {
var sql = """
CREATE TABLE IF NOT EXISTS {0} (
{1} INTEGER PRIMARY KEY,
{2} LONG NOT NULL,
{3} LONG NOT NULL,
{4} TEXT,
{5} TEXT
);
""";
sql = format(sql,TABLE_MESSAGES, ID, TIMESTAMP, SENDER_USER_ID, SUBJECT, BODY);
try {
db.prepareStatement(sql).execute();
} catch (SQLException e) {
throw failedToCreateTable(TABLE_MESSAGES);
}
sql = """
CREATE TABLE IF NOT EXISTS {0} (
{1} INTEGER NOT NULL,
{2} VARCHAR(255) NOT NULL,
{3} VARCHAR(255),
PRIMARY KEY ({1}, {2})
);
""";
sql = format(sql,TABLE_RECEIVERS, MESSAGE_ID, EMAIL, NAME);
try {
db.prepareStatement(sql).execute();
} catch (SQLException e) {
throw failedToCreateTable(TABLE_MESSAGES);
}
sql = """
CREATE TABLE IF NOT EXISTS {0} (
{1} INTEGER NOT NULL,
{2} VARCHAR(255) NOT NULL,
{3} VARCHAR(100),
{4} BLOB NOT NULL,
PRIMARY KEY ({1}, {2})
);
""";
sql = format(sql,TABLE_ATTACHMENTS, MESSAGE_ID, NAME, MIME, DATA);
try {
db.prepareStatement(sql).execute();
} catch (SQLException e) {
throw failedToCreateTable(TABLE_MESSAGES);
}
}
private void createSubmissionTable() {
var createTable = """
CREATE TABLE IF NOT EXISTS {0} ( {1} Integer PRIMARY KEY, {2} VARCHAR(255) NOT NULL);
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));
@@ -54,37 +104,16 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} Integer PRIMARY KEY, {2} VARCHAR(255) NOT N
}
}
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) {
throw failedToCreateTable(TABLE_SETTINGS).causedBy(e);
@Override
protected int createTables() {
int currentVersion = createSettingsTable();
switch (currentVersion){
case 0:
createSubmissionTable();
case 1:
createMessageTables();
}
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) {
throw databaseException(FAILED_TO_UPDATE_OBJECT, OBJECT,DB_VERSION).causedBy(e);
}
}
private int createTables() {
createSubmissionTable();
return createSettingsTable();
return setCurrentVersion(2);
}
@Override
@@ -132,8 +161,28 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
}
@Override
public void push(Envelope<TranslatedMessage> message) {
throw new UmbrellaException(HTTP_SERVER_ERROR,"{class}.push(message) not implemented!","class",getClass().getSimpleName()); // TODO
public void push(Envelope<TranslatedMessage> envelope) {
var timestamp = envelope.time().toEpochSecond(UTC);
var message = envelope.message();
var sender = message.sender().id();
var subject = message.subject();
var body = message.body();
try {
var rs = insertInto(TABLE_MESSAGES, TIMESTAMP, SENDER_USER_ID, SUBJECT, BODY).values(timestamp, sender, subject, body).execute(db).getGeneratedKeys();
Long messageId = null;
if (rs.next()) messageId = rs.getLong(1);
rs.close();
if (messageId == null) throw failedToStoreObject(envelope);
for (var receiver : envelope.receivers()){
insertInto(TABLE_RECEIVERS,MESSAGE_ID,EMAIL,NAME).values(messageId,receiver.email(),receiver.name()).execute(db).close();
}
for (var attachment : envelope.message().attachments()){
insertInto(TABLE_ATTACHMENTS,MESSAGE_ID,NAME,MIME,DATA).values(messageId,attachment.name(),attachment.mime(),attachment.content()).execute(db).close();
}
} catch (SQLException e) {
throw failedToStoreObject(envelope).causedBy(e);
}
}
private Settings toSettings(ResultSet rs) throws SQLException {