[cvs] expresso commit by rauld: Refactored searchAndRetrieveList()
to make
JCorporate Ltd
jcorp at jcorporate.com
Mon Jan 17 17:00:12 UTC 2005
Log Message:
-----------
Refactored searchAndRetrieveList() to make use of the new getSQLSelectStatement() method.
Contributed by Yves Henri Amaizo
Modified Files:
--------------
expresso/expresso-web/WEB-INF/src/com/jcorporate/expresso/core/dbobj:
MultiDBObject.java
Revision Data
-------------
Index: MultiDBObject.java
===================================================================
RCS file: /home/javacorp/.cvs/expresso/expresso/expresso-web/WEB-INF/src/com/jcorporate/expresso/core/dbobj/MultiDBObject.java,v
retrieving revision 1.64
retrieving revision 1.65
diff -Lexpresso-web/WEB-INF/src/com/jcorporate/expresso/core/dbobj/MultiDBObject.java -Lexpresso-web/WEB-INF/src/com/jcorporate/expresso/core/dbobj/MultiDBObject.java -u -r1.64 -r1.65
--- expresso-web/WEB-INF/src/com/jcorporate/expresso/core/dbobj/MultiDBObject.java
+++ expresso-web/WEB-INF/src/com/jcorporate/expresso/core/dbobj/MultiDBObject.java
@@ -92,7 +92,6 @@
import java.util.StringTokenizer;
import java.util.Vector;
-
/**
* This class handles SQL joins with java coding only. It is not deprectated, but
* @see com.jcorporate.expresso.core.dataobjects.jdbc.JoinedDataObject for a more flexible approach to joins
@@ -127,361 +126,392 @@
*/
public class MultiDBObject {
- // ----------------------------------------------------
- // 2003-11-05 /ebn-ma: added...
- /**
- * Holds the shortName of these DBObjects, which have to be ignored in the
- * where-clause because they are still used in a on-clause of a join.
- * Ex.: ignoreInWhereClause = ",bt,,an,,qu,";
- * if (ignoreInWhereClause.indexOf(",bt,") >= 0) { continue; }
- */
- private String ignoreInWhereClause = "";
-
- /**
- * Hold the join-conditions in "original" form.
- * For the getThisMultiDBObj method and for to create the from-clause
- * at execution-time.
- */
- private Vector originalJoins = new Vector();
-
- /**
- * If we are using a custom from clause for this query, it's stored here.
- * If null, then build the from clause with the join or the foreign-key
- * definitions.
- * Do not include the sql-keyword FROM.
- * Note: If you define a customFromClause, you will usually have to define
- * a custemWhereClause too.
- */
- private String customFromClause = null;
- // 2003-11-05 /ebn-ma: ...added
- // ----------------------------------------------------
-
- /**
- * Use a DISTINCT keyword right after SELECT keyword
- */
- private boolean selectDistinct = false;
-
- /**
- * Attributes of this DB Object
- */
- private HashMap attributes = null;
-
- /**
- * The number of records we must skip over before we start reading
- * the <code>ResultSet</code> proper in a searchAndRetrieve.
- * 0 means no limit
- * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
- */
- transient protected int offsetRecord = 0;
-
- /**
- * If we are using a custom where clause for this query, this flag will
- * signify if we need to append the custom where clause to that generated
- * by the setForeignKey() calls
- */
- private boolean appendCustomWhereClause = false;
-
- /**
- * Static variables for join type
- */
- protected static final int INNER_JOIN = 0;
- protected static final int RIGHT_JOIN = 1;
- protected static final int LEFT_JOIN = 2;
-
- /**
- * Constant for shortName DBObject attribute
- */
- protected static final String SHORT_NAME = "shortName";
-
- /**
- * 'FROM' clause formed by calls to setJoin().
- */
- private String fromClause = null;
-
- /**
- * If set to true, the shortname for the DBObject will be used as an alias
- * in the query; defaults to false for backward-compatiblity
- */
- private boolean shortNameAsAlias = false;
-
- /**
- * Return an "attribute". Attributes are temporary (e.g. not stored in the DBMS)
- * values associated with this particular DB object instance.
- *
- * @param attribName The attribute name to check
- * @return the object associated with this attribute
- */
- public Object getAttribute(String attribName) {
- if (attributes != null) {
- return attributes.get(attribName);
- } else {
- return null;
+ // ----------------------------------------------------
+ // 2003-11-05 /ebn-ma: added...
+ /**
+ * Holds the shortName of these DBObjects, which have to be ignored in the
+ * where-clause because they are still used in a on-clause of a join.
+ * Ex.: ignoreInWhereClause = ",bt,,an,,qu,";
+ * if (ignoreInWhereClause.indexOf(",bt,") >= 0) { continue; }
+ */
+ private String ignoreInWhereClause = "";
+
+ /**
+ * Hold the join-conditions in "original" form.
+ * For the getThisMultiDBObj method and for to create the from-clause
+ * at execution-time.
+ */
+ private Vector originalJoins = new Vector();
+
+ /**
+ * If we are using a custom from clause for this query, it's stored here.
+ * If null, then build the from clause with the join or the foreign-key
+ * definitions.
+ * Do not include the sql-keyword FROM.
+ * Note: If you define a customFromClause, you will usually have to define
+ * a custemWhereClause too.
+ */
+ private String customFromClause = null;
+ // 2003-11-05 /ebn-ma: ...added
+ // ----------------------------------------------------
+
+ /**
+ * Use a DISTINCT keyword right after SELECT keyword
+ */
+ private boolean selectDistinct = false;
+
+ /**
+ * Attributes of this DB Object
+ */
+ private HashMap attributes = null;
+
+ /**
+ * The number of records we must skip over before we start reading
+ * the <code>ResultSet</code> proper in a searchAndRetrieve.
+ * 0 means no limit
+ * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
+ */
+ transient protected int offsetRecord = 0;
+
+ /**
+ * If we are using a custom where clause for this query, this flag will
+ * signify if we need to append the custom where clause to that generated
+ * by the setForeignKey() calls
+ */
+ private boolean appendCustomWhereClause = false;
+
+ /**
+ * Static variables for join type
+ */
+ protected static final int INNER_JOIN = 0;
+ protected static final int RIGHT_JOIN = 1;
+ protected static final int LEFT_JOIN = 2;
+
+ /**
+ * Constant for shortName DBObject attribute
+ */
+ protected static final String SHORT_NAME = "shortName";
+
+ /**
+ * 'FROM' clause formed by calls to setJoin().
+ */
+ private String fromClause = null;
+
+ /**
+ * If set to true, the shortname for the DBObject will be used as an alias
+ * in the query; defaults to false for backward-compatiblity
+ */
+ private boolean shortNameAsAlias = false;
+
+ /**
+ * Return an "attribute". Attributes are temporary (e.g. not stored in the DBMS)
+ * values associated with this particular DB object instance.
+ *
+ * @param attribName The attribute name to check
+ * @return the object associated with this attribute
+ */
+ public Object getAttribute(String attribName) {
+ if (attributes != null) {
+ return attributes.get(attribName);
+ }
+ else {
+ return null;
+ }
+ }
+
+ /* getAttribute(String) */
+
+ /**
+ * Set an attribute. Attributes are temporary (e.g. not stored in the DBMS) values
+ * associated with this particular DB object instance.
+ *
+ * @param attribName The name of the attribute being defined
+ * @param attribValue The object to store under this attribute name
+ */
+ public synchronized void setAttribute(String attribName,
+ Object attribValue) {
+ if (attributes == null) {
+ attributes = new HashMap();
+ }
+
+ attributes.put(attribName, attribValue);
+ }
+
+ /* setAttribute(String, Object) */
+
+ /**
+ * A DB Object can be told to only retrieve a certain number of records. If a
+ * "max records" value has been specified, this method provides access to it.
+ *
+ * @return The maximum number of records that should be retrieved, or zero
+ * if no max has been set
+ */
+ public int getMaxRecords() {
+ return maxRecords;
+ }
+
+ /* getMaxRecords() */
+
+ /**
+ * Specifies the number of records that should be skipped over
+ * before any data from the <code>ResultSet</code>
+ * is retrieved in any subsequent
+ * searchAndRetrieve() call. Records will be skipped over (in the specified
+ * sort order) until the record counts is equal to or greater
+ * than the offset record. Specifying zero indicates that no
+ * records should be skipped over and the
+ * <code>ResultSet</code> immediately from the start.
+ *
+ * @param newOffset The maximum number of records to retrieve.
+ * @throws DBException If the max number is less than 0
+ * <p/>
+ * author Peter Pilgrim <peterp at xenonsoft dot demon dot co dot uk>
+ * date Tue Feb 05 23:06:38 GMT 2002
+ */
+ public synchronized void setOffsetRecord(int newOffset) throws DBException {
+ if (newOffset < 0) {
+ throw new DBException("Offset records can't be less than 0");
+ }
+
+ offsetRecord = newOffset;
+ }
+
+ /* setOffsetRecord(int) */
+
+ /**
+ * Gets the number of records that be skipped. The offset records.
+ * A DB Object can be told to skip a certain number of
+ * records, before reading records from the <code>ResultSet</code>.
+ * <p/>
+ * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
+ *
+ * @return The maximum number of records that should be
+ * skipped over before reading the data records.
+ * @see #setOffsetRecord(int)
+ */
+ public int getOffsetRecord() {
+ return offsetRecord;
+ }
+
+ /* getOffsetRecord() */
+
+ // ----------------------------------------------------
+ // 2003-11-05 /ebn-ma: added...
+ /**
+ * Specify a custom "from" clause for the SQL used to retrieve
+ * records for this object.
+ *
+ * @param newCustomFrom java.lang.String
+ */
+ public synchronized void setCustomFromClause(String newCustomFrom) {
+ customFromClause = newCustomFrom;
+ }
+
+ /**
+ * Gets the customFromClause
+ *
+ * @return customFromClause
+ */
+ public String getCustomFromClause() {
+ return customFromClause;
+ }
+
+ /**
+ * Build a string consisting of an SQL 'from' clause using the
+ * customFromClause, the foreign-key or the join definitions.
+ * The result will be found in property fromClause.
+ *
+ * @return true = success.
+ * <p/>
+ * Modify by Yves Henri AMAIZO <amy_amaizo at compuserve.com>
+ * @since $DatabaseSchema $Date$
+ */
+ public boolean buildFromClause() throws DBException {
+ boolean success = false;
+ FastStringBuffer fsb = new FastStringBuffer(256);
+ int dboCount = myDBObjects.size();
+
+ try {
+ // ----------------------------------------------------
+ if (customFromClause != null &&
+ customFromClause.trim().length() > 0) {
+ // As long as a customFromClause is defined , we will use it.
+ fromClause = customFromClause;
+ success = true;
+ }
+ // ----------------------------------------------------
+ else if (!originalJoins.isEmpty()) {
+ if (!originalRelations.isEmpty()) {
+ throw new DBException(thisClass + "count()" +
+ "You cannot mix set???Join() with setForeignKey() definitions." +
+ "Use setInnerJoin() instead of setForeignKey().");
}
- } /* getAttribute(String) */
+ // Build the from clause with the join definitions...
+ fromClause = null;
+ String oneJoin = null;
- /**
- * Set an attribute. Attributes are temporary (e.g. not stored in the DBMS) values
- * associated with this particular DB object instance.
- *
- * @param attribName The name of the attribute being defined
- * @param attribValue The object to store under this attribute name
- */
- public synchronized void setAttribute(String attribName,
- Object attribValue) {
- if (attributes == null) {
- attributes = new HashMap();
- }
-
- attributes.put(attribName, attribValue);
- } /* setAttribute(String, Object) */
-
-
- /**
- * A DB Object can be told to only retrieve a certain number of records. If a
- * "max records" value has been specified, this method provides access to it.
- *
- * @return The maximum number of records that should be retrieved, or zero
- * if no max has been set
- */
- public int getMaxRecords() {
- return maxRecords;
- } /* getMaxRecords() */
-
- /**
- * Specifies the number of records that should be skipped over
- * before any data from the <code>ResultSet</code>
- * is retrieved in any subsequent
- * searchAndRetrieve() call. Records will be skipped over (in the specified
- * sort order) until the record counts is equal to or greater
- * than the offset record. Specifying zero indicates that no
- * records should be skipped over and the
- * <code>ResultSet</code> immediately from the start.
- *
- * @param newOffset The maximum number of records to retrieve.
- * @throws DBException If the max number is less than 0
- * <p/>
- * author Peter Pilgrim <peterp at xenonsoft dot demon dot co dot uk>
- * date Tue Feb 05 23:06:38 GMT 2002
- */
- public synchronized void setOffsetRecord(int newOffset)
- throws DBException {
- if (newOffset < 0) {
- throw new DBException("Offset records can't be less than 0");
- }
-
- offsetRecord = newOffset;
- } /* setOffsetRecord(int) */
-
- /**
- * Gets the number of records that be skipped. The offset records.
- * A DB Object can be told to skip a certain number of
- * records, before reading records from the <code>ResultSet</code>.
- * <p/>
- * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
- *
- * @return The maximum number of records that should be
- * skipped over before reading the data records.
- * @see #setOffsetRecord(int)
- */
- public int getOffsetRecord() {
- return offsetRecord;
- } /* getOffsetRecord() */
-
- // ----------------------------------------------------
- // 2003-11-05 /ebn-ma: added...
- /**
- * Specify a custom "from" clause for the SQL used to retrieve
- * records for this object.
- *
- * @param newCustomFrom java.lang.String
- */
- public synchronized void setCustomFromClause(String newCustomFrom) {
- customFromClause = newCustomFrom;
- }
+ for (Enumeration n = originalJoins.elements();
+ n.hasMoreElements(); ) {
+ oneJoin = (String) n.nextElement();
- /**
- * Gets the customFromClause
- *
- * @return customFromClause
- */
- public String getCustomFromClause() {
- return customFromClause;
- }
+ StringTokenizer stk = new StringTokenizer(oneJoin, "|");
+ String leftDbo = stk.nextToken();
+ String leftField = stk.nextToken();
+ String rightDbo = stk.nextToken();
+ String rightField = stk.nextToken();
+ String joinTyp = stk.nextToken().toLowerCase();
+
+ if ("left".equals(joinTyp)) {
+ buildJoin(leftDbo, leftField, rightDbo, rightField, LEFT_JOIN);
+ }
+ else if ("inner".equals(joinTyp)) {
+ buildJoin(leftDbo, leftField, rightDbo, rightField, INNER_JOIN);
+ }
+ else if ("right".equals(joinTyp)) {
+ buildJoin(leftDbo, leftField, rightDbo, rightField, RIGHT_JOIN);
+ }
+ else {
+ throw new DBException(thisClass + "count()" +
+ "Missing join-type in '" + oneJoin + "'");
+ }
+ }
+ success = true;
+ }
+ // ----------------------------------------------------
+ else if (!originalRelations.isEmpty() || dboCount == 1) {
+ // To build the relations with the foreign-key definitions,
+ // we need to have all the DBObejcts in the from clause.
+ // If this is not the special case, where our Object has only
+ // one embedded DBObject: We have to link them later in the
+ // where clause.
+ boolean needComma = false;
+ DBObject oneObj = null;
- /**
- * Build a string consisting of an SQL 'from' clause using the
- * customFromClause, the foreign-key or the join definitions.
- * The result will be found in property fromClause.
- *
- * @return true = success.
- * <p/>
- * Modify by Yves Henri AMAIZO <amy_amaizo at compuserve.com>
- * @since $DatabaseSchema $Date$
- */
- public boolean buildFromClause() throws DBException {
- boolean success = false;
- FastStringBuffer fsb = new FastStringBuffer(256);
- int dboCount = myDBObjects.size();
+ for (Enumeration eachObj = myDBObjects.elements();
+ eachObj.hasMoreElements(); ) {
+ oneObj = (DBObject) eachObj.nextElement();
- try {
- // ----------------------------------------------------
- if (customFromClause != null &&
- customFromClause.trim().length() > 0) {
- // As long as a customFromClause is defined , we will use it.
- fromClause = customFromClause;
- success = true;
- }
- // ----------------------------------------------------
- else if (!originalJoins.isEmpty()) {
- if (!originalRelations.isEmpty()) {
- throw new DBException(thisClass + "count()" +
- "You cannot mix set???Join() with setForeignKey() definitions." +
- "Use setInnerJoin() instead of setForeignKey().");
- }
-
- // Build the from clause with the join definitions...
- fromClause = null;
- String oneJoin = null;
-
- for (Enumeration n = originalJoins.elements();
- n.hasMoreElements();) {
- oneJoin = (String) n.nextElement();
-
- StringTokenizer stk = new StringTokenizer(oneJoin, "|");
- String leftDbo = stk.nextToken();
- String leftField = stk.nextToken();
- String rightDbo = stk.nextToken();
- String rightField = stk.nextToken();
- String joinTyp = stk.nextToken().toLowerCase();
-
- if ("left".equals(joinTyp)) {
- buildJoin(leftDbo, leftField, rightDbo, rightField, LEFT_JOIN);
- } else if ("inner".equals(joinTyp)) {
- buildJoin(leftDbo, leftField, rightDbo, rightField, INNER_JOIN);
- } else if ("right".equals(joinTyp)) {
- buildJoin(leftDbo, leftField, rightDbo, rightField, RIGHT_JOIN);
- } else {
- throw new DBException(thisClass + "count()" +
- "Missing join-type in '" + oneJoin + "'");
- }
- }
- success = true;
- }
- // ----------------------------------------------------
- else if (!originalRelations.isEmpty() || dboCount == 1) {
- // To build the relations with the foreign-key definitions,
- // we need to have all the DBObejcts in the from clause.
- // If this is not the special case, where our Object has only
- // one embedded DBObject: We have to link them later in the
- // where clause.
- boolean needComma = false;
- DBObject oneObj = null;
-
- for (Enumeration eachObj = myDBObjects.elements();
- eachObj.hasMoreElements();) {
- oneObj = (DBObject) eachObj.nextElement();
-
- if (needComma) {
- fsb.append(",");
- }
+ if (needComma) {
+ fsb.append(",");
+ }
//Edit by Christian Reibnegger 2004-12-03
//Including the DB-Name in the SQL-FROM-Statement
//***********************************************
- try {
- String dbKey = oneObj.getDataContext();
- String dataContext = oneObj.getMappedDataContext();
-
- if (!dbKey.equals(dataContext)) {
-
- // Get The DataBaseName from the ConfigContext
- com.jcorporate.expresso.core.misc.ConfigContext ctx =
- ConfigManager.getContext(oneObj.getMappedDataContext());
- ConfigJdbc confJdbc = ctx.getJdbc();
- String serverURL = confJdbc.getUrl();
- int lastIndex = serverURL.lastIndexOf("/");
- String dbName = serverURL.substring(lastIndex + 1);
-
- // append the DatabaseName to the SQL-FROM-Statement
- fsb.append(dbName + ".");
- }
- } catch (IndexOutOfBoundsException iOOBex) {
- throw new DBException(this + " IndexOutOfBoundsException: " + iOOBex.getMessage());
- }
-
- String targetTable = oneObj.getJDBCMetaData().getTargetSQLTable(oneObj.getDataContext());
- String tableName = getTableName(oneObj);
- fsb.append(targetTable);
- // AS keyword to set table short name is not standard and not supported by all
- // SQL manipulation languages. This need to be set properly with each driver
- // Keyword to be set in expresso config file for table alias name syntax
-
- if (!targetTable.equals(tableName)) {
- if (ConfigManager.getJdbcRequired(getDataContext()).getTableAliasKeyword() != null) {
- fsb.append(
- " " + ConfigManager.getJdbcRequired(getDataContext()).getTableAliasKeyword() + " " + tableName);
- } else {
- fsb.append(" AS " + tableName);
- }
- }
-
- needComma = true;
- }
-
- fromClause = fsb.toString();
- success = true;
+ try {
+ String dbKey = oneObj.getDataContext();
+ String dataContext = oneObj.getMappedDataContext();
+
+ if (!dbKey.equals(dataContext)) {
+
+ // Get The DataBaseName from the ConfigContext
+ com.jcorporate.expresso.core.misc.ConfigContext ctx =
+ ConfigManager.getContext(oneObj.getMappedDataContext());
+ ConfigJdbc confJdbc = ctx.getJdbc();
+ String serverURL = confJdbc.getUrl();
+ int lastIndex = serverURL.lastIndexOf("/");
+ String dbName = serverURL.substring(lastIndex + 1);
+
+ // append the DatabaseName to the SQL-FROM-Statement
+ fsb.append(dbName + ".");
+ }
+ }
+ catch (IndexOutOfBoundsException iOOBex) {
+ throw new DBException(this +" IndexOutOfBoundsException: " +
+ iOOBex.getMessage());
+ }
+
+ String targetTable = oneObj.getJDBCMetaData().getTargetSQLTable(
+ oneObj.getDataContext());
+ String tableName = getTableName(oneObj);
+ fsb.append(targetTable);
+ // AS keyword to set table short name is not standard and not supported by all
+ // SQL manipulation languages. This need to be set properly with each driver
+ // Keyword to be set in expresso config file for table alias name syntax
+
+ if (!targetTable.equals(tableName)) {
+ if (ConfigManager.getJdbcRequired(getDataContext()).
+ getTableAliasKeyword() != null) {
+ fsb.append(
+ " " +
+ ConfigManager.getJdbcRequired(getDataContext()).
+ getTableAliasKeyword() +
+ " " + tableName);
}
- // ----------------------------------------------------
else {
- // build clause
- boolean needComma = false;
-
- for (Enumeration eachObj = myDBObjects.elements();
- eachObj.hasMoreElements();) {
- DBObject oneObj = (DBObject) eachObj.nextElement();
-
- if (needComma) {
- fsb.append(",");
- }
-
- String targetTable = oneObj.getJDBCMetaData().getTargetSQLTable(oneObj.getDataContext());
- String tableName = getTableName(oneObj);
- fsb.append(targetTable);
- if (!targetTable.equals(tableName)) {
- if (ConfigManager.getJdbcRequired(getDataContext()).getTableAliasKeyword() != null) {
- fsb.append(
- " " + ConfigManager.getJdbcRequired(getDataContext()).getTableAliasKeyword() + " " + tableName);
- } else {
- fsb.append(" AS " + tableName);
- }
- }
+ //fsb.append(" AS " + tableName);
+ // AS keyword to set table short name is not standard and not supported by all
+ // SQL manipulation languages. This need to be set properly with each driver
+ // Standard SQL implementation is space. AS keyword should be added in expresso config
+ fsb.append(" " + tableName);
+ }
+ }
+
+ needComma = true;
+ }
+
+ fromClause = fsb.toString();
+ success = true;
+ }
+ // ----------------------------------------------------
+ else {
+ // build clause
+ boolean needComma = false;
- needComma = true;
- }
+ for (Enumeration eachObj = myDBObjects.elements();
+ eachObj.hasMoreElements(); ) {
+ DBObject oneObj = (DBObject) eachObj.nextElement();
- fromClause = fsb.toString();
- success = true;
+ if (needComma) {
+ fsb.append(",");
+ }
+
+ String targetTable = oneObj.getJDBCMetaData().getTargetSQLTable(
+ oneObj.getDataContext());
+ String tableName = getTableName(oneObj);
+ fsb.append(targetTable);
+ if (!targetTable.equals(tableName)) {
+ if (ConfigManager.getJdbcRequired(getDataContext()).
+ getTableAliasKeyword() != null) {
+ fsb.append(
+ " " +
+ ConfigManager.getJdbcRequired(getDataContext()).
+ getTableAliasKeyword() +
+ " " + tableName);
+ }
+ else {
+ fsb.append(" AS " + tableName);
}
- } catch (Throwable t) {
- throw new DBException(t);
- } finally {
- fsb.release();
+ }
+
+ needComma = true;
}
- return (success);
+ fromClause = fsb.toString();
+ success = true;
+ }
+ }
+ catch (Throwable t) {
+ throw new DBException(t);
+ }
+ finally {
+ fsb.release();
}
- // 2003-11-05 /ebn-ma: ...added
- // ----------------------------------------------------
+ return (success);
+ }
- /**
- * Just like find, but only retrieves the count, not the records themselves.
- *
- * @return integer Count of the records matching the criteria
- * @throws DBException If the search could not be completed
- */
- public synchronized int count(String expr)
- throws DBException {
+ // 2003-11-05 /ebn-ma: ...added
+ // ----------------------------------------------------
+
+
+ /**
+ * Just like find, but only retrieves the count, not the records themselves.
+ *
+ * @return integer Count of the records matching the criteria
+ * @throws DBException If the search could not be completed
+ */
+ public synchronized int count(String expr) throws DBException {
// boolean needComma = false;
// DBObject oneObj = null;
// DBField oneField = null;
@@ -547,43 +577,45 @@
// }
- DBConnectionPool myPool = null;
- DBConnection myConnection = null;
+ DBConnectionPool myPool = null;
+ DBConnection myConnection = null;
- try {
- if (localConnection != null) {
- myConnection = localConnection;
- } else {
- myPool = DBConnectionPool.getInstance(getDataContext());
- myConnection = myPool.getConnection("com.jcorporate.expresso.core.dbobj.DBObject");
- }
-
- if (recordSet == null) {
- String myName = (thisClass + "count()");
- throw new DBException(myName +
- ":Database object not correctly initialized");
- }
-
- recordSet.clear();
-
- FastStringBuffer myStatement = new FastStringBuffer(256);
- myStatement.append("SELECT ");
-
- if (selectDistinct) {
- myStatement.append(" DISTINCT ");
- }
- if (StringUtil.isBlankOrNull(expr)) {
- expr = "*";
- }
- myStatement.append("COUNT(" + expr + ") ");
-
- // ----------------------------------------------------
- // 2003-11-05 /ebn-ma: changed...
- // We build the from clause every time we genereate a
- // sql-statement. Because:
- // If we use joins, this is the only chance to integrate
- // filter-conditions that follow the actual values in
- // the properties of the related DBObjects.
+ try {
+ if (localConnection != null) {
+ myConnection = localConnection;
+ }
+ else {
+ myPool = DBConnectionPool.getInstance(getDataContext());
+ myConnection = myPool.getConnection(
+ "com.jcorporate.expresso.core.dbobj.DBObject");
+ }
+
+ if (recordSet == null) {
+ String myName = (thisClass + "count()");
+ throw new DBException(myName +
+ ":Database object not correctly initialized");
+ }
+
+ recordSet.clear();
+
+ FastStringBuffer myStatement = new FastStringBuffer(256);
+ myStatement.append("SELECT ");
+
+ if (selectDistinct) {
+ myStatement.append(" DISTINCT ");
+ }
+ if (StringUtil.isBlankOrNull(expr)) {
+ expr = "*";
+ }
+ myStatement.append("COUNT(" + expr + ") ");
+
+ // ----------------------------------------------------
+ // 2003-11-05 /ebn-ma: changed...
+ // We build the from clause every time we genereate a
+ // sql-statement. Because:
+ // If we use joins, this is the only chance to integrate
+ // filter-conditions that follow the actual values in
+ // the properties of the related DBObjects.
// myStatement.append(" FROM ");
// if (fromClause == null) {
@@ -611,1763 +643,1919 @@
// */
// }
- myStatement.append(" FROM ");
- if (buildFromClause() &&
- fromClause != null &&
- fromClause.trim().length() > 0) {
- myStatement.append(fromClause);
- } else {
- throw new DBException(thisClass + "count()" +
- " :Building of FROM clause failed.");
- }
- // 2003-11-05 /ebn-ma: ...changed
- // ----------------------------------------------------
-
- String whereClause;
- if (customWhereClause != null) {
- if (appendCustomWhereClause) {
- whereClause = buildWhereClause(true) + " AND " + customWhereClause;
- } else {
- whereClause = " WHERE " + customWhereClause;
- }
- } else {
- whereClause = buildWhereClause(true);
- }
-
- myStatement.append(whereClause);
-
- appendCustomWhereClause = false;
-
- if (log.isDebugEnabled()) {
- log.debug("Executing " + myStatement.toString());
- }
-
- myConnection.execute(myStatement.toString());
-
- if (myConnection.next()) {
- return myConnection.getInt(1);
- }
- } finally {
- if (localConnection == null) {
- myPool.release(myConnection);
- }
- }
-
-
- return 0;
- } /* count() */
-
- /**
- * Just like find, but only retrieves the count, not the records themselves.
- *
- * @return integer Count of the records matching the criteria
- * @throws DBException If the search could not be completed
- */
- public synchronized int count()
- throws DBException {
- return count("");
- } /* count() */
-
-
- /**
- * Creates the limitation syntax optimisation stub
- * to embed inside the SQL command that performs
- * search and retrieve.
- * <p/>
- * <p>This method takes the limitation syntax string
- * and performs a string replacement on the following
- * tokens
- * <p/>
- * <ul>
- * <p/>
- * <li><b>%offset%</b><li><br>
- * the number of rows in the <code>ResultSet</code> to skip
- * before reading the data.
- * <p/>
- * <li><b>%maxrecord%</b><li><br>
- * the maximum number of rows to read from the <code>ResultSet</code>.
- * Also known as the <i>rowlength</i>.
- * <p/>
- * <li><b>%endrecord%</b><li><br>
- * the last record of in the <code>ResultSet</code> that the
- * search and retrieved should retrieve. The end record number
- * is equal to <code>( %offset% + %maxrecord% - 1 )</code>
- * <p/>
- * </ul>
- * <p/>
- * </p>
- * <p/>
- * <p/>
- * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
- *
- * @param theConnection the db connection to make this stub from
- * @return the limitation syntax stub string
- * @see #searchAndRetrieveList()
- * @see #setOffsetRecord( int )
- * @see #setMaxRecords( int )
- */
- protected String makeLimitationStub(DBConnection theConnection) {
- String limit = theConnection.getLimitationSyntax();
- int offset = this.getOffsetRecord();
- int maxrec = this.getMaxRecords();
- int endrec = offset + maxrec - 1;
- limit = StringUtil.replace(limit, "%offset%", Integer.toString(offset));
- limit = StringUtil.replace(limit, "%maxrecords%",
- Integer.toString(maxrec));
-
- // limit = StringUtil.replace( limit, "%length%", Integer.toString( maxrec ) );
- limit = StringUtil.replace(limit, "%endrecord%",
- Integer.toString(endrec));
-
- return limit;
- } /* makeLimitationStub(DBConnection) */
-
+ myStatement.append(" FROM ");
+ if (buildFromClause() &&
+ fromClause != null &&
+ fromClause.trim().length() > 0) {
+ myStatement.append(fromClause);
+ }
+ else {
+ throw new DBException(thisClass + "count()" +
+ " :Building of FROM clause failed.");
+ }
+ // 2003-11-05 /ebn-ma: ...changed
+ // ----------------------------------------------------
+
+ String whereClause;
+ if (customWhereClause != null) {
+ if (appendCustomWhereClause) {
+ whereClause = buildWhereClause(true) + " AND " + customWhereClause;
+ }
+ else {
+ whereClause = " WHERE " + customWhereClause;
+ }
+ }
+ else {
+ whereClause = buildWhereClause(true);
+ }
+
+ myStatement.append(whereClause);
+
+ appendCustomWhereClause = false;
+
+ if (log.isDebugEnabled()) {
+ log.debug("Executing " + myStatement.toString());
+ }
+
+ myConnection.execute(myStatement.toString());
+
+ if (myConnection.next()) {
+ return myConnection.getInt(1);
+ }
+ }
+ finally {
+ if (localConnection == null) {
+ myPool.release(myConnection);
+ }
+ }
+
+ return 0;
+ }
+
+ /* count() */
+
+ /**
+ * Just like find, but only retrieves the count, not the records themselves.
+ *
+ * @return integer Count of the records matching the criteria
+ * @throws DBException If the search could not be completed
+ */
+ public synchronized int count() throws DBException {
+ return count("");
+ }
+
+ /* count() */
+
+ /**
+ * Creates the limitation syntax optimisation stub
+ * to embed inside the SQL command that performs
+ * search and retrieve.
+ * <p/>
+ * <p>This method takes the limitation syntax string
+ * and performs a string replacement on the following
+ * tokens
+ * <p/>
+ * <ul>
+ * <p/>
+ * <li><b>%offset%</b><li><br>
+ * the number of rows in the <code>ResultSet</code> to skip
+ * before reading the data.
+ * <p/>
+ * <li><b>%maxrecord%</b><li><br>
+ * the maximum number of rows to read from the <code>ResultSet</code>.
+ * Also known as the <i>rowlength</i>.
+ * <p/>
+ * <li><b>%endrecord%</b><li><br>
+ * the last record of in the <code>ResultSet</code> that the
+ * search and retrieved should retrieve. The end record number
+ * is equal to <code>( %offset% + %maxrecord% - 1 )</code>
+ * <p/>
+ * </ul>
+ * <p/>
+ * </p>
+ * <p/>
+ * <p/>
+ * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
+ *
+ * @param theConnection the db connection to make this stub from
+ * @return the limitation syntax stub string
+ * @see #searchAndRetrieveList()
+ * @see #setOffsetRecord( int )
+ * @see #setMaxRecords( int )
+ */
+ protected String makeLimitationStub(DBConnection theConnection) {
+ String limit = theConnection.getLimitationSyntax();
+ int offset = this.getOffsetRecord();
+ int maxrec = this.getMaxRecords();
+ int endrec = offset + maxrec - 1;
+ limit = StringUtil.replace(limit, "%offset%", Integer.toString(offset));
+ limit = StringUtil.replace(limit, "%maxrecords%",
+ Integer.toString(maxrec));
+
+ // limit = StringUtil.replace( limit, "%length%", Integer.toString( maxrec ) );
+ limit = StringUtil.replace(limit, "%endrecord%",
+ Integer.toString(endrec));
+
+ return limit;
+ }
+
+ /* makeLimitationStub(DBConnection) */
+
+ private static final String thisClass = MultiDBObject.class.getName() + ".";
+
+ /**
+ * Hash that contains the DB objects that relate to make up this query,
+ * indexed by the "short" name provided by the user.
+ */
+ private Hashtable myDBObjects = new Hashtable();
+
+ /**
+ * Vector to hold the "relations" between the different db objects that
+ * make up this query
+ */
+ private Vector relations = new Vector();
+ private String dbName = null;
+
+ /**
+ * This flag tells the buildWhereClause method(s) to either be case
+ * sensitive (normal queries) or to be case insensitive. The case
+ * insensitive query is useful when you want to do a search and retreive
+ * and want case insensitive matching.
+ */
+ private boolean caseSensitiveQuery = true;
+
+ /**
+ * broken into a vector
+ */
+ private Vector sortKeys = new Vector();
+
+ /**
+ * The vector of MultiDB objects retrieved by the last searchAndRetrieve method
+ */
+ private List recordSet = new ArrayList();
+
+ /**
+ * If we are using a custom where clause for this query, it's stored here. If
+ * null, then build the where clause
+ */
+ private String customWhereClause = null;
+
+ /**
+ * Hold the relations in "original" form - for the getThisMultiDBObj method
+ */
+ private Vector originalRelations = new Vector();
+
+ /**
+ * Local connection that we use if it's initialized, but
+ * if it's null we generate our own connection
+ */
+ protected DBConnection localConnection = null;
+
+ /* The max number of records we retrieve in a searchAndRetrieve.
+ * 0 means no limit
+ */
+ protected int maxRecords = 0;
+ private static Logger log = Logger.getLogger(MultiDBObject.class);
+
+ /**
+ * MultiDBObject constructor. calls setupFields.
+ */
+ public MultiDBObject() throws DBException {
+ setupFields();
+ }
+
+ /* MultiDBObject() */
+
+ /**
+ * MultiDBObject constructor which sets dbname from request
+ */
+ public MultiDBObject(ControllerRequest request) throws DBException {
+ this();
+ setDataContext(request.getDataContext());
+ }
+
+ /* MultiDBObject() */
+
+ /**
+ * Add a DB Object to the objects being used for this multidbobj query. The
+ * object is specified with a full classname, then a "short" name used to refer
+ * to it in this object. For example, the class name might be
+ * com.jcorporate.expresso.services.dbobj.SchemaList, the short name might be
+ * "schema".
+ *
+ * @param dbobjClassName java.lang.String
+ * @param shortName java.lang.String
+ */
+ public void addDBObj(String dbobjClassName, String shortName) throws
+ DBException {
+ String myName = thisClass + "addDBObj(String, String)";
+
+ if (StringUtil.notNull(dbobjClassName).equals("")) {
+ throw new DBException(myName + ":Must specify a class name");
+ }
+ if (StringUtil.notNull(shortName).equals("")) {
+ throw new DBException(myName + ":Must specify a short name");
+ }
+
+ DBObject oneDBObj = null;
+
+ try {
+ Class c = ClassLocator.loadClass(dbobjClassName);
+ oneDBObj = (DBObject) c.newInstance();
+ }
+ catch (ClassNotFoundException cn) {
+ throw new DBException(myName + ":DBObject '" + dbobjClassName +
+ "' not found", cn);
+ }
+ catch (InstantiationException ie) {
+ throw new DBException(myName + ":DBObject '" + dbobjClassName +
+ "' cannot be instantiated", ie);
+ }
+ catch (IllegalAccessException iae) {
+ throw new DBException(myName +
+ ":Illegal access loading DBObject '" +
+ dbobjClassName + "'", iae);
+ }
+
+ addDBObj(oneDBObj, shortName);
+ }
+
+ public void addDBObj(DBObject oneDBObj, String shortName) throws DBException {
+ StringUtil.assertNotBlank(shortName, "Short name cannot be blank here");
+ oneDBObj.setAttribute(SHORT_NAME, shortName);
+ myDBObjects.put(shortName, oneDBObj);
+
+ if (getDataContext() == null) {
+ setDataContext(oneDBObj.getDataContext());
+ }
+
+ /* Check to see if all of the db objects are in the same database */
+ oneDBObj.setDataContext(getDataContext());
+
+ if (!oneDBObj.getDataContext().equals(getDataContext())) {
+ throw new DBException("DB Object '" +
+ oneDBObj.getClass().getName() +
+ "' was mapped to db/context '" +
+ oneDBObj.getDataContext() +
+ "', but this MultiDBObject is in context '" +
+ getDataContext() + "'");
+ }
+ }
+
+ /* addDBOj(String, String) */
+
+ /**
+ * Build and return a string consisting of an SQL 'where' clause
+ * using the current field values as criteria for the search. See
+ * setCustomWhereClause for information on specifying a more complex where clause.
+ *
+ * @param useAllFields True if all fields are to be used,
+ * false for only key fields
+ * @return The where clause to use in a query.
+ */
+ public String buildWhereClause(boolean useAllFields) throws DBException {
+ FastStringBuffer fsb = FastStringBuffer.getInstance();
+ try {
+ return buildWhereClauseBuffer(useAllFields, fsb).toString();
+ }
+ finally {
+ fsb.release();
+ }
+ }
+
+ /* buildWhereClause(boolean) */
+
+ // ----------------------------------------------------
+ // 2003-11-05 /ebn-ma: added...
+ // Method is overwritten for to support a new parameter dboAlias.
+ /**
+ * Build and return a string consisting of an SQL 'where' clause
+ * using the current field values as criteria for the search. See
+ * setCustomWhereClause for information on specifying a more complex where clause.
+ *
+ * @param useAllFields True if all fields are to be used, false for only key fields
+ * @return java.lang.String.
+ */
+ protected String buildWhereClauseBuffer(boolean useAllFields,
+ FastStringBuffer myStatement) throws
+ DBException {
+ return buildWhereClauseBuffer(useAllFields, myStatement, " ").toString();
+ }
+
+ // 2003-11-05 /ebn-ma: ...added
+ // ----------------------------------------------------
+
+ // ----------------------------------------------------
+ // 2003-11-05 /ebn-ma: changed...
+ // Method supports a new parameter dboAlias. With the help of this parameter
+ // we build selective clauses for a single DBObject.
+ // These clauses are used in method buildJoin.
+ /**
+ * Build and return a string consisting of an SQL 'where' clause
+ * using the current field values as criteria for the search. See
+ * setCustomWhereClause for information on specifying a more complex where clause.
+ *
+ * @param useAllFields True if all fields are to be used, false for only key fields
+ * @param myStatement Buffer for to build the new where-clause.
+ * @param dboAlias Build the where-clause for this DBObject. If empty,
+ * work with all DBObjects that are not marked to be ignored.
+ * @return java.lang.String.
+ */
+ protected String buildWhereClauseBuffer(boolean useAllFields,
+ FastStringBuffer myStatement,
+ String dboAlias) throws DBException {
+
+ /* list of field names (with table names prefixed) */
+ Vector fields = new Vector();
+ DBObject oneObj = null;
+ String fieldName = null;
+ Hashtable byTableName = new Hashtable();
+
+ if (useAllFields) {
+ for (Enumeration eachObj = myDBObjects.elements();
+ eachObj.hasMoreElements(); ) {
+ oneObj = (DBObject) eachObj.nextElement();
+ byTableName.put(getTableName(oneObj), oneObj);
- private static final String thisClass = MultiDBObject.class.getName() + ".";
-
- /**
- * Hash that contains the DB objects that relate to make up this query,
- * indexed by the "short" name provided by the user.
- */
- private Hashtable myDBObjects = new Hashtable();
-
- /**
- * Vector to hold the "relations" between the different db objects that
- * make up this query
- */
- private Vector relations = new Vector();
- private String dbName = null;
-
- /**
- * This flag tells the buildWhereClause method(s) to either be case
- * sensitive (normal queries) or to be case insensitive. The case
- * insensitive query is useful when you want to do a search and retreive
- * and want case insensitive matching.
- */
- private boolean caseSensitiveQuery = true;
-
- /**
- * broken into a vector
- */
- private Vector sortKeys = new Vector();
-
- /**
- * The vector of MultiDB objects retrieved by the last searchAndRetrieve method
- */
- private List recordSet = new ArrayList();
-
- /**
- * If we are using a custom where clause for this query, it's stored here. If
- * null, then build the where clause
- */
- private String customWhereClause = null;
-
- /**
- * Hold the relations in "original" form - for the getThisMultiDBObj method
- */
- private Vector originalRelations = new Vector();
-
- /**
- * Local connection that we use if it's initialized, but
- * if it's null we generate our own connection
- */
- protected DBConnection localConnection = null;
-
- /* The max number of records we retrieve in a searchAndRetrieve.
- * 0 means no limit
- */
- protected int maxRecords = 0;
- private static Logger log = Logger.getLogger(MultiDBObject.class);
-
- /**
- * MultiDBObject constructor. calls setupFields.
- */
- public MultiDBObject()
- throws DBException {
- setupFields();
- } /* MultiDBObject() */
-
- /**
- * MultiDBObject constructor which sets dbname from request
- */
- public MultiDBObject(ControllerRequest request)
- throws DBException {
- this();
- setDataContext(request.getDataContext());
- } /* MultiDBObject() */
-
- /**
- * Add a DB Object to the objects being used for this multidbobj query. The
- * object is specified with a full classname, then a "short" name used to refer
- * to it in this object. For example, the class name might be
- * com.jcorporate.expresso.services.dbobj.SchemaList, the short name might be
- * "schema".
- *
- * @param dbobjClassName java.lang.String
- * @param shortName java.lang.String
- */
- public void addDBObj(String dbobjClassName, String shortName)
- throws DBException {
- String myName = thisClass + "addDBObj(String, String)";
-
- if (StringUtil.notNull(dbobjClassName).equals("")) {
- throw new DBException(myName + ":Must specify a class name");
- }
- if (StringUtil.notNull(shortName).equals("")) {
- throw new DBException(myName + ":Must specify a short name");
- }
-
- DBObject oneDBObj = null;
-
- try {
- Class c = ClassLocator.loadClass(dbobjClassName);
- oneDBObj = (DBObject) c.newInstance();
- } catch (ClassNotFoundException cn) {
- throw new DBException(myName + ":DBObject '" + dbobjClassName +
- "' not found", cn);
- } catch (InstantiationException ie) {
- throw new DBException(myName + ":DBObject '" + dbobjClassName +
- "' cannot be instantiated", ie);
- } catch (IllegalAccessException iae) {
- throw new DBException(myName +
- ":Illegal access loading DBObject '" +
- dbobjClassName + "'", iae);
- }
-
- addDBObj(oneDBObj, shortName);
- }
-
- public void addDBObj(DBObject oneDBObj, String shortName)
- throws DBException {
- StringUtil.assertNotBlank(shortName, "Short name cannot be blank here");
- oneDBObj.setAttribute(SHORT_NAME, shortName);
- myDBObjects.put(shortName, oneDBObj);
-
- if (getDataContext() == null) {
- setDataContext(oneDBObj.getDataContext());
- }
-
- /* Check to see if all of the db objects are in the same database */
- oneDBObj.setDataContext(getDataContext());
-
- if (!oneDBObj.getDataContext().equals(getDataContext())) {
- throw new DBException("DB Object '" +
- oneDBObj.getClass().getName() +
- "' was mapped to db/context '" +
- oneDBObj.getDataContext() +
- "', but this MultiDBObject is in context '" +
- getDataContext() + "'");
+ // ----------------------------------------------------
+ // 2003-11-05 /ebn-ma: added...
+ // Two cases:
+ // 1. If dboAlias tells us to compute the on-clause of a join,
+ // then we will ignore every DBObject that is not the one
+ // specified in dboAlias.
+ // 2. If dboAlias is empty, we are computing the where-clause of
+ // our sql-statement.
+ // In this case we ignore the current DBObject, if it is a
+ // member of ignoreInWhereClause.
+ String thisDbo = (String) oneObj.getAttribute(SHORT_NAME);
+
+ if (dboAlias.trim().length() > 0) {
+ if (!thisDbo.equals(dboAlias)) {
+ continue;
+ }
}
- } /* addDBOj(String, String) */
-
- /**
- * Build and return a string consisting of an SQL 'where' clause
- * using the current field values as criteria for the search. See
- * setCustomWhereClause for information on specifying a more complex where clause.
- *
- * @param useAllFields True if all fields are to be used,
- * false for only key fields
- * @return The where clause to use in a query.
- */
- public String buildWhereClause(boolean useAllFields)
- throws DBException {
- FastStringBuffer fsb = FastStringBuffer.getInstance();
- try {
- return buildWhereClauseBuffer(useAllFields, fsb).toString();
- } finally {
- fsb.release();
+ else if (ignoreInWhereClause.indexOf("," + thisDbo + ",") >= 0) {
+ continue;
}
- } /* buildWhereClause(boolean) */
-
- // ----------------------------------------------------
- // 2003-11-05 /ebn-ma: added...
- // Method is overwritten for to support a new parameter dboAlias.
- /**
- * Build and return a string consisting of an SQL 'where' clause
- * using the current field values as criteria for the search. See
- * setCustomWhereClause for information on specifying a more complex where clause.
- *
- * @param useAllFields True if all fields are to be used, false for only key fields
- * @return java.lang.String.
- */
- protected String buildWhereClauseBuffer(boolean useAllFields, FastStringBuffer myStatement)
- throws DBException {
- return buildWhereClauseBuffer(useAllFields, myStatement, " ").toString();
- }
- // 2003-11-05 /ebn-ma: ...added
- // ----------------------------------------------------
-
- // ----------------------------------------------------
- // 2003-11-05 /ebn-ma: changed...
- // Method supports a new parameter dboAlias. With the help of this parameter
- // we build selective clauses for a single DBObject.
- // These clauses are used in method buildJoin.
- /**
- * Build and return a string consisting of an SQL 'where' clause
- * using the current field values as criteria for the search. See
- * setCustomWhereClause for information on specifying a more complex where clause.
- *
- * @param useAllFields True if all fields are to be used, false for only key fields
- * @param myStatement Buffer for to build the new where-clause.
- * @param dboAlias Build the where-clause for this DBObject. If empty,
- * work with all DBObjects that are not marked to be ignored.
- * @return java.lang.String.
- */
- protected String buildWhereClauseBuffer(boolean useAllFields, FastStringBuffer myStatement, String dboAlias)
- throws DBException {
-
- /* list of field names (with table names prefixed) */
- Vector fields = new Vector();
- DBObject oneObj = null;
- String fieldName = null;
- Hashtable byTableName = new Hashtable();
-
- if (useAllFields) {
- for (Enumeration eachObj = myDBObjects.elements();
- eachObj.hasMoreElements();) {
- oneObj = (DBObject) eachObj.nextElement();
- byTableName.put(getTableName(oneObj), oneObj);
-
- // ----------------------------------------------------
- // 2003-11-05 /ebn-ma: added...
- // Two cases:
- // 1. If dboAlias tells us to compute the on-clause of a join,
- // then we will ignore every DBObject that is not the one
- // specified in dboAlias.
- // 2. If dboAlias is empty, we are computing the where-clause of
- // our sql-statement.
- // In this case we ignore the current DBObject, if it is a
- // member of ignoreInWhereClause.
- String thisDbo = (String) oneObj.getAttribute(SHORT_NAME);
-
- if (dboAlias.trim().length() > 0) {
- if (!thisDbo.equals(dboAlias)) {
- continue;
- }
- } else if (ignoreInWhereClause.indexOf("," + thisDbo + ",") >= 0) {
- continue;
- }
- // 2003-11-05 /ebn-ma: ...added
- // ----------------------------------------------------
-
- for (Iterator i = oneObj.getMetaData().getFieldListArray().iterator(); i.hasNext();) {
- fieldName = (String) i.next();
-
- if (!oneObj.getMetaData().getFieldMetadata(fieldName).isVirtual()) {
- fields.addElement(getTableName(oneObj) + "." +
- fieldName);
- }
- } /* for each field */
- }
- } else { /* for each db object */
- for (Enumeration eachObj = myDBObjects.elements();
- eachObj.hasMoreElements();) {
- oneObj = (DBObject) eachObj.nextElement();
-
- // ----------------------------------------------------
- // 2003-11-05 /ebn-ma: added...
- // Two cases:
- // 1. If dboAlias tells us to compute the on-clause of a join,
- // then we will ignore every DBObject that is not the one
- // specified in dboAlias.
- // 2. If dboAlias is empty, we are computing the where-clause of
- // our sql-statement.
- // In this case we ignore the current DBObject, if it is a
- // member of ignoreInWhereClause.
- String thisDbo = (String) oneObj.getAttribute(SHORT_NAME);
-
- if (dboAlias.trim().length() > 0) {
- if (!thisDbo.equals(dboAlias)) {
- continue;
- }
- } else if (ignoreInWhereClause.indexOf("," + thisDbo + ",") >= 0) {
- continue;
- }
- // 2003-11-05 /ebn-ma: ...added
- // ----------------------------------------------------
-
- for (Iterator i = oneObj.getKeyFieldListIterator();
- i.hasNext();) {
- fieldName = (String) i.next();
-
- if (!oneObj.getMetaData().getFieldMetadata(fieldName).isVirtual()) {
- fields.addElement(getTableName(oneObj) + "." +
- fieldName);
- }
- } /* for each field */
- } /* for each db object */
- }
-
- /* Now go thru each field - if it is non-empty, add it's criteria */
-
- /* to the where clause. If it is empty, just skip to the next one */
- boolean addWhere = true;
- boolean addAnd = false;
- String oneFieldName = null;
- String oneTableName = null;
- String oneFullName = null;
- String oneFieldValue = null;
- boolean skipText = false;
-
- try {
- ConfigJdbc myConfig = ConfigManager.getJdbcRequired(getDataContext());
- skipText = myConfig.skipText();
- } catch (ConfigurationException ce) {
- throw new DBException(ce);
- }
-
- boolean skipField = false;
-
- for (Enumeration fieldsToUse = fields.elements();
- fieldsToUse.hasMoreElements();) {
- oneFullName = (String) fieldsToUse.nextElement();
-
- StringTokenizer stk = new StringTokenizer(oneFullName, ".");
- int stkCount = stk.countTokens();
- if (stkCount == 2) {
- oneTableName = stk.nextToken();
- oneFieldName = stk.nextToken();
- } else if (stkCount == 3) {
- String oneSchemaName = stk.nextToken();
- oneTableName = stk.nextToken();
- oneFieldName = stk.nextToken();
- oneTableName = oneSchemaName + "." + oneTableName;
- }
-
- oneObj = (DBObject) byTableName.get(oneTableName);
- skipField = false;
- // ----------------------------------------------------
- // 2003-11-18 /ebn-ma: changed...
- // getField() makes a translation using the charset-filter.
- // FieldRangeParser cannot succeed, if his control-characters
- // are changed, e.g. '<' to '<'
- // getFieldData() doesn't do this translation and so it works.
- // Anyway: The corresponding code-block in JDBCUtil seems to be
-
-
- // a better solution.
- // oneFieldValue =StringUtil.notNull(oneObj.getField(oneFieldName));
-
-
- oneFieldValue = StringUtil.notNull(oneObj.getFieldData(oneFieldName));
- // 2003-11-18 /ebn-ma: ...changed
- // ----------------------------------------------------
-
- String rangeString = oneObj.denotesRange(oneFieldValue);
-
- if (!oneFieldValue.equals("")) {
- oneFieldValue = oneObj.quoteIfNeeded(oneFieldName, rangeString);
- }
- if (oneFieldValue.equals("")) {
- skipField = true;
- }
- if (oneFieldValue == null) {
- skipField = true;
- }
- if (oneFieldValue.equals("\'\'")) {
- skipField = true;
- }
- if ((oneObj.getMetaData().getType(oneFieldName).equals("text")) && (skipText)) {
- skipField = true;
- }
- if (!skipField) {
- // check to see if the field value is valid (protects agains sql injection)
- String unalteredFieldValue = oneObj.getDataField(oneFieldName).asString();
- if (rangeString != null) {
- FieldRangeParser rangeParser = new FieldRangeParser();
- boolean valid = rangeParser.isValidRange(oneObj.getFieldMetaData(oneFieldName),
- unalteredFieldValue);
- if (!valid) {
- throw new DBException("Invalid field range value: " + unalteredFieldValue);
- }
- } else if (oneObj.containsWildCards(oneFieldValue)) {
- Object origValue = oneObj.getDataField(oneFieldName).getValue();
-
- String[] wildcards = null;
- wildcards = (String[]) oneObj.getConnectionPool().getWildCardsList().toArray(new String[0]);
- Filter filter = new Filter(wildcards, wildcards);
- String valueWithoutWildCards = filter.stripFilter(unalteredFieldValue);
- // if the value without wildcards is empty, then we know the field is valid
- if (!valueWithoutWildCards.equals("")) {
- oneObj.getDataField(oneFieldName).setValue(valueWithoutWildCards);
- oneObj.getDataField(oneFieldName).checkValue();
- oneObj.getDataField(oneFieldName).setValue(origValue);
- }
- } else {
- oneObj.getDataField(oneFieldName).checkValue();
- }
-
-
- if (addWhere) {
- myStatement.append(" WHERE ");
- addWhere = false;
- }
- if (addAnd) {
- myStatement.append(" AND ");
- }
- if (oneObj.containsWildCards(oneFieldValue)) {
- if (caseSensitiveQuery) {
- myStatement.append(getTableName(oneObj) + "." +
- oneFieldName);
- myStatement.append(" LIKE ");
- myStatement.append(oneFieldValue);
- } else {
- myStatement.append("UPPER(");
- myStatement.append(getTableName(oneObj) + "." +
- oneFieldName);
- myStatement.append(") LIKE ");
- myStatement.append(oneFieldValue.toUpperCase());
- }
- } else if (rangeString != null) {
- myStatement.append(getTableName(oneObj) + "." +
- oneFieldName);
- myStatement.append(" " + rangeString + " ");
- myStatement.append(oneFieldValue);
- } else {
- if (caseSensitiveQuery) {
- myStatement.append(getTableName(oneObj) + "." +
- oneFieldName);
- myStatement.append(" = ");
- myStatement.append(oneFieldValue);
- } else {
- myStatement.append("UPPER(");
- myStatement.append(getTableName(oneObj) + "." +
- oneFieldName);
- myStatement.append(") = ");
- myStatement.append(oneFieldValue.toUpperCase());
- }
- }
-
- addAnd = true;
- }
+ // 2003-11-05 /ebn-ma: ...added
+ // ----------------------------------------------------
- /* if field is not skipped for some reason */
+ for (Iterator i = oneObj.getMetaData().getFieldListArray().iterator();
+ i.hasNext(); ) {
+ fieldName = (String) i.next();
+
+ if (!oneObj.getMetaData().getFieldMetadata(fieldName).isVirtual()) {
+ fields.addElement(getTableName(oneObj) + "." +
+ fieldName);
+ }
}
-
/* for each field */
- boolean needAnd = false;
-
- /**
- * FIXED: ma 17.10.2003
- * FIXED: Don't do that at here. We do not need
- * FIXED: WHERE, if we do not
- * FIXED: have any where-condition.
- * FIXED: So check that in the following for-loop.
- * if (addWhere) {
- * myStatement.append(" WHERE ");
- * } else {
- * needAnd = true;
- * }
- */
+ }
+ }
+ else { /* for each db object */
+ for (Enumeration eachObj = myDBObjects.elements();
+ eachObj.hasMoreElements(); ) {
+ oneObj = (DBObject) eachObj.nextElement();
// ----------------------------------------------------
- // 2003-11-05 /ebn-ma: changed...
- // If originalJoins is not empty, we are working with joins and
- // define our relations in the from clause.
- // In this case ignore all accidentially defined relations...
- if (originalJoins.isEmpty()) {
- String oneRelation = null;
-
- for (Enumeration e = relations.elements(); e.hasMoreElements();) {
- /**
- * FIXED: ma 17.10.2003 Here is a better
- * FIXED: place for addWhere...
- */
- if (addWhere) {
- myStatement.append(" WHERE ");
- addWhere = false;
- } else {
- needAnd = true;
- }
-
- oneRelation = (String) e.nextElement();
-
- if (needAnd) {
- myStatement.append(" AND ");
- }
-
- myStatement.append(oneRelation);
- needAnd = true;
- }
+ // 2003-11-05 /ebn-ma: added...
+ // Two cases:
+ // 1. If dboAlias tells us to compute the on-clause of a join,
+ // then we will ignore every DBObject that is not the one
+ // specified in dboAlias.
+ // 2. If dboAlias is empty, we are computing the where-clause of
+ // our sql-statement.
+ // In this case we ignore the current DBObject, if it is a
+ // member of ignoreInWhereClause.
+ String thisDbo = (String) oneObj.getAttribute(SHORT_NAME);
+
+ if (dboAlias.trim().length() > 0) {
+ if (!thisDbo.equals(dboAlias)) {
+ continue;
+ }
}
- // 2003-11-05 /ebn-ma: ...changed
+ else if (ignoreInWhereClause.indexOf("," + thisDbo + ",") >= 0) {
+ continue;
+ }
+ // 2003-11-05 /ebn-ma: ...added
// ----------------------------------------------------
- if (log.isDebugEnabled()) {
- log.debug(myStatement.toString());
+ for (Iterator i = oneObj.getKeyFieldListIterator();
+ i.hasNext(); ) {
+ fieldName = (String) i.next();
+
+ if (!oneObj.getMetaData().getFieldMetadata(fieldName).isVirtual()) {
+ fields.addElement(getTableName(oneObj) + "." +
+ fieldName);
+ }
}
+ /* for each field */
+ }
+ /* for each db object */
+ }
- return myStatement.toString();
- } /* buildWhereClause(boolean) */
-
+ /* Now go thru each field - if it is non-empty, add it's criteria */
- /**
- * Insert the method's description here.
- * <p/>
- * Creation date: (10/3/00 10:48:12 AM)
- *
- * @throws com.jcorporate.expresso.core.db.DBException
- * The exception description.
+ /* to the where clause. If it is empty, just skip to the next one */
+ boolean addWhere = true;
+ boolean addAnd = false;
+ String oneFieldName = null;
+ String oneTableName = null;
+ String oneFullName = null;
+ String oneFieldValue = null;
+ boolean skipText = false;
+
+ try {
+ ConfigJdbc myConfig = ConfigManager.getJdbcRequired(getDataContext());
+ skipText = myConfig.skipText();
+ }
+ catch (ConfigurationException ce) {
+ throw new DBException(ce);
+ }
+
+ boolean skipField = false;
+
+ for (Enumeration fieldsToUse = fields.elements();
+ fieldsToUse.hasMoreElements(); ) {
+ oneFullName = (String) fieldsToUse.nextElement();
+
+ StringTokenizer stk = new StringTokenizer(oneFullName, ".");
+ int stkCount = stk.countTokens();
+ if (stkCount == 2) {
+ oneTableName = stk.nextToken();
+ oneFieldName = stk.nextToken();
+ }
+ else if (stkCount == 3) {
+ String oneSchemaName = stk.nextToken();
+ oneTableName = stk.nextToken();
+ oneFieldName = stk.nextToken();
+ oneTableName = oneSchemaName + "." + oneTableName;
+ }
+
+ oneObj = (DBObject) byTableName.get(oneTableName);
+ skipField = false;
+ // ----------------------------------------------------
+ // 2003-11-18 /ebn-ma: changed...
+ // getField() makes a translation using the charset-filter.
+ // FieldRangeParser cannot succeed, if his control-characters
+ // are changed, e.g. '<' to '<'
+ // getFieldData() doesn't do this translation and so it works.
+ // Anyway: The corresponding code-block in JDBCUtil seems to be
+
+
+ // a better solution.
+ // oneFieldValue =StringUtil.notNull(oneObj.getField(oneFieldName));
+
+
+ oneFieldValue = StringUtil.notNull(oneObj.getFieldData(oneFieldName));
+ // 2003-11-18 /ebn-ma: ...changed
+ // ----------------------------------------------------
+
+ String rangeString = oneObj.denotesRange(oneFieldValue);
+
+ if (!oneFieldValue.equals("")) {
+ oneFieldValue = oneObj.quoteIfNeeded(oneFieldName, rangeString);
+ }
+ if (oneFieldValue.equals("")) {
+ skipField = true;
+ }
+ if (oneFieldValue == null) {
+ skipField = true;
+ }
+ if (oneFieldValue.equals("\'\'")) {
+ skipField = true;
+ }
+ if ( (oneObj.getMetaData().getType(oneFieldName).equals("text")) &&
+ (skipText)) {
+ skipField = true;
+ }
+ if (!skipField) {
+ // check to see if the field value is valid (protects agains sql injection)
+ String unalteredFieldValue = oneObj.getDataField(oneFieldName).asString();
+ if (rangeString != null) {
+ FieldRangeParser rangeParser = new FieldRangeParser();
+ boolean valid = rangeParser.isValidRange(oneObj.getFieldMetaData(
+ oneFieldName),
+ unalteredFieldValue);
+ if (!valid) {
+ throw new DBException("Invalid field range value: " +
+ unalteredFieldValue);
+ }
+ }
+ else if (oneObj.containsWildCards(oneFieldValue)) {
+ Object origValue = oneObj.getDataField(oneFieldName).getValue();
+
+ String[] wildcards = null;
+ wildcards = (String[]) oneObj.getConnectionPool().getWildCardsList().
+ toArray(new String[0]);
+ Filter filter = new Filter(wildcards, wildcards);
+ String valueWithoutWildCards = filter.stripFilter(unalteredFieldValue);
+ // if the value without wildcards is empty, then we know the field is valid
+ if (!valueWithoutWildCards.equals("")) {
+ oneObj.getDataField(oneFieldName).setValue(valueWithoutWildCards);
+ oneObj.getDataField(oneFieldName).checkValue();
+ oneObj.getDataField(oneFieldName).setValue(origValue);
+ }
+ }
+ else {
+ oneObj.getDataField(oneFieldName).checkValue();
+ }
+
+ if (addWhere) {
+ myStatement.append(" WHERE ");
+ addWhere = false;
+ }
+ if (addAnd) {
+ myStatement.append(" AND ");
+ }
+ if (oneObj.containsWildCards(oneFieldValue)) {
+ if (caseSensitiveQuery) {
+ myStatement.append(getTableName(oneObj) + "." +
+ oneFieldName);
+ myStatement.append(" LIKE ");
+ myStatement.append(oneFieldValue);
+ }
+ else {
+ myStatement.append("UPPER(");
+ myStatement.append(getTableName(oneObj) + "." +
+ oneFieldName);
+ myStatement.append(") LIKE ");
+ myStatement.append(oneFieldValue.toUpperCase());
+ }
+ }
+ else if (rangeString != null) {
+ myStatement.append(getTableName(oneObj) + "." +
+ oneFieldName);
+ myStatement.append(" " + rangeString + " ");
+ myStatement.append(oneFieldValue);
+ }
+ else {
+ if (caseSensitiveQuery) {
+ myStatement.append(getTableName(oneObj) + "." +
+ oneFieldName);
+ myStatement.append(" = ");
+ myStatement.append(oneFieldValue);
+ }
+ else {
+ myStatement.append("UPPER(");
+ myStatement.append(getTableName(oneObj) + "." +
+ oneFieldName);
+ myStatement.append(") = ");
+ myStatement.append(oneFieldValue.toUpperCase());
+ }
+ }
+
+ addAnd = true;
+ }
+
+ /* if field is not skipped for some reason */
+ }
+
+ /* for each field */
+ boolean needAnd = false;
+
+ /**
+ * FIXED: ma 17.10.2003
+ * FIXED: Don't do that at here. We do not need
+ * FIXED: WHERE, if we do not
+ * FIXED: have any where-condition.
+ * FIXED: So check that in the following for-loop.
+ * if (addWhere) {
+ * myStatement.append(" WHERE ");
+ * } else {
+ * needAnd = true;
+ * }
*/
- public void clear()
- throws com.jcorporate.expresso.core.db.DBException {
- DBObject oneObj = null;
- for (Enumeration eachObj = myDBObjects.elements();
- eachObj.hasMoreElements();) {
- oneObj = (DBObject) eachObj.nextElement();
- oneObj.clear();
- }
+ // ----------------------------------------------------
+ // 2003-11-05 /ebn-ma: changed...
+ // If originalJoins is not empty, we are working with joins and
+ // define our relations in the from clause.
+ // In this case ignore all accidentially defined relations...
+ if (originalJoins.isEmpty()) {
+ String oneRelation = null;
+ for (Enumeration e = relations.elements(); e.hasMoreElements(); ) {
/**
- * FIXED: ma 17.10.2003 Kill the fromClause here!
+ * FIXED: ma 17.10.2003 Here is a better
+ * FIXED: place for addWhere...
*/
- fromClause = null;
-
- } /* clear() */
-
-
- /**
- * Return the name of the context/database connection that this DB object is
- * using. If none is set, then we are using the "default" database/context.
- *
- * @return the name of the datacontext
- * @deprecated 12/2004; use getDataContext instead
- */
- public synchronized String getDBName() {
- return getDataContext();
- } /* getDBName() */
-
- /**
- * Return the name of the context/database connection that this DB object is
- * using. If none is set, then we are using the "default" database/context.
- *
- * @return the name of the datacontext
- */
- public synchronized String getDataContext() {
- // set from RequestRegistry if this is first access
- if (dbName == null || dbName.length() == 0) {
- try {
- this.setDataContext(RequestRegistry.getDataContext());
- } catch (Exception ex) {
- log.warn("Problem getting data context from Registry: " +
- ex.getClass().getName() + ", msg: " + ex.getMessage());
- try {
- setDataContext(DBConnection.DEFAULT_DB_CONTEXT_NAME);
- } catch (DBException de) {
- log.error("Unable to set database to 'default'", de);
- }
- }
-
+ if (addWhere) {
+ myStatement.append(" WHERE ");
+ addWhere = false;
}
-
- return dbName;
- }
-
-
- /**
- * This returns the encapsulated instance of the 'model' DBObject
- * that was provided in 'addDBObj()';
- * <p/>
- * After a searchAndRetrieveList(), each MultiDBObject in the list has,
- * encapsulated, an object of each type which was previously added as a model.
- * Fields of this encapsulated object have been filled from whatever was retrieved.
- * The original query object has just the original model instance.
- *
- * @param shortName the shortname of the model object
- * @return the instance encapsulated by this MultiDBObject
- * author Abhi
- * @throws DBException upon error
- * @see #addDBObj(String, String)
- * Creation date: (02/01/2002 9:33 AM)
- */
- public DBObject getDBObject(String shortName)
- throws DBException {
-
- DBObject oneObj = (DBObject) myDBObjects.get(shortName);
- if (oneObj == null) {
- String myName = thisClass + "getDBObject(String)";
- throw new DBException(myName + ":No such object as '"
- + shortName + "'");
- }
- return oneObj;
- } /* getDBObject(String) */
-
-
- /**
- * Get the actual DBField value specified by fieldname
- * <p/>
- * Creation date: (9/18/00 11:37:10 AM)
- *
- * @param shortName the shortname of the field
- * @param fieldName name of the field to retrieve
- * @return The value of the field/
- */
- public String getField(String shortName, String fieldName)
- throws DBException {
- DBObject oneObj = (DBObject) myDBObjects.get(shortName);
-
- if (oneObj == null) {
- String myName = thisClass + "getField(String, String)";
- throw new DBException(myName + ":No such object as '" + shortName +
- "'");
+ else {
+ needAnd = true;
}
- return oneObj.getField(fieldName);
- } /* getFields(String, STring) */
-
-
- private DBObject getByShortName(String shortName)
- throws DBException {
- StringUtil.assertNotBlank(shortName, "Short name may not be blank");
-
- DBObject oneObj = (DBObject) myDBObjects.get(shortName);
+ oneRelation = (String) e.nextElement();
- if (oneObj == null) {
- throw new DBException("No such object as '" + shortName + "'");
+ if (needAnd) {
+ myStatement.append(" AND ");
}
- return oneObj;
- }
-
- public String getFieldDecimalFormatted(String shortName, String fieldName,
- String formatPattern)
- throws DBException {
- return getByShortName(shortName).getFieldDecimalFormatted(fieldName,
- formatPattern);
- } /* getFieldDecimalFormatted(String, String) */
-
-
- public float getFieldFloat(String shortName, String fieldName)
- throws DBException {
- return getByShortName(shortName).getFieldFloat(fieldName);
- } /* getFieldFloat(String, String) */
-
- /**
- * Returns a double object
- * author Peter Pilgrim <peterp at xenonsoft.demon.co.uk>
- * date Wed Jul 24 19:36:37 BST 2002
- */
- public double getFieldDouble(String shortName, String fieldName)
- throws DBException {
- return getByShortName(shortName).getFieldDouble(fieldName);
- } /* getFieldDouble(String, String) */
-
- /**
- * Returns a BigDecimal object
- * author Peter Pilgrim <peterp at xenonsoft.demon.co.uk>
- * date Wed Jul 24 19:36:37 BST 2002
- */
- public BigDecimal getFieldBigDecimal(String shortName, String fieldName)
- throws DBException {
- return getByShortName(shortName).getFieldBigDecimal(fieldName);
- } /* getFieldBigDecimal(String, String) */
-
- public Date getFieldDate(String shortName, String fieldName)
- throws DBException {
- return getByShortName(shortName).getFieldDate(fieldName);
- } /* getFieldDate(String, String) */
-
-
- public int getFieldInt(String shortName, String fieldName)
- throws DBException {
- return getByShortName(shortName).getFieldInt(fieldName);
+ myStatement.append(oneRelation);
+ needAnd = true;
+ }
}
+ // 2003-11-05 /ebn-ma: ...changed
+ // ----------------------------------------------------
- public long getFieldLong(String shortName, String fieldName)
- throws DBException {
- return getByShortName(shortName).getFieldLong(fieldName);
+ if (log.isDebugEnabled()) {
+ log.debug(myStatement.toString());
}
- /**
- * Construct a new MultiDBObject
- *
- * @return new MultiDBObject
- * @throws DBException upon error
- */
- protected MultiDBObject getThisMultiDBObj()
- throws DBException {
- MultiDBObject newObj = new MultiDBObject();
- newObj.setDataContext(getDataContext());
-
- String oneKey = null;
- DBObject oneDBObj = null;
-
- for (Enumeration ek = myDBObjects.keys(); ek.hasMoreElements();) {
- oneKey = (String) ek.nextElement();
- oneDBObj = (DBObject) myDBObjects.get(oneKey);
- newObj.addDBObj(oneDBObj.newInstance(), oneKey);
- }
-
- String oneRelation = null;
+ return myStatement.toString();
+ }
- for (Enumeration er = originalRelations.elements();
- er.hasMoreElements();) {
- oneRelation = (String) er.nextElement();
-
- StringTokenizer stk = new StringTokenizer(oneRelation, "|");
- newObj.setForeignKey(stk.nextToken(), stk.nextToken(),
- stk.nextToken(), stk.nextToken());
- }
-
- // ----------------------------------------------------
- // 2003-11-05 /ebn-ma: added...
- // In the new Object we will also need this join-definitions.
- String oneJoin = null;
-
- for (Enumeration n = originalJoins.elements();
- n.hasMoreElements();) {
- oneJoin = (String) n.nextElement();
+ /* buildWhereClause(boolean) */
- StringTokenizer stk = new StringTokenizer(oneJoin, "|");
- String leftDbo = stk.nextToken();
- String leftField = stk.nextToken();
- String rightDbo = stk.nextToken();
- String rightField = stk.nextToken();
- String joinTyp = stk.nextToken().toLowerCase();
-
- if ("left".equals(joinTyp)) {
- newObj.setLeftJoin(leftDbo, leftField, rightDbo, rightField);
- } else if ("inner".equals(joinTyp)) {
- newObj.setInnerJoin(leftDbo, leftField, rightDbo, rightField);
- } else if ("right".equals(joinTyp)) {
- newObj.setRightJoin(leftDbo, leftField, rightDbo, rightField);
- }
- }
- // 2003-11-05 /ebn-ma: ...added
- // ----------------------------------------------------
-
- return newObj;
- } /* getThisMultiDBObj() */
-
- /**
- * Search and retrieve in a particular order
- *
- * @param sortKeyString A pipe-delimited list of key fields to sort
- * the returned set by
- * @return Vector A vector of new database objects retrieved by the search
- * @throws DBException If the search could not be completed
- * @deprecated Use searchAndRetrieveList(String) instead
- */
- public synchronized Vector searchAndRetrieve(String sortKeyString)
- throws DBException {
-
- return new Vector(searchAndRetrieveList(sortKeyString));
- } /* searchAndRetrieve(String) */
-
- /**
- * Search and retrieve in a particular order
- *
- * @param sortKeyString A pipe-delimited list of key fields to sort
- * the returned set by
- * @return A list of new database objects retrieved by the search
- * @throws DBException If the search could not be completed
- */
- public synchronized List searchAndRetrieveList(String sortKeyString) throws DBException {
-
- sortKeys.clear();
- if (sortKeyString != null) {
- StringTokenizer stk = new StringTokenizer(sortKeyString, "|");
- while (stk.hasMoreTokens()) {
- sortKeys.addElement(stk.nextToken());
- }
- }
-
- return searchAndRetrieveList();
+ /**
+ * Insert the method's description here.
+ * <p/>
+ * Creation date: (10/3/00 10:48:12 AM)
+ *
+ * @throws com.jcorporate.expresso.core.db.DBException
+ * The exception description.
+ */
+ public void clear() throws com.jcorporate.expresso.core.db.DBException {
+ DBObject oneObj = null;
+
+ for (Enumeration eachObj = myDBObjects.elements();
+ eachObj.hasMoreElements(); ) {
+ oneObj = (DBObject) eachObj.nextElement();
+ oneObj.clear();
}
/**
- * Search and retrieve in a particular order
- *
- * @return A list of new database objects retrieved by the search
- * @throws DBException If the search could not be completed
- */
- public synchronized List searchAndRetrieveList() throws DBException {
- boolean needComma = false;
- DBObject oneObj = null;
-
- HashMap rtrvListByTable = new HashMap();
-
- DBConnectionPool myPool = null;
- DBConnection myConnection = null;
-
+ * FIXED: ma 17.10.2003 Kill the fromClause here!
+ */
+ fromClause = null;
+
+ }
+
+ /* clear() */
+
+ /**
+ * Return the name of the context/database connection that this DB object is
+ * using. If none is set, then we are using the "default" database/context.
+ *
+ * @return the name of the datacontext
+ * @deprecated 12/2004; use getDataContext instead
+ */
+ public synchronized String getDBName() {
+ return getDataContext();
+ }
+
+ /* getDBName() */
+
+ /**
+ * Return the name of the context/database connection that this DB object is
+ * using. If none is set, then we are using the "default" database/context.
+ *
+ * @return the name of the datacontext
+ */
+ public synchronized String getDataContext() {
+ // set from RequestRegistry if this is first access
+ if (dbName == null || dbName.length() == 0) {
+ try {
+ this.setDataContext(RequestRegistry.getDataContext());
+ }
+ catch (Exception ex) {
+ log.warn("Problem getting data context from Registry: " +
+ ex.getClass().getName() + ", msg: " + ex.getMessage());
try {
- if (localConnection != null) {
- myConnection = localConnection;
- } else {
- myPool = DBConnectionPool.getInstance(getDataContext());
- myConnection = myPool.getConnection("com.jcorporate.expresso.core.dbobj.DBObject");
- }
-
- if (recordSet == null) {
- String myName = (thisClass + "searchAndRetrieve()");
- throw new DBException(myName +
- ":Database object not correctly initialized");
- }
-
- recordSet.clear();
-
- String fieldName = null;
- FastStringBuffer myStatement = new FastStringBuffer(256);
- myStatement.append("SELECT ");
-
- if (myConnection.getLimitationPosition() == DBConnection.LIMITATION_AFTER_SELECT &&
- (offsetRecord > 0 || maxRecords > 0)) {
-
- // Insert limitation stub after table nomination
- String limitStub = makeLimitationStub(myConnection);
-
- myStatement.append(" ");
- myStatement.append(limitStub);
- myStatement.append(" ");
- }
-
- if (selectDistinct) {
- myStatement.append(" ");
- myStatement.append("DISTINCT");
- myStatement.append(" ");
- }
-
- for (Enumeration eachObj = myDBObjects.elements();
- eachObj.hasMoreElements();) {
- oneObj = (DBObject) eachObj.nextElement();
-
- ArrayList retrievedFieldList = (ArrayList) rtrvListByTable.get(getTableName(oneObj));
- if (retrievedFieldList == null) {
- retrievedFieldList = new ArrayList();
- rtrvListByTable.put(getTableName(oneObj), retrievedFieldList);
- }
-
- if (oneObj.anyFieldsDistinct) {
- String oneFieldName = null;
- for (Iterator i = oneObj.getDistinctFieldArrayList().iterator();
- i.hasNext();
- ) {
- oneFieldName = (String) i.next();
- if (needComma) {
- myStatement.append(", ");
- }
- myStatement.append(" ");
- myStatement.append(myPool.getDistinctRowsetKeyword());
- myStatement.append(" ");
- myStatement.append(selectFieldString(oneObj, oneFieldName));
- retrievedFieldList.add(oneFieldName);
- needComma = true;
- }
- } else if (oneObj.anyFieldsToRetrieveMulti) {
- String oneFieldName = null;
- for (Iterator i = oneObj.getFieldsToRetrieveIterator();
- i.hasNext();
- ) {
- oneFieldName = (String) i.next();
- if (needComma) {
- myStatement.append(", ");
- }
- myStatement.append(selectFieldString(oneObj, oneFieldName));
- retrievedFieldList.add(oneFieldName);
- needComma = true;
- } /* for each field */
- } else {
- for (Iterator i = oneObj.getMetaData().getFieldListArray().iterator();
- i.hasNext();
- ) {
- fieldName = (String) i.next();
- DataFieldMetaData metaData =
- oneObj.getFieldMetaData(fieldName);
-
- if (!metaData.isVirtual()
- && !metaData.isBinaryObjectType()) {
- if (needComma) {
- myStatement.append(", ");
- }
-
- myStatement.append(selectFieldString(oneObj, fieldName));
- retrievedFieldList.add(fieldName);
- needComma = true;
- }
-
- /* if field is not virtual & not binary*/
- }
-
- /* for each field */
- }
- }
-
- myStatement.append(" FROM ");
- if (buildFromClause() &&
- fromClause != null &&
- fromClause.trim().length() > 0) {
- myStatement.append(fromClause);
- } else {
- throw new DBException(thisClass + "count()" +
- " :Building of FROM clause failed.");
- }
- // 2003-11-05 /ebn-ma: ...changed
- // ----------------------------------------------------
-
- if (myConnection.getLimitationPosition() == DBConnection.LIMITATION_AFTER_TABLE &&
- (offsetRecord > 0 || maxRecords > 0)) {
-
- // Insert limitation stub after table nomination
- String limitStub = makeLimitationStub(myConnection);
- myStatement.append(" ");
- myStatement.append(limitStub);
- myStatement.append(" ");
- }
-
- String whereClause;
- if (customWhereClause != null) {
- if (appendCustomWhereClause) {
- whereClause = buildWhereClause(true) + " AND " + customWhereClause;
- } else {
- whereClause = " WHERE " + customWhereClause;
- }
- } else {
- whereClause = buildWhereClause(true);
- }
-
- myStatement.append(whereClause);
-
- appendCustomWhereClause = false;
-
- if (myConnection.getLimitationPosition() == DBConnection.LIMITATION_AFTER_WHERE &&
- (offsetRecord > 0 || maxRecords > 0)) {
-
- // Insert limitation stub after table nomination
- String limitStub = makeLimitationStub(myConnection);
-
- if (whereClause.length() > 0) {
- myStatement.append(" AND");
- }
-
- myStatement.append(" ");
- myStatement.append(limitStub);
- myStatement.append(" ");
- }
-
- /* Add the ORDER BY clause if any sortKeys are specified */
- if (sortKeys.size() > 0) {
- myStatement.append(" ORDER BY ");
-
- boolean needComma2 = false;
-
- for (Enumeration e = sortKeys.elements(); e.hasMoreElements();) {
- if (needComma2) {
- myStatement.append(", ");
- }
-
- myStatement.append((String) e.nextElement());
- needComma2 = true;
- }
- }
-
- if (myConnection.getLimitationPosition() == DBConnection.LIMITATION_AFTER_ORDER_BY &&
- (offsetRecord > 0 || maxRecords > 0)) {
- myStatement.append(" ");
- myStatement.append(makeLimitationStub(myConnection));
- }
-
- if (log.isDebugEnabled()) {
- log.debug("Executing " + myStatement.toString());
- }
-
- myConnection.execute(myStatement.toString());
-
- int returnRecordCount = 0;
- int loopCount = 0;
- while (myConnection.next()) {
- loopCount++;
-
- //If there's limitation syntax on, then the first record will be the
- //maximum record.
- if (loopCount <= offsetRecord && offsetRecord > 0 &&
- myConnection.getLimitationPosition() == DBConnection.LIMITATION_DISABLED) {
- continue;
- }
-
- returnRecordCount++;
-
- // maxRecords = 0 by default, so I guess this means 0 doesn't count as max number... should default to -1 ?? LAH 12/03
- if ((returnRecordCount > maxRecords) && (maxRecords > 0)) {
- break;
- }
-
-
- if (log.isDebugEnabled()) {
- log.debug("Returning row " + loopCount);
- }
-
- MultiDBObject myObj = getThisMultiDBObj();
- String oneFieldValue = null;
- int i = 1;
-
- for (Enumeration eachObj = myDBObjects.elements();
- eachObj.hasMoreElements();) {
- oneObj = (DBObject) eachObj.nextElement();
-
- ArrayList retrievedFieldList = (ArrayList) rtrvListByTable.get(getTableName(oneObj));
- // The following should never happen .... but CYA
- if (retrievedFieldList == null) {
- retrievedFieldList = new ArrayList();
- }
- for (Iterator it = retrievedFieldList.listIterator();
- it.hasNext();) {
- fieldName = (String) it.next();
- DataFieldMetaData metaData = oneObj.getFieldMetaData(fieldName);
-
- if (!metaData.isVirtual() && !metaData.isBinaryObjectType()) {
- try {
- oneFieldValue = myConnection.getString(i);
- } catch (DBException de) {
- String myName = (thisClass + "searchAndRetrieve()");
- throw new DBException(myName +
- ":Error retrieving field '" +
- getTableName(oneObj) +
- "." + fieldName + "'",
- de);
- }
-
- i++;
-
- if (log.isDebugEnabled()) {
- log.debug("Setting " +
- getTableName(oneObj) + "." +
- fieldName + " to " + oneFieldValue);
- }
-
- myObj.setField((String) oneObj.getAttribute(SHORT_NAME),
- fieldName, oneFieldValue);
- }
- }
- } /* each db object */
-
-
- myObj.setDataContext(getDataContext());
- recordSet.add(myObj);
- }
-
- /* each row retrieved from the db */
- } finally {
- if (localConnection == null) {
- myPool.release(myConnection);
- }
+ setDataContext(DBConnection.DEFAULT_DB_CONTEXT_NAME);
+ }
+ catch (DBException de) {
+ log.error("Unable to set database to 'default'", de);
}
+ }
- return recordSet;
}
- /**
- * This tells the buildWhereClause to either respect case (true) or
- * ignore case (false). You can call this method before doing a search and
- * retreive if you want to match without worrying about case. For example
- * if you where to call this method with isCaseSensitiveQuery = FALSE
- * then this comparison would match in the search:
- * <p/>
- * vendor_name actual value = "My Name"
- * <p/>
- * query value = "my name"
- * <p/>
- * This would match in a search and retrieve.
- * <p/>
- * author Adam Rossi, PlatinumSolutions
- *
- * @param isCaseSensitiveQuery boolean
- */
- public void setCaseSensitiveQuery(boolean isCaseSensitiveQuery) {
- caseSensitiveQuery = isCaseSensitiveQuery;
+ return dbName;
+ }
+
+ /**
+ * This returns the encapsulated instance of the 'model' DBObject
+ * that was provided in 'addDBObj()';
+ * <p/>
+ * After a searchAndRetrieveList(), each MultiDBObject in the list has,
+ * encapsulated, an object of each type which was previously added as a model.
+ * Fields of this encapsulated object have been filled from whatever was retrieved.
+ * The original query object has just the original model instance.
+ *
+ * @param shortName the shortname of the model object
+ * @return the instance encapsulated by this MultiDBObject
+ * author Abhi
+ * @throws DBException upon error
+ * @see #addDBObj(String, String)
+ * Creation date: (02/01/2002 9:33 AM)
+ */
+ public DBObject getDBObject(String shortName) throws DBException {
+
+ DBObject oneObj = (DBObject) myDBObjects.get(shortName);
+ if (oneObj == null) {
+ String myName = thisClass + "getDBObject(String)";
+ throw new DBException(myName + ":No such object as '"
+ + shortName + "'");
+ }
+ return oneObj;
+ }
+
+ /* getDBObject(String) */
+
+ /**
+ * Get the actual DBField value specified by fieldname
+ * <p/>
+ * Creation date: (9/18/00 11:37:10 AM)
+ *
+ * @param shortName the shortname of the field
+ * @param fieldName name of the field to retrieve
+ * @return The value of the field/
+ */
+ public String getField(String shortName, String fieldName) throws DBException {
+ DBObject oneObj = (DBObject) myDBObjects.get(shortName);
+
+ if (oneObj == null) {
+ String myName = thisClass + "getField(String, String)";
+ throw new DBException(myName + ":No such object as '" + shortName +
+ "'");
+ }
+
+ return oneObj.getField(fieldName);
+ }
+
+ /* getFields(String, STring) */
+
+ private DBObject getByShortName(String shortName) throws DBException {
+ StringUtil.assertNotBlank(shortName, "Short name may not be blank");
+
+ DBObject oneObj = (DBObject) myDBObjects.get(shortName);
+
+ if (oneObj == null) {
+ throw new DBException("No such object as '" + shortName + "'");
+ }
+
+ return oneObj;
+ }
+
+ public String getFieldDecimalFormatted(String shortName, String fieldName,
+ String formatPattern) throws
+ DBException {
+ return getByShortName(shortName).getFieldDecimalFormatted(fieldName,
+ formatPattern);
+ }
+
+ /* getFieldDecimalFormatted(String, String) */
+
+ public float getFieldFloat(String shortName, String fieldName) throws
+ DBException {
+ return getByShortName(shortName).getFieldFloat(fieldName);
+ }
+
+ /* getFieldFloat(String, String) */
+
+ /**
+ * Returns a double object
+ * author Peter Pilgrim <peterp at xenonsoft.demon.co.uk>
+ * date Wed Jul 24 19:36:37 BST 2002
+ */
+ public double getFieldDouble(String shortName, String fieldName) throws
+ DBException {
+ return getByShortName(shortName).getFieldDouble(fieldName);
+ }
+
+ /* getFieldDouble(String, String) */
+
+ /**
+ * Returns a BigDecimal object
+ * author Peter Pilgrim <peterp at xenonsoft.demon.co.uk>
+ * date Wed Jul 24 19:36:37 BST 2002
+ */
+ public BigDecimal getFieldBigDecimal(String shortName, String fieldName) throws
+ DBException {
+ return getByShortName(shortName).getFieldBigDecimal(fieldName);
+ }
+
+ /* getFieldBigDecimal(String, String) */
+
+ public Date getFieldDate(String shortName, String fieldName) throws
+ DBException {
+ return getByShortName(shortName).getFieldDate(fieldName);
+ }
+
+ /* getFieldDate(String, String) */
+
+ public int getFieldInt(String shortName, String fieldName) throws DBException {
+ return getByShortName(shortName).getFieldInt(fieldName);
+ }
+
+ public long getFieldLong(String shortName, String fieldName) throws
+ DBException {
+ return getByShortName(shortName).getFieldLong(fieldName);
+ }
+
+ /**
+ * Construct a new MultiDBObject
+ *
+ * @return new MultiDBObject
+ * @throws DBException upon error
+ */
+ protected MultiDBObject getThisMultiDBObj() throws DBException {
+ MultiDBObject newObj = new MultiDBObject();
+ newObj.setDataContext(getDataContext());
+
+ String oneKey = null;
+ DBObject oneDBObj = null;
+
+ for (Enumeration ek = myDBObjects.keys(); ek.hasMoreElements(); ) {
+ oneKey = (String) ek.nextElement();
+ oneDBObj = (DBObject) myDBObjects.get(oneKey);
+ newObj.addDBObj(oneDBObj.newInstance(), oneKey);
+ }
+
+ String oneRelation = null;
+
+ for (Enumeration er = originalRelations.elements();
+ er.hasMoreElements(); ) {
+ oneRelation = (String) er.nextElement();
+
+ StringTokenizer stk = new StringTokenizer(oneRelation, "|");
+ newObj.setForeignKey(stk.nextToken(), stk.nextToken(),
+ stk.nextToken(), stk.nextToken());
}
- /**
- * Specify a custom "where" clause for the SQL used to retrieve records for
- * this object. The where clause 'reset' after each call to searchAndRetrieve()
- * or other retrieval methods, so it must be set just before the call to
- * retrieve the records is made. If no custom where clause is specified by this
- * method, the where clause is built from the field values in the object.
- * <p/>
- * DO NOT INCLUDE THE 'where' KEYWORD. Just what comes after the 'where'
- *
- * @param newCustomWhere java.lang.String
- */
- public synchronized void setCustomWhereClause(String newCustomWhere) {
- setCustomWhereClause(newCustomWhere, false);
- } /* setCustomWhereClause(String) */
-
- /**
- * Specify a custom "where" clause for the SQL used to retrieve records for
- * this object. The where clause 'reset' after each call to searchAndRetrieve()
- * or other retrieval methods, so it must be set just before the call to
- * retrieve the records is made. If no custom where clause is specified by this
- * method, the where clause is built from the field values in the object.
- *
- * @param newCustomWhere java.lang.String
- * @param append true if the custom where clause is to be appended to the 'built'
- * where clause; THIS IS DIFFERENT THAN DBObject where 'append' means to append another condition onto the custom where clause
- */
- public synchronized void setCustomWhereClause(String newCustomWhere, boolean append) {
- customWhereClause = newCustomWhere;
- appendCustomWhereClause = append;
- } /* setCustomWhereClause(String, boolean) */
-
// ----------------------------------------------------
// 2003-11-05 /ebn-ma: added...
- /**
- * Gets the customWhereClause
- *
- * @return customFromClause
- */
- public String getCustomWhereClause() {
- return customWhereClause;
- }
+ // In the new Object we will also need this join-definitions.
+ String oneJoin = null;
- /**
- * Specify if the customWhereClause should be appended to a generated
- * whereClause.
- *
- * @param newValue true = append to whereClause, else overwrite it.
- */
- public synchronized void setAppendCustomWhereClause(boolean newValue) {
- appendCustomWhereClause = newValue;
- }
-
- /**
- * Gets the settings of appendCustomWhereClause.
- *
- * @return appendCustomWhereClause
- */
- public boolean getAppendCustomWhereClause() {
- return appendCustomWhereClause;
+ for (Enumeration n = originalJoins.elements();
+ n.hasMoreElements(); ) {
+ oneJoin = (String) n.nextElement();
+
+ StringTokenizer stk = new StringTokenizer(oneJoin, "|");
+ String leftDbo = stk.nextToken();
+ String leftField = stk.nextToken();
+ String rightDbo = stk.nextToken();
+ String rightField = stk.nextToken();
+ String joinTyp = stk.nextToken().toLowerCase();
+
+ if ("left".equals(joinTyp)) {
+ newObj.setLeftJoin(leftDbo, leftField, rightDbo, rightField);
+ }
+ else if ("inner".equals(joinTyp)) {
+ newObj.setInnerJoin(leftDbo, leftField, rightDbo, rightField);
+ }
+ else if ("right".equals(joinTyp)) {
+ newObj.setRightJoin(leftDbo, leftField, rightDbo, rightField);
+ }
}
// 2003-11-05 /ebn-ma: ...added
// ----------------------------------------------------
- /**
- * Set the database name/context for this multi db object. If setDataContext is not called,
- * the "default" db name and context is used. See
- * com.jcorporate.expresso.core.misc.ConfigManager for information about multiple
- * contexts. Note that setting a db/context name only affects the object when it
- * allocates it's own db connections - if a specific connection is used (via the
- * setConnection(DBConnection) method) then that connection must be already
- * associated with the correct db/context.
- *
- * @param newOther The name of the context or database to use
- * @deprecated 12/2004 v5.6; use setDataContext() instead
- */
- public synchronized void setDBName(String newOther)
- throws DBException {
- dbName = newOther;
- } /* setDBName(String) */
-
- /**
- * Set the database name/context for this multi db object. If setDataContext is not called,
- * the "default" db name and context is used. See
- * com.jcorporate.expresso.core.misc.ConfigManager for information about multiple
- * contexts. Note that setting a db/context name only affects the object when it
- * allocates it's own db connections - if a specific connection is used (via the
- * setConnection(DBConnection) method) then that connection must be already
- * associated with the correct db/context.
- *
- * @param context The name of the context or database to use
- */
- public synchronized void setDataContext(String context)
- throws DBException {
- dbName = context;
- } /* setDataContext(String) */
-
-
- /**
- * Specify that the DISTINCT keyword for unique rows must be specified right
- * after the SELECT keyword
- *
- * @param flag true if DISTINCT supported right after SELECT, false (default) otherwise.
- */
- public void setSelectDistinct(boolean flag) {
- selectDistinct = flag;
- }
-
- /**
- * Specify a select list of fields to retrieve from a particular DBObject component
- *
- * @param shortName The alias for the DBObject
- * @param fieldNames Pipe("|")-separated list of fieldnames
- */
- public void setFieldsToRetrieve(String shortName, String fieldNames) throws DBException {
- DBObject oneObj = (DBObject) myDBObjects.get(shortName);
-
- if (oneObj == null) {
- String myName = thisClass + "setFieldsToRetrieve(String, String)";
- throw new DBException(myName + ":No such object as '" + shortName +
- "'");
- }
-
- oneObj.setFieldsToRetrieve(fieldNames);
- }
+ return newObj;
+ }
- /**
- * Specify to retrieve NO fields from a particular DBObject component
- * <p/>
- * author Zaz Harris, SRI International
- *
- * @param shortName The alias for the DBObject
- */
- public void setFieldsToRetrieveToNone(String shortName) throws DBException {
- DBObject oneObj = (DBObject) myDBObjects.get(shortName);
+ /* getThisMultiDBObj() */
- if (oneObj == null) {
- String myName = thisClass + "setFieldsToRetrieveToNone(String)";
- throw new DBException(myName + ":No such object as '" + shortName +
- "'");
+ /**
+ * Search and retrieve in a particular order
+ *
+ * @param sortKeyString A pipe-delimited list of key fields to sort
+ * the returned set by
+ * @return Vector A vector of new database objects retrieved by the search
+ * @throws DBException If the search could not be completed
+ * @deprecated Use searchAndRetrieveList(String) instead
+ */
+ public synchronized Vector searchAndRetrieve(String sortKeyString) throws
+ DBException {
+
+ return new Vector(searchAndRetrieveList(sortKeyString));
+ }
+
+ /* searchAndRetrieve(String) */
+
+ /**
+ * Search and retrieve in a particular order
+ *
+ * @param sortKeyString A pipe-delimited list of key fields to sort
+ * the returned set by
+ * @return A list of new database objects retrieved by the search
+ * @throws DBException If the search could not be completed
+ */
+ public synchronized List searchAndRetrieveList(String sortKeyString) throws
+ DBException {
+
+ sortKeys.clear();
+ if (sortKeyString != null) {
+ StringTokenizer stk = new StringTokenizer(sortKeyString, "|");
+ while (stk.hasMoreTokens()) {
+ sortKeys.addElement(stk.nextToken());
+ }
+ }
+
+ return searchAndRetrieveList();
+ }
+
+ /**
+ * Search and retrieve in a particular order
+ *
+ * @return A list of new database objects retrieved by the search
+ * @throws DBException If the search could not be completed
+ */
+ public synchronized List searchAndRetrieveList() throws DBException {
+
+ DBObject oneObj = null;
+
+ HashMap rtrvListByTable = new HashMap();
+
+ DBConnectionPool myPool = null;
+ DBConnection myConnection = null;
+
+ try {
+ if (localConnection != null) {
+ myConnection = localConnection;
+ }
+ else {
+ myPool = DBConnectionPool.getInstance(getDataContext());
+ myConnection = myPool.getConnection(
+ "com.jcorporate.expresso.core.dbobj.DBObject");
+ }
+
+ if (recordSet == null) {
+ String myName = (thisClass + "searchAndRetrieve()");
+ throw new DBException(myName +
+ ":Database object not correctly initialized");
+ }
+
+ recordSet.clear();
+
+ myConnection.execute(getSQLSelectStatement(myPool, myConnection));
+
+ int returnRecordCount = 0;
+ int loopCount = 0;
+ while (myConnection.next()) {
+ loopCount++;
+
+ //If there's limitation syntax on, then the first record will be the
+ //maximum record.
+ if (loopCount <= offsetRecord && offsetRecord > 0 &&
+ myConnection.getLimitationPosition() ==
+ DBConnection.LIMITATION_DISABLED) {
+ continue;
+ }
+
+ returnRecordCount++;
+
+ // maxRecords = 0 by default, so I guess this means 0 doesn't count as max number... should default to -1 ?? LAH 12/03
+ if ( (returnRecordCount > maxRecords) && (maxRecords > 0)) {
+ break;
}
- oneObj.retrieveFields = null;
- oneObj.anyFieldsToRetrieveMulti = true;
- }
-
- /**
- * Specify a field to be retieved uniquely froma component DBObject
- *
- * @param shortName The alias for the DBObject
- * @param fieldName The field to mark as unique
- * @param flag true=distinct, flase=all matching rows
- */
- public void setFieldDistinct(String shortName, String fieldName, boolean flag) throws DBException {
- DBObject oneObj = (DBObject) myDBObjects.get(shortName);
-
- if (oneObj == null) {
- String myName = thisClass + "setFieldDistinct(String, String, boolean)";
- throw new DBException(myName + ":No such object as '" + shortName +
- "'");
+ if (log.isDebugEnabled()) {
+ log.debug("Returning row " + loopCount);
}
- oneObj.setFieldDistinct(fieldName, flag);
- }
+ MultiDBObject myObj = getThisMultiDBObj();
+ String oneFieldValue = null;
+ int i = 1;
- /**
- * Insert the method's description here.
- * <p/>
- * Creation date: (9/18/00 11:37:10 AM)
- *
- * @param shortName the short name to set
- * @param fieldName the fieldname to set
- * @param fieldValue the value to set the field at.
- */
- public void setField(String shortName, String fieldName, String fieldValue)
- throws DBException {
- DBObject oneObj = (DBObject) myDBObjects.get(shortName);
-
- if (oneObj == null) {
- String myName = thisClass + "setField(String, String, String)";
- throw new DBException(myName + ":No such object as '" + shortName +
- "'");
- }
+ for (Enumeration eachObj = myDBObjects.elements();
+ eachObj.hasMoreElements(); ) {
+ oneObj = (DBObject) eachObj.nextElement();
- oneObj.setField(fieldName, fieldValue);
- } /* setField(String, String, String) */
+ ArrayList retrievedFieldList = (ArrayList) rtrvListByTable.get(
+ getTableName(oneObj));
+ // The following should never happen .... but CYA
+ if (retrievedFieldList == null) {
+ retrievedFieldList = new ArrayList();
+ }
+ for (Iterator it = retrievedFieldList.listIterator();
+ it.hasNext(); ) {
+ java.lang.String fieldName = (String) it.next();
+ DataFieldMetaData metaData = oneObj.getFieldMetaData(fieldName);
+
+ if (!metaData.isVirtual() && !metaData.isBinaryObjectType()) {
+ try {
+ oneFieldValue = myConnection.getString(i);
+ }
+ catch (DBException de) {
+ String myName = (thisClass + "searchAndRetrieve()");
+ throw new DBException(myName +
+ ":Error retrieving field '" +
+ getTableName(oneObj) +
+ "." + fieldName + "'",
+ de);
+ }
+
+ i++;
+
+ if (log.isDebugEnabled()) {
+ log.debug("Setting " +
+ getTableName(oneObj) + "." +
+ fieldName + " to " + oneFieldValue);
+ }
+
+ myObj.setField( (String) oneObj.getAttribute(SHORT_NAME),
+ fieldName, oneFieldValue);
+ }
+ }
+ }
+ /* each db object */
+
+ myObj.setDataContext(getDataContext());
+ recordSet.add(myObj);
+ }
+
+ /* each row retrieved from the db */
+ }
+ finally {
+ if (localConnection == null) {
+ myPool.release(myConnection);
+ }
+ }
+
+ return recordSet;
+ }
+
+ /**
+ * get the SQL select statment to be executed, if searchAnd RetrieveList happenned
+ * on this MULTIDBOBJECT
+ *
+ * @return String of select statement to be executed
+ * @throws DBException If the search could not be completed
+ */
+ public synchronized String getSQLSelectStatement() throws DBException {
+ DBConnectionPool myPool = null;
+ DBConnection myConnection = null;
+ try {
+ if (localConnection != null) {
+ myConnection = localConnection;
+ }
+ else {
+ myPool = DBConnectionPool.getInstance(getDBName());
+ myConnection = myPool.getConnection(
+ "com.jcorporate.expresso.core.dbobj.DBObject");
+ }
+ return getSQLSelectStatement(myPool, myConnection);
+ }
+ finally {
+ if (localConnection == null) {
+ myPool.release(myConnection);
+ }
+ }
+ }
+
+ /**
+ * get the SQL select statment to be executed, if searchAnd RetrieveList happenned
+ * on this MULTIDBOBJECT
+ * The use of this method is when building complex custom WHERE clauses
+ * with nested queries one can call it to get the nested select built dynamically
+ *
+ * @return String of select statement to be executed
+ * @throws DBException If the search could not be completed
+ * author Yves Henri AMAIZO
+ */
+ public synchronized String getSQLSelectStatement(DBConnectionPool myPool,
+ DBConnection myConnection) throws DBException {
+
+ boolean needComma = false;
+ DBObject oneObj = null;
+
+ HashMap rtrvListByTable = new HashMap();
+
+ String fieldName = null;
+ FastStringBuffer myStatement = new FastStringBuffer(256);
+ try {
+ myStatement.append("SELECT ");
+
+ if (myConnection.getLimitationPosition() ==
+ DBConnection.LIMITATION_AFTER_SELECT &&
+ (offsetRecord > 0 || maxRecords > 0)) {
+
+ // Insert limitation stub after table nomination
+ String limitStub = makeLimitationStub(myConnection);
+
+ myStatement.append(" ");
+ myStatement.append(limitStub);
+ myStatement.append(" ");
+ }
+
+ if (selectDistinct) {
+ myStatement.append(" ");
+ myStatement.append("DISTINCT");
+ myStatement.append(" ");
+ }
+
+ for (Enumeration eachObj = myDBObjects.elements();
+ eachObj.hasMoreElements(); ) {
+ oneObj = (DBObject) eachObj.nextElement();
+
+ ArrayList retrievedFieldList = (ArrayList) rtrvListByTable.get(
+ getTableName(oneObj));
+ if (retrievedFieldList == null) {
+ retrievedFieldList = new ArrayList();
+ rtrvListByTable.put(getTableName(oneObj), retrievedFieldList);
+ }
+
+ if (oneObj.anyFieldsDistinct) {
+ String oneFieldName = null;
+ for (Iterator i = oneObj.getDistinctFieldArrayList().iterator();
+ i.hasNext();
+ ) {
+ oneFieldName = (String) i.next();
+ if (needComma) {
+ myStatement.append(", ");
+ }
+ myStatement.append(" ");
+ myStatement.append(myPool.getDistinctRowsetKeyword());
+ myStatement.append(" ");
+ myStatement.append(selectFieldString(oneObj, oneFieldName));
+ retrievedFieldList.add(oneFieldName);
+ needComma = true;
+ }
+ }
+ else if (oneObj.anyFieldsToRetrieveMulti) {
+ String oneFieldName = null;
+ for (Iterator i = oneObj.getFieldsToRetrieveIterator();
+ i.hasNext();
+ ) {
+ oneFieldName = (String) i.next();
+ if (needComma) {
+ myStatement.append(", ");
+ }
+ myStatement.append(selectFieldString(oneObj, oneFieldName));
+ retrievedFieldList.add(oneFieldName);
+ needComma = true;
+ }
+ /* for each field */
+ }
+ else {
+ for (Iterator i = oneObj.getMetaData().getFieldListArray().iterator();
+ i.hasNext();
+ ) {
+ fieldName = (String) i.next();
+ DataFieldMetaData metaData =
+ oneObj.getFieldMetaData(fieldName);
+
+ if (!metaData.isVirtual()
+ && !metaData.isBinaryObjectType()) {
+ if (needComma) {
+ myStatement.append(", ");
+ }
+
+ myStatement.append(selectFieldString(oneObj, fieldName));
+