001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010: package org.mmbase.storage.search.implementation.database;
011:
012: import org.mmbase.storage.search.*;
013: import org.mmbase.util.logging.*;
014:
015: /**
016: * The HSQL query handler, implements {@link
017: * org.mmbase.storage.search.implementation.database.SqlHandler SqlHandler} for standard
018: * hsql functionality.
019:
020: * @author Michiel Meeuwissen
021: * @version $Id: HSqlSqlHandler.java,v 1.11 2007/06/12 10:59:41 michiel Exp $
022: * @since MMBase-1.7
023: */
024: public class HSqlSqlHandler extends BasicSqlHandler implements
025: SqlHandler {
026:
027: private static final Logger log = Logging
028: .getLoggerInstance(HSqlSqlHandler.class);
029:
030: /**
031: * Constructor.
032: */
033: public HSqlSqlHandler() {
034: super ();
035: }
036:
037: // javadoc is inherited
038: @Override
039: public int getSupportLevel(int feature, SearchQuery query)
040: throws SearchQueryException {
041: int result;
042: switch (feature) {
043: case SearchQueryHandler.FEATURE_MAX_NUMBER:
044: result = SearchQueryHandler.SUPPORT_OPTIMAL;
045: break;
046:
047: case SearchQueryHandler.FEATURE_OFFSET:
048: result = SearchQueryHandler.SUPPORT_OPTIMAL;
049: break;
050:
051: default:
052: result = super .getSupportLevel(feature, query);
053: }
054: return result;
055: }
056:
057: /**
058: * @javadoc
059: */
060: @Override
061: protected void appendDateField(StringBuilder sb, Step step,
062: String fieldName, boolean multipleSteps, int datePart) {
063: String datePartFunction = null;
064: switch (datePart) {
065: case FieldValueDateConstraint.CENTURY:
066: datePartFunction = "CENTURY";
067: break;
068: case FieldValueDateConstraint.QUARTER:
069: datePartFunction = "QUARTER";
070: break;
071: case FieldValueDateConstraint.WEEK:
072: datePartFunction = "WEEK";
073: break;
074: case FieldValueDateConstraint.DAY_OF_YEAR:
075: datePartFunction = "DAYOFYEAR";
076: break;
077: case FieldValueDateConstraint.DAY_OF_WEEK:
078: datePartFunction = "DAYOFWEEK";
079: break;
080: default:
081: log.debug("Unknown datePart " + datePart);
082: }
083: if (datePartFunction != null) {
084: sb.append(datePartFunction);
085: sb.append("(");
086: appendField(sb, step, fieldName, multipleSteps);
087: sb.append(")");
088: } else {
089: super .appendDateField(sb, step, fieldName, multipleSteps,
090: datePart);
091: }
092: }
093:
094: // javadoc is inherited
095: @Override
096: public String toSql(SearchQuery query, SqlHandler firstInChain)
097: throws SearchQueryException {
098: // XXX should table and field aliases be tested for uniqueness?
099:
100: // Test for at least 1 step and 1 field.
101: if (query.getSteps().isEmpty()) {
102: throw new IllegalStateException(
103: "Searchquery has no step (at leas 1 step is required).");
104: }
105: if (query.getFields().isEmpty()) {
106: throw new IllegalStateException(
107: "Searchquery has no field (at least 1 field is required).");
108: }
109:
110: // SELECT
111: StringBuilder sbQuery = new StringBuilder("SELECT ");
112:
113: // OFFSET & LIMIT
114: int offset = query.getOffset();
115: int limit = query.getMaxNumber();
116: if (offset != 0 || limit > -1) {
117: if (offset == 0) {
118: sbQuery.append("TOP ").append(limit).append(' ');
119: } else {
120: if (limit == -1) {
121: sbQuery.append("LIMIT ").append(offset).append(
122: " 0 ");
123: } else {
124: sbQuery.append("LIMIT ").append(offset).append(' ')
125: .append(limit).append(' ');
126: // what if 'limit' == 0?
127: // logically, that should give no results, but it will now be interpreted as -1
128: }
129: }
130:
131: }
132: // DISTINCT
133: if (query.isDistinct()) {
134: sbQuery.append("DISTINCT ");
135: }
136:
137: firstInChain.appendQueryBodyToSql(sbQuery, query, firstInChain);
138:
139: String strSQL = sbQuery.toString();
140: if (log.isDebugEnabled()) {
141: log.debug("generated SQL: " + query + " -- >" + strSQL);
142: }
143: return strSQL;
144: }
145: }
|