You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@empire-db.apache.org by do...@apache.org on 2022/01/26 00:40:48 UTC
[empire-db] branch version3 updated: EMPIREDB-367 DBUtils queryDataList method and classes
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 8311365 EMPIREDB-367 DBUtils queryDataList method and classes
8311365 is described below
commit 83113652da07cc756eeb0640867dcc7f722e03bd
Author: Rainer Döbele <do...@apache.org>
AuthorDate: Wed Jan 26 01:40:46 2022 +0100
EMPIREDB-367 DBUtils queryDataList method and classes
---
.../org/apache/empire/samples/db/SampleApp.java | 5 ++
.../org/apache/empire/data/list/DataListEntry.java | 54 +++++++++++-----
.../org/apache/empire/data/list/DataListHead.java | 60 ++++++++++++------
.../main/java/org/apache/empire/db/DBUtils.java | 73 +++++++++++++++++-----
4 files changed, 143 insertions(+), 49 deletions(-)
diff --git a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleApp.java b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleApp.java
index 91d6b3a..0cb0f56 100644
--- a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleApp.java
+++ b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleApp.java
@@ -628,9 +628,14 @@ public class SampleApp
cmd.orderBy(EMPLOYEE_FULLNAME);
/*
+ * Test data list entry
+ *
List<DataListEntry> list = context.getUtils().queryDataList(cmd);
for (DataListEntry dle : list)
{
+ int empId = dle.getId(EMP);
+ int empId2 = dle.getInt(EMP.ID);
+ boolean test = dle.hasField(EMP.FIRSTNAME);
System.out.println(dle.toString());
}
*/
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 b10e546..f400962 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
@@ -22,9 +22,6 @@ import org.slf4j.LoggerFactory;
public class DataListEntry implements RecordData, Serializable
{
- /**
- * Comment for <code>serialVersionUID</code>
- */
private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(DataListEntry.class);
@@ -40,6 +37,12 @@ public class DataListEntry implements RecordData, Serializable
this.values = values;
}
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public <H extends DataListHead> H getHead()
+ {
+ return (H)this.head;
+ }
+
public Object[] getKey(Entity entity)
{
Column[] keyColumns = entity.getKeyColumns();
@@ -129,6 +132,11 @@ public class DataListEntry implements RecordData, Serializable
return head.columns.length;
}
+ public boolean hasField(ColumnExpr column)
+ {
+ return (head.getColumnIndex(column)>=0);
+ }
+
@Override
public int getFieldIndex(ColumnExpr column)
{
@@ -142,9 +150,11 @@ public class DataListEntry implements RecordData, Serializable
}
@Override
- public ColumnExpr getColumnExpr(int i)
+ public ColumnExpr getColumnExpr(int index)
{
- return head.columns[i];
+ if (index<0 || index>=values.length)
+ throw new InvalidArgumentException("index", index);
+ return head.columns[index];
}
@Override
@@ -158,19 +168,21 @@ public class DataListEntry implements RecordData, Serializable
@Override
public Object getValue(ColumnExpr column)
{
- return getValue(getFieldIndex(column));
+ return getValue(indexOf(column));
}
@Override
public boolean isNull(int index)
{
+ if (index<0 || index>=values.length)
+ throw new InvalidArgumentException("index", index);
return ObjectUtils.isEmpty(values[index]);
}
@Override
public boolean isNull(ColumnExpr column)
{
- return isNull(getFieldIndex(column));
+ return isNull(indexOf(column));
}
@Override
@@ -186,7 +198,7 @@ public class DataListEntry implements RecordData, Serializable
}
/*
- * Additional
+ * Conversion functions
*/
public String getString(int index)
@@ -197,7 +209,7 @@ public class DataListEntry implements RecordData, Serializable
public final String getString(ColumnExpr column)
{
- return getString(getFieldIndex(column));
+ return getString(indexOf(column));
}
public int getInt(int index)
@@ -208,7 +220,7 @@ public class DataListEntry implements RecordData, Serializable
public final int getInt(ColumnExpr column)
{
- return getInt(getFieldIndex(column));
+ return getInt(indexOf(column));
}
public BigDecimal getDecimal(int index)
@@ -219,7 +231,7 @@ public class DataListEntry implements RecordData, Serializable
public final BigDecimal getDecimal(ColumnExpr column)
{
- return getDecimal(getFieldIndex(column));
+ return getDecimal(indexOf(column));
}
public boolean getBoolean(int index)
@@ -230,7 +242,7 @@ public class DataListEntry implements RecordData, Serializable
public final boolean getBoolean(ColumnExpr column)
{
- return getBoolean(getFieldIndex(column));
+ return getBoolean(indexOf(column));
}
public <T extends Enum<?>> T getEnum(int index, Class<T> enumType)
@@ -245,7 +257,7 @@ public class DataListEntry implements RecordData, Serializable
public final <T extends Enum<?>> T getEnum(ColumnExpr column, Class<T> enumType)
{
- return getEnum(getFieldIndex(column), enumType);
+ return getEnum(indexOf(column), enumType);
}
@SuppressWarnings("unchecked")
@@ -256,7 +268,7 @@ public class DataListEntry implements RecordData, Serializable
{ // Not an enum column (Attribute "enumType" has not been set)
throw new InvalidArgumentException("column", column);
}
- return getEnum(getFieldIndex(column), enumType);
+ return getEnum(indexOf(column), enumType);
}
public Date getDate(int index)
@@ -267,9 +279,13 @@ public class DataListEntry implements RecordData, Serializable
public final Date getDate(ColumnExpr column)
{
- return getDate(getFieldIndex(column));
+ return getDate(indexOf(column));
}
+ /*
+ * Miscellaneous functions
+ */
+
@Override
public String toString()
{
@@ -281,5 +297,13 @@ public class DataListEntry implements RecordData, Serializable
}
return b.toString();
}
+
+ protected int indexOf(ColumnExpr column)
+ {
+ int index = head.getColumnIndex(column);
+ if (index<0)
+ throw new ItemNotFoundException(column.getName());
+ return index;
+ }
}
diff --git a/empire-db/src/main/java/org/apache/empire/data/list/DataListHead.java b/empire-db/src/main/java/org/apache/empire/data/list/DataListHead.java
index d6e92d5..2d1e909 100644
--- a/empire-db/src/main/java/org/apache/empire/data/list/DataListHead.java
+++ b/empire-db/src/main/java/org/apache/empire/data/list/DataListHead.java
@@ -14,6 +14,7 @@ import org.apache.empire.data.ColumnExpr;
import org.apache.empire.data.RecordData;
import org.apache.empire.exceptions.InternalException;
import org.apache.empire.exceptions.InvalidArgumentException;
+import org.apache.empire.exceptions.ItemNotFoundException;
import org.apache.empire.exceptions.NotSupportedException;
import org.apache.empire.exceptions.UnsupportedTypeException;
import org.slf4j.Logger;
@@ -29,29 +30,51 @@ public class DataListHead<T extends DataListEntry> implements Serializable
protected String columnSeparator = "\t";
- public DataListHead(Class<T> listEntryClass, ColumnExpr[] columns)
+ /**
+ * findEntryConstructor
+ * @param listEntryClass
+ * @param listHeadClass
+ * @return the constructor
+ */
+ @SuppressWarnings("unchecked")
+ protected static <T extends DataListEntry> Constructor<T> findEntryConstructor(Class<?> listEntryClass, @SuppressWarnings("rawtypes") Class<? extends DataListHead> listHeadClass)
{
- if (listEntryClass!=null)
- { try
- { // Find the constructor
- this.constructor = listEntryClass.getDeclaredConstructor(DataListHead.class, int.class, Object[].class);
- }
- catch (NoSuchMethodException e)
- {
- throw new UnsupportedTypeException(listEntryClass);
- }
- catch (SecurityException e)
- {
- throw new UnsupportedTypeException(listEntryClass);
- }
+ /*
+ Constructor<?> constructor = ClassUtils.findMatchingAccessibleConstructor(listEntryClass, new Class<?>[] { listHeadClass, int.class, Object[].class });
+ if (constructor==null)
+ throw new UnsupportedTypeException(listEntryClass);
+ return constructor;
+ */
+ try
+ { // Find the constructor
+ return (Constructor<T>)listEntryClass.getDeclaredConstructor(listHeadClass, int.class, Object[].class);
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new UnsupportedTypeException(listEntryClass);
}
- else
- { // Must override newEntry for this to work
- this.constructor = null;
+ catch (SecurityException e)
+ {
+ throw new UnsupportedTypeException(listEntryClass);
}
+ }
+
+ /**
+ * Constructs a DataListHead based on an DataListEntry constructor
+ * @param constructor the DataListEntry constructor
+ * @param columns the list entry columns
+ */
+ public DataListHead(Constructor<T> constructor, ColumnExpr[] columns)
+ {
+ this.constructor = constructor;
this.columns = columns;
}
+ public DataListHead(Class<T> listEntryClass, ColumnExpr[] columns)
+ {
+ this(findEntryConstructor(listEntryClass, DataListHead.class), columns);
+ }
+
public ColumnExpr[] getColumns()
{
return columns;
@@ -71,8 +94,7 @@ public class DataListHead<T extends DataListEntry> implements Serializable
for (int i=0; i<columns.length; i++)
if (columnName.equalsIgnoreCase(columns[i].getName()))
return i;
- // Not found
- log.warn("Column \"{}\" not found in DataListEntry!", columnName);
+ // not found
return -1;
}
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBUtils.java b/empire-db/src/main/java/org/apache/empire/db/DBUtils.java
index 2098c04..0484c15 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBUtils.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBUtils.java
@@ -11,11 +11,14 @@ import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.commons.Options;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.data.DataType;
+import org.apache.empire.data.list.DataListEntry;
+import org.apache.empire.data.list.DataListHead;
import org.apache.empire.db.context.DBContextAware;
import org.apache.empire.db.exceptions.ConstraintViolationException;
import org.apache.empire.db.exceptions.QueryFailedException;
import org.apache.empire.db.exceptions.QueryNoResultException;
import org.apache.empire.db.exceptions.StatementFailedException;
+import org.apache.empire.dbms.DBMSFeature;
import org.apache.empire.dbms.DBMSHandler;
import org.apache.empire.exceptions.InternalException;
import org.apache.empire.exceptions.InvalidArgumentException;
@@ -97,7 +100,7 @@ public class DBUtils implements DBContextAware
throw new StatementFailedException(dbms, sqlCmd, sqle);
}
}
-
+
/**
* Returns the value of the first row/column of a sql-query as an object.
* If the query does not return a result the value ObjectUtils.NO_VALUE is returned.
@@ -291,7 +294,45 @@ public class DBUtils implements DBContextAware
Object value = querySingleValue(cmd.getSelect(), cmd.getParamValues(), DataType.VARCHAR, true);
return StringUtils.toString(value);
}
-
+
+ /**
+ * Returns the number of rows returned by executing the select statement
+ * @param cmd the select command
+ * @return the number of rows that will be returned
+ */
+ public int queryRowCount(DBCommand cmd)
+ { // execute Native Query
+ if (cmd==null || !cmd.isValid())
+ return 0;
+ // Check for aggregation
+ boolean aggregate = false;
+ DBColumnExpr[] exprList = cmd.getSelectExprList();
+ for (int i=0; i<exprList.length; i++)
+ {
+ if (exprList[i].isAggregate())
+ { aggregate = true;
+ break;
+ }
+ }
+ // check if aggregate
+ if (aggregate)
+ { // For Aggregations: Wrap
+ DBCommand subCmd = cmd.clone();
+ subCmd.clearOrderBy();
+ String sql = "SELECT COUNT(*) FROM ("+subCmd.getSelect() + ") q";
+ return querySingleInt(sql, null, 0);
+ }
+ // find any rowset
+ DBRowSet rs = exprList[0].getUpdateColumn().getRowSet();
+ // create the count command
+ DBCommand countCmd = cmd.clone();
+ countCmd.clearSelect();
+ countCmd.clearOrderBy();
+ countCmd.select(rs.count());
+ // perform query
+ return querySingleInt(countCmd);
+ }
+
/**
* Adds the first column of a query result to a collection.
* If the query has no result, an empty list is returned.
@@ -614,11 +655,11 @@ public class DBUtils implements DBContextAware
* DataListEntry(DataListHead<? extends DataListEntry> head, int rownum, Object values[])
* @param entryClass the entryClass for which to create the list head
* @return
+ */
protected <T extends DataListEntry> DataListHead<T> createDefaultDataListHead(DBCommand cmd, Class<T> entryClass)
{
return new DataListHead<T>(entryClass, cmd.getSelectExprList());
}
- */
/**
* Executes a query and returns a list of DataListEntry items
@@ -627,7 +668,8 @@ public class DBUtils implements DBContextAware
* @param first the number of records to skip from the beginning of the result
* @param pageSize the maximum number of item to return
* @return the list
- public <T extends DataListEntry<?>> List<T> queryDataList(DBCommand cmd, DataListHead<T> listHead, int first, int pageSize)
+ */
+ public <T extends DataListEntry> List<T> queryDataList(DBCommand cmd, DataListHead<T> listHead, int first, int pageSize)
{
DBReader r = new DBReader(context);
try
@@ -682,39 +724,40 @@ public class DBUtils implements DBContextAware
r.close();
}
}
- */
/**
* Queries a list of DataListEntry items
- public final <T extends DataListEntry<?>> List<T> queryDataList(DBCommand cmd, Class<T> entryClass)
+ */
+ public final <T extends DataListEntry> List<T> queryDataList(DBCommand cmd, Class<T> entryClass)
{
return queryDataList(cmd, createDefaultDataListHead(cmd, entryClass), 0, -1);
}
- */
/**
* Queries a list of DataListEntry items
- public final List<DataListEntry> queryDataList(DBCommand cmd)
+ */
+ @SuppressWarnings("unchecked")
+ public final <T extends DataListEntry> List<T> queryDataList(DBCommand cmd)
{
- return queryDataList(cmd, DataListEntry.class);
+ return (List<T>)queryDataList(cmd, DataListEntry.class);
}
- */
/**
* Queries a single DataListEntry item
- public final <T extends DataListEntry<?>> T queryDataEntry(DBCommand cmd, Class<T> entryClass)
+ */
+ public final <T extends DataListEntry> T queryDataEntry(DBCommand cmd, Class<T> entryClass)
{
List<T> dle = queryDataList(cmd, createDefaultDataListHead(cmd, entryClass), 0, 1);
return (dle.isEmpty() ? null : dle.get(0));
}
- */
/**
* Queries a single DataListEntry item
- public final DataListEntry<?> queryDataEntry(DBCommand cmd)
+ */
+ @SuppressWarnings("unchecked")
+ public final <T extends DataListEntry> T queryDataEntry(DBCommand cmd)
{
- return queryDataEntry(cmd, DataListEntry.class);
+ return (T)queryDataEntry(cmd, DataListEntry.class);
}
- */
}