001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free Software Foundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.amber.expr;
030:
031: import com.caucho.amber.query.FromItem;
032: import com.caucho.amber.query.QueryParser;
033: import com.caucho.amber.table.LinkColumns;
034: import com.caucho.amber.table.Table;
035: import com.caucho.util.CharBuffer;
036:
037: /**
038: * Represents a member query expression
039: */
040: public class EmptyExpr extends AbstractAmberExpr {
041: private AmberExpr _collectionExpr;
042:
043: private String _tableName;
044:
045: public EmptyExpr(AmberExpr collectionExpr) {
046: _collectionExpr = collectionExpr;
047: }
048:
049: /**
050: * Returns true as a boolean expression.
051: */
052: public boolean isBoolean() {
053: return true;
054: }
055:
056: /**
057: * Binds the expression as a select item.
058: */
059: public AmberExpr bindSelect(QueryParser parser) {
060: _tableName = parser.createTableName();
061:
062: return this ;
063: }
064:
065: /**
066: * Returns true if the expression uses the from item.
067: */
068: public boolean usesFrom(FromItem from, int type, boolean isNot) {
069: return (_collectionExpr.usesFrom(from, type));
070: }
071:
072: /**
073: * Returns true if the expression uses the from item.
074: */
075: public AmberExpr replaceJoin(JoinExpr join) {
076: _collectionExpr = _collectionExpr.replaceJoin(join);
077:
078: return this ;
079: }
080:
081: /**
082: * Generates the where expression.
083: */
084: public void generateWhere(CharBuffer cb) {
085: generateInternalWhere(cb, true);
086: }
087:
088: /**
089: * Generates the (update) where expression.
090: */
091: public void generateUpdateWhere(CharBuffer cb) {
092: generateInternalWhere(cb, false);
093: }
094:
095: /**
096: * Generates the having expression.
097: */
098: public void generateHaving(CharBuffer cb) {
099: generateWhere(cb);
100: }
101:
102: //
103: // private
104:
105: private void generateInternalWhere(CharBuffer cb, boolean select) {
106: OneToManyExpr oneToMany = null;
107:
108: // ManyToMany is implemented as a
109: // ManyToOne[embeddeding OneToMany]
110: if (_collectionExpr instanceof ManyToOneExpr) {
111: PathExpr expr = ((ManyToOneExpr) _collectionExpr)
112: .getParent();
113: if (expr instanceof OneToManyExpr)
114: oneToMany = (OneToManyExpr) expr;
115:
116: } else if (_collectionExpr instanceof OneToManyExpr) {
117: oneToMany = (OneToManyExpr) _collectionExpr;
118: } else
119: throw new UnsupportedOperationException();
120:
121: LinkColumns join = oneToMany.getLinkColumns();
122:
123: Table table = join.getSourceTable();
124: cb.append("EXISTS(SELECT ");
125:
126: if (table.getIdColumns().size() > 0)
127: cb.append(table.getIdColumns().get(0).getName());
128: else
129: cb.append('*');
130:
131: cb.append(" FROM " + table.getName() + " " + _tableName);
132: cb.append(" WHERE ");
133:
134: String targetTable = oneToMany.getParent().getChildFromItem()
135: .getName();
136:
137: cb.append(join.generateJoin(_tableName, targetTable));
138:
139: cb.append(')');
140: }
141: }
|