Skip to content

Commit

Permalink
add nested indexes
Browse files Browse the repository at this point in the history
  • Loading branch information
firestar committed Nov 29, 2023
1 parent aeca990 commit 401926f
Show file tree
Hide file tree
Showing 19 changed files with 210 additions and 229 deletions.
149 changes: 18 additions & 131 deletions library/src/main/java/com/nucleocore/library/NucleoDB.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
package com.nucleocore.library;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.collect.Queues;
import com.nucleocore.library.database.modifications.Create;
import com.nucleocore.library.database.tables.annotation.Conn;
import com.nucleocore.library.database.tables.connection.Connection;
import com.nucleocore.library.database.tables.connection.ConnectionConfig;
import com.nucleocore.library.database.tables.connection.ConnectionHandler;
import com.nucleocore.library.database.tables.annotation.Index;
import com.nucleocore.library.database.tables.annotation.Relationship;
import com.nucleocore.library.database.tables.annotation.Relationships;
import com.nucleocore.library.database.tables.annotation.Table;
import com.nucleocore.library.database.utils.TreeSetExt;
import com.nucleocore.library.database.utils.exceptions.IncorrectDataEntryClassException;
import com.nucleocore.library.database.utils.exceptions.MissingDataEntryConstructorsException;
import com.nucleocore.library.database.utils.index.TreeIndex;
import com.nucleocore.library.database.utils.sql.SQLHandler;
import com.nucleocore.library.database.tables.table.DataTable;
import com.nucleocore.library.database.tables.table.DataTableBuilder;
Expand All @@ -30,13 +24,14 @@
import org.reflections.Reflections;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.logging.Logger;

import static com.nucleocore.library.utils.field.FieldFinder.getAllAnnotatedFields;

public class NucleoDB{
private static Logger logger = Logger.getLogger(DataTable.class.getName());
private TreeMap<String, DataTable> tables = new TreeMap<>();
Expand Down Expand Up @@ -136,6 +131,9 @@ private void startTables(String bootstrap, String[] packagesToScan, DBType dbTyp
for (Class<?> type : tableTypes) {
Table tableAnnotation = type.getAnnotation(Table.class);
String tableName = tableAnnotation.tableName();
if(tableName.isEmpty()){
tableName = type.getName().toLowerCase();
}
Class dataEntryClass = tableAnnotation.dataEntryClass();
if(!DataEntry.class.isAssignableFrom(dataEntryClass)){
throw new IncorrectDataEntryClassException(String.format("%s does not extend DataEntry", dataEntryClass.getName()));
Expand All @@ -149,7 +147,9 @@ private void startTables(String bootstrap, String[] packagesToScan, DBType dbTyp
} catch (NoSuchMethodException e) {
throw new MissingDataEntryConstructorsException(String.format("%s does not have all DataEntry constructors overridden!", dataEntryClass.getName()), e);
}
processTableClass(tableName, indexes, type);

indexes.put(tableName, processIndexListForClass(type));

switch (dbType) {
case ALL -> tables.add(launchTable(bootstrap, tableName, dataEntryClass, type, new StartupRun(){
public void run(DataTable table) {
Expand All @@ -169,7 +169,7 @@ public void run(DataTable table) {
}
}
tables.stream().forEach(table -> {
table.setIndexes(indexes.get(table.getConfig().getTable()).toArray(new String[0]));
table.addIndexes(indexes.get(table.getConfig().getTable()));
table.build();
});
try {
Expand All @@ -181,130 +181,17 @@ public void run(DataTable table) {
}
}

public Set<DataEntry> getAllRelated(DataEntry dataEntry) {
Set<DataEntry> set = new TreeSetExt<>();
if (dataEntry.getData().getClass().isAnnotationPresent(Table.class)) {
Table localTable = dataEntry.getData().getClass().getAnnotation(Table.class);
String localTableName = localTable.tableName();
for (Relationship relationship : getRelationships(dataEntry.getData().getClass())) {
getRelatedByRelationship(dataEntry, set, localTableName, relationship);
}
}
return set;
}

public Set<DataEntry> getRelated(DataEntry dataEntry, Class clazz) {
Set<DataEntry> set = new TreeSetExt<>();
if (dataEntry.getData().getClass().isAnnotationPresent(Table.class)) {
Table localTable = dataEntry.getData().getClass().getAnnotation(Table.class);
String localTableName = localTable.tableName();
for (Relationship relationship : getRelationships(dataEntry.getData().getClass())) {
if (relationship.clazz() == clazz) {
getRelatedByRelationship(dataEntry, set, localTableName, relationship);
} else {
//logger.info("Relation ignored");
}
}
}
return set;
}

public Set<DataEntry> getRelatedRemote(DataEntry dataEntry, Class clazz, String index) {
Set<DataEntry> set = new TreeSetExt<>();
if (dataEntry.getData().getClass().isAnnotationPresent(Table.class)) {
Table localTable = dataEntry.getData().getClass().getAnnotation(Table.class);
String localTableName = localTable.tableName();
for (Relationship relationship : getRelationships(dataEntry.getData().getClass())) {
if (relationship.clazz() == clazz && index.equals(relationship.remoteKey())) {
getRelatedByRelationship(dataEntry, set, localTableName, relationship);
} else {
//logger.info("Relation ignored");
}
}
}
return set;
}

public Set<DataEntry> getRelatedLocal(DataEntry dataEntry, Class clazz, String index) {
Set<DataEntry> set = new TreeSetExt<>();
if (dataEntry.getData().getClass().isAnnotationPresent(Table.class)) {
Table localTable = dataEntry.getData().getClass().getAnnotation(Table.class);
String localTableName = localTable.tableName();
for (Relationship relationship : getRelationships(dataEntry.getData().getClass())) {
if (relationship.clazz() == clazz && index.equals(relationship.localKey())) {
getRelatedByRelationship(dataEntry, set, localTableName, relationship);
} else {
//logger.info("Relation ignored");
}
}
}
return set;
}

private void getRelatedByRelationship(DataEntry dataEntry, Set<DataEntry> set, String localTableName, Relationship relationship) {
if (relationship.clazz().isAnnotationPresent(Table.class)) {
Table remoteTable = (Table) relationship.clazz().getAnnotation(Table.class);
String remoteTableName = remoteTable.tableName();
//logger.info("getting for relationship from " + localTableName + " to " + remoteTableName);
try {
//logger.info(relationship.localKey());
List<Object> values = new TreeIndex().getValues(Queues.newLinkedBlockingDeque(Arrays.asList(relationship.localKey().split("\\."))), dataEntry.getData());
if (values.size() > 0) {
for (Object value : values) {
set.addAll(this.getTable(remoteTableName).get(relationship.remoteKey(), value, null));
}
}
} catch (JsonProcessingException e) {
e.printStackTrace();
}
} else {
logger.info("Target class not a NucleoDB Table.");
}

}

private void processRelationship(String tableName, Map<String, Set<String>> indexes, Relationship relationship) {
indexes.get(tableName).add(relationship.localKey());
if (relationship.clazz().isAnnotationPresent(Table.class)) {
String tableNameRemote = ((Table) relationship.clazz().getAnnotation(Table.class)).tableName();
if (!indexes.containsKey(tableNameRemote)) {
processTableClass(tableNameRemote, indexes, relationship.clazz());
}
indexes.get(tableNameRemote).add(relationship.remoteKey());
}
}

private List<Relationship> getRelationships(Class<?> clazz) {
List<Relationship> relationships = new LinkedList<>();
if (clazz.isAnnotationPresent(Relationship.class)) {
Relationship relationship = clazz.getAnnotation(Relationship.class);
relationships.add(relationship);
}
if (clazz.isAnnotationPresent(Relationships.class)) {
Relationships relationship = clazz.getAnnotation(Relationships.class);
relationships.addAll(Arrays.stream(relationship.value()).toList());
}
return relationships;
}
private Set<String> processIndexListForClass(Class<?> clazz) {
Set<String> indexes = new TreeSet<>();

private void processTableClass(String tableName, Map<String, Set<String>> indexes, Class<?> clazz) {
if (!indexes.containsKey(tableName)) {
indexes.put(tableName, new TreeSetExt<>());
}
for (Field declaredField : clazz.getDeclaredFields()) {
if (declaredField.isAnnotationPresent(Index.class)) {
Index i = declaredField.getAnnotation(Index.class);
if (i.value().isEmpty()) {
indexes.get(tableName).addAll(Arrays.asList(declaredField.getName().toLowerCase()));
} else {
indexes.get(tableName).addAll(Arrays.asList(i.value()));
}
getAllAnnotatedFields(clazz, Index.class, "").forEach(field->{
if (field.getAnnotation().value().isEmpty()) {
indexes.add(field.getPath());
} else {
indexes.add(field.getAnnotation().value());
}
}

for (Relationship relationship : getRelationships(clazz)) {
processRelationship(tableName, indexes, relationship);
}
});
return indexes;
}

public <T> Object sql(String sqlStr) throws JSQLParserException {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.nucleocore.library.database.modifications;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.nucleocore.library.database.tables.connection.Connection;
import com.nucleocore.library.database.utils.Serializer;

import java.time.Instant;
import java.util.Map;
Expand All @@ -9,11 +11,9 @@

public class ConnectionCreate extends Modify {

private String connectionData;
private String uuid;
private String fromKey;
private String toKey;
private Instant date;
private Map<String, String> metadata = new TreeMap<>();

public long version;
public String changeUUID = UUID.randomUUID().toString();
Expand All @@ -24,22 +24,26 @@ public ConnectionCreate() {

public ConnectionCreate(Connection connection) {
this.date = connection.getDate();
this.fromKey = connection.getFromKey();
this.toKey = connection.getToKey();
this.uuid = connection.getUuid();
this.date = connection.getDate();
this.metadata = connection.getMetadata();
this.version = connection.getVersion();
try {
this.connectionData = Serializer.getObjectMapper().getOm().writeValueAsString(connection);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}

public ConnectionCreate(String changeUUID, Connection connection) {
this.changeUUID = changeUUID;
this.fromKey = connection.getFromKey();
this.toKey = connection.getToKey();
this.uuid = connection.getUuid();
this.date = connection.getDate();
this.metadata = connection.getMetadata();
this.version = connection.getVersion();
try {
this.connectionData = Serializer.getObjectMapper().getOm().writeValueAsString(connection);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}

public long getVersion() {
Expand All @@ -66,22 +70,6 @@ public void setUuid(String uuid) {
this.uuid = uuid;
}

public String getFromKey() {
return fromKey;
}

public void setFromKey(String fromKey) {
this.fromKey = fromKey;
}

public String getToKey() {
return toKey;
}

public void setToKey(String toKey) {
this.toKey = toKey;
}

public Instant getDate() {
return date;
}
Expand All @@ -90,11 +78,11 @@ public void setDate(Instant date) {
this.date = date;
}

public Map<String, String> getMetadata() {
return metadata;
public String getConnectionData() {
return connectionData;
}

public void setMetadata(Map<String, String> metadata) {
this.metadata = metadata;
public void setConnectionData(String connectionData) {
this.connectionData = connectionData;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,6 @@ public Connection(F from, T to) {
this.modified = Instant.now();
}

public Connection(ConnectionCreate connectionCreate) {
this.uuid = connectionCreate.getUuid();
this.fromKey = connectionCreate.getFromKey();
this.toKey = connectionCreate.getToKey();;
this.date = connectionCreate.getDate();
this.version = connectionCreate.getVersion();
this.metadata = new TreeMap<>(connectionCreate.getMetadata());

}

public <T> T copy(Class<T> clazz) {
ObjectMapper om = new ObjectMapper()
.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS)
Expand Down
Loading

0 comments on commit 401926f

Please sign in to comment.