This is an automated email from the ASF dual-hosted git repository.
doebele pushed a commit to branch version3
in repository https://gitbox.apache.org/repos/asf/empire-db.git
The following commit(s) were added to refs/heads/version3 by this push:
new 2942514 EMPIREDB-362 multi-column-join
2942514 is described below
commit 2942514b5f6277c3923f39f613617701fd5efc91
Author: Rainer Döbele <[email protected]>
AuthorDate: Sun Feb 13 22:43:47 2022 +0100
EMPIREDB-362 multi-column-join
---
.../org/apache/empire/commons/ObjectUtils.java | 17 +++++++++
.../org/apache/empire/data/list/DataListEntry.java | 37 +++++++++++++++----
.../main/java/org/apache/empire/db/DBCommand.java | 42 +++++++++++++++++++++-
.../main/java/org/apache/empire/db/DBReader.java | 35 ++++++++++++++++++
.../db/exceptions/NoPrimaryKeyException.java | 6 ++++
5 files changed, 130 insertions(+), 7 deletions(-)
diff --git a/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
b/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
index 7ad985c..886741c 100644
--- a/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
+++ b/empire-db/src/main/java/org/apache/empire/commons/ObjectUtils.java
@@ -33,6 +33,7 @@ import java.util.List;
import java.util.Locale;
import org.apache.commons.beanutils.MethodUtils;
+import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.InvalidValueException;
import org.apache.empire.exceptions.ItemNotFoundException;
import org.slf4j.Logger;
@@ -920,6 +921,22 @@ public final class ObjectUtils
}
/**
+ * Converts varArgs to an array
+ *
+ * @param t the type of the array
+ * @param values the array values
+ *
+ * @return the array
+ */
+ @SafeVarargs
+ public static <T> T[] toArray(Class<T> t, T... values)
+ {
+ if (values.length==0)
+ throw new InvalidArgumentException("values", values);
+ return values;
+ }
+
+ /**
* Converts an array to a list
*
* @param t the type of the list items
diff --git
a/empire-db/src/main/java/org/apache/empire/data/list/DataListEntry.java
b/empire-db/src/main/java/org/apache/empire/data/list/DataListEntry.java
index bf80cad..cb33954 100644
--- a/empire-db/src/main/java/org/apache/empire/data/list/DataListEntry.java
+++ b/empire-db/src/main/java/org/apache/empire/data/list/DataListEntry.java
@@ -29,6 +29,7 @@ import org.apache.empire.data.Column;
import org.apache.empire.data.ColumnExpr;
import org.apache.empire.data.EntityType;
import org.apache.empire.data.RecordData;
+import org.apache.empire.db.exceptions.NoPrimaryKeyException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.ItemNotFoundException;
import org.apache.empire.exceptions.NotImplementedException;
@@ -58,24 +59,44 @@ public class DataListEntry implements RecordData,
Serializable
return (T)this.head;
}
- public Object[] getRecordKey(EntityType entity)
+ /**
+ * Returns the record key for a type of entity
+ * @param entityType the entity type or rowset for which to get key
+ * @return the record key
+ */
+ public Object[] getRecordKey(EntityType entityType)
{
- Column[] keyColumns = entity.getKeyColumns();
+ Column[] keyColumns = entityType.getKeyColumns();
+ if (keyColumns==null || keyColumns.length==0)
+ throw new NoPrimaryKeyException(entityType);
+ // Collect key
Object[] key = new Object[keyColumns.length];
for (int i=0; i<key.length; i++)
key[i] = this.get(keyColumns[i]);
return key;
}
- public long getRecordId(EntityType entity)
+ /**
+ * Returns the record id for a type of entity which has a single numeric
primary key
+ * @param entityType the entity type or rowset for which to get key
+ * @return the record id
+ * @throws InvalidArgumentException if the entity has not a single numeric
primary key
+ */
+ public long getRecordId(EntityType entityType)
{
- Column[] keyColumns = entity.getKeyColumns();
- if (keyColumns.length!=1)
- throw new InvalidArgumentException("entity",
entity.getEntityName());
+ Column[] keyColumns = entityType.getKeyColumns();
+ if (keyColumns==null || keyColumns.length!=1)
+ throw new InvalidArgumentException("entityType",
entityType.getEntityName());
// return id
return ObjectUtils.getLong(get(keyColumns[0]));
}
+ /**
+ * Compares a given record key with the key of the entry
+ * @param keyColumns the columns which make up the key
+ * @param key the key to compare the current entry to
+ * @return true if the keys match or false otherwise
+ */
public boolean compareKey(Column[] keyColumns, Object[] key)
{
for (int i=0; i<keyColumns.length; i++)
@@ -91,6 +112,10 @@ public class DataListEntry implements RecordData,
Serializable
return true;
}
+ /**
+ * Updates the fields of the entry with the corresponding fields of a
record.
+ * @param recData the record with the updated (newer) fields
+ */
public void updateData(RecordData recData)
{
ColumnExpr[] cols = head.getColumns();
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
b/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
index 8156fef..7106c75 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
@@ -636,17 +636,57 @@ public abstract class DBCommand extends DBCommandExpr
* @param joinType type of join ({@link DBJoinType#INNER}, {@link
DBJoinType#LEFT}, {@link DBJoinType#RIGHT})
* @return itself (this)
*/
- public final DBCommand join(DBColumnExpr left, DBColumnExpr right,
DBJoinType joinType, DBCompareExpr... addlConstraints)
+ public final DBCommand join(DBColumnExpr left, DBColumn right, DBJoinType
joinType, DBCompareExpr... addlConstraints)
{
+ if (left==null || right==null || left.getSourceColumn()==null)
+ throw new InvalidArgumentException("left|right", left);
+ if (left.getSourceColumn().getRowSet()==right.getRowSet())
+ throw new InvalidArgumentException("rowset",
left.getSourceColumn().getRowSet().getName()+"|"+right.getRowSet().getName());
+ // create the expression
DBColumnJoinExpr join = new DBColumnJoinExpr(left, right, joinType);
+ // additional constraints
+ DBCompareExpr where = null;
+ for (int i=0; i<addlConstraints.length; i++)
+ where = (where!=null ? where.and(addlConstraints[i]) :
addlConstraints[i]);
+ if (where!=null)
+ join.where(where);
+ // done
join(join);
+ return this;
+ }
+
+ /**
+ * Multi-Column version of column based join expression
+ * @param left the columsn on the left
+ * @param right the columns on the right
+ * @param joinType the joinType
+ * @param addlConstraints addlConstraints
+ * @return itself (this)
+ */
+ public final DBCommand join(DBColumn[] left, DBColumn[] right, DBJoinType
joinType, DBCompareExpr... addlConstraints)
+ {
+ // check params
+ if (left==null || right==null || left.length==0 ||
left.length!=right.length)
+ throw new InvalidArgumentException("left|right", left);
+ if (left[0].getRowSet()==right[0].getRowSet())
+ throw new InvalidArgumentException("rowset",
left[0].getSourceColumn().getRowSet().getName()+"|"+right[0].getRowSet().getName());
+ /*
+ * TODO: Find a better solution / Make DBColumnJoinExpr multi-column
+ */
+ DBColumnJoinExpr join = new DBColumnJoinExpr(left[0], right[0],
joinType);
// additional constraints
DBCompareExpr where = null;
+ for (int i=1; i<left.length; i++)
+ { // add to where list
+ DBCompareExpr cmpExpr = right[i].is(left[i]);
+ where = (where!=null ? where.and(cmpExpr) : cmpExpr);
+ }
for (int i=0; i<addlConstraints.length; i++)
where = (where!=null ? where.and(addlConstraints[i]) :
addlConstraints[i]);
if (where!=null)
join.where(where);
// done
+ join(join);
return this;
}
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBReader.java
b/empire-db/src/main/java/org/apache/empire/db/DBReader.java
index e8ccd5f..acfd9d1 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBReader.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBReader.java
@@ -33,9 +33,12 @@ import java.util.Map;
import org.apache.empire.commons.ClassUtils;
import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.data.Column;
import org.apache.empire.data.ColumnExpr;
import org.apache.empire.data.DataType;
+import org.apache.empire.data.EntityType;
import org.apache.empire.db.exceptions.EmpireSQLException;
+import org.apache.empire.db.exceptions.NoPrimaryKeyException;
import org.apache.empire.db.exceptions.QueryNoResultException;
import org.apache.empire.db.expr.join.DBJoinExpr;
import org.apache.empire.db.list.DataBean;
@@ -409,6 +412,38 @@ public class DBReader extends DBRecordData implements
Closeable
throw new EmpireSQLException(context.getDbms(), e);
}
}
+
+ /**
+ * Returns the record key for a type of entity
+ * @param entityType the entity type or rowset for which to get key
+ * @return the record key
+ */
+ public Object[] getRecordKey(EntityType entityType)
+ {
+ Column[] keyColumns = entityType.getKeyColumns();
+ if (keyColumns==null || keyColumns.length==0)
+ throw new NoPrimaryKeyException(entityType);
+ // Collect key
+ Object[] key = new Object[keyColumns.length];
+ for (int i=0; i<key.length; i++)
+ key[i] = this.get(keyColumns[i]);
+ return key;
+ }
+
+ /**
+ * Returns the record id for a type of entity which has a single numeric
primary key
+ * @param entityType the entity type or rowset for which to get key
+ * @return the record id
+ * @throws InvalidArgumentException if the entity has not a single numeric
primary key
+ */
+ public long getRecordId(EntityType entityType)
+ {
+ Column[] keyColumns = entityType.getKeyColumns();
+ if (keyColumns==null || keyColumns.length!=1)
+ throw new InvalidArgumentException("entityType",
entityType.getEntityName());
+ // return id
+ return this.getLong(keyColumns[0]);
+ }
/**
* Checks if the rowset is open
diff --git
a/empire-db/src/main/java/org/apache/empire/db/exceptions/NoPrimaryKeyException.java
b/empire-db/src/main/java/org/apache/empire/db/exceptions/NoPrimaryKeyException.java
index 463c8ca..6e2277a 100644
---
a/empire-db/src/main/java/org/apache/empire/db/exceptions/NoPrimaryKeyException.java
+++
b/empire-db/src/main/java/org/apache/empire/db/exceptions/NoPrimaryKeyException.java
@@ -20,6 +20,7 @@ package org.apache.empire.db.exceptions;
import org.apache.empire.commons.ErrorType;
import org.apache.empire.commons.StringUtils;
+import org.apache.empire.data.EntityType;
import org.apache.empire.db.DBRowSet;
import org.apache.empire.exceptions.EmpireException;
@@ -33,4 +34,9 @@ public class NoPrimaryKeyException extends EmpireException
{
super(errorType, new String[] { StringUtils.coalesce(rowset.getName(),
rowset.getAlias()) });
}
+
+ public NoPrimaryKeyException(EntityType entityType)
+ {
+ super(errorType, new String[] { entityType.getEntityName() });
+ }
}