Skip to content

Commit

Permalink
1.0.4
Browse files Browse the repository at this point in the history
  • Loading branch information
casperwtf committed Oct 30, 2024
1 parent c875df9 commit 766672a
Show file tree
Hide file tree
Showing 11 changed files with 45 additions and 492 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>wtf.casper.storageapi</groupId>
<artifactId>StorageAPI</artifactId>
<version>1.0.3-SNAPSHOT</version>
<version>1.0.4</version>
<packaging>jar</packaging>

<properties>
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/wtf/casper/storageapi/FilterType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package wtf.casper.storageapi;

public enum FilterType {
NOT_ENDS_WITH, STARTS_WITH, NOT_STARTS_WITH, CONTAINS, NOT_CONTAINS, LESS_THAN, NOT_GREATER_THAN_OR_EQUAL_TO, EQUALS, GREATER_THAN, NOT_LESS_THAN_OR_EQUAL_TO, LESS_THAN_OR_EQUAL_TO, NOT_GREATER_THAN, GREATER_THAN_OR_EQUAL_TO, NOT_LESS_THAN, NOT_EQUALS, ENDS_WITH

}
102 changes: 0 additions & 102 deletions src/main/java/wtf/casper/storageapi/SortingType.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,106 +27,4 @@ public boolean isApplicable(@NotNull final Class<?> type) {
}
return false;
}

// this needs to be turned into in-query sorting instead of in-memory sorting
public <V> Collection<V> sort(Collection<V> values, String field) {
if (values.isEmpty() || this == NONE) {
return values;
}

values = new ArrayList<>(values);

// Get the first value and check if the field exists.
V next = values.iterator().next();
Optional<Object> fieldValue = ReflectionUtil.getFieldValue(next, field);
if (fieldValue.isEmpty()) {
throw new IllegalArgumentException("Field " + field + " does not exist in " + next.getClass().getSimpleName());
}

// Check if the field is of a valid type for sorting.
final Object o = fieldValue.get();
if (!isApplicable(o.getClass()) && !(o instanceof Map<?, ?>)) {
throw new IllegalArgumentException("Field " + field + " is not of a valid type for sorting.");
}

// Sort the values if map
if (o instanceof Map<?, ?>) {
// check if map key and value are sortable
Iterator<? extends Map.Entry<?, ?>> entryIterator = ((Map<?, ?>) o).entrySet().iterator();
Map.Entry<?, ?> entry = entryIterator.next();
if (!isApplicable(entry.getKey().getClass()) || !isApplicable(entry.getValue().getClass())) {
throw new IllegalArgumentException("Field " + field + " is not of a valid type for sorting.");
}

// we prefer to sort by value because the key is usually the id
boolean useValue = isApplicable(entry.getValue().getClass());

if (useValue) {
values = values.stream().sorted((o1, o2) -> {
Optional<Object> fieldValue1 = ReflectionUtil.getFieldValue(o1, field);
if (fieldValue1.isEmpty()) {
throw new IllegalArgumentException("Field " + field + " does not exist in " + o1.getClass().getSimpleName());
}
Object o1Value = ((Map<?, ?>) fieldValue1.get()).values().iterator().next();
Optional<Object> fieldValue2 = ReflectionUtil.getFieldValue(o2, field);
if (fieldValue2.isEmpty()) {
throw new IllegalArgumentException("Field " + field + " does not exist in " + o2.getClass().getSimpleName());
}
Object o2Value = ((Map<?, ?>) fieldValue2.get()).values().iterator().next();

if (o1Value instanceof Comparable) {
return ((Comparable) o1Value).compareTo(o2Value);
}

if (o1Value instanceof Number) {
return Double.compare(((Number) o1Value).doubleValue(), ((Number) o2Value).doubleValue());
}

return o1Value.toString().compareTo(o2Value.toString());
}).collect(Collectors.toList());
} else {
values = values.stream().sorted((o1, o2) -> {
Object o1Value = ((Map<?, ?>) ReflectionUtil.getFieldValue(o1, field).get()).keySet().iterator().next();
Object o2Value = ((Map<?, ?>) ReflectionUtil.getFieldValue(o2, field).get()).keySet().iterator().next();

if (o1Value instanceof Comparable) {
return ((Comparable) o1Value).compareTo(o2Value);
}

if (o1Value instanceof Number) {
return Double.compare(((Number) o1Value).doubleValue(), ((Number) o2Value).doubleValue());
}

return o1Value.toString().compareTo(o2Value.toString());
}).collect(Collectors.toList());
}

if (this == DESCENDING) {
Collections.reverse((List<?>) values);
}

return values;
}

values = values.stream().sorted((o1, o2) -> {
Object o1Value = ReflectionUtil.getFieldValue(o1, field).get();
Object o2Value = ReflectionUtil.getFieldValue(o2, field).get();

if (o1Value instanceof Comparable) {
return ((Comparable) o1Value).compareTo(o2Value);
}

if (o1Value instanceof Number) {
return Double.compare(((Number) o1Value).doubleValue(), ((Number) o2Value).doubleValue());
}

return o1Value.toString().compareTo(o2Value.toString());
}).collect(Collectors.toList());

if (this == DESCENDING) {
Collections.reverse((List<?>) values);
}

return values;
}
}
54 changes: 2 additions & 52 deletions src/main/java/wtf/casper/storageapi/StatelessFieldStorage.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
package wtf.casper.storageapi;

import dev.dejvokep.boostedyaml.YamlDocument;
import dev.dejvokep.boostedyaml.block.implementation.Section;
import wtf.casper.storageapi.misc.ConstructableValue;
import wtf.casper.storageapi.misc.KeyValue;
import wtf.casper.storageapi.utils.ReflectionUtil;
import wtf.casper.storageapi.utils.StorageAPIConstants;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

public interface StatelessFieldStorage<K, V> {

Expand Down Expand Up @@ -180,62 +176,16 @@ default CompletableFuture<Void> close() {
*/
default CompletableFuture<Boolean> migrate(final StatelessFieldStorage<K, V> storage) {
return CompletableFuture.supplyAsync(() -> {
storage.allValues().thenAccept((values) -> values.forEach(v -> save(v).join())).join();
storage.allValues().thenAccept(this::saveAll).join();
return true;
}, StorageAPIConstants.DB_THREAD_POOL);
}

/**
* @param oldStorageSupplier supplier to provide the old storage
* @param config the config
* @param path the path to the storage
* @return a future that will complete with a boolean that represents whether the migration was successful.
*/
default CompletableFuture<Boolean> migrateFrom(Supplier<StatelessFieldStorage<K, V>> oldStorageSupplier, YamlDocument config, String path) {
return CompletableFuture.supplyAsync(() -> {
if (config == null) return false;
Section section = config.getSection(path);
if (section == null) return false;
if (!section.getBoolean("migrate", false)) return false;
section.set("migrate", false);
try {
config.save();
} catch (IOException e) {
e.printStackTrace();
}
// storage that we are migrating to the new storage
StatelessFieldStorage<K, V> oldStorage = oldStorageSupplier.get();
try {
this.migrate(oldStorage).join();
return true;
} catch (Exception e) {
return false;
}
}, StorageAPIConstants.DB_THREAD_POOL);
}

/**
* @return a future that will complete with a collection of all values in the storage.
*/
CompletableFuture<Collection<V>> allValues();

/**
* @param field the field to search for.
* @param sortingType the sorting type to use.
* @return a future that will complete with a collection of all values in the storage that match the given field and value.
*/
default CompletableFuture<Collection<V>> allValues(String field, SortingType sortingType) {
return CompletableFuture.supplyAsync(() -> {
Collection<V> values = allValues().join();
if (values.isEmpty()) {
return values;
}

// Sort the values.
return sortingType.sort(values, field);
}, StorageAPIConstants.DB_THREAD_POOL);
}

/**
* Adds an index to the storage.
* @param field the field to add an index for.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package wtf.casper.storageapi.impl.direct.statelessfstorage;

import wtf.casper.storageapi.Credentials;
import wtf.casper.storageapi.impl.statelessfstorage.StatelessMongoFStorage;
import wtf.casper.storageapi.misc.ConstructableValue;

import java.util.function.Function;

public class DirectStatelessMongoFStorage<K, V> extends StatelessMongoFStorage<K, V> implements ConstructableValue<K, V> {

private final Function<K, V> function;

public DirectStatelessMongoFStorage(Class<K> keyClass, Class<V> valueClass, Credentials credentials, Function<K, V> function) {
super(keyClass, valueClass, credentials);
this.function = function;
}

@Override
public V constructValue(K key) {
return function.apply(key);
}
}
Loading

0 comments on commit 766672a

Please sign in to comment.