|
|
|
@@ -3,6 +3,7 @@ package de.srsoftware.cal.db;
|
|
|
|
|
|
|
|
|
|
import static de.srsoftware.cal.db.Fields.*;
|
|
|
|
|
import static de.srsoftware.cal.db.Fields.ALL;
|
|
|
|
|
import static de.srsoftware.tools.Error.error;
|
|
|
|
|
import static de.srsoftware.tools.Optionals.*;
|
|
|
|
|
import static de.srsoftware.tools.Result.transform;
|
|
|
|
|
import static de.srsoftware.tools.jdbc.Condition.*;
|
|
|
|
@@ -14,7 +15,6 @@ import de.srsoftware.cal.Util;
|
|
|
|
|
import de.srsoftware.cal.api.Appointment;
|
|
|
|
|
import de.srsoftware.cal.api.Attachment;
|
|
|
|
|
import de.srsoftware.cal.api.Link;
|
|
|
|
|
import de.srsoftware.tools.Error;
|
|
|
|
|
import de.srsoftware.tools.Payload;
|
|
|
|
|
import de.srsoftware.tools.Result;
|
|
|
|
|
import de.srsoftware.tools.jdbc.Query;
|
|
|
|
@@ -69,7 +69,7 @@ public class MariaDB implements Database {
|
|
|
|
|
Appointment saved = null;
|
|
|
|
|
if (keys.next()) saved = appointment.clone(keys.getLong(1));
|
|
|
|
|
keys.close();
|
|
|
|
|
if (saved == null) return Error.of("Insert query did not return appointment id!");
|
|
|
|
|
if (saved == null) return error("Insert query did not return appointment id!");
|
|
|
|
|
|
|
|
|
|
{ // link to attachments
|
|
|
|
|
var attachments = saved.attachments();
|
|
|
|
@@ -83,7 +83,7 @@ public class MariaDB implements Database {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{ // link to links
|
|
|
|
|
var links = saved.urls();
|
|
|
|
|
var links = saved.links();
|
|
|
|
|
InsertQuery assignQuery = null;
|
|
|
|
|
for (var link : links) {
|
|
|
|
|
var urlId = getOrCreateUrl(link.url());
|
|
|
|
@@ -106,7 +106,7 @@ public class MariaDB implements Database {
|
|
|
|
|
return Payload.of(saved);
|
|
|
|
|
} catch (SQLException e) {
|
|
|
|
|
LOG.log(ERROR, "Failed to store appointment", e);
|
|
|
|
|
return Error.of("Failed to store appointment", e);
|
|
|
|
|
return error(e, "Failed to store appointment");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -149,28 +149,43 @@ public class MariaDB implements Database {
|
|
|
|
|
rs.close();
|
|
|
|
|
return Payload.of(results);
|
|
|
|
|
} catch (SQLException e) {
|
|
|
|
|
return Error.format("failed to gather tags from DB.", e);
|
|
|
|
|
return error(e, "failed to gather tags from DB.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<Appointment> list(Integer count, Integer offset) throws SQLException {
|
|
|
|
|
var list = new ArrayList<Appointment>();
|
|
|
|
|
var results = select(ALL).from(APPOINTMENTS).sort("start").exec(connection);
|
|
|
|
|
while (results.next()) createAppointmentOf(results).optional().ifPresent(list::add);
|
|
|
|
|
results.close();
|
|
|
|
|
return list;
|
|
|
|
|
public Result<List<Appointment>> list(LocalDateTime from, LocalDateTime till, Integer count, Integer offset) {
|
|
|
|
|
var query = Query //
|
|
|
|
|
.select("appointments.*", "GROUP_CONCAT(keyword) AS tags")
|
|
|
|
|
.from(APPOINTMENTS)
|
|
|
|
|
.leftJoin(AID, "appointment_tags", AID)
|
|
|
|
|
.leftJoin("tid", "tags", "tid")
|
|
|
|
|
.groupBy(AID)
|
|
|
|
|
.sort("start DESC");
|
|
|
|
|
if (from != null) query.where(START, moreThan(Timestamp.valueOf(from)));
|
|
|
|
|
if (till != null) query.where(END, lessThan(Timestamp.valueOf(till)));
|
|
|
|
|
if (count != null) query.limit(count);
|
|
|
|
|
if (offset != null) query.skip(offset);
|
|
|
|
|
try {
|
|
|
|
|
var results = query.exec(connection);
|
|
|
|
|
var list = new ArrayList<Appointment>();
|
|
|
|
|
while (results.next()) createAppointmentOf(results).optional().ifPresent(list::add);
|
|
|
|
|
results.close();
|
|
|
|
|
return Payload.of(list);
|
|
|
|
|
} catch (SQLException e) {
|
|
|
|
|
return SqlError.of(e, "Failed to fetch appointments from database!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Result<Appointment> loadEvent(long id) {
|
|
|
|
|
try {
|
|
|
|
|
var rs = 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);
|
|
|
|
|
Result<Appointment> result = rs.next() ? createAppointmentOf(rs).map(MariaDB::loadExtra) : NotFound.of("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);
|
|
|
|
|
return SqlError.of(e, "Failed to load appointment with id = %s", id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -178,11 +193,11 @@ public class MariaDB implements Database {
|
|
|
|
|
public Result<Appointment> loadEvent(String location, LocalDateTime start) {
|
|
|
|
|
try {
|
|
|
|
|
var rs = select(ALL).from(APPOINTMENTS).where(LOCATION, equal(location)).where(START, equal(Timestamp.valueOf(start))).exec(connection);
|
|
|
|
|
Result<Appointment> result = rs.next() ? createAppointmentOf(rs).map(MariaDB::loadExtra) : Error.format("Failed to find appointment starting %s @ %s".formatted(start, location));
|
|
|
|
|
Result<Appointment> result = rs.next() ? createAppointmentOf(rs).map(MariaDB::loadExtra) : error("Failed to find appointment starting %s @ %s", start, location);
|
|
|
|
|
rs.close();
|
|
|
|
|
return result;
|
|
|
|
|
} catch (SQLException e) {
|
|
|
|
|
return Error.of("Failed to load appointment starting %s @ %s".formatted(start, location), e);
|
|
|
|
|
return error(e, "Failed to load appointment starting %s @ %s", start, location);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -200,7 +215,7 @@ public class MariaDB implements Database {
|
|
|
|
|
rs.close();
|
|
|
|
|
return Payload.of(event);
|
|
|
|
|
} catch (SQLException e) {
|
|
|
|
|
return Error.of("Failed to load tags for appointment %s".formatted(id), e);
|
|
|
|
|
return error(e, "Failed to load tags for appointment %s", id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -223,7 +238,7 @@ public class MariaDB implements Database {
|
|
|
|
|
rs.close();
|
|
|
|
|
return Payload.of(event);
|
|
|
|
|
} catch (SQLException e) {
|
|
|
|
|
return Error.of("Failed to load tags for appointment %s".formatted(id), e);
|
|
|
|
|
return error(e, "Failed to load tags for appointment %s", id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -246,7 +261,7 @@ public class MariaDB implements Database {
|
|
|
|
|
rs.close();
|
|
|
|
|
return Payload.of(event);
|
|
|
|
|
} catch (SQLException e) {
|
|
|
|
|
return Error.of("Failed to load tags for appointment %s".formatted(id), e);
|
|
|
|
|
return error(e, "Failed to load tags for appointment %s".formatted(id));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -254,7 +269,7 @@ public class MariaDB implements Database {
|
|
|
|
|
var id = results.getInt(AID);
|
|
|
|
|
var title = results.getString(TITLE);
|
|
|
|
|
var description = results.getString(DESCRIPTION);
|
|
|
|
|
if (allEmpty(title, description)) return Error.format("Title and Description of appointment %s are empty", id);
|
|
|
|
|
if (allEmpty(title, description)) return error("Title and Description of appointment %s are empty", id);
|
|
|
|
|
var start = results.getTimestamp(START).toLocalDateTime();
|
|
|
|
|
var end = nullable(results.getTimestamp(END)).map(Timestamp::toLocalDateTime).orElse(null);
|
|
|
|
|
var location = results.getString(LOCATION);
|
|
|
|
@@ -275,24 +290,6 @@ public class MariaDB implements Database {
|
|
|
|
|
return Payload.of(appointment);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<Appointment> list(LocalDateTime from, LocalDateTime till) throws SQLException {
|
|
|
|
|
var list = new ArrayList<Appointment>();
|
|
|
|
|
var query = Query //
|
|
|
|
|
.select("appointments.*", "GROUP_CONCAT(keyword) AS tags")
|
|
|
|
|
.from(APPOINTMENTS)
|
|
|
|
|
.leftJoin(AID, "appointment_tags", AID)
|
|
|
|
|
.leftJoin("tid", "tags", "tid")
|
|
|
|
|
.groupBy(AID)
|
|
|
|
|
.sort("start DESC");
|
|
|
|
|
nullable(from).ifPresent(start -> query.where("start", moreThan(start)));
|
|
|
|
|
nullable(till).ifPresent(end -> query.where("end", lessThan(end)));
|
|
|
|
|
|
|
|
|
|
var results = query.exec(connection);
|
|
|
|
|
while (results.next()) createAppointmentOf(results).optional().ifPresent(list::add);
|
|
|
|
|
results.close();
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<Appointment> listByTags(Set<String> tags, Integer count, Integer offset) {
|
|
|
|
@@ -302,13 +299,13 @@ public class MariaDB implements Database {
|
|
|
|
|
@Override
|
|
|
|
|
public Result<Long> removeAppointment(long id) {
|
|
|
|
|
try {
|
|
|
|
|
Query.delete().from(APPOINTMENTS).where(AID,equal(id)).execute(connection);
|
|
|
|
|
Query.delete().from(APPOINTMENT_TAGS).where(AID,equal(id)).execute(connection);
|
|
|
|
|
Query.delete().from(APPOINTMENT_ATTACHMENTS).where(AID,equal(id)).execute(connection);
|
|
|
|
|
Query.delete().from(APPOINTMENT_URLS).where(AID,equal(id)).execute(connection);
|
|
|
|
|
Query.delete().from(APPOINTMENTS).where(AID, equal(id)).execute(connection);
|
|
|
|
|
Query.delete().from(APPOINTMENT_TAGS).where(AID, equal(id)).execute(connection);
|
|
|
|
|
Query.delete().from(APPOINTMENT_ATTACHMENTS).where(AID, equal(id)).execute(connection);
|
|
|
|
|
Query.delete().from(APPOINTMENT_URLS).where(AID, equal(id)).execute(connection);
|
|
|
|
|
return Payload.of(id);
|
|
|
|
|
} catch (SQLException e) {
|
|
|
|
|
return Error.of("Failed to delete event %s".formatted(id),e);
|
|
|
|
|
return SqlError.of(e, "Failed to delete event %s", id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -327,7 +324,7 @@ public class MariaDB implements Database {
|
|
|
|
|
|
|
|
|
|
return Payload.of(event);
|
|
|
|
|
} catch (SQLException sqle) {
|
|
|
|
|
return Error.of("Failed to update database entry", sqle);
|
|
|
|
|
return error(sqle, "Failed to update database entry");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|