001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019: package org.openharmonise.commons.dsi.dml;
020:
021: import java.util.*;
022:
023: import org.openharmonise.commons.dsi.*;
024:
025: /**
026: * A DML select statement query.
027: *
028: * @author Michael Bell
029: * @version $Revision: 1.2 $
030: *
031: */
032: public class SelectStatement extends AbstractDMLStatement {
033:
034: /**
035: * Constant to indicate results should be ordered in ascending order.
036: */
037: static public String ORDER_ASCENDING = "ASC";
038:
039: /**
040: * Constant to indicate results should be ordered in descending order.
041: */
042: static public String ORDER_DESCENDING = "DESC";
043:
044: /**
045: * Join conditions for this select statement.
046: */
047: private JoinConditions m_join = null;
048:
049: /**
050: * List of column references to be returned by query.
051: */
052: private List m_SelectCols = null;
053:
054: /**
055: * Mapping of column refs to order by with the order direction to be
056: * ordered by.
057: */
058: private Map m_orderColMap = null;
059:
060: /**
061: * The maximum number of rows to be returned.
062: */
063: private int m_nLimit = -1;
064:
065: /**
066: * Flag to indicate whether this select statement is to return distict
067: * result rows.
068: */
069: private boolean m_distinct = false;
070:
071: /**
072: * List of select column references to have the 'max' function applied to.
073: */
074: private List m_maxcols = null;
075:
076: /**
077: * Constructs a select statement.
078: *
079: */
080: public SelectStatement() {
081: m_SelectCols = new Vector();
082: }
083:
084: /**
085: * Adds a constant to be returned in select statement result.
086: *
087: * @param i <code>int</code> constant to be returned by query
088: */
089: public void addSelectColumn(int i) {
090: if (m_SelectCols == null) {
091: m_SelectCols = new Vector(16);
092: }
093:
094: m_SelectCols.add(new Integer(i));
095: }
096:
097: /**
098: * Adds list of column references to be added to list of columns
099: * to be returned by this query.
100: *
101: * @param colrefs list of <code>ColumnRef</code>s to be returned
102: */
103: public void addSelectColumns(List colrefs) {
104: if (m_SelectCols == null) {
105: m_SelectCols = new Vector(16);
106: }
107:
108: m_SelectCols.addAll(colrefs);
109: }
110:
111: /**
112: * Adds a column reference to be added to list of columns
113: * to be returned by this query.
114: *
115: * @param colref
116: */
117: public void addSelectColumn(ColumnRef colref) {
118: if (m_SelectCols == null) {
119: m_SelectCols = new Vector(16);
120: }
121:
122: m_SelectCols.add(colref);
123: }
124:
125: /**
126: * Returns the list of column references to be returned by this query.
127: *
128: * @return the list of column references to be returned by this query
129: */
130: public List getSelectColumns() {
131: return m_SelectCols;
132: }
133:
134: /**
135: * Returns the index of the <code>ColumnRef</code> object in result set
136: * of this query.
137: *
138: * @param colRef the column reference
139: *
140: * @return the index of the column in the result set
141: */
142: public int getResultSetIndex(ColumnRef colRef) {
143: return m_SelectCols.indexOf(colRef) + 1;
144: }
145:
146: /**
147: * Returns <code>true</code> if colRef is a select column.
148: *
149: * @param colRef the column reference
150: *
151: * @return <code>true</code> if colRef is a select column.
152: */
153: public boolean containsSelectColumn(ColumnRef colRef) {
154: return m_SelectCols.contains(colRef);
155: }
156:
157: /**
158: * Adds a column to be returned in select column with the 'max()' function
159: * applied.
160: *
161: * @param colref the column reference
162: */
163: public void addSelectMaxColumn(ColumnRef colref) {
164: if (m_maxcols == null) {
165: m_maxcols = new Vector(16);
166: }
167:
168: m_maxcols.add(new Integer(m_SelectCols.size()));
169:
170: m_SelectCols.add(colref);
171: }
172:
173: /**
174: * Returns the list of column references which have to have the 'max()'
175: * function applied to by the query.
176: *
177: * @return the list of column references
178: */
179: public List getSelectMaxColumns() {
180: return m_maxcols;
181: }
182:
183: /**
184: * Set the column reference which is to be used to order the result of this
185: * query.
186: *
187: * @param colref the column reference
188: * @throws DataStoreException
189: */
190: public void setOrderBy(ColumnRef colref) {
191: addOrderBy(colref);
192: }
193:
194: /**
195: * Sets the maximum number of rows that can be returned by this query.
196: *
197: * @param num maximum number of rows to be returned
198: */
199: public void setLimit(int num) {
200: m_nLimit = num;
201: }
202:
203: /**
204: * Returns <code>true</code> if a maximum number of rows that can be
205: * returned by this query has been set.
206: *
207: * @return <code>true</code> if a limit has been set
208: */
209: public boolean isLimit() {
210: return (m_nLimit > 0);
211: }
212:
213: /**
214: * Returns the maximum number of rows that can be returned by this query.
215: *
216: * @return the maximum number of rows that can be returned
217: */
218: public int getLimit() {
219: return m_nLimit;
220: }
221:
222: /**
223: * Adds a collection of join conditions to this query.
224: *
225: * @param join the collection of join conditions
226: * @throws DataStoreException if an error occurs merging the join conditions
227: */
228: public void addJoinConditions(JoinConditions join)
229: throws DataStoreException {
230: if (join != null) {
231: if (m_join == null) {
232: m_join = new JoinConditions();
233: }
234:
235: m_join.merge(join);
236: }
237: }
238:
239: /**
240: * Adds an inner join condition to this query.
241: *
242: * @param colref1 the left column reference for this join
243: * @param colref2 the right column reference for this join
244: * @throws DataStoreException if the join is invalid
245: */
246: public void addJoinCondition(ColumnRef colref1, ColumnRef colref2)
247: throws DataStoreException {
248: if (m_join == null) {
249: m_join = new JoinConditions();
250: }
251:
252: m_join.addCondition(colref1, colref2);
253: }
254:
255: /**
256: * Adds an outer join condition to this query.
257: *
258: * @param innerMember the inner memeber column reference of this join
259: * @param outerMember the outer memeber column reference of this join
260: * @throws DataStoreException if the join is invalid
261: */
262: public void addOuterJoinCondition(ColumnRef innerMember,
263: ColumnRef outerMember) throws DataStoreException {
264: if (m_join == null) {
265: m_join = new JoinConditions();
266: }
267:
268: m_join.addOuterJoin(innerMember, outerMember);
269: }
270:
271: /**
272: * Returns the collection of join conditions applicable to this query.
273: *
274: * @return the collection of join conditions
275: */
276: public JoinConditions getJoinConditions() {
277: return m_join;
278: }
279:
280: /**
281: * Returns <code>true</code> if this query has join conditions.
282: *
283: * @return <code>true</code> if this query has join conditions.
284: */
285: public boolean hasJoinConditions() {
286: if ((m_join == null) || (m_join.size() == 0)) {
287: return false;
288: } else {
289: return true;
290: }
291: }
292:
293: /* (non-Javadoc)
294: * @see org.openharmonise.commons.dsi.dml.AbstractDMLStatement#addWhereCondition(org.openharmonise.commons.dsi.dml.WhereCondition)
295: */
296: public void addWhereCondition(WhereCondition where)
297: throws DataStoreException {
298: super .addWhereCondition(where);
299:
300: //get associated joins
301: JoinConditions joins = where.getAssociatedJoinConditions();
302:
303: addJoinConditions(joins);
304: }
305:
306: /* (non-Javadoc)
307: * @see org.openharmonise.commons.dsi.dml.AbstractDMLStatement#addWhereCondition(org.openharmonise.commons.dsi.dml.WhereConditionGroup)
308: */
309: public void addWhereCondition(WhereConditionGroup where)
310: throws DataStoreException {
311: super .addWhereCondition(where);
312:
313: //get associated joins
314: for (int i = 0; i < where.size(); i++) {
315: Object cond = where.getCondition(i);
316:
317: if (cond instanceof WhereCondition) {
318: JoinConditions joins = ((WhereCondition) cond)
319: .getAssociatedJoinConditions();
320:
321: addJoinConditions(joins);
322: }
323: }
324: }
325:
326: /**
327: * Sets whether this query will return distinct results.
328: *
329: * @param bIsDistinct <code>true</code> if the results should be distinct
330: */
331: public void setDistinct(boolean bIsDistinct) {
332: m_distinct = bIsDistinct;
333: }
334:
335: /**
336: * Returns <code>true</code> if the results of this query should be
337: * distinct.
338: *
339: * @return<code>true</code> if the results should be distinct
340: */
341: public boolean isDistinct() {
342: return m_distinct;
343: }
344:
345: /* (non-Javadoc)
346: * @see org.openharmonise.commons.dsi.dml.AbstractDMLStatement#clear()
347: */
348: public void clear() {
349: super .clear();
350:
351: if (m_join != null) {
352: m_join.empty();
353: }
354:
355: if (m_SelectCols != null) {
356: m_SelectCols.clear();
357: }
358:
359: m_orderColMap.clear();
360: m_nLimit = -1;
361: }
362:
363: /**
364: * Add column reference to order the results of this select statement by.
365: *
366: * @param colref the column reference
367: */
368: public void addOrderBy(ColumnRef colref) {
369: addOrderBy(colref, ORDER_ASCENDING);
370: }
371:
372: /**
373: * Add column reference to order the results of this select statement by.
374: *
375: * @param colref the column reference
376: * @param orderDir the direction of ordering
377: */
378: public void addOrderBy(ColumnRef colref, String orderDir) {
379: initialiseOrderByMap();
380:
381: m_orderColMap.put(colref, orderDir);
382: }
383:
384: /**
385: * Returns the <code>Set<code> of column references to order
386: * the results of this select statment by.
387: *
388: * @return the <code>Set<code> of column references
389: */
390: public Set getOrderByColumns() {
391: initialiseOrderByMap();
392:
393: return m_orderColMap.keySet();
394: }
395:
396: /**
397: * Returns the ordering direction for the specified 'order by' column.
398: *
399: * @param colref the column reference
400: * @return the ordering direction
401: */
402: public String getOrderByDirection(ColumnRef colref) {
403: initialiseOrderByMap();
404:
405: return (String) m_orderColMap.get(colref);
406: }
407:
408: /**
409: * Initialise the mapping between 'order by' column references
410: * and the associated ordering direction.
411: *
412: */
413: private void initialiseOrderByMap() {
414: if (m_orderColMap == null) {
415: //use LinkedHashMap to ensure ordering is maintained
416: m_orderColMap = new LinkedHashMap();
417: }
418: }
419:
420: /**
421: * Add order by column reference to ordering direction mappings
422: * to this select statement.
423: *
424: * @param byColMap Map of column reference ordering direction pairs
425: */
426: public void addOrderBy(Map byColMap) {
427: if (m_orderColMap == null) {
428: m_orderColMap = new LinkedHashMap(byColMap);
429: } else {
430: Iterator iter = byColMap.keySet().iterator();
431:
432: while (iter.hasNext()) {
433: ColumnRef colref = (ColumnRef) iter.next();
434: m_orderColMap.put(colref, byColMap.get(colref));
435: }
436: }
437:
438: }
439: }
|