diff --git a/src/main/java/me/braydon/feather/database/impl/mongodb/MongoRepository.java b/src/main/java/me/braydon/feather/database/impl/mongodb/MongoRepository.java index 6632d93..71d56cc 100644 --- a/src/main/java/me/braydon/feather/database/impl/mongodb/MongoRepository.java +++ b/src/main/java/me/braydon/feather/database/impl/mongodb/MongoRepository.java @@ -75,7 +75,7 @@ public class MongoRepository extends Repository { */ @Override public List findAll() { - List entities = new ArrayList<>(); + List entities = new ArrayList<>(); // The entities to return try (MongoCursor 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 extends Repository { 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. * diff --git a/src/main/java/me/braydon/feather/database/impl/redis/Redis.java b/src/main/java/me/braydon/feather/database/impl/redis/Redis.java index 309c0de..d47e8df 100644 --- a/src/main/java/me/braydon/feather/database/impl/redis/Redis.java +++ b/src/main/java/me/braydon/feather/database/impl/redis/Redis.java @@ -97,26 +97,39 @@ public class Redis implements IDatabase, return connection; } -// /** -// * Create a new repository -// * using this database. -// * -// * @return the repository instance -// * @see RedisRepository for repository -// */ -// @NonNull -// public RedisRepository newRepository() { -// return new RedisRepository<>(this); -// } + /** + * Create a new repository using this database. + * + * @param the identifier for type for entities + * @param 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 RedisRepository newRepository(@NonNull Class 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 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 the identifier for type for entities + * @param 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 RedisRepository newRepository(@NonNull Class 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 diff --git a/src/main/java/me/braydon/feather/database/impl/redis/RedisRepository.java b/src/main/java/me/braydon/feather/database/impl/redis/RedisRepository.java index 7c133d2..bba9180 100644 --- a/src/main/java/me/braydon/feather/database/impl/redis/RedisRepository.java +++ b/src/main/java/me/braydon/feather/database/impl/redis/RedisRepository.java @@ -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 the entity type this repository stores */ public class RedisRepository extends Repository { - public RedisRepository(@NonNull Redis database, @NonNull Class entityClass) { + /** + * The prefix to use for keys in this repository. + */ + @NonNull private final String keyPrefix; + + public RedisRepository(@NonNull Redis database, @NonNull Class entityClass, @NonNull String keyPrefix) { super(database, entityClass); + this.keyPrefix = keyPrefix; } /** @@ -32,7 +42,7 @@ public class RedisRepository extends Repository { */ @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 extends Repository { */ @Override public List findAll() { - throw new UnsupportedOperationException(); + RedisCommands commands = getDatabase().getBootstrap().sync(); // The sync command executor + List 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 extends Repository { */ @Override public void saveAll(@NonNull E... entities) { - throw new UnsupportedOperationException(); + boolean multi = entities.length > 1; // Should we run multiple commands? + RedisCommands 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 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 extends Repository { */ @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 extends Repository { */ @Override public void drop(@NonNull E entity) { - throw new UnsupportedOperationException(); + me.braydon.feather.data.Document document = new me.braydon.feather.data.Document<>(entity); // Create a document from the entity + getDatabase().getBootstrap().sync().del(keyPrefix + ":" + document.getKey()); } } \ No newline at end of file diff --git a/src/main/java/me/braydon/feather/repository/Repository.java b/src/main/java/me/braydon/feather/repository/Repository.java index 45a0fe8..7b12ac0 100644 --- a/src/main/java/me/braydon/feather/repository/Repository.java +++ b/src/main/java/me/braydon/feather/repository/Repository.java @@ -89,6 +89,15 @@ public abstract class Repository, 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, ID, E> { * @return the created entity, null if none * @see E for entity */ - protected final E newEntity(Map mappedData) { + protected final E newEntity(Map mappedData) { if (mappedData == null) { // No mapped data given return null; } @@ -121,7 +130,7 @@ public abstract class Repository, 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); }