Impl the Redis repository

This commit is contained in:
Braydon 2023-12-15 02:10:53 -05:00
parent 4828933702
commit 4bd23c365d
4 changed files with 113 additions and 28 deletions

@ -75,7 +75,7 @@ public class MongoRepository<ID, E> extends Repository<MongoDB, ID, E> {
*/
@Override
public List<E> findAll() {
List<E> entities = new ArrayList<>();
List<E> entities = new ArrayList<>(); // The entities to return
try (MongoCursor<Document> cursor = collection.find().cursor()) {
while (cursor.hasNext()) { // Add the entity to the list
entities.add(newEntity(cursor.next()));
@ -130,6 +130,30 @@ public class MongoRepository<ID, E> extends Repository<MongoDB, ID, E> {
return collection.countDocuments();
}
/**
* Drop the entity with the given id
*
* @param id the entity id to drop
* @see ID for id
* @see E for entity
*/
@Override
public void dropById(@NonNull ID id) {
dropById("_id", id);
}
/**
* Drop the entity with the given id
*
* @param idKey the key of the id
* @param id the entity id to drop
* @see ID for id
* @see E for entity
*/
public void dropById(@NonNull String idKey, @NonNull ID id) {
collection.deleteOne(new Document(idKey, id.toString())); // Delete the entity
}
/**
* Drop the given entity.
*

@ -97,26 +97,39 @@ public class Redis implements IDatabase<StatefulRedisConnection<String, String>,
return connection;
}
// /**
// * Create a new repository
// * using this database.
// *
// * @return the repository instance
// * @see RedisRepository for repository
// */
// @NonNull
// public <ID, E> RedisRepository<ID, E> newRepository() {
// return new RedisRepository<>(this);
// }
/**
* Create a new repository using this database.
*
* @param <ID> the identifier for type for entities
* @param <E> the entity type the repository stores
* @param entityClass the class of the entity the repository uses
* @return the repository instance
* @throws IllegalStateException if not connected
* @see RedisRepository for repository
*/
@NonNull
public <ID, E> RedisRepository<ID, E> newRepository(@NonNull Class<? extends E> entityClass) {
return newRepository(entityClass, entityClass.getSimpleName());
}
// @Override
// public void write(@NonNull Object element) {
// if (!element.getClass().isAnnotationPresent(Collection.class)) { // Missing annotation
// throw new IllegalStateException("Element is missing @Collection annotation");
// }
// Document<String> document = new Document<>(element); // Construct the document from the element
// sync().hmset(String.valueOf(document.getKey()), document.toMappedData()); // Set the map in the database
// }
/**
* Create a new repository using this database.
*
* @param <ID> the identifier for type for entities
* @param <E> the entity type the repository stores
* @param entityClass the class of the entity the repository uses
* @param keyPrefix the key to prefix fields with
* @return the repository instance
* @throws IllegalStateException if not connected
* @see RedisRepository for repository
*/
@NonNull
public <ID, E> RedisRepository<ID, E> newRepository(@NonNull Class<? extends E> entityClass, @NonNull String keyPrefix) {
if (!isConnected()) { // Not connected
throw new IllegalStateException("Not connected");
}
return new RedisRepository<>(this, entityClass, keyPrefix);
}
/**
* Closes this stream and releases any system resources associated

@ -5,9 +5,13 @@
*/
package me.braydon.feather.database.impl.redis;
import io.lettuce.core.api.sync.RedisCommands;
import lombok.NonNull;
import me.braydon.feather.data.Document;
import me.braydon.feather.repository.Repository;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@ -18,8 +22,14 @@ import java.util.List;
* @param <E> the entity type this repository stores
*/
public class RedisRepository<ID, E> extends Repository<Redis, ID, E> {
public RedisRepository(@NonNull Redis database, @NonNull Class<? extends E> entityClass) {
/**
* The prefix to use for keys in this repository.
*/
@NonNull private final String keyPrefix;
public RedisRepository(@NonNull Redis database, @NonNull Class<? extends E> entityClass, @NonNull String keyPrefix) {
super(database, entityClass);
this.keyPrefix = keyPrefix;
}
/**
@ -32,7 +42,7 @@ public class RedisRepository<ID, E> extends Repository<Redis, ID, E> {
*/
@Override
public E find(@NonNull ID id) {
throw new UnsupportedOperationException();
return newEntity(getDatabase().getBootstrap().sync().hgetall(keyPrefix + ":" + id));
}
/**
@ -43,7 +53,12 @@ public class RedisRepository<ID, E> extends Repository<Redis, ID, E> {
*/
@Override
public List<E> findAll() {
throw new UnsupportedOperationException();
RedisCommands<String, String> commands = getDatabase().getBootstrap().sync(); // The sync command executor
List<E> entities = new ArrayList<>(); // The entities to return
for (String key : commands.keys(keyPrefix + ":*")) {
entities.add(newEntity(commands.hgetall(key)));
}
return Collections.unmodifiableList(entities);
}
/**
@ -54,7 +69,18 @@ public class RedisRepository<ID, E> extends Repository<Redis, ID, E> {
*/
@Override
public void saveAll(@NonNull E... entities) {
throw new UnsupportedOperationException();
boolean multi = entities.length > 1; // Should we run multiple commands?
RedisCommands<String, String> commands = getDatabase().getBootstrap().sync(); // The sync command executor
if (multi) { // Prepare for setting the entities
commands.multi();
}
for (E entity : entities) { // Set our entities
Document<String> document = new Document<>(entity); // Create a document from the entity
commands.hmset(keyPrefix + ":" + document.getKey(), document.toMappedData());
}
if (multi) { // Execute the commands in bulk
commands.exec();
}
}
/**
@ -65,7 +91,19 @@ public class RedisRepository<ID, E> extends Repository<Redis, ID, E> {
*/
@Override
public long count() {
throw new UnsupportedOperationException();
return findAll().size();
}
/**
* Drop the entity with the given id
*
* @param id the entity id to drop
* @see ID for id
* @see E for entity
*/
@Override
public void dropById(@NonNull ID id) {
getDatabase().getBootstrap().sync().del(keyPrefix + ":" + id);
}
/**
@ -76,6 +114,7 @@ public class RedisRepository<ID, E> extends Repository<Redis, ID, E> {
*/
@Override
public void drop(@NonNull E entity) {
throw new UnsupportedOperationException();
me.braydon.feather.data.Document<Object> document = new me.braydon.feather.data.Document<>(entity); // Create a document from the entity
getDatabase().getBootstrap().sync().del(keyPrefix + ":" + document.getKey());
}
}

@ -89,6 +89,15 @@ public abstract class Repository<D extends IDatabase<?, ?>, ID, E> {
*/
public abstract long count();
/**
* Drop the entity with the given id
*
* @param id the entity id to drop
* @see ID for id
* @see E for entity
*/
public abstract void dropById(@NonNull ID id);
/**
* Drop the given entity.
*
@ -104,7 +113,7 @@ public abstract class Repository<D extends IDatabase<?, ?>, ID, E> {
* @return the created entity, null if none
* @see E for entity
*/
protected final E newEntity(Map<String, Object> mappedData) {
protected final E newEntity(Map<String, ?> mappedData) {
if (mappedData == null) { // No mapped data given
return null;
}
@ -121,7 +130,7 @@ public abstract class Repository<D extends IDatabase<?, ?>, ID, E> {
// Field is serializable and is a string, deserialize it using Gson
if (field.isAnnotationPresent(Serializable.class) && value.getClass() == String.class) {
value = FeatherSettings.getGson().fromJson((String) value, type);
} else if (type == UUID.class) { // Type is a UUID, convert it
} else if (type == UUID.class && value != null) { // Type is a UUID, convert it
value = UUID.fromString((String) value);
}