001: /*
002: * Copyright 2003 (C) TJDO.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the TJDO License version 1.0.
006: * See the terms of the TJDO License in the documentation provided with this software.
007: *
008: * $Id: CandidateSetExpression.java,v 1.2 2003/08/12 18:15:34 jackknifebarber Exp $
009: */
010:
011: package com.triactive.jdo.store;
012:
013: import javax.jdo.JDOUserException;
014:
015: /**
016: * A set expression that represents some set field in a query candidate class,
017: * or a set field in an object linked from the candidate class by navigation.
018: * <p>
019: * When navigated through using contains(expr), the elements of the set are
020: * relationally joined onto the query statement.
021: *
022: * @author <a href="mailto:mmartin5@austin.rr.com">Mike Martin</a>
023: * @version $Revision: 1.2 $
024: */
025:
026: class CandidateSetExpression extends SetExpression {
027: private final QueryStatement.QueryColumn ownerQsc;
028: private final SetStore setStore;
029: private final String fieldName;
030: private final DatabaseAdapter dba;
031:
032: public CandidateSetExpression(QueryStatement qs,
033: QueryStatement.QueryColumn ownerQsc, SetStore setStore,
034: String fieldName) {
035: super (qs);
036:
037: this .ownerQsc = ownerQsc;
038: this .setStore = setStore;
039: this .fieldName = fieldName;
040:
041: dba = qs.getStoreManager().getDatabaseAdapter();
042: }
043:
044: /**
045: * Executed when the contains() method is found in a query filter.
046: *
047: * @param expr The SQLExpression passed as a parameter to contains().
048: *
049: * @return The BooleanExpression resulting from the contains() method.
050: */
051:
052: public BooleanExpression containsMethod(SQLExpression expr) {
053: /* st... = "set table" */
054: /* et... = "element table" */
055: String stJavaName = ownerQsc.te.getRangeVariable()
056: .getJavaName()
057: + '.' + fieldName;
058: String etJavaNameBase = qs.getDefaultTableExpression()
059: .getRangeVariable().getJavaName();
060:
061: if (expr instanceof UnboundVariable) {
062: UnboundVariable var = (UnboundVariable) expr;
063: String etJavaName = qs.getDefaultTableExpression()
064: .getRangeVariable().getJavaName()
065: + '.' + var.getVariableName();
066:
067: TableIdentifier stRangeVar = new TableIdentifier(dba,
068: stJavaName);
069: TableIdentifier etRangeVar = new TableIdentifier(dba,
070: etJavaName);
071:
072: var.bindTo(setStore.joinElementsTo(qs, ownerQsc,
073: stRangeVar, var.getVariableType(), etRangeVar));
074: qs.setDistinctResults(true);
075:
076: return new BooleanLiteral(qs, true);
077: } else {
078: TableIdentifier stRangeVar = new TableIdentifier(dba,
079: stJavaName);
080: TableIdentifier etRangeVar;
081: int n = 0;
082:
083: do {
084: String etJavaName = stJavaName + '.' + (++n);
085:
086: etRangeVar = new TableIdentifier(dba, etJavaName);
087: } while (qs.getTableExpression(etRangeVar) != null);
088:
089: QueryStatement.QueryColumn qsc = setStore.joinElementsTo(
090: qs, ownerQsc, stRangeVar,
091: setStore.getElementType(), etRangeVar);
092: qs.setDistinctResults(true);
093:
094: SQLExpression elemExpr = dba.getMapping(qsc.column)
095: .newSQLExpression(qs, qsc, "" + n);
096:
097: return elemExpr.eq(expr);
098: }
099: }
100:
101: /**
102: * Return the BooleanExpression for a query filter in the form "set.isEmpty()".
103: *
104: * @return The BooleanExpression for a query filter in the form "set.isEmpty()".
105: */
106: public BooleanExpression isEmptyMethod() {
107: /* st... = "set table" */
108: String stJavaName = ownerQsc.te.getRangeVariable()
109: .getJavaName()
110: + '.' + fieldName;
111: TableIdentifier stRangeVar = new TableIdentifier(dba,
112: stJavaName);
113:
114: return new ExistsExpression(qs, setStore.getExistsSubquery(
115: ownerQsc, stRangeVar), false);
116: }
117:
118: public StatementText toStatementText() {
119: throw new JDOUserException(
120: "Cannot reference set object directly: field name = "
121: + fieldName);
122: }
123: }
|