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.fun;
030:
031: import com.caucho.amber.expr.AbstractAmberExpr;
032: import com.caucho.amber.expr.AmberExpr;
033: import com.caucho.amber.expr.IdExpr;
034: import com.caucho.amber.expr.KeyColumnExpr;
035: import com.caucho.amber.manager.AmberConnection;
036: import com.caucho.amber.query.FromItem;
037: import com.caucho.amber.query.QueryParser;
038: import com.caucho.amber.type.Type;
039: import com.caucho.util.CharBuffer;
040: import com.caucho.util.L10N;
041:
042: import java.sql.ResultSet;
043: import java.sql.SQLException;
044: import java.util.ArrayList;
045:
046: /**
047: * Function expression
048: */
049: public class FunExpr extends AbstractAmberExpr {
050: private static final L10N L = new L10N(FunExpr.class);
051:
052: QueryParser _parser;
053:
054: String _id;
055: ArrayList<AmberExpr> _args;
056: boolean _distinct;
057:
058: /**
059: * Creates a new function expression
060: */
061: protected FunExpr(QueryParser parser, String id,
062: ArrayList<AmberExpr> args, boolean distinct) {
063: _parser = parser;
064: _id = id;
065: _args = args;
066: _distinct = distinct;
067: }
068:
069: public static FunExpr create(QueryParser parser, String id,
070: ArrayList<AmberExpr> args, boolean distinct) {
071: return new FunExpr(parser, id, args, distinct);
072: }
073:
074: /**
075: * Binds the expression as a select item.
076: */
077: public AmberExpr bindSelect(QueryParser parser) {
078: for (int i = 0; i < _args.size(); i++) {
079: AmberExpr arg = _args.get(i);
080:
081: arg = arg.bindSelect(parser);
082:
083: _args.set(i, arg);
084: }
085:
086: return this ;
087: }
088:
089: /**
090: * Returns the expr type.
091: */
092: public Type getType() {
093: if (getArgs().size() == 0)
094: return super .getType();
095:
096: // jpa/141j
097: return getArgs().get(0).getType();
098: }
099:
100: /**
101: * Returns true if the expression uses the from item.
102: */
103: public boolean usesFrom(FromItem from, int type, boolean isNot) {
104: for (int i = 0; i < _args.size(); i++) {
105: AmberExpr arg = _args.get(i);
106:
107: if (arg instanceof IdExpr) {
108: IdExpr id = (IdExpr) arg;
109:
110: // jpa/0i18
111: if (id.getFromItem() == from)
112: return true;
113: }
114:
115: if (arg instanceof KeyColumnExpr) {
116: KeyColumnExpr key = (KeyColumnExpr) arg;
117:
118: // jpa/1123
119: if (key.usesFrom(from, IS_INNER_JOIN, false))
120: return true;
121: }
122:
123: if (arg.usesFrom(from, type))
124: return true;
125: }
126:
127: return false;
128: }
129:
130: /**
131: * Generates the where expression.
132: */
133: public void generateWhere(CharBuffer cb) {
134: generateInternalWhere(cb, true);
135: }
136:
137: /**
138: * Generates the (update) where expression.
139: */
140: public void generateUpdateWhere(CharBuffer cb) {
141: generateInternalWhere(cb, false);
142: }
143:
144: /**
145: * Generates the having expression.
146: */
147: public void generateHaving(CharBuffer cb) {
148: generateWhere(cb);
149: }
150:
151: /**
152: * Returns the object for the expr.
153: */
154: public Object getObject(AmberConnection aConn, ResultSet rs,
155: int index) throws SQLException {
156: if (_id.equalsIgnoreCase("count"))
157: return rs.getLong(index);
158:
159: if (_id.equalsIgnoreCase("avg"))
160: return rs.getDouble(index);
161:
162: // jpa/1199
163: if (_id.equalsIgnoreCase("size"))
164: return rs.getInt(index);
165:
166: return super .getObject(aConn, rs, index);
167: }
168:
169: public String toString() {
170: String str = _id + "(";
171:
172: if (_distinct)
173: str += "distinct ";
174:
175: for (int i = 0; i < _args.size(); i++) {
176: if (i != 0)
177: str += ',';
178:
179: str += _args.get(i);
180: }
181:
182: return str + ")";
183: }
184:
185: // protected
186:
187: /**
188: * Returns the args.
189: */
190: public ArrayList<AmberExpr> getArgs() {
191: return _args;
192: }
193:
194: /**
195: * Generates the where clause.
196: */
197: private void generateInternalWhere(CharBuffer cb, boolean select) {
198: cb.append(_id);
199: cb.append('(');
200:
201: if (_distinct)
202: cb.append("distinct ");
203:
204: for (int i = 0; i < _args.size(); i++) {
205: if (i != 0)
206: cb.append(',');
207:
208: if (select)
209: _args.get(i).generateWhere(cb);
210: else
211: _args.get(i).generateUpdateWhere(cb);
212: }
213:
214: cb.append(')');
215: }
216: }
|