001: //$Id: QuerySelect.java 6999 2005-06-03 02:04:13Z oneovthafew $
002: package org.hibernate.sql;
003:
004: import java.util.HashSet;
005: import java.util.Iterator;
006:
007: import org.hibernate.dialect.Dialect;
008:
009: /**
010: * A translated HQL query
011: * @author Gavin King
012: */
013: public class QuerySelect {
014: private Dialect dialect;
015: private JoinFragment joins;
016: private StringBuffer select = new StringBuffer();
017: private StringBuffer where = new StringBuffer();
018: private StringBuffer groupBy = new StringBuffer();
019: private StringBuffer orderBy = new StringBuffer();
020: private StringBuffer having = new StringBuffer();
021: private String comment;
022: private boolean distinct = false;
023:
024: private static final HashSet DONT_SPACE_TOKENS = new HashSet();
025: static {
026: //dontSpace.add("'");
027: DONT_SPACE_TOKENS.add(".");
028: DONT_SPACE_TOKENS.add("+");
029: DONT_SPACE_TOKENS.add("-");
030: DONT_SPACE_TOKENS.add("/");
031: DONT_SPACE_TOKENS.add("*");
032: DONT_SPACE_TOKENS.add("<");
033: DONT_SPACE_TOKENS.add(">");
034: DONT_SPACE_TOKENS.add("=");
035: DONT_SPACE_TOKENS.add("#");
036: DONT_SPACE_TOKENS.add("~");
037: DONT_SPACE_TOKENS.add("|");
038: DONT_SPACE_TOKENS.add("&");
039: DONT_SPACE_TOKENS.add("<=");
040: DONT_SPACE_TOKENS.add(">=");
041: DONT_SPACE_TOKENS.add("=>");
042: DONT_SPACE_TOKENS.add("=<");
043: DONT_SPACE_TOKENS.add("!=");
044: DONT_SPACE_TOKENS.add("<>");
045: DONT_SPACE_TOKENS.add("!#");
046: DONT_SPACE_TOKENS.add("!~");
047: DONT_SPACE_TOKENS.add("!<");
048: DONT_SPACE_TOKENS.add("!>");
049: DONT_SPACE_TOKENS.add("("); //for MySQL
050: DONT_SPACE_TOKENS.add(")");
051: }
052:
053: public QuerySelect(Dialect dialect) {
054: this .dialect = dialect;
055: joins = new QueryJoinFragment(dialect, false);
056: }
057:
058: public JoinFragment getJoinFragment() {
059: return joins;
060: }
061:
062: public void addSelectFragmentString(String fragment) {
063: if (fragment.length() > 0 && fragment.charAt(0) == ',')
064: fragment = fragment.substring(1);
065: fragment = fragment.trim();
066: if (fragment.length() > 0) {
067: if (select.length() > 0)
068: select.append(", ");
069: select.append(fragment);
070: }
071: }
072:
073: public void addSelectColumn(String columnName, String alias) {
074: addSelectFragmentString(columnName + ' ' + alias);
075: }
076:
077: public void setDistinct(boolean distinct) {
078: this .distinct = distinct;
079: }
080:
081: public void setWhereTokens(Iterator tokens) {
082: //if ( conjunctiveWhere.length()>0 ) conjunctiveWhere.append(" and ");
083: appendTokens(where, tokens);
084: }
085:
086: public void prependWhereConditions(String conditions) {
087: if (where.length() > 0) {
088: where.insert(0, conditions + " and ");
089: } else {
090: where.append(conditions);
091: }
092: }
093:
094: public void setGroupByTokens(Iterator tokens) {
095: //if ( groupBy.length()>0 ) groupBy.append(" and ");
096: appendTokens(groupBy, tokens);
097: }
098:
099: public void setOrderByTokens(Iterator tokens) {
100: //if ( orderBy.length()>0 ) orderBy.append(" and ");
101: appendTokens(orderBy, tokens);
102: }
103:
104: public void setHavingTokens(Iterator tokens) {
105: //if ( having.length()>0 ) having.append(" and ");
106: appendTokens(having, tokens);
107: }
108:
109: public void addOrderBy(String orderByString) {
110: if (orderBy.length() > 0)
111: orderBy.append(", ");
112: orderBy.append(orderByString);
113: }
114:
115: public String toQueryString() {
116: StringBuffer buf = new StringBuffer(50);
117: if (comment != null)
118: buf.append("/* ").append(comment).append(" */ ");
119: buf.append("select ");
120: if (distinct)
121: buf.append("distinct ");
122: String from = joins.toFromFragmentString();
123: if (from.startsWith(",")) {
124: from = from.substring(1);
125: } else if (from.startsWith(" inner join")) {
126: from = from.substring(11);
127: }
128:
129: buf.append(select.toString()).append(" from").append(from);
130:
131: String outerJoinsAfterWhere = joins.toWhereFragmentString()
132: .trim();
133: String whereConditions = where.toString().trim();
134: boolean hasOuterJoinsAfterWhere = outerJoinsAfterWhere.length() > 0;
135: boolean hasWhereConditions = whereConditions.length() > 0;
136: if (hasOuterJoinsAfterWhere || hasWhereConditions) {
137: buf.append(" where ");
138: if (hasOuterJoinsAfterWhere) {
139: buf.append(outerJoinsAfterWhere.substring(4));
140: }
141: if (hasWhereConditions) {
142: if (hasOuterJoinsAfterWhere) {
143: buf.append(" and (");
144: }
145: buf.append(whereConditions);
146: if (hasOuterJoinsAfterWhere) {
147: buf.append(")");
148: }
149: }
150: }
151:
152: if (groupBy.length() > 0)
153: buf.append(" group by ").append(groupBy.toString());
154: if (having.length() > 0)
155: buf.append(" having ").append(having.toString());
156: if (orderBy.length() > 0)
157: buf.append(" order by ").append(orderBy.toString());
158:
159: return dialect.transformSelectString(buf.toString());
160: }
161:
162: private static void appendTokens(StringBuffer buf, Iterator iter) {
163: boolean lastSpaceable = true;
164: boolean lastQuoted = false;
165: while (iter.hasNext()) {
166: String token = (String) iter.next();
167: boolean spaceable = !DONT_SPACE_TOKENS.contains(token);
168: boolean quoted = token.startsWith("'");
169: if (spaceable && lastSpaceable) {
170: if (!quoted || !lastQuoted)
171: buf.append(' ');
172: }
173: lastSpaceable = spaceable;
174: buf.append(token);
175: lastQuoted = token.endsWith("'");
176: }
177: }
178:
179: public void setComment(String comment) {
180: this .comment = comment;
181: }
182:
183: public QuerySelect copy() {
184: QuerySelect copy = new QuerySelect(dialect);
185: copy.joins = this.joins.copy();
186: copy.select.append(this.select.toString());
187: copy.where.append(this.where.toString());
188: copy.groupBy.append(this.groupBy.toString());
189: copy.orderBy.append(this.orderBy.toString());
190: copy.having.append(this.having.toString());
191: copy.comment = this.comment;
192: copy.distinct = this.distinct;
193: return copy;
194: }
195:
196: }
|