first implementation of cal.db, that
- successfully connects to db - updated db sheme - succeeds in listing appointments Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.cal.db;
|
||||
|
||||
import de.srsoftware.cal.api.Appointment;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Interface for calendar database
|
||||
*/
|
||||
public interface Database {
|
||||
/**
|
||||
* add an appointment to the database
|
||||
* @param appointment the appointment to store
|
||||
* @return the Database object
|
||||
*/
|
||||
public Database add(Appointment appointment);
|
||||
|
||||
/**
|
||||
* list appointments unfiltered
|
||||
* @param count the maximum number of appointments to return
|
||||
* @param offset the number of appointments to skip
|
||||
* @return the list of appointments fetched from the db
|
||||
*/
|
||||
public List<Appointment> list(Integer count, Integer offset) throws SQLException;
|
||||
|
||||
/**
|
||||
* list appointments
|
||||
* @param tags only list appointments which have matching tags
|
||||
* @param count the maximum number of appointments to return
|
||||
* @param offset the number of appointments to skip
|
||||
* @return the list of appointments fetched from the db
|
||||
*/
|
||||
public List<Appointment> listByTags(Set<String> tags, Integer count, Integer offset);
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.cal.db;
|
||||
|
||||
import static de.srsoftware.tools.Optionals.allEmpty;
|
||||
import static de.srsoftware.tools.Optionals.nullable;
|
||||
|
||||
import de.srsoftware.cal.BaseAppointment;
|
||||
import de.srsoftware.cal.api.Appointment;
|
||||
import de.srsoftware.tools.Calc;
|
||||
import de.srsoftware.tools.jdbc.Query;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class MariaDB implements Database {
|
||||
private static final String SELECT_APPOINTMENTS = "SELECT * FROM appointments";
|
||||
private static final String SELECT_APPOINTMENTS_WITH_HASHES = SELECT_APPOINTMENTS + " a LEFT JOIN appointment_hashes h ON a.aid = h.aid";
|
||||
private static final String SELECT_VERSION = "SELECT value FROM config WHERE keyname = 'dbversion'";
|
||||
private static final String CREATE_HASHES = "CREATE TABLE appointment_hashes (aid INT NOT NULL, hash VARCHAR(255) NOT NULL, UNIQUE(aid), UNIQUE(hash))";
|
||||
private static final String INSERT_HASH = "INSERT INTO appointment_hashes (aid, hash) values (?, ?) ON DUPLICATE KEY UPDATE hash=hash;";
|
||||
private static final String UPDATE_DB_VERSION = "UPDATE config SET value = ? WHERE keyname = 'dbversion'";
|
||||
private static Connection connection;
|
||||
|
||||
private MariaDB(Connection conn) throws SQLException {
|
||||
connection = conn;
|
||||
applyUpdates();
|
||||
}
|
||||
|
||||
private void applyUpdates() throws SQLException {
|
||||
var rs = Query.of(SELECT_VERSION).execute(connection);
|
||||
var version = 0;
|
||||
if (rs.next()) {
|
||||
version = rs.getInt("value");
|
||||
}
|
||||
rs.close();
|
||||
switch (version) {
|
||||
case 0:
|
||||
createTables();
|
||||
case 1:
|
||||
update1();
|
||||
}
|
||||
}
|
||||
|
||||
private void update1() throws SQLException {
|
||||
var list = new ArrayList<Appointment>();
|
||||
var results = Query.of(SELECT_APPOINTMENTS).execute(connection);
|
||||
while (results.next()) {
|
||||
var id = results.getInt("aid");
|
||||
var title = results.getString("title");
|
||||
var description = results.getString("description");
|
||||
if (allEmpty(title, description)) continue;
|
||||
var stamp = results.getTimestamp("start");
|
||||
var start = nullable(stamp).map(Timestamp::toLocalDateTime).orElse(null);
|
||||
var end = nullable(results.getTimestamp("end")).map(Timestamp::toLocalDateTime).orElse(null);
|
||||
var location = results.getString("location");
|
||||
Calc //
|
||||
.hash(start + "@" + location)
|
||||
.map(hash -> new BaseAppointment(id, title, description, start, end, location, hash))
|
||||
.ifPresent(list::add);
|
||||
}
|
||||
results.close();
|
||||
connection.setAutoCommit(false);
|
||||
|
||||
Query.of(CREATE_HASHES).statement(connection).execute();
|
||||
for (var appointment : list) {
|
||||
var stmt = Query.of(INSERT_HASH).statement(connection);
|
||||
stmt.setLong(1, appointment.id());
|
||||
stmt.setString(2, appointment.hash());
|
||||
stmt.execute();
|
||||
}
|
||||
connection.commit();
|
||||
var stmt = Query.of(UPDATE_DB_VERSION).statement(connection);
|
||||
stmt.setLong(1, 2);
|
||||
stmt.execute();
|
||||
connection.setAutoCommit(true);
|
||||
}
|
||||
|
||||
private void createTables() {
|
||||
throw new RuntimeException("%s.createTables() not implemented!");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Database add(Appointment appointment) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Database connect(String jdbc, String user, String pass) throws SQLException {
|
||||
return new MariaDB(DriverManager.getConnection(jdbc, user, pass));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Appointment> list(Integer count, Integer offset) throws SQLException {
|
||||
var list = new ArrayList<Appointment>();
|
||||
var results = Query.of(SELECT_APPOINTMENTS_WITH_HASHES).execute(connection);
|
||||
while (results.next()) {
|
||||
var id = results.getInt("aid");
|
||||
var title = results.getString("title");
|
||||
var description = results.getString("description");
|
||||
if (allEmpty(title, description)) continue;
|
||||
var start = results.getTimestamp("start").toLocalDateTime();
|
||||
var end = nullable(results.getTimestamp("end")).map(Timestamp::toLocalDateTime).orElse(null);
|
||||
var location = results.getString("location");
|
||||
var hash = results.getString("hash");
|
||||
if (hash == null) hash = Calc.hash(start + "@" + location).orElse(null);
|
||||
list.add(new BaseAppointment(id, title, description, start, end, location, hash));
|
||||
}
|
||||
results.close();
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Appointment> listByTags(Set<String> tags, Integer count, Integer offset) {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user