Added queries
This commit is contained in:
parent
dea0eea5b7
commit
a1624bf91e
4
pom.xml
4
pom.xml
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>it.cavallium</groupId>
|
||||
<artifactId>strangedb</artifactId>
|
||||
<version>1.5.5</version>
|
||||
<version>1.5.7</version>
|
||||
|
||||
<name>strangedb-java</name>
|
||||
<url>https://git.ignuranza.net/andreacavalli/strangedb</url>
|
||||
@ -45,7 +45,7 @@
|
||||
<dependency>
|
||||
<groupId>it.cavallium</groupId>
|
||||
<artifactId>strangedb-core</artifactId>
|
||||
<version>1.5.5</version>
|
||||
<version>1.5.7</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
|
||||
<dependency>
|
||||
|
@ -10,4 +10,5 @@ import java.lang.annotation.Target;
|
||||
public @interface DbField {
|
||||
int id();
|
||||
DbDataType type() default DbDataType.OBJECT;
|
||||
String name() default "";
|
||||
}
|
||||
|
@ -10,4 +10,5 @@ import java.lang.annotation.Target;
|
||||
public @interface DbPrimitiveField {
|
||||
int id();
|
||||
DbPrimitiveType type();
|
||||
String name() default "";
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
package it.cavallium.strangedb.java.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface DbProperty {
|
||||
int id();
|
||||
DbDataType type() default DbDataType.OBJECT;
|
||||
String name() default "";
|
||||
}
|
@ -8,6 +8,4 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface DbPropertyGetter {
|
||||
int id();
|
||||
DbDataType type() default DbDataType.OBJECT;
|
||||
}
|
||||
|
@ -8,6 +8,4 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface DbPropertySetter {
|
||||
int id();
|
||||
DbDataType type() default DbDataType.OBJECT;
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ public class DatabaseDataInitializer implements IDataInitializer {
|
||||
long[] propertyUIDs = objectsIO.allocateNewUIDs(biggestPropertyId + 1);
|
||||
|
||||
for (Method property : unorderedPropertySetters) {
|
||||
DbPropertySetter fieldAnnotation = property.getAnnotation(DbPropertySetter.class);
|
||||
DbProperty fieldAnnotation = property.getAnnotation(DbProperty.class);
|
||||
int propertyId = fieldAnnotation.id();
|
||||
if (propertyId > biggestPropertyId) {
|
||||
biggestPropertyId = propertyId;
|
||||
@ -131,12 +131,12 @@ public class DatabaseDataInitializer implements IDataInitializer {
|
||||
DbDataType[] propertyTypes = new DbDataType[biggestPropertyId + 1];
|
||||
Method[] propertyGetters = new Method[biggestPropertyId + 1];
|
||||
Method[] propertySetters = new Method[biggestPropertyId + 1];
|
||||
Map<String, DbPropertySetter> setterMethods = new LinkedHashMap<>();
|
||||
Map<String, DbPropertyGetter> getterMethods = new LinkedHashMap<>();
|
||||
Map<String, DbProperty> setterMethods = new LinkedHashMap<>();
|
||||
Map<String, DbProperty> getterMethods = new LinkedHashMap<>();
|
||||
|
||||
// Load the properties metadata
|
||||
for (Method property : unorderedPropertyGetters) {
|
||||
DbPropertyGetter propertyAnnotation = property.getAnnotation(DbPropertyGetter.class);
|
||||
DbProperty propertyAnnotation = property.getAnnotation(DbProperty.class);
|
||||
int propertyId = propertyAnnotation.id();
|
||||
DbDataType propertyType = propertyAnnotation.type();
|
||||
propertyTypes[propertyId] = propertyType;
|
||||
@ -144,7 +144,7 @@ public class DatabaseDataInitializer implements IDataInitializer {
|
||||
getterMethods.put(property.getName(), propertyAnnotation);
|
||||
}
|
||||
for (Method property : unorderedPropertySetters) {
|
||||
DbPropertySetter propertyAnnotation = property.getAnnotation(DbPropertySetter.class);
|
||||
DbProperty propertyAnnotation = property.getAnnotation(DbProperty.class);
|
||||
int propertyId = propertyAnnotation.id();
|
||||
DbDataType propertyType = propertyAnnotation.type();
|
||||
propertyTypes[propertyId] = propertyType;
|
||||
|
@ -23,14 +23,14 @@ public class DatabaseEnhancedObjectUpgrader implements EnhancedObjectUpgrader {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object getField(int id, DbDataType type, Supplier<Class<?>> enhancedClassType) throws IOException {
|
||||
return objectsIO.loadData(type, fieldRefs[id], enhancedClassType);
|
||||
public Object getField(int id, DbDataType type) throws IOException {
|
||||
return objectsIO.loadData(type, fieldRefs[id]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object getMethod(int id, DbDataType type, Supplier<Class<?>> enhancedClassType) throws IOException {
|
||||
return objectsIO.loadData(type, methodRefs[id], enhancedClassType);
|
||||
public Object getMethod(int id, DbDataType type) throws IOException {
|
||||
return objectsIO.loadData(type, methodRefs[id]);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -27,13 +27,13 @@ public class DatabaseJava extends DatabaseCore implements IDatabaseTools {
|
||||
super.close();
|
||||
}
|
||||
|
||||
public <T extends EnhancedObject> T loadRoot(Class<T> type, FunctionWithIO<IDatabaseTools, T> ifAbsent) throws IOException {
|
||||
public <T extends EnhancedObject> T loadRoot(FunctionWithIO<IDatabaseTools, T> ifAbsent) throws IOException {
|
||||
if (loadedRootObject != null) {
|
||||
throw new RuntimeException("Root already set!");
|
||||
}
|
||||
T root;
|
||||
if (referencesMetadata.getFirstFreeReference() > 0) {
|
||||
root = objectsIO.loadEnhancedObject(0, type);
|
||||
root = objectsIO.loadEnhancedObject(0);
|
||||
} else {
|
||||
if (objectsIO.newNullObject() != 0) {
|
||||
throw new IOException("Can't allocate root!");
|
||||
|
@ -7,6 +7,12 @@ import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObjectFullInfo;
|
||||
import it.cavallium.strangedb.database.references.DatabaseReferencesIO;
|
||||
import it.cavallium.strangedb.java.annotations.*;
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObjectFullInfo;
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObjectIndices;
|
||||
import it.cavallium.strangedb.java.objects.lists.EnhancedObjectStrangeDbList;
|
||||
import it.cavallium.strangedb.java.objects.lists.ObjectStrangeDbList;
|
||||
import it.cavallium.strangedb.java.objects.lists.StrangeDbList;
|
||||
import it.unimi.dsi.fastutil.booleans.BooleanArrayList;
|
||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
|
||||
import it.unimi.dsi.fastutil.chars.CharArrayList;
|
||||
@ -92,8 +98,14 @@ public class DatabaseObjectsIO implements IObjectsIO {
|
||||
registerClass(TreeSet.class, id++);
|
||||
registerClass(SortedSet.class, id++);
|
||||
registerClass(SortedMap.class, id++);
|
||||
|
||||
registerClass(EnhancedObject.class, id++);
|
||||
registerClass(EnhancedObjectStrangeDbList.class, id++);
|
||||
registerClass(ObjectStrangeDbList.class, id++);
|
||||
registerClass(StrangeDbList.class, id++);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends EnhancedObject> T loadEnhancedObject(long reference, Class<T> objectType) throws IOException {
|
||||
synchronized (accessLock) {
|
||||
@ -101,6 +113,10 @@ public class DatabaseObjectsIO implements IObjectsIO {
|
||||
if (buffer.limit() == 0) {
|
||||
return null;
|
||||
}
|
||||
int serializedClassLength = 0xFF & buffer.get();
|
||||
byte[] serializedClassData = new byte[serializedClassLength];
|
||||
buffer.get(serializedClassData);
|
||||
Class<T> objectType = kryo.readClass(new Input(serializedClassData)).getType();
|
||||
int serializedVersion = Byte.toUnsignedInt(buffer.get());
|
||||
int fieldsCount = buffer.getInt();
|
||||
int methodsCount = buffer.getInt();
|
||||
@ -118,11 +134,43 @@ public class DatabaseObjectsIO implements IObjectsIO {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Object loadData(DbDataType propertyType, long dataReference, Supplier<Class<?>> returnType) throws IOException {
|
||||
@Override
|
||||
public EnhancedObjectIndices loadEnhancedObjectUids(long reference) throws IOException {
|
||||
lock.readLock().lock();
|
||||
readLock.lock();
|
||||
try {
|
||||
ByteBuffer buffer = referencesIO.readFromReference(reference);
|
||||
if (buffer.limit() == 0) {
|
||||
return null;
|
||||
}
|
||||
//noinspection unused
|
||||
int serializedClassLength = 0xFF & buffer.get();
|
||||
byte[] serializedClassData = new byte[serializedClassLength];
|
||||
buffer.get(serializedClassData);
|
||||
int serializedVersion = Byte.toUnsignedInt(buffer.get());
|
||||
int fieldsCount = buffer.getInt();
|
||||
int methodsCount = buffer.getInt();
|
||||
long[] fieldRefs = new long[fieldsCount];
|
||||
long[] methodRefs = new long[methodsCount];
|
||||
for (int i = 0; i < fieldsCount; i++) {
|
||||
fieldRefs[i] = buffer.getLong();
|
||||
}
|
||||
for (int i = 0; i < methodsCount; i++) {
|
||||
methodRefs[i] = buffer.getLong();
|
||||
}
|
||||
long nativeFieldsDataReference = buffer.getLong();
|
||||
return new EnhancedObjectIndices(reference, fieldRefs, methodRefs, nativeFieldsDataReference);
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object loadData(DbDataType propertyType, long dataReference) throws IOException {
|
||||
switch (propertyType) {
|
||||
case ENHANCED_OBJECT:
|
||||
return loadEnhancedObject(dataReference, (Class<? extends EnhancedObject>) returnType.get());
|
||||
return loadEnhancedObject(dataReference);
|
||||
case OBJECT:
|
||||
return loadObject(dataReference);
|
||||
case REFERENCES_LIST:
|
||||
@ -211,9 +259,17 @@ public class DatabaseObjectsIO implements IObjectsIO {
|
||||
final long[] propertyReferences = objectFullInfo.getPropertyReferences();
|
||||
final DbDataType[] propertyTypes = objectFullInfo.getPropertyTypes();
|
||||
final Object[] propertyValues = objectFullInfo.getLoadedPropertyValues();
|
||||
final int totalSize = Byte.BYTES + Integer.BYTES * 2 + fieldReferences.length * Long.BYTES
|
||||
Output serializedClassDataStream = new Output(1024, 8192);
|
||||
kryo.writeClass(serializedClassDataStream, value.getClass());
|
||||
byte[] serializedClassData = serializedClassDataStream.toBytes();
|
||||
final int totalSize = Byte.BYTES + serializedClassData.length + Byte.BYTES + Integer.BYTES * 2 + fieldReferences.length * Long.BYTES
|
||||
+ propertyReferences.length * Long.BYTES + Long.BYTES;
|
||||
ByteBuffer buffer = ByteBuffer.allocate(totalSize);
|
||||
if (serializedClassData.length > 255) {
|
||||
throw new IndexOutOfBoundsException("The class name is too long!");
|
||||
}
|
||||
buffer.put((byte) serializedClassData.length);
|
||||
buffer.put(serializedClassData);
|
||||
buffer.put((byte) objectFullInfo.getVersion());
|
||||
buffer.putInt(fieldReferences.length);
|
||||
buffer.putInt(propertyReferences.length);
|
||||
@ -337,10 +393,11 @@ public class DatabaseObjectsIO implements IObjectsIO {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadProperty(EnhancedObject obj, int propertyId, Method property, DbDataType propertyType,
|
||||
public void loadProperty(EnhancedObject obj, int propertyId, DbDataType propertyType,
|
||||
long propertyUID) throws IOException {
|
||||
synchronized (accessLock) {
|
||||
obj.setProperty(propertyId, loadData(propertyType, propertyUID, property::getReturnType));
|
||||
obj.setProperty(propertyId, loadData(propertyType, propertyUID));
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,7 +420,7 @@ public class DatabaseObjectsIO implements IObjectsIO {
|
||||
int biggestPropertyId = biggestGetter > biggestSetter ? biggestGetter : biggestSetter;
|
||||
|
||||
for (Method property : unorderedPropertySetters) {
|
||||
DbPropertySetter fieldAnnotation = property.getAnnotation(DbPropertySetter.class);
|
||||
DbProperty fieldAnnotation = property.getAnnotation(DbProperty.class);
|
||||
int propertyId = fieldAnnotation.id();
|
||||
if (propertyId > biggestPropertyId) {
|
||||
biggestPropertyId = propertyId;
|
||||
@ -374,12 +431,12 @@ public class DatabaseObjectsIO implements IObjectsIO {
|
||||
DbDataType[] propertyTypes = new DbDataType[biggestPropertyId + 1];
|
||||
Method[] propertyGetters = new Method[biggestPropertyId + 1];
|
||||
Method[] propertySetters = new Method[biggestPropertyId + 1];
|
||||
Map<String, DbPropertySetter> setterMethods = new LinkedHashMap<>();
|
||||
Map<String, DbPropertyGetter> getterMethods = new LinkedHashMap<>();
|
||||
Map<String, DbProperty> setterMethods = new LinkedHashMap<>();
|
||||
Map<String, DbProperty> getterMethods = new LinkedHashMap<>();
|
||||
|
||||
// Load the properties metadata
|
||||
for (Method property : unorderedPropertyGetters) {
|
||||
DbPropertyGetter propertyAnnotation = property.getAnnotation(DbPropertyGetter.class);
|
||||
DbProperty propertyAnnotation = property.getAnnotation(DbProperty.class);
|
||||
int propertyId = propertyAnnotation.id();
|
||||
DbDataType propertyType = propertyAnnotation.type();
|
||||
propertyTypes[propertyId] = propertyType;
|
||||
@ -387,7 +444,7 @@ public class DatabaseObjectsIO implements IObjectsIO {
|
||||
getterMethods.put(property.getName(), propertyAnnotation);
|
||||
}
|
||||
for (Method property : unorderedPropertySetters) {
|
||||
DbPropertySetter propertyAnnotation = property.getAnnotation(DbPropertySetter.class);
|
||||
DbProperty propertyAnnotation = property.getAnnotation(DbProperty.class);
|
||||
int propertyId = propertyAnnotation.id();
|
||||
DbDataType propertyType = propertyAnnotation.type();
|
||||
propertyTypes[propertyId] = propertyType;
|
||||
@ -402,7 +459,7 @@ public class DatabaseObjectsIO implements IObjectsIO {
|
||||
int getBiggestPropertyGetterId(Method[] unorderedPropertyGetters) {
|
||||
int biggestPropertyId = -1;
|
||||
for (Method property : unorderedPropertyGetters) {
|
||||
DbPropertyGetter fieldAnnotation = property.getAnnotation(DbPropertyGetter.class);
|
||||
DbProperty fieldAnnotation = property.getAnnotation(DbProperty.class);
|
||||
int propertyId = fieldAnnotation.id();
|
||||
if (propertyId > biggestPropertyId) {
|
||||
biggestPropertyId = propertyId;
|
||||
@ -414,7 +471,7 @@ public class DatabaseObjectsIO implements IObjectsIO {
|
||||
int getBiggestPropertySetterId(Method[] unorderedPropertySetters) {
|
||||
int biggestPropertyId = -1;
|
||||
for (Method property : unorderedPropertySetters) {
|
||||
DbPropertySetter fieldAnnotation = property.getAnnotation(DbPropertySetter.class);
|
||||
DbProperty fieldAnnotation = property.getAnnotation(DbProperty.class);
|
||||
int propertyId = fieldAnnotation.id();
|
||||
if (propertyId > biggestPropertyId) {
|
||||
biggestPropertyId = propertyId;
|
||||
@ -513,10 +570,10 @@ public class DatabaseObjectsIO implements IObjectsIO {
|
||||
|
||||
<T extends EnhancedObject> void loadField(T obj, Field field, DbDataType fieldType, long fieldReference)
|
||||
throws IOException {
|
||||
Object data = loadData(fieldType, fieldReference, field::getType);
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
if (fieldType == DbDataType.OBJECT && data != null) {
|
||||
if (!field.getType().isInstance(data)) {
|
||||
Object data = loadData(fieldType, fieldReference);
|
||||
try {
|
||||
throw new IOException("There is an attempt to load an object of type " + data.getClass()
|
||||
+ " into a field of type " + field.getType());
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package it.cavallium.strangedb.java.database;
|
||||
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObjectIndices;
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
import it.unimi.dsi.fastutil.longs.LongList;
|
||||
|
||||
@ -9,7 +10,10 @@ import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public interface IObjectsIO {
|
||||
<T extends EnhancedObject> T loadEnhancedObject(long reference, Class<T> objectType) throws IOException;
|
||||
@SuppressWarnings("unchecked")
|
||||
<T extends EnhancedObject> T loadEnhancedObject(long reference) throws IOException;
|
||||
|
||||
EnhancedObjectIndices loadEnhancedObjectUids(long reference) throws IOException;
|
||||
|
||||
<T> T loadObject(long reference) throws IOException;
|
||||
|
||||
@ -47,7 +51,7 @@ public interface IObjectsIO {
|
||||
return reference;
|
||||
}
|
||||
|
||||
void loadProperty(EnhancedObject enhancedObject, int propertyId, Method propertyGetter, DbDataType propertyType, long propertyUID) throws IOException;
|
||||
void loadProperty(EnhancedObject enhancedObject, int propertyId, DbDataType propertyType, long propertyUID) throws IOException;
|
||||
|
||||
void registerClass(Class<?> type, int id);
|
||||
|
||||
|
@ -29,8 +29,8 @@ public abstract class EnhancedObject {
|
||||
private long[] propertyReferences;
|
||||
private boolean[] loadedProperties;
|
||||
private Object[] loadedPropertyValues;
|
||||
private Map<String, DbPropertySetter> setterMethods;
|
||||
private Map<String, DbPropertyGetter> getterMethods;
|
||||
private Map<String, DbProperty> setterMethods;
|
||||
private Map<String, DbProperty> getterMethods;
|
||||
|
||||
public EnhancedObject() {
|
||||
version = getClassVersion();
|
||||
@ -82,7 +82,7 @@ public abstract class EnhancedObject {
|
||||
StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
|
||||
StackWalker.StackFrame stackFrame = walker.walk(f -> f.skip(1).findFirst().orElse(null));
|
||||
try {
|
||||
int propertyId = stackFrame.getDeclaringClass().getDeclaredMethod(stackFrame.getMethodName()).getAnnotation(DbPropertyGetter.class).id();
|
||||
int propertyId = stackFrame.getDeclaringClass().getDeclaredMethod(stackFrame.getMethodName()).getAnnotation(DbProperty.class).id();
|
||||
return getProperty(propertyId);
|
||||
} catch (IOException | NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
@ -90,10 +90,10 @@ public abstract class EnhancedObject {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T getProperty(int propertyId) throws IOException {
|
||||
public <T> T getProperty(int propertyId) throws IOException {
|
||||
if (!loadedProperties[propertyId]) {
|
||||
long propertyUID = propertyReferences[propertyId];
|
||||
databaseTools.getObjectsIO().loadProperty(this, propertyId, propertyGetters[propertyId], propertyTypes[propertyId], propertyUID);
|
||||
databaseTools.getObjectsIO().loadProperty(this, propertyId, propertyTypes[propertyId], propertyUID);
|
||||
}
|
||||
return (T) loadedPropertyValues[propertyId];
|
||||
}
|
||||
@ -101,7 +101,7 @@ public abstract class EnhancedObject {
|
||||
public <T> void setProperty(T value) {
|
||||
StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
|
||||
StackWalker.StackFrame stackFrame = walker.walk(f -> f.skip(1).findFirst().orElse(null));
|
||||
DbPropertySetter propertyAnnotation = setterMethods.get(stackFrame.getMethodName());
|
||||
DbProperty propertyAnnotation = setterMethods.get(stackFrame.getMethodName());
|
||||
setProperty(propertyAnnotation.id(), value);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,15 @@
|
||||
package it.cavallium.strangedb.java.objects;
|
||||
|
||||
public class EnhancedObjectIndices {
|
||||
public final long objectUid;
|
||||
public final long[] fieldUids;
|
||||
public final long[] propertyUids;
|
||||
public final long nativeDataUid;
|
||||
|
||||
public EnhancedObjectIndices(long objectUid, long[] fieldUids, long[] propertyUids, long nativeDataUid) {
|
||||
this.objectUid = objectUid;
|
||||
this.fieldUids = fieldUids;
|
||||
this.propertyUids = propertyUids;
|
||||
this.nativeDataUid = nativeDataUid;
|
||||
}
|
||||
}
|
@ -41,15 +41,7 @@ public interface EnhancedObjectUpgrader {
|
||||
return getPrimitiveField(id, DbPrimitiveType.DOUBLE);
|
||||
}
|
||||
|
||||
Object getField(int id, DbDataType type, Supplier<Class<?>> enhancedClassType) throws IOException;
|
||||
Object getField(int id, DbDataType type) throws IOException;
|
||||
|
||||
default Object getField(int id, DbDataType type) throws IOException {
|
||||
return getField(id, type, null);
|
||||
}
|
||||
|
||||
Object getMethod(int id, DbDataType type, Supplier<Class<?>> enhancedClassType) throws IOException;
|
||||
|
||||
default Object getMethod(int id, DbDataType type) throws IOException {
|
||||
return getField(id, type, null);
|
||||
}
|
||||
Object getMethod(int id, DbDataType type) throws IOException;
|
||||
}
|
||||
|
@ -0,0 +1,70 @@
|
||||
package it.cavallium.strangedb.java.objects.lists;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class ElementsArrayList<T> implements ElementsList<T> {
|
||||
|
||||
private final ArrayList<T> list;
|
||||
|
||||
public ElementsArrayList() {
|
||||
this.list = new ArrayList<>();
|
||||
}
|
||||
|
||||
public ElementsArrayList(Collection<T> collection) {
|
||||
this.list = new ArrayList<>(collection);
|
||||
}
|
||||
|
||||
public ElementsArrayList(int initialCapacity) {
|
||||
this.list = new ArrayList<>(initialCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(int index) {
|
||||
return list.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(T value) {
|
||||
list.add(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(int index, T value) {
|
||||
set(index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(int index, T value) {
|
||||
list.set(index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, T value) {
|
||||
list.add(index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getLast() {
|
||||
return list.get(list.size() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return list.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
public boolean contains(Object o) {
|
||||
return list.contains(o);
|
||||
}
|
||||
|
||||
public ArrayList<T> asList() {
|
||||
return list;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package it.cavallium.strangedb.java.objects.lists;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
interface ElementsList<T> {
|
||||
T get(int index) throws IOException;
|
||||
void add(T value) throws IOException;
|
||||
void update(int index, T value) throws IOException;
|
||||
void set(int index, T value) throws IOException;
|
||||
void add(int index, T value) throws IOException;
|
||||
T getLast() throws IOException;
|
||||
boolean isEmpty();
|
||||
int size();
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package it.cavallium.strangedb.java.objects.lists;
|
||||
|
||||
import it.cavallium.strangedb.java.database.IObjectsIO;
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||
@ -33,11 +34,156 @@ public class EnhancedObjectStrangeDbList<T extends EnhancedObject> extends Stran
|
||||
|
||||
@Override
|
||||
protected T loadItem(long uid) throws IOException {
|
||||
return databaseTools.getObjectsIO().loadEnhancedObject(uid, type);
|
||||
return databaseTools.getObjectsIO().loadEnhancedObject(uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeItemToDisk(long uid, T item) throws IOException {
|
||||
databaseTools.getObjectsIO().setEnhancedObject(uid, item);
|
||||
}
|
||||
|
||||
public ElementsArrayList<EnhancedObjectIndices> queryUids(ListQuery query) throws IOException {
|
||||
ElementsArrayList<EnhancedObjectIndices> uids = executeQuery(query, this, databaseTools.getObjectsIO());
|
||||
return uids;
|
||||
}
|
||||
|
||||
public ElementsArrayList<T> query(ListQuery query) throws IOException {
|
||||
ElementsArrayList<EnhancedObjectIndices> uids = queryUids(query);
|
||||
ElementsArrayList<T> elements = new ElementsArrayList<>(uids.size());
|
||||
for (int i = 0; i < uids.size(); i++) {
|
||||
T element = databaseTools.getObjectsIO().loadEnhancedObject(uids.get(i).objectUid);
|
||||
elements.add(element);
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
private ElementsArrayList<EnhancedObjectIndices> executeQuery(ListQuery query, ElementsList<?> inputList, IObjectsIO dbio) throws IOException {
|
||||
if (query instanceof ListQuery.ListQueryElement) {
|
||||
return executeQueryElement((ListQuery.ListQueryElement) query, inputList, dbio);
|
||||
} else if (query instanceof ListQuery.ListQueryAnd) {
|
||||
ListQuery[] children = ((ListQuery.ListQueryAnd) query).getQueryChildren();
|
||||
ElementsArrayList<EnhancedObjectIndices> results = null;
|
||||
for (ListQuery childQuery : children) {
|
||||
results = executeQuery(childQuery, results == null ? inputList : results, dbio);
|
||||
if (results.size() == 0) break;
|
||||
}
|
||||
return results;
|
||||
} else if (query instanceof ListQuery.ListQueryOr) {
|
||||
ListQuery[] children = ((ListQuery.ListQueryOr) query).getQueryChildren();
|
||||
ElementsArrayList<EnhancedObjectIndices> results = new ElementsArrayList<>();
|
||||
for (ListQuery childQuery : children) {
|
||||
ElementsArrayList<EnhancedObjectIndices> childResults = executeQuery(childQuery, inputList, dbio);
|
||||
int childResultsSize = childResults.size();
|
||||
if (childResultsSize == inputList.size()) {
|
||||
return childResults;
|
||||
}
|
||||
addMissingElements(results, childResults);
|
||||
}
|
||||
return results;
|
||||
} else {
|
||||
throw new RuntimeException("Not implemented!");
|
||||
}
|
||||
}
|
||||
|
||||
static void addMissingElements(ElementsArrayList<EnhancedObjectIndices> main, ElementsList<EnhancedObjectIndices> elementsToAdd) throws IOException {
|
||||
int elementsSize = elementsToAdd.size();
|
||||
for (int i = 0; i < elementsSize; i++) {
|
||||
EnhancedObjectIndices childResultElement = elementsToAdd.get(i);
|
||||
if (!main.contains(childResultElement)) {
|
||||
main.add(childResultElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static ElementsArrayList<Long> toElementsArrayList(ElementsList<?> elementsList) {
|
||||
if (elementsList instanceof EnhancedObjectStrangeDbList<?>) {
|
||||
return new ElementsArrayList<>(((EnhancedObjectStrangeDbList) elementsList).getIndices());
|
||||
} else if (elementsList instanceof ElementsArrayList<?>) {
|
||||
return (ElementsArrayList<Long>) elementsList;
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static ElementsArrayList<EnhancedObjectIndices> executeQueryElement(ListQuery.ListQueryElement query, ElementsList<?> inputList, IObjectsIO dbio) throws IOException {
|
||||
ElementsArrayList<EnhancedObjectIndices> results = new ElementsArrayList<>();
|
||||
if (inputList instanceof EnhancedObjectStrangeDbList<?>) {
|
||||
EnhancedObjectStrangeDbList<?> dbList = ((EnhancedObjectStrangeDbList<?>) inputList);
|
||||
final int listSize = inputList.size();
|
||||
final LongArrayList indices = dbList.getIndices();
|
||||
for (int i = 0; i < listSize; i++) {
|
||||
Long elementUid = indices.get(i);
|
||||
EnhancedObjectIndices elementUids = dbio.loadEnhancedObjectUids(elementUid);
|
||||
Object result = resolveItemFromDb(query.valuePointer, dbio, elementUids);
|
||||
if (query.valueOperation.evaluate(result)) {
|
||||
results.add(elementUids);
|
||||
}
|
||||
}
|
||||
} else if (inputList instanceof ElementsArrayList<?>) {
|
||||
final int listSize = inputList.size();
|
||||
ElementsArrayList<EnhancedObjectIndices> elementsUids = ((ElementsArrayList<EnhancedObjectIndices>) inputList);
|
||||
for (int i = 0; i < listSize; i++) {
|
||||
EnhancedObjectIndices elementUid = elementsUids.get(i);
|
||||
Object result = resolveItemFromDb(query.valuePointer, dbio, elementUid);
|
||||
if (query.valueOperation.evaluate(result)) {
|
||||
results.add(elementUid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
static Object resolveItemFromDb(ValuePointer pointer, IObjectsIO objectsIO, EnhancedObjectIndices element) throws IOException {
|
||||
EnhancedObjectIndices currentElement = element;
|
||||
boolean isLastElement;
|
||||
for (int i = 0; i < pointer.size(); i++) {
|
||||
isLastElement = i >= pointer.size() - 1;
|
||||
ValuePointer currentPointer = pointer.at(i);
|
||||
|
||||
int pathNumber = currentPointer.getPathNumber();
|
||||
ValueType valueType = currentPointer.getPathType();
|
||||
|
||||
Object value;
|
||||
switch (valueType) {
|
||||
case FIELD: {
|
||||
if (isLastElement) {
|
||||
//TODO: get field data type. it can be an enhancedObject or an object
|
||||
value = objectsIO.loadObject(currentElement.fieldUids[pathNumber]);
|
||||
} else {
|
||||
value = objectsIO.loadEnhancedObjectUids(currentElement.fieldUids[pathNumber]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PRIMITIVE_FIELD: {
|
||||
if (isLastElement) {
|
||||
//TODO: get primitive type
|
||||
value = objectsIO.loadPrimitiveData(currentElement.nativeDataUid).getLong(pathNumber);
|
||||
} else {
|
||||
throw new IllegalArgumentException("You can access to a type field only in the last pointer");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROPERTY: {
|
||||
if (isLastElement) {
|
||||
//TODO: get field data type. it can be an enhancedObject or an object
|
||||
value = objectsIO.loadObject(currentElement.fieldUids[pathNumber]);
|
||||
} else {
|
||||
value = objectsIO.loadEnhancedObjectUids(currentElement.propertyUids[pathNumber]);
|
||||
}
|
||||
}
|
||||
default: {
|
||||
throw new IllegalArgumentException("Not implemented");
|
||||
}
|
||||
}
|
||||
if (isLastElement) {
|
||||
return value;
|
||||
} else {
|
||||
currentElement = (EnhancedObjectIndices) value;
|
||||
}
|
||||
}
|
||||
throw new IOException("The pointer is empty");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
package it.cavallium.strangedb.java.objects.lists;
|
||||
|
||||
public class KMP {
|
||||
public static int KMP(CharSequence content, CharSequence stringToFind) {
|
||||
int[] failureTable = failureTable(stringToFind);
|
||||
|
||||
int targetPointer = 0; // current char in target string
|
||||
int searchPointer = 0; // current char in search string
|
||||
|
||||
while (searchPointer < content.length()) { // while there is more to search with, keep searching
|
||||
if (content.charAt(searchPointer) == stringToFind.charAt(targetPointer)) { // case 1
|
||||
// found current char in targetPointer in search string
|
||||
targetPointer++;
|
||||
if (targetPointer == stringToFind.length()) { // found all characters
|
||||
int x = stringToFind.length() + 1;
|
||||
return searchPointer - x; // return starting index of found target inside searched string
|
||||
}
|
||||
searchPointer++; // move forward if not found target string
|
||||
} else if (targetPointer > 0) { // case 2
|
||||
// use failureTable to use pointer pointed at nearest location of usable string prefix
|
||||
targetPointer = failureTable[targetPointer];
|
||||
} else { // case 3
|
||||
// targetPointer is pointing at state 0, so restart search with current searchPointer index
|
||||
searchPointer++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an int[] that points to last valid string prefix, given target string
|
||||
*/
|
||||
public static int[] failureTable(CharSequence target) {
|
||||
int[] table = new int[target.length() + 1];
|
||||
// state 0 and 1 are guarenteed be the prior
|
||||
table[0] = -1;
|
||||
table[1] = 0;
|
||||
|
||||
// the pointers pointing at last failure and current satte
|
||||
int left = 0;
|
||||
int right = 2;
|
||||
|
||||
while (right < table.length) { // RIGHT NEVER MOVES RIGHT UNTIL ASSIGNED A VALID POINTER
|
||||
if (target.charAt(right - 1) == target.charAt(left)) { // when both chars before left and right are equal, link both and move both forward
|
||||
left++;
|
||||
table[right] = left;
|
||||
right++;
|
||||
} else if (left > 0) { // if left isn't at the very beginning, then send left backward
|
||||
// by following the already set pointer to where it is pointing to
|
||||
left = table[left];
|
||||
} else { // left has fallen all the way back to the beginning
|
||||
table[right] = left;
|
||||
right++;
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package it.cavallium.strangedb.java.objects.lists;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ListQuery {
|
||||
|
||||
public static ListQuery create(ValuePointer valuePointer, ValueOperation valueOperation) {
|
||||
return new ListQueryElement(valuePointer, valueOperation);
|
||||
}
|
||||
|
||||
public ListQuery and(ValuePointer valuePointer, ValueOperation operation) {
|
||||
return new ListQueryAnd(this, create(valuePointer, operation));
|
||||
}
|
||||
|
||||
public ListQuery and(ListQuery query) {
|
||||
return new ListQueryAnd(this, query);
|
||||
}
|
||||
|
||||
public ListQuery or(ValuePointer valuePointer, ValueOperation operation) {
|
||||
return new ListQueryOr(this, create(valuePointer, operation));
|
||||
}
|
||||
|
||||
public ListQuery or(ListQuery query) {
|
||||
return new ListQueryOr(this, query);
|
||||
}
|
||||
|
||||
abstract List<ListQueryElement> getQueryElementsRecursively();
|
||||
|
||||
static class ListQueryElement extends ListQuery {
|
||||
public final ValuePointer valuePointer;
|
||||
public final ValueOperation valueOperation;
|
||||
|
||||
private ListQueryElement(ValuePointer valuePointer, ValueOperation valueOperation) {
|
||||
this.valuePointer = valuePointer;
|
||||
this.valueOperation = valueOperation;
|
||||
}
|
||||
|
||||
@Override
|
||||
List<ListQueryElement> getQueryElementsRecursively() {
|
||||
return Collections.singletonList(this);
|
||||
}
|
||||
}
|
||||
|
||||
static class ListQueryCollection extends ListQuery {
|
||||
protected ListQuery[] queries;
|
||||
|
||||
private ListQueryCollection(ListQuery... queries) {
|
||||
this.queries = queries;
|
||||
}
|
||||
|
||||
@Override
|
||||
List<ListQueryElement> getQueryElementsRecursively() {
|
||||
List<ListQueryElement> elements = new ArrayList<>();
|
||||
for (ListQuery query : queries) {
|
||||
elements.addAll(query.getQueryElementsRecursively());
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
ListQuery[] getQueryChildren() {
|
||||
return queries.clone();
|
||||
}
|
||||
}
|
||||
|
||||
static class ListQueryAnd extends ListQueryCollection {
|
||||
private ListQueryAnd(ListQuery... queries) {
|
||||
super(queries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListQuery and(ListQuery query) {
|
||||
return new ListQueryAnd(append(this.queries, query));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListQuery and(ValuePointer valuePointer, ValueOperation operation) {
|
||||
return and(create(valuePointer, operation));
|
||||
}
|
||||
}
|
||||
|
||||
static class ListQueryOr extends ListQueryCollection {
|
||||
private ListQueryOr(ListQuery... queries) {
|
||||
super(queries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListQuery or(ListQuery query) {
|
||||
return new ListQueryOr(append(this.queries, query));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListQuery or(ValuePointer valuePointer, ValueOperation operation) {
|
||||
return or(create(valuePointer, operation));
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T[] append(T[] array, T value) {
|
||||
T[] newArray = Arrays.copyOf(array, array.length + 1);
|
||||
newArray[array.length] = value;
|
||||
return newArray;
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ public class ObjectStrangeDbList<T> extends StrangeDbList<T> {
|
||||
return indices;
|
||||
}
|
||||
|
||||
protected ObjectStrangeDbList() {
|
||||
public ObjectStrangeDbList() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,9 @@ import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public abstract class StrangeDbList<T> extends EnhancedObject {
|
||||
public abstract class StrangeDbList<T> extends EnhancedObject implements ElementsList<T> {
|
||||
|
||||
private final Object indicesAccessLock = new Object();
|
||||
|
||||
@ -22,6 +21,7 @@ public abstract class StrangeDbList<T> extends EnhancedObject {
|
||||
super(databaseTools);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(int index) throws IOException {
|
||||
synchronized (indicesAccessLock) {
|
||||
long uid = getIndices().getLong(index);
|
||||
@ -29,6 +29,7 @@ public abstract class StrangeDbList<T> extends EnhancedObject {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(T value) throws IOException {
|
||||
long uid = databaseTools.getObjectsIO().newNullObject();
|
||||
synchronized (indicesAccessLock) {
|
||||
@ -37,13 +38,16 @@ public abstract class StrangeDbList<T> extends EnhancedObject {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(int index, T value) throws IOException {
|
||||
synchronized (indicesAccessLock) {
|
||||
long uid = getIndices().getLong(index);
|
||||
writeItemToDisk(uid, value);
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
set(index, value);
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(int index, T value) throws IOException {
|
||||
long uid = databaseTools.getObjectsIO().newNullObject();
|
||||
synchronized (indicesAccessLock) {
|
||||
@ -52,6 +56,7 @@ public abstract class StrangeDbList<T> extends EnhancedObject {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, T value) throws IOException {
|
||||
long uid = databaseTools.getObjectsIO().newNullObject();
|
||||
synchronized (indicesAccessLock) {
|
||||
@ -88,7 +93,7 @@ public abstract class StrangeDbList<T> extends EnhancedObject {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringJoiner(", ", StrangeDbList.class.getSimpleName() + "[", "]")
|
||||
return new StringJoiner(", ", StrangeDbList.class.getSimpleName() + "[", "]")
|
||||
.add(getIndices().size() + " items")
|
||||
.toString();
|
||||
}
|
||||
|
@ -0,0 +1,5 @@
|
||||
package it.cavallium.strangedb.java.objects.lists;
|
||||
|
||||
public interface ValueOperation<T> {
|
||||
public boolean evaluate(Object value);
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
package it.cavallium.strangedb.java.objects.lists;
|
||||
|
||||
import it.cavallium.strangedb.java.annotations.DbField;
|
||||
import it.cavallium.strangedb.java.annotations.DbPrimitiveField;
|
||||
import it.cavallium.strangedb.java.annotations.DbProperty;
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||
import org.apache.commons.lang3.reflect.MethodUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ValuePointer {
|
||||
|
||||
private static ValuePointer base = new ValuePointer(new int[0], new ValueType[0]);
|
||||
|
||||
private final int[] pathNumbers;
|
||||
private final ValueType[] pathTypes;
|
||||
|
||||
private ValuePointer(int[] pathNumbers, ValueType[] pathTypes) {
|
||||
this.pathNumbers = pathNumbers;
|
||||
this.pathTypes = pathTypes;
|
||||
}
|
||||
|
||||
public static <T extends EnhancedObject> ValuePointer ofField(Class<T> parentType, String field) {
|
||||
return base.field(parentType, field);
|
||||
}
|
||||
|
||||
public static <T extends EnhancedObject> ValuePointer ofProp(Class<T> parentType, String property) {
|
||||
return base.prop(parentType, property);
|
||||
}
|
||||
public static <T extends EnhancedObject> ValuePointer ofPrimitiveField(Class<T> parentType, String primitiveFieldName) {
|
||||
return base.primitiveField(parentType, primitiveFieldName);
|
||||
}
|
||||
|
||||
public <T extends EnhancedObject> ValuePointer prop(Class<T> parentType, String propertyName) {
|
||||
|
||||
ValueType[] newPathTypes = append(this.pathTypes, ValueType.FIELD);
|
||||
|
||||
Method[] methods = MethodUtils.getMethodsWithAnnotation(parentType, DbProperty.class);
|
||||
DbProperty dbProperty = null;
|
||||
for (Method method : methods) {
|
||||
DbProperty annotation = method.getAnnotation(DbProperty.class);
|
||||
if (annotation.name().equals(propertyName)) {
|
||||
dbProperty = annotation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dbProperty == null) {
|
||||
throw new IllegalArgumentException("Property '" + propertyName + "' not found in class " + parentType.getSimpleName());
|
||||
}
|
||||
|
||||
int[] newPathNumbers = append(this.pathNumbers, dbProperty.id());
|
||||
return new ValuePointer(newPathNumbers, newPathTypes);
|
||||
}
|
||||
|
||||
public <T extends EnhancedObject> ValuePointer field(Class<T> parentType, String fieldName) {
|
||||
ValueType[] newPathTypes = append(this.pathTypes, ValueType.FIELD);
|
||||
|
||||
Field[] fields = FieldUtils.getFieldsWithAnnotation(parentType, DbField.class);
|
||||
DbField dbField = null;
|
||||
for (Field field : fields) {
|
||||
DbField annotation = field.getAnnotation(DbField.class);
|
||||
if (annotation.name().equals(fieldName)) {
|
||||
dbField = annotation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dbField == null) {
|
||||
throw new IllegalArgumentException("Field '" + fieldName + "' not found in class " + parentType.getSimpleName());
|
||||
}
|
||||
|
||||
int[] newPathNumbers = append(this.pathNumbers, dbField.id());
|
||||
return new ValuePointer(newPathNumbers, newPathTypes);
|
||||
}
|
||||
|
||||
public <T extends EnhancedObject> ValuePointer primitiveField(Class<T> parentType, String primitiveFieldName) {
|
||||
ValueType[] newPathTypes = append(this.pathTypes, ValueType.PRIMITIVE_FIELD);
|
||||
|
||||
Field[] fields = FieldUtils.getFieldsWithAnnotation(parentType, DbPrimitiveField.class);
|
||||
DbPrimitiveField dbField = null;
|
||||
for (Field field : fields) {
|
||||
DbPrimitiveField annotation = field.getAnnotation(DbPrimitiveField.class);
|
||||
if (annotation.name().equals(primitiveFieldName)) {
|
||||
dbField = annotation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dbField == null) {
|
||||
throw new IllegalArgumentException("Field '" + primitiveFieldName + "' not found in class " + parentType.getSimpleName());
|
||||
}
|
||||
|
||||
int[] newPathNumbers = append(this.pathNumbers, dbField.id());
|
||||
return new ValuePointer(newPathNumbers, newPathTypes);
|
||||
}
|
||||
|
||||
public ValuePointer at(int index) {
|
||||
if (index >= pathNumbers.length) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (index == pathNumbers.length - 1) {
|
||||
return this;
|
||||
}
|
||||
return new ValuePointer(Arrays.copyOf(this.pathNumbers, index + 1), Arrays.copyOf(this.pathTypes, index + 1));
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.pathNumbers.length;
|
||||
}
|
||||
|
||||
public boolean hasPrevious() {
|
||||
return pathNumbers.length > 0;
|
||||
}
|
||||
|
||||
public ValuePointer previous() {
|
||||
return at(pathNumbers.length - 2);
|
||||
}
|
||||
|
||||
private static int[] append(int[] array, int value) {
|
||||
int[] newArray = Arrays.copyOf(array, array.length + 1);
|
||||
newArray[array.length] = value;
|
||||
return newArray;
|
||||
}
|
||||
|
||||
private static <T> T[] append(T[] array, T value) {
|
||||
T[] newArray = Arrays.copyOf(array, array.length + 1);
|
||||
newArray[array.length] = value;
|
||||
return newArray;
|
||||
}
|
||||
|
||||
public int getPathNumber() {
|
||||
return pathNumbers[pathNumbers.length - 1];
|
||||
}
|
||||
|
||||
public ValueType getPathType() {
|
||||
return pathTypes[pathTypes.length - 1];
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package it.cavallium.strangedb.java.objects.lists;
|
||||
|
||||
public enum ValueType {
|
||||
PROPERTY,
|
||||
FIELD,
|
||||
PRIMITIVE_FIELD
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package it.cavallium.strangedb.java.objects.lists.operations;
|
||||
|
||||
import it.cavallium.strangedb.java.objects.lists.KMP;
|
||||
import it.cavallium.strangedb.java.objects.lists.ValueOperation;
|
||||
|
||||
public class Contains<T extends CharSequence> implements ValueOperation<T> {
|
||||
|
||||
private final T containsValue;
|
||||
|
||||
private Contains(T containsValue) {
|
||||
this.containsValue = containsValue;
|
||||
}
|
||||
|
||||
public static <T extends CharSequence> Contains<T> containsValue(T value) {
|
||||
return new Contains<T>(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean evaluate(Object value) {
|
||||
if (value instanceof CharSequence) {
|
||||
return KMP.KMP((CharSequence) value, containsValue) != -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package it.cavallium.strangedb.java.objects.lists.operations;
|
||||
|
||||
import it.cavallium.strangedb.java.objects.lists.KMP;
|
||||
import it.cavallium.strangedb.java.objects.lists.ValueOperation;
|
||||
|
||||
public class ContainsIgnoreCase implements ValueOperation<String> {
|
||||
|
||||
private final String containsValue;
|
||||
|
||||
private ContainsIgnoreCase(String containsValue) {
|
||||
this.containsValue = containsValue.toLowerCase();
|
||||
}
|
||||
|
||||
public static ContainsIgnoreCase containsValue(String value) {
|
||||
return new ContainsIgnoreCase(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean evaluate(Object value) {
|
||||
if (value instanceof String) {
|
||||
return KMP.KMP(((String) value).toLowerCase(), containsValue) != -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package it.cavallium.strangedb.java.objects.lists.operations;
|
||||
|
||||
import it.cavallium.strangedb.java.objects.lists.ValueOperation;
|
||||
|
||||
public class Equals<T> implements ValueOperation<T> {
|
||||
|
||||
private final T equalToValue;
|
||||
|
||||
private Equals(T equalToValue) {
|
||||
this.equalToValue = equalToValue;
|
||||
}
|
||||
|
||||
public static <T> Equals<T> to(T value) {
|
||||
return new Equals<T>(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean evaluate(Object value) {
|
||||
return equalToValue.equals(value);
|
||||
}
|
||||
}
|
@ -1,14 +1,11 @@
|
||||
package it.cavallium.strangedb.tests;
|
||||
|
||||
import it.cavallium.strangedb.java.annotations.*;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||
import it.cavallium.strangedb.java.annotations.DbField;
|
||||
import it.cavallium.strangedb.java.annotations.DbPropertyGetter;
|
||||
import it.cavallium.strangedb.java.annotations.DbPropertySetter;
|
||||
import it.cavallium.strangedb.utils.NTestUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -20,7 +17,7 @@ public class Clean {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
db = NTestUtils.wrapDb().create((db) -> {
|
||||
root = db.get().loadRoot(RootTwoClasses.class, RootTwoClasses::new);
|
||||
root = db.get().loadRoot(RootTwoClasses::new);
|
||||
});
|
||||
root.class1 = new NTestUtils.RootClass(db.get());
|
||||
db.setRootClassValues(root.class1);
|
||||
@ -40,7 +37,7 @@ public class Clean {
|
||||
db.testRootClassValues(root.getClass4());
|
||||
db.get().closeAndClean();
|
||||
db = NTestUtils.wrapDb().create((db) -> {
|
||||
root = db.get().loadRoot(RootTwoClasses.class, RootTwoClasses::new);
|
||||
root = db.get().loadRoot(RootTwoClasses::new);
|
||||
});
|
||||
}
|
||||
|
||||
@ -65,22 +62,26 @@ public class Clean {
|
||||
super(databaseTools);
|
||||
}
|
||||
|
||||
@DbPropertyGetter(id = 0, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbProperty(id = 0, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbPropertyGetter
|
||||
public NTestUtils.RootClass getClass3() {
|
||||
return getProperty();
|
||||
}
|
||||
|
||||
@DbPropertySetter(id = 0, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbProperty(id = 0, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbPropertySetter
|
||||
public void setClass3(NTestUtils.RootClass value) {
|
||||
setProperty(value);
|
||||
}
|
||||
|
||||
@DbPropertyGetter(id = 1, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbProperty(id = 1, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbPropertyGetter
|
||||
public NTestUtils.RootClass getClass4() {
|
||||
return getProperty();
|
||||
}
|
||||
|
||||
@DbPropertySetter(id = 1, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbProperty(id = 1, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbPropertySetter
|
||||
public void setClass4(NTestUtils.RootClass value) {
|
||||
setProperty(value);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class EnhancedClassUpdate {
|
||||
path2 = Files.createTempFile("db-tests-blocks-", ".db");
|
||||
path3 = Files.createTempFile("db-tests-references-", ".db");
|
||||
db = new DatabaseJava(path1, path2, path3);
|
||||
OldClass root = db.loadRoot(OldClass.class, OldClass::new);
|
||||
OldClass root = db.loadRoot(OldClass::new);
|
||||
root.field1 = "Abc";
|
||||
root.field2 = 12;
|
||||
root.field4 = 13;
|
||||
@ -35,7 +35,7 @@ public class EnhancedClassUpdate {
|
||||
@Test
|
||||
public void shouldUpdateClass() throws IOException {
|
||||
db = new DatabaseJava(path1, path2, path3);
|
||||
V2Class root = db.loadRoot(V2Class.class, V2Class::new);
|
||||
V2Class root = db.loadRoot(V2Class::new);
|
||||
assertEquals(root.field4, "Abc");
|
||||
assertEquals(root.field2, 12);
|
||||
assertEquals(root.field1, 13L);
|
||||
|
@ -0,0 +1,44 @@
|
||||
package it.cavallium.strangedb.tests;
|
||||
|
||||
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||
import it.cavallium.strangedb.java.annotations.DbField;
|
||||
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||
import it.cavallium.strangedb.java.objects.lists.EnhancedObjectStrangeDbList;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Random;
|
||||
|
||||
public class ListContainer extends EnhancedObject {
|
||||
|
||||
@DbField(id = 0, type = DbDataType.ENHANCED_OBJECT)
|
||||
public EnhancedObjectStrangeDbList<User> usersList;
|
||||
|
||||
public ListContainer() {
|
||||
}
|
||||
|
||||
public ListContainer(IDatabaseTools databaseTools, int count) throws IOException {
|
||||
super(databaseTools);
|
||||
this.usersList = new EnhancedObjectStrangeDbList<>(databaseTools, User.class);
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < count; i++) {
|
||||
User usr;
|
||||
int randomInt = random.nextInt(2);
|
||||
switch (randomInt) {
|
||||
case 0:
|
||||
usr = new User(databaseTools, "Rossi" + count + "Mario"+count, "the" + count + "_mariorossi99", "Long long big " + count + " giant bio mario rossi 99 abcdefghijklmnopqrstuvwxyz");
|
||||
break;
|
||||
case 1:
|
||||
usr = new User(databaseTools, QueryTests.constantFirstName, QueryTests.constantUsername, QueryTests.constantBio);
|
||||
break;
|
||||
case 2:
|
||||
usr = new User(databaseTools, QueryTests.constantFirstName, "b" + count + "a", QueryTests.constantBio);
|
||||
break;
|
||||
default:
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
this.usersList.add(usr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +1,7 @@
|
||||
package it.cavallium.strangedb.tests;
|
||||
|
||||
import it.cavallium.strangedb.java.annotations.*;
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||
import it.cavallium.strangedb.java.annotations.DbField;
|
||||
import it.cavallium.strangedb.java.annotations.DbPropertyGetter;
|
||||
import it.cavallium.strangedb.java.annotations.DbPropertySetter;
|
||||
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||
import it.cavallium.strangedb.utils.NTestUtils;
|
||||
import org.junit.After;
|
||||
@ -20,7 +17,7 @@ public class MultipleEnhancedObjects {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
db = NTestUtils.wrapDb().create((db) -> {
|
||||
root = db.get().loadRoot(RootTwoClasses.class, RootTwoClasses::new);
|
||||
root = db.get().loadRoot(RootTwoClasses::new);
|
||||
});
|
||||
root.class1 = new NTestUtils.RootClass(db.get());
|
||||
db.setRootClassValues(root.class1);
|
||||
@ -62,22 +59,26 @@ public class MultipleEnhancedObjects {
|
||||
super(databaseTools);
|
||||
}
|
||||
|
||||
@DbPropertyGetter(id = 0, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbProperty(id = 0, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbPropertyGetter
|
||||
public NTestUtils.RootClass getClass3() {
|
||||
return getProperty();
|
||||
}
|
||||
|
||||
@DbPropertySetter(id = 0, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbProperty(id = 0, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbPropertySetter
|
||||
public void setClass3(NTestUtils.RootClass value) {
|
||||
setProperty(value);
|
||||
}
|
||||
|
||||
@DbPropertyGetter(id = 1, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbProperty(id = 1, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbPropertyGetter
|
||||
public NTestUtils.RootClass getClass4() {
|
||||
return getProperty();
|
||||
}
|
||||
|
||||
@DbPropertySetter(id = 1, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbProperty(id = 1, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbPropertySetter
|
||||
public void setClass4(NTestUtils.RootClass value) {
|
||||
setProperty(value);
|
||||
}
|
||||
|
139
src/test/java/it/cavallium/strangedb/tests/ObjectListTests.java
Normal file
139
src/test/java/it/cavallium/strangedb/tests/ObjectListTests.java
Normal file
@ -0,0 +1,139 @@
|
||||
package it.cavallium.strangedb.tests;
|
||||
|
||||
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||
import it.cavallium.strangedb.java.annotations.DbField;
|
||||
import it.cavallium.strangedb.java.database.DatabaseJava;
|
||||
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||
import it.cavallium.strangedb.java.objects.lists.EnhancedObjectStrangeDbList;
|
||||
import it.cavallium.strangedb.java.objects.lists.ObjectStrangeDbList;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class ObjectListTests {
|
||||
|
||||
private Path path1;
|
||||
private Path path2;
|
||||
private Path path3;
|
||||
private DatabaseJava db;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
path1 = Files.createTempFile("db-tests-data-", ".db");
|
||||
path2 = Files.createTempFile("db-tests-blocks-", ".db");
|
||||
path3 = Files.createTempFile("db-tests-references-", ".db");
|
||||
db = new DatabaseJava(path1, path2, path3);
|
||||
ListsRoot root = db.loadRoot(ListsRoot::new);
|
||||
for (int i = 0; i < 5000; i++) {
|
||||
root.objectList.add(new ObjectItem(i));
|
||||
root.enhancedObjectList.add(new EnhancedObjectItem(db, i));
|
||||
}
|
||||
for (int i = 0; i < 5000; i++) {
|
||||
if (i % 10 == 0) {
|
||||
root.objectList.update(i, new ObjectItem(i));
|
||||
root.enhancedObjectList.update(i, new EnhancedObjectItem(db, i));
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 5000; i++) {
|
||||
if (i % 11 == 0) {
|
||||
root.objectList.set(i, new ObjectItem(i));
|
||||
root.enhancedObjectList.set(i, new EnhancedObjectItem(db, i));
|
||||
}
|
||||
}
|
||||
for (int i = 5000; i < 6000; i++) {
|
||||
root.objectList.add(new ObjectItem(0));
|
||||
root.enhancedObjectList.add(i, new EnhancedObjectItem(db, 0));
|
||||
}
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdateClass() throws IOException {
|
||||
db = new DatabaseJava(path1, path2, path3);
|
||||
ListsRoot root = db.loadRoot(ListsRoot::new);
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
for (int i = 0; i < 5000; i++) {
|
||||
String val = root.objectList.get(i).value;
|
||||
assertEquals(val, "test_" + i);
|
||||
val = root.enhancedObjectList.get(i).value;
|
||||
assertEquals(val, "test_" + i);
|
||||
}
|
||||
for (int i = 5000; i < 6000; i++) {
|
||||
assertEquals(root.objectList.get(i).value, "test_" + 0);
|
||||
assertEquals(root.enhancedObjectList.get(i).value, "test_" + 0);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
try {
|
||||
Thread.sleep(10000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
db.close();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
Files.deleteIfExists(path1);
|
||||
Files.deleteIfExists(path2);
|
||||
Files.deleteIfExists(path3);
|
||||
}
|
||||
|
||||
public static class ListsRoot extends EnhancedObject {
|
||||
|
||||
@DbField(id = 0,name = "objectList", type = DbDataType.ENHANCED_OBJECT)
|
||||
public ObjectStrangeDbList<ObjectItem> objectList;
|
||||
@DbField(id = 1,name = "enhancedObjectList", type = DbDataType.ENHANCED_OBJECT)
|
||||
public EnhancedObjectStrangeDbList<EnhancedObjectItem> enhancedObjectList;
|
||||
|
||||
@Deprecated
|
||||
public ListsRoot() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public ListsRoot(IDatabaseTools tools) throws IOException {
|
||||
super(tools);
|
||||
objectList = new ObjectStrangeDbList<>(tools);
|
||||
enhancedObjectList = new EnhancedObjectStrangeDbList<>(tools, EnhancedObjectItem.class);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ObjectItem {
|
||||
private String value;
|
||||
|
||||
public ObjectItem() {
|
||||
|
||||
}
|
||||
|
||||
private ObjectItem(int i) {
|
||||
this.value = "test_" + i;
|
||||
}
|
||||
}
|
||||
|
||||
public static class EnhancedObjectItem extends EnhancedObject {
|
||||
@DbField(id = 0, type = DbDataType.OBJECT, name = "value")
|
||||
private String value;
|
||||
|
||||
@Deprecated
|
||||
public EnhancedObjectItem() {
|
||||
|
||||
}
|
||||
|
||||
public EnhancedObjectItem(IDatabaseTools tools, int i) throws IOException {
|
||||
super(tools);
|
||||
this.value = "test_" + i;
|
||||
}
|
||||
}
|
||||
}
|
@ -49,16 +49,16 @@ public class Performance {
|
||||
System.out.println("Test name Total Time | Time at 1 Time at 10 Time at 100 Time at 1K Time at 10K");
|
||||
System.out.println("-------------------------------------------------------+-----------------------------------------------------------------");
|
||||
testS("DatabaseCore creation", 3000, Performance::deleteDb, Performance::generateDb, () -> {});
|
||||
testS("DatabaseCore root creation", 3000, Performance::regenDb, () -> db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new), () -> {});
|
||||
testS("DatabaseCore root creation", 3000, Performance::regenDb, () -> db.loadRoot(PreloadedListContainer::new), () -> {});
|
||||
final VariableWrapper<PreloadedListContainer> preloadedListContainer = new VariableWrapper<>(null);
|
||||
final VariableWrapper<SimpleEnhancedObject> simpleEnhancedObjectContainer = new VariableWrapper<>(null);
|
||||
testS("ObjectStrangeDbList<Int> creation", 3000, () -> {
|
||||
regenDb();
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new);
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
|
||||
}, () -> preloadedListContainer.var.list = new ObjectStrangeDbList<>(db), () -> {});
|
||||
testS("ObjectStrangeDbList<Int>: Filling with 1000 items", 100, () -> {
|
||||
regenDb();
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new);
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
|
||||
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
|
||||
}, () -> {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
@ -67,7 +67,7 @@ public class Performance {
|
||||
}, () -> {});
|
||||
testS("ObjectStrangeDbList<EnhancedObject>: Filling with 1000 items", 100, () -> {
|
||||
regenDb();
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new);
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
|
||||
preloadedListContainer.var.listOfEnhancedObj = new EnhancedObjectStrangeDbList<>(db, SimpleEnhancedObject.class);
|
||||
simpleEnhancedObjectContainer.var = new SimpleEnhancedObject(db);
|
||||
simpleEnhancedObjectContainer.var.integerNumber = 10;
|
||||
@ -83,7 +83,7 @@ public class Performance {
|
||||
}, () -> {});
|
||||
testS("ObjectStrangeDbList<Int>: Filling with 10000 items", 10, () -> {
|
||||
regenDb();
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new);
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
|
||||
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
|
||||
}, () -> {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
@ -92,7 +92,7 @@ public class Performance {
|
||||
}, () -> {});
|
||||
testS("ObjectStrangeDbList<Int>: Filling with 100000 items", 1, () -> {
|
||||
regenDb();
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new);
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
|
||||
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
|
||||
}, () -> {
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
@ -101,7 +101,7 @@ public class Performance {
|
||||
}, () -> {});
|
||||
testS("ObjectStrangeDbList<Int>: Loading 1000 items", 100, () -> {
|
||||
regenDb();
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new);
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
|
||||
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
preloadedListContainer.var.list.add(1000);
|
||||
@ -113,7 +113,7 @@ public class Performance {
|
||||
}, () -> {});
|
||||
testS("ObjectStrangeDbList<EnhancedObject>: Loading with 1000 items", 100, () -> {
|
||||
regenDb();
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new);
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
|
||||
preloadedListContainer.var.listOfEnhancedObj = new EnhancedObjectStrangeDbList<>(db, SimpleEnhancedObject.class);
|
||||
simpleEnhancedObjectContainer.var = new SimpleEnhancedObject(db);
|
||||
simpleEnhancedObjectContainer.var.integerNumber = 10;
|
||||
@ -132,7 +132,7 @@ public class Performance {
|
||||
}, () -> {});
|
||||
testS("ObjectStrangeDbList<Int>: Loading 10000 items", 10, () -> {
|
||||
regenDb();
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new);
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
|
||||
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
preloadedListContainer.var.list.add(1000);
|
||||
@ -144,7 +144,7 @@ public class Performance {
|
||||
}, () -> {});
|
||||
testS("ObjectStrangeDbList<Int>: getLast() with 1000 items", 100, () -> {
|
||||
regenDb();
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new);
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
|
||||
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
preloadedListContainer.var.list.add(1000);
|
||||
@ -154,7 +154,7 @@ public class Performance {
|
||||
}, () -> {});
|
||||
testS("ObjectStrangeDbList<EnhancedObject>: getLast() with 1000 items", 100, () -> {
|
||||
regenDb();
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new);
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
|
||||
preloadedListContainer.var.listOfEnhancedObj = new EnhancedObjectStrangeDbList<>(db, SimpleEnhancedObject.class);
|
||||
simpleEnhancedObjectContainer.var = new SimpleEnhancedObject(db);
|
||||
simpleEnhancedObjectContainer.var.integerNumber = 10;
|
||||
@ -171,7 +171,7 @@ public class Performance {
|
||||
}, () -> {});
|
||||
testS("ObjectStrangeDbList<Int>: size() with 1000 items", 100, () -> {
|
||||
regenDb();
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer.class, PreloadedListContainer::new);
|
||||
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
|
||||
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
preloadedListContainer.var.list.add(1000);
|
||||
@ -318,12 +318,14 @@ public class Performance {
|
||||
}
|
||||
|
||||
|
||||
@DbPropertyGetter(id = 0, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbProperty(id = 0, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbPropertyGetter()
|
||||
public ObjectStrangeDbList<Integer> getList() {
|
||||
return getProperty();
|
||||
}
|
||||
|
||||
@DbPropertySetter(id = 1, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbProperty(id = 1, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbPropertySetter()
|
||||
public void setList(ObjectStrangeDbList<Integer> list) {
|
||||
setProperty(list);
|
||||
}
|
||||
|
59
src/test/java/it/cavallium/strangedb/tests/QueryTests.java
Normal file
59
src/test/java/it/cavallium/strangedb/tests/QueryTests.java
Normal file
@ -0,0 +1,59 @@
|
||||
package it.cavallium.strangedb.tests;
|
||||
|
||||
import it.cavallium.strangedb.java.database.DatabaseJava;
|
||||
import it.cavallium.strangedb.java.objects.lists.ListQuery;
|
||||
import it.cavallium.strangedb.java.objects.lists.ValuePointer;
|
||||
import it.cavallium.strangedb.java.objects.lists.operations.Equals;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
public class QueryTests {
|
||||
|
||||
public static final String constantFirstName = "Jesus christ this is a very strange first name";
|
||||
public static final String constantUsername = "is this an username?";
|
||||
public static final String constantBio = "and is this a bio??? Are you mad?";
|
||||
private Path path1;
|
||||
private Path path2;
|
||||
private Path path3;
|
||||
private DatabaseJava db;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
path1 = Files.createTempFile("db-tests-data-", ".db");
|
||||
path2 = Files.createTempFile("db-tests-blocks-", ".db");
|
||||
path3 = Files.createTempFile("db-tests-references-", ".db");
|
||||
db = new DatabaseJava(path1, path2, path3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateListAndQuery() throws IOException {
|
||||
ListContainer root = db.loadRoot((db) -> new ListContainer(db, 1000));
|
||||
ListQuery query = ListQuery.create(ValuePointer.ofField(User.class, "firstName"), Equals.to(constantFirstName))
|
||||
.and(ValuePointer.ofField(User.class, "username"), Equals.to(constantUsername))
|
||||
.and(ValuePointer.ofField(User.class, "fullInfo").field(UserFullInfo.class, "bio"), Equals.to(constantBio));
|
||||
long time1 = System.currentTimeMillis();
|
||||
ArrayList<User> elements = root.usersList.query(query).asList();
|
||||
System.out.println("Time elapsed: " + (System.currentTimeMillis() - time1));
|
||||
System.out.println("Found " + elements.size() + " elements. First 5 items:");
|
||||
assertNotEquals(elements.size(), 0);
|
||||
for (int i = 0; i < (elements.size() > 10 ? 10 : elements.size()); i++) {
|
||||
System.out.println(elements.get(i));
|
||||
}
|
||||
db.close();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
Files.deleteIfExists(path1);
|
||||
Files.deleteIfExists(path2);
|
||||
Files.deleteIfExists(path3);
|
||||
}
|
||||
}
|
40
src/test/java/it/cavallium/strangedb/tests/User.java
Normal file
40
src/test/java/it/cavallium/strangedb/tests/User.java
Normal file
@ -0,0 +1,40 @@
|
||||
package it.cavallium.strangedb.tests;
|
||||
|
||||
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||
import it.cavallium.strangedb.java.annotations.DbField;
|
||||
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class User extends EnhancedObject {
|
||||
|
||||
@DbField(id = 0, name = "firstName")
|
||||
public String firstName;
|
||||
|
||||
@DbField(id = 1, name = "username")
|
||||
public String username;
|
||||
|
||||
@DbField(id = 2, type = DbDataType.ENHANCED_OBJECT, name = "fullInfo")
|
||||
public UserFullInfo fullInfo;
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
public User(IDatabaseTools databaseTools, String firstName, String username, String bio) throws IOException {
|
||||
super(databaseTools);
|
||||
this.firstName = firstName;
|
||||
this.username = username;
|
||||
this.fullInfo = new UserFullInfo(databaseTools, bio);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringJoiner(", ", User.class.getSimpleName() + "[", "]")
|
||||
.add("firstName='" + firstName + "'")
|
||||
.add("username='" + username + "'")
|
||||
.add("fullInfo=" + fullInfo)
|
||||
.toString();
|
||||
}
|
||||
}
|
31
src/test/java/it/cavallium/strangedb/tests/UserFullInfo.java
Normal file
31
src/test/java/it/cavallium/strangedb/tests/UserFullInfo.java
Normal file
@ -0,0 +1,31 @@
|
||||
package it.cavallium.strangedb.tests;
|
||||
|
||||
import it.cavallium.strangedb.java.annotations.DbDataType;
|
||||
import it.cavallium.strangedb.java.annotations.DbField;
|
||||
import it.cavallium.strangedb.java.database.IDatabaseTools;
|
||||
import it.cavallium.strangedb.java.objects.EnhancedObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class UserFullInfo extends EnhancedObject {
|
||||
|
||||
@DbField(id = 0, name = "bio")
|
||||
public String bio;
|
||||
|
||||
public UserFullInfo() {
|
||||
|
||||
}
|
||||
|
||||
public UserFullInfo(IDatabaseTools databaseTools, String bio) throws IOException {
|
||||
super(databaseTools);
|
||||
this.bio = bio;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringJoiner(", ", UserFullInfo.class.getSimpleName() + "[", "]")
|
||||
.add("bio='" + bio + "'")
|
||||
.toString();
|
||||
}
|
||||
}
|
@ -247,32 +247,38 @@ public class NTestUtils {
|
||||
super(databaseTools);
|
||||
}
|
||||
|
||||
@DbPropertyGetter(id = 0, type = DbDataType.OBJECT)
|
||||
@DbProperty(id = 0, type = DbDataType.OBJECT)
|
||||
@DbPropertyGetter
|
||||
public String get7() {
|
||||
return getProperty();
|
||||
}
|
||||
|
||||
@DbPropertyGetter(id = 1, type = DbDataType.REFERENCES_LIST)
|
||||
@DbProperty(id = 1, type = DbDataType.REFERENCES_LIST)
|
||||
@DbPropertyGetter
|
||||
public LongArrayList get8() {
|
||||
return getProperty();
|
||||
}
|
||||
|
||||
@DbPropertyGetter(id = 2, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbProperty(id = 2, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbPropertyGetter
|
||||
public NSimplestClass get9() {
|
||||
return getProperty();
|
||||
}
|
||||
|
||||
@DbPropertySetter(id = 0, type = DbDataType.OBJECT)
|
||||
@DbProperty(id = 0, type = DbDataType.OBJECT)
|
||||
@DbPropertySetter
|
||||
public void set7(String val) {
|
||||
setProperty(val);
|
||||
}
|
||||
|
||||
@DbPropertySetter(id = 1, type = DbDataType.REFERENCES_LIST)
|
||||
@DbProperty(id = 1, type = DbDataType.REFERENCES_LIST)
|
||||
@DbPropertySetter
|
||||
public void set8(LongArrayList val) {
|
||||
setProperty(val);
|
||||
}
|
||||
|
||||
@DbPropertySetter(id = 2, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbProperty(id = 2, type = DbDataType.ENHANCED_OBJECT)
|
||||
@DbPropertySetter
|
||||
public void set9(NSimplestClass val) {
|
||||
setProperty(val);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user