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 19:45:03 UTC
[empire-db] branch version3 updated: EMPIREDB-367 DataListFactory interface and impl
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 89f2e52 EMPIREDB-367 DataListFactory interface and impl
89f2e52 is described below
commit 89f2e5207f90c7b9ae6406fedb5671d7d64b3401
Author: Rainer Döbele <do...@apache.org>
AuthorDate: Wed Jan 26 20:45:00 2022 +0100
EMPIREDB-367 DataListFactory interface and impl
---
.../org/apache/empire/samples/db/SampleApp.java | 13 +--
.../org/apache/empire/data/list/DataListEntry.java | 10 +-
.../apache/empire/data/list/DataListFactory.java | 16 +++
.../empire/data/list/DataListFactoryImpl.java | 113 +++++++++++++++++++++
.../org/apache/empire/data/list/DataListHead.java | 90 +---------------
.../main/java/org/apache/empire/db/DBUtils.java | 41 +++++---
6 files changed, 173 insertions(+), 110 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 13eb058..724fc15 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
@@ -131,12 +131,6 @@ public class SampleApp
// SECTION 5 AND 6: Populate Database and modify Data
populateAndModify(clearExistingData);
- /*
- int idEmp = testTransactionCreate(idDevDep);
- testTransactionUpdate(idEmp);
- testTransactionDelete(idEmp);
- */
-
// SECTION 7: Option 1: Query Records and print tab-separated
log.info("Step 8 Option 1: queryRecords() / Tab-Output");
queryRecords(QueryType.Reader); // Tab-Output
@@ -158,6 +152,13 @@ public class SampleApp
// SECTION 10: Use Bean Result to query beans
queryBeans();
+
+ /*
+ int idEmp = testTransactionCreate(idDevDep);
+ testTransactionUpdate(idEmp);
+ testTransactionDelete(idEmp);
+ */
+
// Finally, commit any changes
context.commit();
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 3121867..98a4ae3 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
@@ -26,21 +26,21 @@ public class DataListEntry implements RecordData, Serializable
private static final Logger log = LoggerFactory.getLogger(DataListEntry.class);
- protected final DataListHead<? extends DataListEntry> head;
+ protected final DataListHead head;
protected final Object values[];
protected int rownum;
- public DataListEntry(DataListHead<? extends DataListEntry> head, int rownum, Object values[])
+ public DataListEntry(DataListHead head, int rownum, Object values[])
{
this.head = head;
this.rownum = rownum;
this.values = values;
}
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public <H extends DataListHead> H getHead()
+ @SuppressWarnings("unchecked")
+ public <T extends DataListHead> T getHead()
{
- return (H)this.head;
+ return (T)this.head;
}
public Object[] getKey(Entity entity)
diff --git a/empire-db/src/main/java/org/apache/empire/data/list/DataListFactory.java b/empire-db/src/main/java/org/apache/empire/data/list/DataListFactory.java
new file mode 100644
index 0000000..d768721
--- /dev/null
+++ b/empire-db/src/main/java/org/apache/empire/data/list/DataListFactory.java
@@ -0,0 +1,16 @@
+package org.apache.empire.data.list;
+
+import java.util.List;
+
+import org.apache.empire.data.RecordData;
+
+public interface DataListFactory<T extends DataListEntry>
+{
+ void prepareQuery();
+
+ List<T> newList(int capacity);
+
+ T newEntry(int rownum, RecordData dataRow);
+
+ void completeQuery(List<T> list);
+}
diff --git a/empire-db/src/main/java/org/apache/empire/data/list/DataListFactoryImpl.java b/empire-db/src/main/java/org/apache/empire/data/list/DataListFactoryImpl.java
new file mode 100644
index 0000000..980a7ae
--- /dev/null
+++ b/empire-db/src/main/java/org/apache/empire/data/list/DataListFactoryImpl.java
@@ -0,0 +1,113 @@
+package org.apache.empire.data.list;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+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.NotSupportedException;
+import org.apache.empire.exceptions.UnsupportedTypeException;
+
+public class DataListFactoryImpl<T extends DataListEntry> implements DataListFactory<T>
+{
+ /**
+ * findEntryConstructor
+ * @param listEntryClass
+ * @param listHeadClass
+ * @return the constructor
+ */
+ @SuppressWarnings("unchecked")
+ protected static <T extends DataListEntry> Constructor<T> findEntryConstructor(Class<?> listEntryClass, Class<? extends DataListHead> listHeadClass)
+ {
+ try
+ { // Alternatively use ClassUtils.findMatchingAccessibleConstructor(listEntryClass, new Class<?>[] { listHeadClass, int.class, Object[].class });
+ return (Constructor<T>) listEntryClass.getDeclaredConstructor(listHeadClass, int.class, Object[].class);
+ }
+ catch (NoSuchMethodException | SecurityException e)
+ {
+ throw new UnsupportedTypeException(listEntryClass);
+ }
+ }
+
+ protected final Constructor<T> constructor;
+ protected final DataListHead head;
+
+ /**
+ * Constructs a DataListHead based on an DataListEntry constructor
+ * @param constructor the DataListEntry constructor
+ * @param columns the list entry columns
+ */
+ public DataListFactoryImpl(Constructor<T> constructor, DataListHead head)
+ {
+ this.constructor = constructor;
+ this.head = head;
+ }
+
+ public DataListFactoryImpl(Class<T> listEntryClass, DataListHead head)
+ {
+ this(findEntryConstructor(listEntryClass, DataListHead.class), head);
+ }
+
+ @Override
+ public void prepareQuery()
+ {
+ /* Nothing */
+ }
+
+ @Override
+ public List<T> newList(int capacity)
+ {
+ return new ArrayList<T>(capacity);
+ }
+
+ @Override
+ public T newEntry(int rownum, RecordData dataRow)
+ { // check
+ ColumnExpr[] columns = head.getColumns();
+ if (columns.length!=dataRow.getFieldCount())
+ throw new InvalidArgumentException("dataRow", dataRow);
+ // copy values
+ Object[] values = new Object[columns.length];
+ for (int i=0; i<columns.length; i++)
+ values[i] = dataRow.getValue(i);
+ // create
+ return newEntry(rownum, values);
+ }
+
+ protected T newEntry(int rownum, Object[] values)
+ { try
+ { // must override newEntry if no constructor is provided
+ if (constructor==null)
+ throw new NotSupportedException(this, "newEntry");
+ // create item
+ return constructor.newInstance(head, rownum, values);
+ }
+ catch (InstantiationException e)
+ {
+ throw new InternalException(e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new InternalException(e);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new InternalException(e);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new InternalException(e);
+ }
+ }
+
+ @Override
+ public void completeQuery(List<T> list)
+ {
+ /* Nothing */
+ }
+
+}
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 3844794..174ad06 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
@@ -4,115 +4,31 @@
package org.apache.empire.data.list;
import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.commons.Options;
import org.apache.empire.commons.StringUtils;
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.NotSupportedException;
-import org.apache.empire.exceptions.UnsupportedTypeException;
-public class DataListHead<T extends DataListEntry> implements Serializable
+public class DataListHead implements Serializable
{
private static final long serialVersionUID = 1L;
// private static final Logger log = LoggerFactory.getLogger(DataListHead.class);
- final Constructor<T> constructor;
- final ColumnExpr[] columns;
+ protected final ColumnExpr[] columns;
protected String columnSeparator = "\t";
-
- /**
- * 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)
- {
- /*
- 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);
- }
- 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)
+ public DataListHead(ColumnExpr[] columns)
{
- this.constructor = constructor;
this.columns = columns;
}
- public DataListHead(Class<T> listEntryClass, ColumnExpr[] columns)
- {
- this(findEntryConstructor(listEntryClass, DataListHead.class), columns);
- }
-
- public T newEntry(int rownum, Object[] values)
- { try
- { // check
- if (columns.length!=values.length)
- throw new InvalidArgumentException("values", values);
- // must override newEntry if no listEntryClass is provided
- if (constructor==null)
- throw new NotSupportedException(this, "newEntry");
- // create item
- return constructor.newInstance(this, rownum, values);
- }
- catch (InstantiationException e)
- {
- throw new InternalException(e);
- }
- catch (IllegalAccessException e)
- {
- throw new InternalException(e);
- }
- catch (IllegalArgumentException e)
- {
- throw new InternalException(e);
- }
- catch (InvocationTargetException e)
- {
- throw new InternalException(e);
- }
- }
-
- public final T newEntry(int rownum, RecordData data)
- { // check
- if (columns.length!=data.getFieldCount())
- throw new InvalidArgumentException("data", data);
- // copy values
- Object[] values = new Object[columns.length];
- for (int i=0; i<columns.length; i++)
- values[i] = data.getValue(i);
- // create
- return newEntry(rownum, values);
- }
-
public ColumnExpr[] getColumns()
{
return columns;
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 1c2fc3d..6b15117 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
@@ -12,6 +12,8 @@ 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.DataListFactory;
+import org.apache.empire.data.list.DataListFactoryImpl;
import org.apache.empire.data.list.DataListHead;
import org.apache.empire.db.context.DBContextAware;
import org.apache.empire.db.exceptions.ConstraintViolationException;
@@ -642,30 +644,33 @@ public class DBUtils implements DBContextAware
}
/**
- * Crates a default DataListHead for a DataListEntry class
+ * Crates a default DataListFactory for a DataListEntry class
* The DataListEntry class must provide the following constructor
- * DataListEntry(DataListHead<? extends DataListEntry> head, int rownum, Object values[])
+ * DataListEntry(DataListFactory<? 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)
+ protected <T extends DataListEntry> DataListFactory<T> createDefaultDataListFactory(Class<T> entryClass, DataListHead head)
{
- return new DataListHead<T>(entryClass, cmd.getSelectExprList());
+ return new DataListFactoryImpl<T>(entryClass, head);
}
/**
* Executes a query and returns a list of DataListEntry items
* @param sqlCmd the SQL-Command for the query
- * @param listHead the HeadInfo to be used for each list item
+ * @param factory the Factory to be used for each list item
* @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, DataListFactory<T> factory, int first, int pageSize)
{
+ List<T> list = null;
DBReader r = new DBReader(context);
try
- { // check pageSize
+ { // prepare
+ factory.prepareQuery();
+ // check pageSize
if (pageSize==0)
{ log.warn("PageSize must not be 0. Setting to -1 for all records!");
pageSize = -1;
@@ -690,12 +695,12 @@ public class DBUtils implements DBContextAware
}
// Create a list of data entries
int maxCount = (pageSize>=0) ? pageSize : MAX_QUERY_ROWS;
- ArrayList<T> list = new ArrayList<T>((pageSize>=0) ? pageSize : 10);
+ list = factory.newList((pageSize>=0) ? pageSize : 10);
// add data
int rownum = 0;
while (r.moveNext() && maxCount != 0)
{ // Create bean an init
- T entry = listHead.newEntry(++rownum, r);
+ T entry = factory.newEntry(++rownum, r);
if (entry==null)
continue;
// add entry
@@ -714,17 +719,28 @@ public class DBUtils implements DBContextAware
return list;
}
finally
- {
+ { // close reader
r.close();
+ // complete
+ if (list!=null)
+ factory.completeQuery(list);
}
}
+
+ /**
+ * Queries a list of DataListEntry items
+ */
+ public final <T extends DataListEntry> List<T> queryDataList(DBCommand cmd, Class<T> entryClass, DataListHead head)
+ {
+ return queryDataList(cmd, createDefaultDataListFactory(entryClass, head), 0, MAX_QUERY_ROWS);
+ }
/**
* Queries a list of DataListEntry items
*/
public final <T extends DataListEntry> List<T> queryDataList(DBCommand cmd, Class<T> entryClass)
{
- return queryDataList(cmd, createDefaultDataListHead(cmd, entryClass), 0, MAX_QUERY_ROWS);
+ return queryDataList(cmd, entryClass, new DataListHead(cmd.getSelectExprList()));
}
/**
@@ -741,7 +757,8 @@ public class DBUtils implements DBContextAware
*/
public final <T extends DataListEntry> T queryDataEntry(DBCommand cmd, Class<T> entryClass, boolean forceResult)
{
- List<T> dle = queryDataList(cmd, createDefaultDataListHead(cmd, entryClass), 0, 1);
+ DataListHead head = new DataListHead(cmd.getSelectExprList());
+ List<T> dle = queryDataList(cmd, createDefaultDataListFactory(entryClass, head), 0, 1);
if (dle.isEmpty())
{ if (forceResult)
throw new QueryNoResultException(cmd.getSelect());