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() });
+    }
 }

Reply via email to