Refactor repository layer using Jakarta Data
Replaced custom repository logic with Jakarta Data interfaces to reduce boilerplate and enhance compile-time query validation. Removed `AbstractRepository` and introduced `TransactionRunner` for consistent transactional support. Updated all repository facades to delegate query operations to generated interfaces while retaining the same API, ensuring backward compatibility. Added dependencies for `jakarta.data-api` and Hibernate's `hibernate-processor` for annotation-based query generation. Verified functional parity and improved testability across the repository layer.
This commit is contained in:
1 parent
677b3f8013
commit
bceab4b2b9
16 files changed
+604
-230
No files matched your search
@@ -1,95 +0,0 @@
|
||||
package me.bobert.netneutrality.db;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import org.hibernate.Session;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Generic, constructor-injected Hibernate repository.
|
||||
*
|
||||
* <p>All work runs through Hibernate's native {@code fromSession}/{@code fromTransaction}/
|
||||
* {@code inTransaction} helpers, which open and close the session and commit or roll back the
|
||||
* transaction. Exceptions are never swallowed: a failed write is rolled back and rethrown.
|
||||
*
|
||||
* @param <T> the entity type
|
||||
* @param <ID> the entity identifier type
|
||||
*/
|
||||
public abstract class AbstractRepository<T, ID> {
|
||||
|
||||
protected final SessionProvider sessions;
|
||||
private final Class<T> type;
|
||||
|
||||
protected AbstractRepository(SessionProvider sessions, Class<T> type) {
|
||||
this.sessions = Objects.requireNonNull(sessions, "sessions");
|
||||
this.type = Objects.requireNonNull(type, "type");
|
||||
}
|
||||
|
||||
protected Class<T> type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<T> findAll() {
|
||||
return read(session -> {
|
||||
CriteriaQuery<T> query = session.getCriteriaBuilder().createQuery(type);
|
||||
query.from(type);
|
||||
return session.createSelectionQuery(query).getResultList();
|
||||
});
|
||||
}
|
||||
|
||||
public Optional<T> findById(ID id) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
return read(session -> Optional.ofNullable(session.find(type, id)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts or updates the entity.
|
||||
*
|
||||
* @param entity the entity to save
|
||||
* @return the persistent (merged) state, which callers should use from then on
|
||||
*/
|
||||
public T save(T entity) {
|
||||
Objects.requireNonNull(entity, "entity");
|
||||
return write(session -> session.merge(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the entity with the given id, if it exists.
|
||||
*
|
||||
* @param id the identifier
|
||||
* @return {@code true} if a row was deleted
|
||||
*/
|
||||
public boolean deleteById(ID id) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
return write(session -> {
|
||||
T entity = session.find(type, id);
|
||||
if (entity == null) {
|
||||
return false;
|
||||
}
|
||||
session.remove(entity);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
protected <R> R read(Function<Session, R> work) {
|
||||
return sessions.getSessionFactory().fromSession(work);
|
||||
}
|
||||
|
||||
protected <R> R write(Function<Session, R> work) {
|
||||
return sessions.getSessionFactory().fromTransaction(work);
|
||||
}
|
||||
|
||||
protected void writeVoid(Consumer<Session> work) {
|
||||
sessions.getSessionFactory().inTransaction(work);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package me.bobert.netneutrality.db;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import org.hibernate.StatelessSession;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Runs work on a Hibernate {@link StatelessSession}, the session type used by the generated
|
||||
* Jakarta Data repositories.
|
||||
*
|
||||
* <p>{@link #inTx(Function)} commits on success and rolls back and rethrows on failure.
|
||||
*/
|
||||
public class TransactionRunner {
|
||||
|
||||
private final SessionProvider sessions;
|
||||
|
||||
public TransactionRunner(SessionProvider sessions) {
|
||||
this.sessions = Objects.requireNonNull(sessions, "sessions");
|
||||
}
|
||||
|
||||
public <R> R read(Function<StatelessSession, R> work) {
|
||||
return sessions.getSessionFactory().fromStatelessSession(work);
|
||||
}
|
||||
|
||||
public <R> R inTx(Function<StatelessSession, R> work) {
|
||||
return sessions.getSessionFactory().fromStatelessTransaction(work);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package me.bobert.netneutrality.db.data;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import jakarta.data.repository.CrudRepository;
|
||||
import jakarta.data.repository.Query;
|
||||
import jakarta.data.repository.Repository;
|
||||
import me.bobert.netneutrality.db.entities.OBlacklist;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface BlacklistQueries extends CrudRepository<OBlacklist, Integer> {
|
||||
|
||||
@Query("from OBlacklist where guild.guildId = :guildId order by id")
|
||||
List<OBlacklist> byGuild(String guildId);
|
||||
|
||||
@Query("select word from OBlacklist where guild.guildId = :guildId and enabled = true")
|
||||
List<String> enabledWords(String guildId);
|
||||
|
||||
@Query("from OBlacklist where upper(word) = upper(:word) and guild.guildId = :guildId")
|
||||
List<OBlacklist> findWord(String guildId, String word);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package me.bobert.netneutrality.db.data;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import jakarta.data.repository.CrudRepository;
|
||||
import jakarta.data.repository.Repository;
|
||||
import me.bobert.netneutrality.db.entities.OGuild;
|
||||
|
||||
@Repository
|
||||
public interface GuildQueries extends CrudRepository<OGuild, String> {
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package me.bobert.netneutrality.db.data;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import jakarta.data.repository.CrudRepository;
|
||||
import jakarta.data.repository.Query;
|
||||
import jakarta.data.repository.Repository;
|
||||
import me.bobert.netneutrality.db.entities.OGuildSetting;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface GuildSettingQueries extends CrudRepository<OGuildSetting, Integer> {
|
||||
|
||||
@Query("from OGuildSetting where guild.guildId = :guildId")
|
||||
List<OGuildSetting> byGuild(String guildId);
|
||||
|
||||
@Query("from OGuildSetting where guild.guildId = :guildId and upper(name) = upper(:name)")
|
||||
List<OGuildSetting> byName(String guildId, String name);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package me.bobert.netneutrality.db.data;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import jakarta.data.Limit;
|
||||
import jakarta.data.repository.CrudRepository;
|
||||
import jakarta.data.repository.Find;
|
||||
import jakarta.data.repository.Query;
|
||||
import jakarta.data.repository.Repository;
|
||||
import me.bobert.netneutrality.db.entities.OLogMessage;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface MessageQueries extends CrudRepository<OLogMessage, Integer> {
|
||||
|
||||
@Find
|
||||
Optional<OLogMessage> byMessageId(String messageId);
|
||||
|
||||
@Query("delete from OLogMessage where messageId = :messageId")
|
||||
int deleteByMessageId(String messageId);
|
||||
|
||||
@Query("from OLogMessage where guild.guildId = :guildId and userId = :userId order by dateSent desc")
|
||||
List<OLogMessage> byUser(String userId, String guildId, Limit limit);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package me.bobert.netneutrality.db.data;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import jakarta.data.repository.CrudRepository;
|
||||
import jakarta.data.repository.Find;
|
||||
import jakarta.data.repository.Query;
|
||||
import jakarta.data.repository.Repository;
|
||||
import me.bobert.netneutrality.db.entities.OTask;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface TaskQueries extends CrudRepository<OTask, Integer> {
|
||||
|
||||
@Find
|
||||
Optional<OTask> byTaskId(String taskId);
|
||||
|
||||
@Query("delete from OTask where taskId = :taskId")
|
||||
int deleteByTaskId(String taskId);
|
||||
}
|
||||
@@ -14,8 +14,6 @@ import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.NamedQueries;
|
||||
import jakarta.persistence.NamedQuery;
|
||||
import jakarta.persistence.Table;
|
||||
import org.hibernate.Hibernate;
|
||||
|
||||
@@ -23,9 +21,6 @@ import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "guild_settings")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = "settings_findByName", query = "select o from OGuildSetting o where o.guild.id = :id and upper(o.name) = upper(:name)")
|
||||
})
|
||||
public class OGuildSetting {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
||||
@@ -6,17 +6,19 @@ package me.bobert.netneutrality.db.repository;
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.db.AbstractRepository;
|
||||
import me.bobert.netneutrality.db.SessionProvider;
|
||||
import me.bobert.netneutrality.db.TransactionRunner;
|
||||
import me.bobert.netneutrality.db.data.BlacklistQueries_;
|
||||
import me.bobert.netneutrality.db.entities.OBlacklist;
|
||||
import me.bobert.netneutrality.db.entities.OGuild;
|
||||
import org.hibernate.Session;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BlacklistRepository extends AbstractRepository<OBlacklist, Integer> {
|
||||
public class BlacklistRepository {
|
||||
|
||||
/**
|
||||
* Outcome of {@link #enableWord(String, String, String)}.
|
||||
@@ -30,23 +32,18 @@ public class BlacklistRepository extends AbstractRepository<OBlacklist, Integer>
|
||||
UNCHANGED
|
||||
}
|
||||
|
||||
private final TransactionRunner tx;
|
||||
|
||||
public BlacklistRepository(SessionProvider sessions) {
|
||||
super(sessions, OBlacklist.class);
|
||||
this.tx = new TransactionRunner(sessions);
|
||||
}
|
||||
|
||||
public List<OBlacklist> findByGuildId(String guildId) {
|
||||
return read(session -> session
|
||||
.createSelectionQuery("FROM OBlacklist o WHERE o.guild.guildId = :guildId ORDER BY o.id", OBlacklist.class)
|
||||
.setParameter("guildId", guildId)
|
||||
.getResultList());
|
||||
return tx.read(session -> new BlacklistQueries_(session).byGuild(guildId));
|
||||
}
|
||||
|
||||
public Set<String> findEnabledWords(String guildId) {
|
||||
return read(session -> session
|
||||
.createSelectionQuery("SELECT o.word FROM OBlacklist o WHERE o.guild.guildId = :guildId AND o.enabled = true", String.class)
|
||||
.setParameter("guildId", guildId)
|
||||
.getResultStream()
|
||||
.collect(Collectors.toUnmodifiableSet()));
|
||||
return tx.read(session -> Set.copyOf(new BlacklistQueries_(session).enabledWords(guildId)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,26 +56,33 @@ public class BlacklistRepository extends AbstractRepository<OBlacklist, Integer>
|
||||
* @return what changed
|
||||
*/
|
||||
public EnableOutcome enableWord(String guildId, String creatorId, String word) {
|
||||
return write(session -> {
|
||||
List<OBlacklist> existing = findWord(session, guildId, word);
|
||||
return tx.inTx(session -> {
|
||||
BlacklistQueries_ queries = new BlacklistQueries_(session);
|
||||
List<OBlacklist> existing = queries.findWord(guildId, word);
|
||||
if (existing.isEmpty()) {
|
||||
OGuild guild = new OGuild();
|
||||
guild.setGuildId(guildId);
|
||||
OBlacklist blacklist = new OBlacklist();
|
||||
blacklist.setGuild(session.getReference(OGuild.class, guildId));
|
||||
blacklist.setGuild(guild);
|
||||
blacklist.setCreatorId(creatorId);
|
||||
blacklist.setWord(word);
|
||||
blacklist.setEnabled(true);
|
||||
session.persist(blacklist);
|
||||
queries.insert(blacklist);
|
||||
return EnableOutcome.CREATED;
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
List<OBlacklist> changed = new ArrayList<>();
|
||||
for (OBlacklist blacklist : existing) {
|
||||
if (!Boolean.TRUE.equals(blacklist.getEnabled())) {
|
||||
blacklist.setEnabled(true);
|
||||
changed = true;
|
||||
changed.add(blacklist);
|
||||
}
|
||||
}
|
||||
return changed ? EnableOutcome.ENABLED : EnableOutcome.UNCHANGED;
|
||||
if (changed.isEmpty()) {
|
||||
return EnableOutcome.UNCHANGED;
|
||||
}
|
||||
queries.updateAll(changed);
|
||||
return EnableOutcome.ENABLED;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -90,18 +94,50 @@ public class BlacklistRepository extends AbstractRepository<OBlacklist, Integer>
|
||||
* @return {@code true} if at least one row was deleted
|
||||
*/
|
||||
public boolean deleteWord(String guildId, String word) {
|
||||
return write(session -> {
|
||||
List<OBlacklist> existing = findWord(session, guildId, word);
|
||||
existing.forEach(session::remove);
|
||||
return tx.inTx(session -> {
|
||||
BlacklistQueries_ queries = new BlacklistQueries_(session);
|
||||
List<OBlacklist> existing = queries.findWord(guildId, word);
|
||||
queries.deleteAll(existing);
|
||||
return !existing.isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
private static List<OBlacklist> findWord(Session session, String guildId, String word) {
|
||||
return session
|
||||
.createSelectionQuery("FROM OBlacklist o WHERE upper(o.word) = upper(:word) AND o.guild.guildId = :guildId", OBlacklist.class)
|
||||
.setParameter("guildId", guildId)
|
||||
.setParameter("word", word)
|
||||
.getResultList();
|
||||
public List<OBlacklist> findAll() {
|
||||
return tx.read(session -> new BlacklistQueries_(session).findAll().toList());
|
||||
}
|
||||
|
||||
public Optional<OBlacklist> findById(Integer id) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
return tx.read(session -> new BlacklistQueries_(session).findById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts or updates the entity.
|
||||
*
|
||||
* @param entity the entity to save
|
||||
* @return the saved state, which callers should use from then on
|
||||
*/
|
||||
public OBlacklist save(OBlacklist entity) {
|
||||
Objects.requireNonNull(entity, "entity");
|
||||
return tx.inTx(session -> new BlacklistQueries_(session).save(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the entity with the given id, if it exists.
|
||||
*
|
||||
* @param id the identifier
|
||||
* @return {@code true} if a row was deleted
|
||||
*/
|
||||
public boolean deleteById(Integer id) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
return tx.inTx(session -> {
|
||||
BlacklistQueries_ queries = new BlacklistQueries_(session);
|
||||
return queries.findById(id)
|
||||
.map(entity -> {
|
||||
queries.delete(entity);
|
||||
return true;
|
||||
})
|
||||
.orElse(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -6,14 +6,21 @@ package me.bobert.netneutrality.db.repository;
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.db.AbstractRepository;
|
||||
import me.bobert.netneutrality.db.SessionProvider;
|
||||
import me.bobert.netneutrality.db.TransactionRunner;
|
||||
import me.bobert.netneutrality.db.data.GuildQueries_;
|
||||
import me.bobert.netneutrality.db.entities.OGuild;
|
||||
|
||||
public class GuildRepository extends AbstractRepository<OGuild, String> {
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class GuildRepository {
|
||||
|
||||
private final TransactionRunner tx;
|
||||
|
||||
public GuildRepository(SessionProvider sessions) {
|
||||
super(sessions, OGuild.class);
|
||||
this.tx = new TransactionRunner(sessions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -23,14 +30,52 @@ public class GuildRepository extends AbstractRepository<OGuild, String> {
|
||||
* @return the persistent guild
|
||||
*/
|
||||
public OGuild findOrCreate(String guildId) {
|
||||
return write(session -> {
|
||||
OGuild guild = session.find(OGuild.class, guildId);
|
||||
if (guild == null) {
|
||||
guild = new OGuild();
|
||||
return tx.inTx(session -> {
|
||||
GuildQueries_ queries = new GuildQueries_(session);
|
||||
return queries.findById(guildId).orElseGet(() -> {
|
||||
OGuild guild = new OGuild();
|
||||
guild.setGuildId(guildId);
|
||||
session.persist(guild);
|
||||
}
|
||||
return guild;
|
||||
return queries.insert(guild);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public List<OGuild> findAll() {
|
||||
return tx.read(session -> new GuildQueries_(session).findAll().toList());
|
||||
}
|
||||
|
||||
public Optional<OGuild> findById(String id) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
return tx.read(session -> new GuildQueries_(session).findById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts or updates the entity.
|
||||
*
|
||||
* @param entity the entity to save
|
||||
* @return the saved state, which callers should use from then on
|
||||
*/
|
||||
public OGuild save(OGuild entity) {
|
||||
Objects.requireNonNull(entity, "entity");
|
||||
return tx.inTx(session -> new GuildQueries_(session).save(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the entity with the given id, if it exists.
|
||||
*
|
||||
* @param id the identifier
|
||||
* @return {@code true} if a row was deleted
|
||||
*/
|
||||
public boolean deleteById(String id) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
return tx.inTx(session -> {
|
||||
GuildQueries_ queries = new GuildQueries_(session);
|
||||
return queries.findById(id)
|
||||
.map(entity -> {
|
||||
queries.delete(entity);
|
||||
return true;
|
||||
})
|
||||
.orElse(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -6,25 +6,27 @@ package me.bobert.netneutrality.db.repository;
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.db.AbstractRepository;
|
||||
import me.bobert.netneutrality.db.GSettings;
|
||||
import me.bobert.netneutrality.db.SessionProvider;
|
||||
import me.bobert.netneutrality.db.TransactionRunner;
|
||||
import me.bobert.netneutrality.db.data.GuildSettingQueries_;
|
||||
import me.bobert.netneutrality.db.entities.OGuild;
|
||||
import me.bobert.netneutrality.db.entities.OGuildSetting;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class GuildSettingRepository extends AbstractRepository<OGuildSetting, Integer> {
|
||||
public class GuildSettingRepository {
|
||||
|
||||
private final TransactionRunner tx;
|
||||
|
||||
public GuildSettingRepository(SessionProvider sessions) {
|
||||
super(sessions, OGuildSetting.class);
|
||||
this.tx = new TransactionRunner(sessions);
|
||||
}
|
||||
|
||||
public List<OGuildSetting> findByGuild(String guildId) {
|
||||
return read(session -> session
|
||||
.createSelectionQuery("FROM OGuildSetting o WHERE o.guild.guildId = :guildId", OGuildSetting.class)
|
||||
.setParameter("guildId", guildId)
|
||||
.getResultList());
|
||||
return tx.read(session -> new GuildSettingQueries_(session).byGuild(guildId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,27 +38,67 @@ public class GuildSettingRepository extends AbstractRepository<OGuildSetting, In
|
||||
* @param value the new value, or {@code null} to reset
|
||||
*/
|
||||
public void upsertOrDelete(String guildId, GSettings setting, String value) {
|
||||
writeVoid(session -> {
|
||||
List<OGuildSetting> existing = session
|
||||
.createNamedSelectionQuery("settings_findByName", OGuildSetting.class)
|
||||
.setParameter("id", guildId)
|
||||
.setParameter("name", setting.getName())
|
||||
.getResultList();
|
||||
tx.inTx(session -> {
|
||||
GuildSettingQueries_ queries = new GuildSettingQueries_(session);
|
||||
List<OGuildSetting> existing = queries.byName(guildId, setting.getName());
|
||||
|
||||
if (value == null || setting.getDefaultValue().equals(value)) {
|
||||
existing.forEach(session::remove);
|
||||
return;
|
||||
queries.deleteAll(existing);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (existing.isEmpty()) {
|
||||
OGuild guild = new OGuild();
|
||||
guild.setGuildId(guildId);
|
||||
OGuildSetting guildSetting = new OGuildSetting();
|
||||
guildSetting.setGuild(session.getReference(OGuild.class, guildId));
|
||||
guildSetting.setGuild(guild);
|
||||
guildSetting.setName(setting.getName());
|
||||
guildSetting.setValue(value);
|
||||
session.persist(guildSetting);
|
||||
queries.insert(guildSetting);
|
||||
} else {
|
||||
existing.forEach(guildSetting -> guildSetting.setValue(value));
|
||||
queries.updateAll(existing);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public List<OGuildSetting> findAll() {
|
||||
return tx.read(session -> new GuildSettingQueries_(session).findAll().toList());
|
||||
}
|
||||
|
||||
public Optional<OGuildSetting> findById(Integer id) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
return tx.read(session -> new GuildSettingQueries_(session).findById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts or updates the entity.
|
||||
*
|
||||
* @param entity the entity to save
|
||||
* @return the saved state, which callers should use from then on
|
||||
*/
|
||||
public OGuildSetting save(OGuildSetting entity) {
|
||||
Objects.requireNonNull(entity, "entity");
|
||||
return tx.inTx(session -> new GuildSettingQueries_(session).save(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the entity with the given id, if it exists.
|
||||
*
|
||||
* @param id the identifier
|
||||
* @return {@code true} if a row was deleted
|
||||
*/
|
||||
public boolean deleteById(Integer id) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
return tx.inTx(session -> {
|
||||
GuildSettingQueries_ queries = new GuildSettingQueries_(session);
|
||||
return queries.findById(id)
|
||||
.map(entity -> {
|
||||
queries.delete(entity);
|
||||
return true;
|
||||
})
|
||||
.orElse(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -6,20 +6,24 @@ package me.bobert.netneutrality.db.repository;
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.db.AbstractRepository;
|
||||
import jakarta.data.Limit;
|
||||
import me.bobert.netneutrality.db.SessionProvider;
|
||||
import me.bobert.netneutrality.db.TransactionRunner;
|
||||
import me.bobert.netneutrality.db.data.MessageQueries_;
|
||||
import me.bobert.netneutrality.db.entities.OGuild;
|
||||
import me.bobert.netneutrality.db.entities.OLogMessage;
|
||||
import org.hibernate.Session;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class MessageRepository extends AbstractRepository<OLogMessage, Integer> {
|
||||
public class MessageRepository {
|
||||
|
||||
private final TransactionRunner tx;
|
||||
|
||||
public MessageRepository(SessionProvider sessions) {
|
||||
super(sessions, OLogMessage.class);
|
||||
this.tx = new TransactionRunner(sessions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,21 +38,22 @@ public class MessageRepository extends AbstractRepository<OLogMessage, Integer>
|
||||
* @return the persistent log entry
|
||||
*/
|
||||
public OLogMessage log(String guildId, String channelId, String userId, String messageId, String content, Instant sentAt) {
|
||||
return write(session -> {
|
||||
return tx.inTx(session -> {
|
||||
OGuild guild = new OGuild();
|
||||
guild.setGuildId(guildId);
|
||||
OLogMessage logMessage = new OLogMessage();
|
||||
logMessage.setGuild(session.getReference(OGuild.class, guildId));
|
||||
logMessage.setGuild(guild);
|
||||
logMessage.setChannelId(channelId);
|
||||
logMessage.setUserId(userId);
|
||||
logMessage.setMessageId(messageId);
|
||||
logMessage.setMessage(content == null ? null : content.trim());
|
||||
logMessage.setDateSent(sentAt);
|
||||
session.persist(logMessage);
|
||||
return logMessage;
|
||||
return new MessageQueries_(session).insert(logMessage);
|
||||
});
|
||||
}
|
||||
|
||||
public Optional<OLogMessage> findByMessageId(String messageId) {
|
||||
return read(session -> findByMessageId(session, messageId));
|
||||
return tx.read(session -> new MessageQueries_(session).byMessageId(messageId));
|
||||
}
|
||||
|
||||
public Optional<String> findMessageContent(String messageId) {
|
||||
@@ -63,19 +68,20 @@ public class MessageRepository extends AbstractRepository<OLogMessage, Integer>
|
||||
* @return {@code true} if the message was found and updated
|
||||
*/
|
||||
public boolean updateEditedMessage(String messageId, String newMessage) {
|
||||
return write(session -> findByMessageId(session, messageId)
|
||||
.map(message -> {
|
||||
message.setEditedMessage(newMessage);
|
||||
return true;
|
||||
})
|
||||
.orElse(false));
|
||||
return tx.inTx(session -> {
|
||||
MessageQueries_ queries = new MessageQueries_(session);
|
||||
return queries.byMessageId(messageId)
|
||||
.map(message -> {
|
||||
message.setEditedMessage(newMessage);
|
||||
queries.update(message);
|
||||
return true;
|
||||
})
|
||||
.orElse(false);
|
||||
});
|
||||
}
|
||||
|
||||
public boolean deleteByMessageId(String messageId) {
|
||||
return write(session -> session
|
||||
.createMutationQuery("DELETE FROM OLogMessage o WHERE o.messageId = :messageId")
|
||||
.setParameter("messageId", messageId)
|
||||
.executeUpdate() > 0);
|
||||
return tx.inTx(session -> new MessageQueries_(session).deleteByMessageId(messageId) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,18 +93,45 @@ public class MessageRepository extends AbstractRepository<OLogMessage, Integer>
|
||||
* @return the messages
|
||||
*/
|
||||
public List<OLogMessage> findByUser(String userId, String guildId, int max) {
|
||||
return read(session -> session
|
||||
.createSelectionQuery("FROM OLogMessage o WHERE o.guild.guildId = :guildId AND o.userId = :userId ORDER BY o.dateSent DESC", OLogMessage.class)
|
||||
.setParameter("guildId", guildId)
|
||||
.setParameter("userId", userId)
|
||||
.setMaxResults(max)
|
||||
.getResultList());
|
||||
return tx.read(session -> new MessageQueries_(session).byUser(userId, guildId, Limit.of(max)));
|
||||
}
|
||||
|
||||
private static Optional<OLogMessage> findByMessageId(Session session, String messageId) {
|
||||
return session
|
||||
.createSelectionQuery("FROM OLogMessage o WHERE o.messageId = :messageId", OLogMessage.class)
|
||||
.setParameter("messageId", messageId)
|
||||
.uniqueResultOptional();
|
||||
public List<OLogMessage> findAll() {
|
||||
return tx.read(session -> new MessageQueries_(session).findAll().toList());
|
||||
}
|
||||
|
||||
public Optional<OLogMessage> findById(Integer id) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
return tx.read(session -> new MessageQueries_(session).findById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts or updates the entity.
|
||||
*
|
||||
* @param entity the entity to save
|
||||
* @return the saved state, which callers should use from then on
|
||||
*/
|
||||
public OLogMessage save(OLogMessage entity) {
|
||||
Objects.requireNonNull(entity, "entity");
|
||||
return tx.inTx(session -> new MessageQueries_(session).save(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the entity with the given id, if it exists.
|
||||
*
|
||||
* @param id the identifier
|
||||
* @return {@code true} if a row was deleted
|
||||
*/
|
||||
public boolean deleteById(Integer id) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
return tx.inTx(session -> {
|
||||
MessageQueries_ queries = new MessageQueries_(session);
|
||||
return queries.findById(id)
|
||||
.map(entity -> {
|
||||
queries.delete(entity);
|
||||
return true;
|
||||
})
|
||||
.orElse(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -6,21 +6,25 @@ package me.bobert.netneutrality.db.repository;
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.db.AbstractRepository;
|
||||
import me.bobert.netneutrality.db.SessionProvider;
|
||||
import me.bobert.netneutrality.db.TransactionRunner;
|
||||
import me.bobert.netneutrality.db.data.TaskQueries_;
|
||||
import me.bobert.netneutrality.db.entities.OTask;
|
||||
import org.hibernate.Session;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class TaskRepository extends AbstractRepository<OTask, Integer> {
|
||||
public class TaskRepository {
|
||||
|
||||
private final TransactionRunner tx;
|
||||
|
||||
public TaskRepository(SessionProvider sessions) {
|
||||
super(sessions, OTask.class);
|
||||
this.tx = new TransactionRunner(sessions);
|
||||
}
|
||||
|
||||
public Optional<OTask> findByTaskId(String taskId) {
|
||||
return read(session -> findByTaskId(session, taskId));
|
||||
return tx.read(session -> new TaskQueries_(session).byTaskId(taskId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -32,32 +36,62 @@ public class TaskRepository extends AbstractRepository<OTask, Integer> {
|
||||
* @return the persistent task
|
||||
*/
|
||||
public OTask upsert(String taskId, String typeId, String payload) {
|
||||
return write(session -> {
|
||||
OTask task = findByTaskId(session, taskId).orElse(null);
|
||||
if (task == null) {
|
||||
task = new OTask();
|
||||
task.setTaskId(taskId);
|
||||
task.setTaskClass(typeId);
|
||||
task.setPayload(payload);
|
||||
session.persist(task);
|
||||
} else {
|
||||
return tx.inTx(session -> {
|
||||
TaskQueries_ queries = new TaskQueries_(session);
|
||||
Optional<OTask> existing = queries.byTaskId(taskId);
|
||||
if (existing.isPresent()) {
|
||||
OTask task = existing.get();
|
||||
task.setPayload(payload);
|
||||
return queries.update(task);
|
||||
}
|
||||
return task;
|
||||
OTask task = new OTask();
|
||||
task.setTaskId(taskId);
|
||||
task.setTaskClass(typeId);
|
||||
task.setPayload(payload);
|
||||
return queries.insert(task);
|
||||
});
|
||||
}
|
||||
|
||||
public boolean deleteByTaskId(String taskId) {
|
||||
return write(session -> session
|
||||
.createMutationQuery("DELETE FROM OTask o WHERE o.taskId = :taskId")
|
||||
.setParameter("taskId", taskId)
|
||||
.executeUpdate() > 0);
|
||||
return tx.inTx(session -> new TaskQueries_(session).deleteByTaskId(taskId) > 0);
|
||||
}
|
||||
|
||||
private static Optional<OTask> findByTaskId(Session session, String taskId) {
|
||||
return session
|
||||
.createSelectionQuery("FROM OTask o WHERE o.taskId = :taskId", OTask.class)
|
||||
.setParameter("taskId", taskId)
|
||||
.uniqueResultOptional();
|
||||
public List<OTask> findAll() {
|
||||
return tx.read(session -> new TaskQueries_(session).findAll().toList());
|
||||
}
|
||||
|
||||
public Optional<OTask> findById(Integer id) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
return tx.read(session -> new TaskQueries_(session).findById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts or updates the entity.
|
||||
*
|
||||
* @param entity the entity to save
|
||||
* @return the saved state, which callers should use from then on
|
||||
*/
|
||||
public OTask save(OTask entity) {
|
||||
Objects.requireNonNull(entity, "entity");
|
||||
return tx.inTx(session -> new TaskQueries_(session).save(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the entity with the given id, if it exists.
|
||||
*
|
||||
* @param id the identifier
|
||||
* @return {@code true} if a row was deleted
|
||||
*/
|
||||
public boolean deleteById(Integer id) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
return tx.inTx(session -> {
|
||||
TaskQueries_ queries = new TaskQueries_(session);
|
||||
return queries.findById(id)
|
||||
.map(entity -> {
|
||||
queries.delete(entity);
|
||||
return true;
|
||||
})
|
||||
.orElse(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user