ORM: Improvement about foreigh keys

This commit is contained in:
Marc Baloup 2019-01-22 15:28:48 +01:00
parent c1778634ad
commit 94138ad79a
3 changed files with 72 additions and 13 deletions

View File

@ -171,14 +171,24 @@ public abstract class SQLElement<E extends SQLElement<E>> {
+ " does not exist or is not set"); + " does not exist or is not set");
} }
public <T, F extends SQLElement<F>> F getForeignKeyTarget(SQLFKField<E, T, F> field) throws ORMException { /**
* @param <T> the type of the specified field
* @param <P> the table class of the primary key targeted by the specified foreign key field
* @return the element in the table P that his primary key correspond to the foreign key value of this element.
*/
public <T, P extends SQLElement<P>> P getReferencedEntry(SQLFKField<E, T, P> field) throws ORMException {
T fkValue = get(field); T fkValue = get(field);
if (fkValue == null) return null; if (fkValue == null) return null;
return ORM.getFirst(field.getForeignElementClass(), return ORM.getFirst(field.getForeignElementClass(),
new SQLWhereComp(field.getPrimaryField(), SQLComparator.EQ, fkValue), null); new SQLWhereComp(field.getPrimaryField(), SQLComparator.EQ, fkValue), null);
} }
public <T, S extends SQLElement<S>> SQLElementList<S> getForeignKeySources(SQLFKField<S, T, E> field, SQLOrderBy orderBy, Integer limit, Integer offset) throws ORMException { /**
* @param <T> the type of the specified field
* @param <F> the table class of the foreign key that reference a primary key of this element.
* @return all elements in the table F for which the specified foreign key value correspond to the primary key of this element.
*/
public <T, F extends SQLElement<F>> SQLElementList<F> getReferencingForeignEntries(SQLFKField<F, T, E> field, SQLOrderBy orderBy, Integer limit, Integer offset) throws ORMException {
T value = get(field.getPrimaryField()); T value = get(field.getPrimaryField());
if (value == null) return new SQLElementList<>(); if (value == null) return new SQLElementList<>();
return ORM.getAll(field.getSQLElementType(), return ORM.getAll(field.getSQLElementType(),

View File

@ -161,7 +161,7 @@ public class SQLElementList<E extends SQLElement<E>> extends ArrayList<E> {
public <T, F extends SQLElement<F>> Map<T, F> getAllForeign(SQLFKField<E, T, F> foreignKey) throws ORMException { public <T, P extends SQLElement<P>> SQLElementList<P> getReferencedEntries(SQLFKField<E, T, P> foreignKey, SQLOrderBy orderBy) throws ORMException {
Set<T> values = new HashSet<>(); Set<T> values = new HashSet<>();
forEach(v -> { forEach(v -> {
T val = v.get(foreignKey); T val = v.get(foreignKey);
@ -170,22 +170,63 @@ public class SQLElementList<E extends SQLElement<E>> extends ArrayList<E> {
}); });
if (values.isEmpty()) { if (values.isEmpty()) {
return new HashMap<>(); return new SQLElementList<>();
} }
SQLWhereChain where = new SQLWhereChain(SQLBoolOp.OR); SQLWhereChain where = new SQLWhereChain(SQLBoolOp.OR);
values.forEach(v -> where.add(new SQLWhereComp(foreignKey.getPrimaryField(), SQLComparator.EQ, v))); values.forEach(v -> where.add(new SQLWhereComp(foreignKey.getPrimaryField(), SQLComparator.EQ, v)));
SQLElementList<F> foreignElemts = ORM.getAll(foreignKey.getForeignElementClass(), where, null, null, null); return ORM.getAll(foreignKey.getForeignElementClass(), where, orderBy, null, null);
Map<T, F> ret = new HashMap<>(); }
public <T, P extends SQLElement<P>> Map<T, P> getReferencedEntriesInGroups(SQLFKField<E, T, P> foreignKey) throws ORMException {
SQLElementList<P> foreignElemts = getReferencedEntries(foreignKey, null);
Map<T, P> ret = new HashMap<>();
foreignElemts.forEach(foreignVal -> ret.put(foreignVal.get(foreignKey.getPrimaryField()), foreignVal)); foreignElemts.forEach(foreignVal -> ret.put(foreignVal.get(foreignKey.getPrimaryField()), foreignVal));
return ret; return ret;
} }
public <T, F extends SQLElement<F>> SQLElementList<F> getReferencingForeignEntries(SQLFKField<F, T, E> foreignKey, SQLOrderBy orderBy, Integer limit, Integer offset) throws ORMException {
Set<T> values = new HashSet<>();
forEach(v -> {
T val = v.get(foreignKey.getPrimaryField());
if (val != null)
values.add(val);
});
if (values.isEmpty()) {
return new SQLElementList<>();
}
SQLWhereChain where = new SQLWhereChain(SQLBoolOp.OR);
values.forEach(v -> where.add(new SQLWhereComp(foreignKey, SQLComparator.EQ, v)));
return ORM.getAll(foreignKey.getSQLElementType(), where, orderBy, limit, offset);
}
public <T, F extends SQLElement<F>> Map<T, SQLElementList<F>> getReferencingForeignEntriesInGroups(SQLFKField<F, T, E> foreignKey, SQLOrderBy orderBy, Integer limit, Integer offset) throws ORMException {
SQLElementList<F> foreignElements = getReferencingForeignEntries(foreignKey, orderBy, limit, offset);
Map<T, SQLElementList<F>> map = new HashMap<>();
foreignElements.forEach(foreignVal -> {
SQLElementList<F> subList = map.getOrDefault(foreignVal.get(foreignKey), new SQLElementList<>());
subList.add(foreignVal);
map.put(foreignVal.get(foreignKey), subList);
});
return map;
}
public JsonArray asJsonArray() { public JsonArray asJsonArray() {

View File

@ -2,12 +2,20 @@ package fr.pandacube.java.util.orm;
import fr.pandacube.java.util.Log; import fr.pandacube.java.util.Log;
public class SQLFKField<E extends SQLElement<E>, T, F extends SQLElement<F>> extends SQLField<E, T> { /**
*
* @author Marc
*
* @param <F> the table class of this current foreign key field
* @param <T> the Java type of this field
* @param <P> the table class of the targeted primary key
*/
public class SQLFKField<F extends SQLElement<F>, T, P extends SQLElement<P>> extends SQLField<F, T> {
private SQLField<F, T> sqlPrimaryKeyField; private SQLField<P, T> sqlPrimaryKeyField;
private Class<F> sqlForeignKeyElemClass; private Class<P> sqlForeignKeyElemClass;
protected SQLFKField(SQLType<T> t, boolean nul, T deflt, Class<F> fkEl, SQLField<F, T> fkF) { protected SQLFKField(SQLType<T> t, boolean nul, T deflt, Class<P> fkEl, SQLField<P, T> fkF) {
super(t, nul, deflt); super(t, nul, deflt);
construct(fkEl, fkF); construct(fkEl, fkF);
} }
@ -36,7 +44,7 @@ public class SQLFKField<E extends SQLElement<E>, T, F extends SQLElement<F>> ext
return new SQLFKField<>(fkF.type, nul, deflt, fkEl, fkF); return new SQLFKField<>(fkF.type, nul, deflt, fkEl, fkF);
} }
private void construct(Class<F> fkEl, SQLField<F, T> fkF) { private void construct(Class<P> fkEl, SQLField<P, T> fkF) {
if (fkF == null) throw new IllegalArgumentException("foreignKeyField can't be null"); if (fkF == null) throw new IllegalArgumentException("foreignKeyField can't be null");
try { try {
ORM.initTable(fkEl); ORM.initTable(fkEl);
@ -51,11 +59,11 @@ public class SQLFKField<E extends SQLElement<E>, T, F extends SQLElement<F>> ext
sqlForeignKeyElemClass = fkEl; sqlForeignKeyElemClass = fkEl;
} }
public SQLField<F, T> getPrimaryField() { public SQLField<P, T> getPrimaryField() {
return sqlPrimaryKeyField; return sqlPrimaryKeyField;
} }
public Class<F> getForeignElementClass() { public Class<P> getForeignElementClass() {
return sqlForeignKeyElemClass; return sqlForeignKeyElemClass;
} }