[cvs]
expresso/expresso-web/WEB-INF/src/com/jcorporate/expresso/core/dataobjects/jdbc
JoinedDataObject.java
JCorporate Ltd
jcorp at jcorp2.servlets.net
Sat Jul 17 12:53:45 PDT 2004
Update of /home/javacorp/.cvs/expresso/expresso/expresso-web/WEB-INF/src/com/jcorporate/expresso/core/dataobjects/jdbc
In directory jcorp2.servlets.net:/tmp/cvs-serv27230
Modified Files:
JoinedDataObject.java
Log Message:
Handle required field list for dataobjects, fix generation of 'ON' clause for compound key joins,
add setCustomWhereClause() method, add setConnection() method
Index: JoinedDataObject.java
===================================================================
RCS file: /home/javacorp/.cvs/expresso/expresso/expresso-web/WEB-INF/src/com/jcorporate/expresso/core/dataobjects/jdbc/JoinedDataObject.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -C2 -d -r1.28 -r1.29
*** JoinedDataObject.java 1 Jun 2004 18:01:27 -0000 1.28
--- JoinedDataObject.java 17 Jul 2004 19:53:43 -0000 1.29
***************
*** 116,119 ****
--- 116,120 ----
* very last relation or all the relations.</p>
* @author Michael Rimov
+ * @version $Revision$ on $Date$
*/
public class JoinedDataObject implements DataObject, Defineable, Securable, NestableDataObject {
***************
*** 193,196 ****
--- 194,204 ----
/**
+ * Flag to indicate if the custom WHERE clause should be appended to the
+ * generated WHERE clause. If false, customWhereClause will be used instead
+ * of generating one
+ */
+ private boolean appendCustomWhere = false;
+
+ /**
* This flag tells the buildWhereClause method(s) to either be case
* sensitive (normal queries) or to be case insensitive. The case
***************
*** 383,387 ****
try {
Class c = ClassLocator.loadClass(oneObj.getClassName());
! metadata.addDataObject(c, oneObj.getDefinitionName(),oneObj.getAlias());
}
catch (ClassNotFoundException ex) {
--- 391,396 ----
try {
Class c = ClassLocator.loadClass(oneObj.getClassName());
! metadata.addDataObject(c, oneObj.getDefinitionName(),oneObj.getAlias(),
! oneObj.getFieldExpressionList());
}
catch (ClassNotFoundException ex) {
***************
*** 502,505 ****
--- 511,526 ----
/**
+ * Set a custom WHERE clause
+ * @param customWhereClause
+ * @param append if true the supplied WHERE clause will be appended to the one
+ * generated, else it will replace it
+ */
+ public synchronized void setCustomWhereClause(String customWhereClause, boolean append) {
+ this.customWhereClause = customWhereClause;
+ this.appendCustomWhere = append;
+
+ }
+
+ /**
* Sets the data context. Also sets the data context for all the nested
* data obejcts
***************
*** 583,587 ****
if ((rightKey == null || rightKey.length() == 0) && (leftKey == null || leftKey.length() ==0 )) {
! return oneObj.getDataField(location[1]);
} else if ((rightKey != null && rightKey.length() > 0) && (leftKey == null || leftKey.length() ==0 )) {
//We have left key... set right key as well.
--- 604,612 ----
if ((rightKey == null || rightKey.length() == 0) && (leftKey == null || leftKey.length() ==0 )) {
! field = oneObj.getDataField(location[1]);
! if (field.getFieldMetaData().isVirtual()) {
! field.setValue(oneObj.getField(location[1]));
! }
! return field;
} else if ((rightKey != null && rightKey.length() > 0) && (leftKey == null || leftKey.length() ==0 )) {
//We have left key... set right key as well.
***************
*** 950,957 ****
isAllowed(SecuredDBObject.ADD);
! DBConnectionPool myPool = DBConnectionPool.getInstance(this.getMappedDataContext());
!
! DBConnection connection = myPool.getConnection("Joined DataObject Add");
! connection.setAutoCommit(false);
JoinedDataObjectMetaData joinMetadata = this.getJoinMetaData();
--- 975,988 ----
isAllowed(SecuredDBObject.ADD);
! DBConnection connection = null;
! boolean localConn = false;
! if (localConnection != null) {
! connection = localConnection;
! localConn = true;
! } else {
! DBConnectionPool myPool = DBConnectionPool.getInstance(this.getMappedDataContext());
! connection = myPool.getConnection("Joined DataObject Add");
! connection.setAutoCommit(false);
! }
JoinedDataObjectMetaData joinMetadata = this.getJoinMetaData();
***************
*** 999,1010 ****
}
! connection.commit();
} catch (DBException ex) {
- connection.rollback();
log.error("Error adding JoinedDataObject",ex);
} finally {
! connection.release();
}
setStatus(BaseDataObject.STATUS_CURRENT);
}
--- 1030,1056 ----
}
! if (!localConn) {
! connection.commit();
! connection.release();
! }
! // if (localConnection == null && connection != null) {
! // connection.commit();
! // }
} catch (DBException ex) {
log.error("Error adding JoinedDataObject",ex);
+ // if (localConnection == null && connection != null) {
+ if (!localConn) {
+ connection.rollback();
+ connection.release();
+ } else {
+ throw ex;
+ }
} finally {
! // if (localConnection == null && connection != null) {
! // connection.release();
! // }
}
+
setStatus(BaseDataObject.STATUS_CURRENT);
}
***************
*** 1117,1128 ****
if (customWhereClause != null) {
! myStatement.append(customWhereClause);
! } else {
! FastStringBuffer fsb = FastStringBuffer.getInstance();
! try {
! myStatement.append(buildWhereClauseBuffer(true, fsb));
! } finally {
! fsb.release();
}
}
--- 1163,1174 ----
if (customWhereClause != null) {
! if (appendCustomWhere) {
! buildWhereClauseBuffer(true, myStatement);
! formatCustomWhereClause(myStatement);
! } else {
! formatCustomWhereClause(myStatement);
}
+ } else {
+ buildWhereClauseBuffer(true, myStatement);
}
***************
*** 1181,1192 ****
if (customWhereClause != null) {
! myStatement.append(customWhereClause);
! } else {
! FastStringBuffer fsb = FastStringBuffer.getInstance();
! try {
! myStatement.append(buildWhereClauseBuffer(true, fsb));
! } finally {
! fsb.release();
}
}
--- 1227,1238 ----
if (customWhereClause != null) {
! if (appendCustomWhere) {
! buildWhereClauseBuffer(true, myStatement);
! formatCustomWhereClause(myStatement);
! } else {
! formatCustomWhereClause(myStatement);
}
+ } else {
+ buildWhereClauseBuffer(true, myStatement);
}
***************
*** 1358,1383 ****
}
! for (Iterator i = metadata.getFieldListArray().iterator();
! i.hasNext();
! ) {
! fieldName = (String) i.next();
! DataFieldMetaData metaData =
oneObj.getFieldMetaData(fieldName);
! if (!metaData.isVirtual()
! && !metaData.isBinaryObjectType() && !metaData.isCharacterLongObjectType()) {
! if (needComma) {
! myStatement.append(", ");
}
!
! myStatement.append(selectFieldString(oneObj, fieldName));
! retrievedFieldList.add(fieldName);
! needComma = true;
}
! /* if field is not virtual & not binary & and not long text*/
! }
/* for each field */
}
--- 1404,1463 ----
}
! List fieldsToRetrieve = this.getJoinMetaData().getFieldsToRetrieve(oneAlias);
! if (fieldsToRetrieve != null) {
! if (fieldsToRetrieve.isEmpty()) {
! // we don't want to include any fields from this table
! continue;
! }
! JoinedDataObjectMetaData.FieldList fieldList = null;
! for (Iterator i = fieldsToRetrieve.iterator(); i.hasNext();) {
! fieldList = (JoinedDataObjectMetaData.FieldList)i.next();
! String fieldExpression = fieldList.getFieldExpression();
! fieldName = fieldList.getFieldName();
! boolean isExpression = fieldList.isExpression();
! DataFieldMetaData metaData =
oneObj.getFieldMetaData(fieldName);
! if (!metaData.isVirtual()
! && !metaData.isBinaryObjectType()) {
! if (needComma) {
! myStatement.append(", ");
! }
! if (isExpression) {
! // add the expression 'as-is' to the select
! myStatement.append(fieldExpression);
! } else {
! myStatement.append(selectFieldString(oneObj, fieldName));
! }
! retrievedFieldList.add(fieldName);
! needComma = true;
}
! /* if field is not virtual & not binary*/
}
+ /* for each field */
+ } else {
+ for (Iterator i = metadata.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 */
+ }
}
***************
*** 1395,1400 ****
}
!
! buildWhereClauseBuffer(true,myStatement);
if (myConnection.getLimitationPosition() == DBConnection.LIMITATION_AFTER_WHERE &&
--- 1475,1488 ----
}
! if (customWhereClause != null) {
! if (appendCustomWhere) {
! buildWhereClauseBuffer(true, myStatement);
! formatCustomWhereClause(myStatement);
! } else {
! formatCustomWhereClause(myStatement);
! }
! } else {
! buildWhereClauseBuffer(true, myStatement);
! }
if (myConnection.getLimitationPosition() == DBConnection.LIMITATION_AFTER_WHERE &&
***************
*** 1551,1560 ****
checkInitialized();
isAllowed(SecuredDBObject.UPDATE);
! DBConnectionPool myPool = DBConnectionPool.getInstance(this.getMappedDataContext());
!
! DBConnection connection = myPool.getConnection("Joined DataObject Update");
! connection.setAutoCommit(false);
try {
--- 1639,1654 ----
checkInitialized();
isAllowed(SecuredDBObject.UPDATE);
+ DBConnection connection = null;
+ boolean localConn = false;
+ if (localConnection != null) {
+ connection = localConnection;
+ localConn = true;
+ } else {
+ DBConnectionPool myPool = DBConnectionPool.getInstance(this.getMappedDataContext());
! connection = myPool.getConnection("Joined DataObject Update");
! connection.setAutoCommit(false);
! }
try {
***************
*** 1564,1578 ****
this.addOrUpdate(oneObj);
}
!
! connection.commit();
} catch (DBException ex) {
- connection.rollback();
log.error("Error executing SQL statement",ex);
} catch (Throwable t) {
log.error("Error updating join",t);
throw new DataException("Error updating join",t);
} finally {
! connection.release();
}
--- 1658,1688 ----
this.addOrUpdate(oneObj);
}
! // if (localConnection == null && connection != null) {
! if (!localConn) {
! connection.commit();
! connection.release();
! }
} catch (DBException ex) {
log.error("Error executing SQL statement",ex);
+ // if (localConnection == null && connection != null) {
+ if (!localConn) {
+ connection.rollback();
+ connection.release();
+ } else {
+ throw ex;
+ }
} catch (Throwable t) {
log.error("Error updating join",t);
+ if (!localConn) {
+ connection.rollback();
+ connection.release();
+ }
throw new DataException("Error updating join",t);
} finally {
! // if (localConnection == null && connection != null) {
! // if (!localConn) {
! // connection.release();
! // }
}
***************
*** 1664,1667 ****
--- 1774,1787 ----
JDBCDataObject rightDBObj = getByShortName(rightShortName);
+ ArrayList leftCols = new ArrayList(3);
+ ArrayList rightCols = new ArrayList(3);
+ StringTokenizer stok = new StringTokenizer(leftColumn, "|");
+ while (stok.hasMoreTokens()) {
+ leftCols.add(stok.nextToken());
+ }
+ stok = new StringTokenizer(rightColumn, "|");
+ while (stok.hasMoreTokens()) {
+ rightCols.add(stok.nextToken());
+ }
FastStringBuffer buffer = FastStringBuffer.getInstance();
***************
*** 1687,1700 ****
buffer.append(rightDBObj.getJDBCMetaData().getTargetTable());
! buffer.append(" ON ");
! buffer.append(leftDBObj.getJDBCMetaData().getTargetTable());
! buffer.append(".");
! buffer.append(leftColumn);
! buffer.append(" = ");
! buffer.append(rightDBObj.getJDBCMetaData().getTargetTable());
! buffer.append(".");
! buffer.append(rightColumn);
! buffer.append(" ");
return buffer.toString();
--- 1807,1827 ----
buffer.append(rightDBObj.getJDBCMetaData().getTargetTable());
! buffer.append(" ON (");
! boolean addAnd = false;
+ for (int i=0; i<leftCols.size(); i++) {
+ if (addAnd) {
+ buffer.append(" AND ");
+ }
+ buffer.append(leftDBObj.getJDBCMetaData().getTargetTable());
+ buffer.append(".");
+ buffer.append((String)leftCols.get(i));
+ buffer.append(" = ");
+ buffer.append(rightDBObj.getJDBCMetaData().getTargetTable());
+ buffer.append(".");
+ buffer.append((String)rightCols.get(i));
+ addAnd = true;
+ }
+ buffer.append(") ");
return buffer.toString();
***************
*** 1827,1831 ****
boolean needComma = false;
-
List aliases = metadata.getAliasesInOrder();
Iterator eachAlias = aliases.iterator();
--- 1954,1957 ----
***************
*** 1887,1893 ****
}
-
-
-
//
//Now add all undefined table relations
--- 2013,2016 ----
***************
*** 2199,2204 ****
}
}
!
! oneFieldValue = oneObj.quoteIfNeeded(oneFieldName, rangeString);
}
--- 2322,2331 ----
}
}
! if (oneFieldValue.trim().equalsIgnoreCase("is null") ||
! oneFieldValue.trim().equalsIgnoreCase("is not null")) {
! ;
! } else {
! oneFieldValue = oneObj.quoteIfNeeded(oneFieldName, rangeString);
! }
}
***************
*** 2208,2244 ****
if (!skipField) {
! // check to see if the field value is valid (protects agains sql injection)
! try {
! String unalteredFieldValue = oneObj.getDataField(oneFieldName).asString();
! if (rangeString != null) {
! boolean valid = parser.isValidRange(oneObj.getFieldMetaData(oneFieldName), unalteredFieldValue);
! if (!valid) {
! throw new DataException("Invalid field range value: " + unalteredFieldValue);
! }
! }
! else if (sJdbcUtil.containsWildCards(oneObj, 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();
- }
- catch (DBException ex) {
- if (ex instanceof DataException) {
- throw ((DataException) ex);
- } else {
- throw new DataException("Error getting field value", ex);
- }
- }
if (addWhere) {
myStatement.append(" WHERE ");
--- 2335,2372 ----
if (!skipField) {
! // check to see if the field value is valid (protects agains sql injection)
! try {
! String unalteredFieldValue = oneObj.getDataField(oneFieldName).asString();
! if (rangeString != null) {
! boolean valid = parser.isValidRange(oneObj.getFieldMetaData(oneFieldName), unalteredFieldValue);
! if (!valid) {
! throw new DataException("Invalid field range value: " + unalteredFieldValue);
! }
! }
! else if (sJdbcUtil.containsWildCards(oneObj, 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();
! }
! catch (DBException ex) {
! if (ex instanceof DataException) {
! throw ((DataException) ex);
! } else {
! throw new DataException("Error getting field value", ex);
! }
! }
if (addWhere) {
myStatement.append(" WHERE ");
***************
*** 2262,2299 ****
}
} else if (rangeString != null) {
myStatement.append(objMetadata.getTargetTable() + "." +
oneFieldName);
! myStatement.append(" " + rangeString + " ");
! myStatement.append(oneFieldValue);
} else {
! if ((oneFieldValue.trim().equalsIgnoreCase("is null")) ||
! (oneFieldValue.trim().equalsIgnoreCase("is not null"))) {
myStatement.append(objMetadata.getTargetTable() + "." +
oneFieldName);
! myStatement.append(" ");
! myStatement.append(oneFieldValue.trim());
} else {
! if (caseSensitiveQuery) {
myStatement.append(objMetadata.getTargetTable() + "." +
! oneFieldName);
myStatement.append(" = ");
myStatement.append(oneFieldValue);
- } else {
- DataFieldMetaData dfmd = oneDataField.getFieldMetaData();
- if (dfmd.isQuotedTextType()) {
- myStatement.append("UPPER(");
- myStatement.append(objMetadata.getTargetTable() + "." +
- oneFieldName);
- myStatement.append(") = ");
- myStatement.append(oneFieldValue.toUpperCase());
- } else {
- myStatement.append(objMetadata.getTargetTable() + "." +
- oneFieldName);
- myStatement.append(" = ");
- myStatement.append(oneFieldValue);
- }
}
}
}
addAnd = true;
}
--- 2390,2427 ----
}
} else if (rangeString != null) {
+ myStatement.append(objMetadata.getTargetTable() + "." +
+ oneFieldName);
+ myStatement.append(" " + rangeString + " ");
+ myStatement.append(oneFieldValue);
+ } else if ((oneFieldValue.trim().equalsIgnoreCase("is null")) ||
+ (oneFieldValue.trim().equalsIgnoreCase(
+ "is not null"))) {
myStatement.append(objMetadata.getTargetTable() + "." +
oneFieldName);
! myStatement.append(" ");
! myStatement.append(oneFieldValue.trim());
} else {
! if (caseSensitiveQuery) {
myStatement.append(objMetadata.getTargetTable() + "." +
oneFieldName);
! myStatement.append(" = ");
! myStatement.append(oneFieldValue);
} else {
! DataFieldMetaData dfmd = oneDataField.getFieldMetaData();
! if (dfmd.isQuotedTextType()) {
! myStatement.append("UPPER(");
myStatement.append(objMetadata.getTargetTable() + "." +
! oneFieldName);
! myStatement.append(") = ");
! myStatement.append(oneFieldValue.toUpperCase());
! } else {
! myStatement.append(objMetadata.getTargetTable() + "." +
! oneFieldName);
myStatement.append(" = ");
myStatement.append(oneFieldValue);
}
}
}
+
addAnd = true;
}
***************
*** 2351,2354 ****
--- 2479,2519 ----
}
+
+ /**
+ * Replaces alias names in the customWhereClause with their correct
+ * table names
+ * @param myStatement the preallocated buffer to append to
+ * @return the formatted customWhereClause
+ */
+ private void formatCustomWhereClause(FastStringBuffer myStatement)
+ throws DBException {
+
+ String customWhere = " " + this.customWhereClause;
+
+ if (myStatement.toString().indexOf(" WHERE ") != -1) {
+ myStatement.append(" AND ");
+ } else {
+ myStatement.append(" WHERE ");
+ }
+ for (Iterator eachAlias = this.getJoinMetaData().getAliasesInOrder().iterator();
+ eachAlias.hasNext();) {
+ String oneAlias = (String)eachAlias.next();
+ JDBCDataObject oneObj = (JDBCDataObject)this.myDataObjects.get(oneAlias);
+ // replace the alias names in the custom where clause with the
+ // table names. Using the following method ensures that if any
+ // alias is a substring of another, we don't hit problems
+ customWhere =
+ StringUtil.replaceAll(customWhere, " " + oneAlias + ".",
+ " " + oneObj.getJDBCMetaData().getTargetTable() + ".");
+ if (customWhere.indexOf("("+ oneAlias + ".") != -1) {
+ customWhere =
+ StringUtil.replaceAll(customWhere, "(" + oneAlias + ".",
+ "(" + oneObj.getJDBCMetaData().getTargetTable() + ".");
+ }
+ }
+ this.setCustomWhereClause(null, false);
+ myStatement.append(customWhere.trim());
+ return;
+ }
/**
* Retrieves a nested dataobject based upon the public field name that
***************
*** 2406,2409 ****
--- 2571,2612 ----
public String getField(String fieldName) throws DBException {
return this.getDataField(fieldName).asString();
+ }
+ /**
+ * Set a specific DB connection for use with this JoinedDataObject. If you do not set
+ * a connection, the db object will request it's own connection from the
+ * appropriate connection pool & release it again after every operation (e.g.
+ * add, update, etc). It is important to use your own explicit connection when
+ * dealing with a database transactional environment (e.g. commit(), rollback()).
+ *
+ * @param newConnection The new DBConnection object to be used by this DB Object
+ * @throws DBException
+ */
+ public synchronized void setConnection(DBConnection newConnection)
+ throws DBException {
+ setConnection(newConnection, newConnection.getDataContext());
+ } /* setConnection(DBConnection) */
+
+ /**
+ * <p>
+ * Set a specific DB connection for use with this JoinedDataObject. If you do not set
+ * a connection, the object will request it's own connection from the
+ * appropriate connection pool & release it again after every operation (e.g.
+ * add, update, etc). It is important to use your own explicit connection when
+ * dealing with a database transactional environment (e.g. commit(), rollback()).
+ * </p>
+ * <p>The difference between this and setConnection(DBConnection) is that this
+ * is used for using otherDB capabilities within a transaction. So you use
+ * a dbconnection from your other pool, but the setup tables are in a different
+ * context</p>
+ *
+ * @param newConnection The new DBConnection object to be used by this DB Object
+ * @param setupTablesContext the data context that is used for the expresso setup tables.
+ * @see #setConnection(DBConnection)
+ * @throws DBException
+ */
+ public synchronized void setConnection(DBConnection newConnection,
+ String setupTablesContext) throws DBException {
+ localConnection = newConnection;
+ this.setDataContext(setupTablesContext);
}
More information about the cvs
mailing list