working on event detail page

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2024-12-26 19:28:24 +01:00
parent 9f806637c2
commit a90627d976
14 changed files with 178 additions and 59 deletions
+1 -1
View File
@@ -6,5 +6,5 @@ dependencies {
implementation("de.srsoftware:tools.jdbc:1.1.0")
implementation("de.srsoftware:tools.optionals:1.0.0")
implementation("de.srsoftware:tools.util:1.2.1")
implementation("de.srsoftware:tools.util:1.2.2")
}
@@ -2,6 +2,7 @@
package de.srsoftware.cal.db;
import static de.srsoftware.tools.Optionals.*;
import static de.srsoftware.tools.Result.transform;
import static de.srsoftware.tools.Strings.camelCase;
import static de.srsoftware.tools.jdbc.Condition.equal;
import static de.srsoftware.tools.jdbc.Condition.moreThan;
@@ -10,20 +11,35 @@ import static java.lang.System.Logger.Level.*;
import de.srsoftware.cal.BaseAppointment;
import de.srsoftware.cal.api.Appointment;
import de.srsoftware.cal.api.Attachment;
import de.srsoftware.cal.api.Link;
import de.srsoftware.tools.Calc;
import de.srsoftware.tools.Error;
import de.srsoftware.tools.Payload;
import de.srsoftware.tools.Result;
import de.srsoftware.tools.jdbc.Query;
import java.net.MalformedURLException;
import java.net.URI;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.*;
public class MariaDB implements Database {
private static final System.Logger LOG = System.getLogger(MariaDB.class.getSimpleName());
private static final String ADD_SLUG = "ALTER TABLE appointments ADD slug VARCHAR(255) UNIQUE";
private static final String APPOINTMENTS = "appointments";
private static final String AID = "aid";
private static final System.Logger LOG = System.getLogger(MariaDB.class.getSimpleName());
private static final String ADD_SLUG = "ALTER TABLE appointments ADD slug VARCHAR(255) UNIQUE";
private static final String APPOINTMENTS = "appointments";
private static final String AID = "aid";
private static final String ALL = "*";
private static final String KEYWORD = "keyword";
private static final String APPOINTMENT_TAGS = "appointment_tags";
private static final String URL = "url";
private static final String APPOINTMENT_URLS = "appointment_urls";
private static final String DESCRIPTION = "description";
private static final String UID = "uid";
private static final String URLS = "urls";
private static final String TID = "tid";
private static final String MIME = "mime";
private static final String APPOINTMENT_ATTACHMENTS = "appointment_attachments";
private static Connection connection;
private MariaDB(Connection conn) throws SQLException {
@@ -57,7 +73,7 @@ public class MariaDB implements Database {
connection.prepareStatement(ADD_SLUG).execute();
var slugMap = new HashMap<Long, String>();
LOG.log(DEBUG, "Reading existing appointments…");
var rs = Query.select("*").from("appointments").exec(connection);
var rs = Query.select(ALL).from("appointments").exec(connection);
while (rs.next()) {
var id = rs.getLong(AID);
var location = nullable(nullIfEmpty(rs.getString("location")));
@@ -101,7 +117,7 @@ public class MariaDB implements Database {
@Override
public List<Appointment> list(Integer count, Integer offset) throws SQLException {
var list = new ArrayList<Appointment>();
var results = Query.select("*").from(APPOINTMENTS).sort("start").exec(connection);
var results = Query.select(ALL).from(APPOINTMENTS).sort("start").exec(connection);
while (results.next()) createAppointmentOf(results).optional().ifPresent(list::add);
results.close();
return list;
@@ -110,21 +126,80 @@ public class MariaDB implements Database {
@Override
public Result<Appointment> loadEvent(long id) {
try {
var rs = Query //
.select("%s.*".formatted(APPOINTMENTS), "GROUP_CONCAT(keyword) AS tags")
.from(APPOINTMENTS)
.leftJoin(AID, "appointment_tags", AID)
.leftJoin("tid", "tags", "tid")
.groupBy(AID)
.where("%s.%s".formatted(APPOINTMENTS, AID), equal(id))
.exec(connection);
return rs.next() ? createAppointmentOf(rs) : Error.format("Failed to find appointment with id %s", id);
var rs = Query.select(ALL).from(APPOINTMENTS).where(AID, equal(id)).exec(connection);
Result<Appointment> result = rs.next() ? createAppointmentOf(rs).map(MariaDB::loadExtra) : Error.format("Failed to find appointment with id %s", id);
rs.close();
return result;
} catch (SQLException e) {
return Error.of("Failed to load appointment with id = %s".formatted(id), e);
}
}
private Result<Appointment> createAppointmentOf(ResultSet results) throws SQLException {
private static Result<Appointment> loadExtra(Result<BaseAppointment> res) {
return loadTags(res).map(MariaDB::loadLinks).map(MariaDB::loadAttachments);
}
private static Result<BaseAppointment> loadTags(Result<BaseAppointment> res) {
if (res.optional().isEmpty()) return transform(res);
BaseAppointment event = res.optional().get();
var id = event.id();
try {
var rs = Query.select(KEYWORD).from(APPOINTMENT_TAGS).leftJoin(TID, "tags", TID).where(AID, equal(id)).exec(connection);
while (rs.next()) event.tags(rs.getString(1));
rs.close();
return Payload.of(event);
} catch (SQLException e) {
return Error.of("Failed to load tags for appointment %s".formatted(id), e);
}
}
private static Result<BaseAppointment> loadLinks(Result<BaseAppointment> res) {
if (res.optional().isEmpty()) return transform(res);
BaseAppointment event = res.optional().get();
var id = event.id();
try {
var rs = Query.select(URL, DESCRIPTION).from(APPOINTMENT_URLS).leftJoin(UID, URLS, UID).where(AID, equal(id)).exec(connection);
while (rs.next()) {
var u = rs.getString(URL);
try {
var url = URI.create(u).toURL();
var description = rs.getString(DESCRIPTION);
event.addLinks(new Link(url, description));
} catch (MalformedURLException e) {
LOG.log(WARNING, () -> "Failed to convert %s to URI!".formatted(u));
}
}
rs.close();
return Payload.of(event);
} catch (SQLException e) {
return Error.of("Failed to load tags for appointment %s".formatted(id), e);
}
}
private static Result<Appointment> loadAttachments(Result<BaseAppointment> res) {
if (res.optional().isEmpty()) return transform(res);
BaseAppointment event = res.optional().get();
var id = event.id();
try {
var rs = Query.select(URL, MIME).from(APPOINTMENT_ATTACHMENTS).leftJoin(UID, URLS, UID).where(AID, equal(id)).exec(connection);
while (rs.next()) {
var u = rs.getString(URL);
try {
var url = URI.create(u).toURL();
var mime = rs.getString(MIME);
event.add(new Attachment(url, mime));
} catch (MalformedURLException e) {
LOG.log(WARNING, () -> "Failed to convert %s to URI!".formatted(u));
}
}
rs.close();
return Payload.of(event);
} catch (SQLException e) {
return Error.of("Failed to load tags for appointment %s".formatted(id), e);
}
}
private Result<BaseAppointment> createAppointmentOf(ResultSet results) throws SQLException {
var id = results.getInt(AID);
var title = results.getString("title");
var description = results.getString("description");
@@ -133,10 +208,13 @@ public class MariaDB implements Database {
var end = nullable(results.getTimestamp("end")).map(Timestamp::toLocalDateTime).orElse(null);
var location = results.getString("location");
var slug = results.getString("slug");
var tags = nullIfEmpty(results.getString("tags"));
if (slug == null) slug = Calc.hash(start + "@" + location).orElse(null);
var appointment = new BaseAppointment(id, title, description, start, end, location, slug);
if (tags != null) appointment.tags(tags.split(","));
try {
var tags = nullIfEmpty(results.getString("tags"));
if (tags != null) appointment.tags(tags.split(","));
} catch (SQLException e) {
}
return Payload.of(appointment);
}