1 16 package org.outerj.daisy.query.model; 17 18 import org.outerj.daisy.repository.query.QueryException; 19 import org.outerj.daisy.repository.query.EvaluationContext; 20 import org.outerj.daisy.repository.query.SortOrder; 21 import org.outerj.daisy.query.QueryContext; 22 import org.outerj.daisy.jdbcutil.JdbcHelper; 23 24 import java.sql.PreparedStatement ; 25 import java.sql.SQLException ; 26 import java.util.List ; 27 import java.util.Map ; 28 import java.util.Iterator ; 29 30 49 public class Query { 50 private ValueExprList selectClause; 51 private PredicateExpr whereClause; 52 private ValueExprList orderByClause; 53 private List sortOrders; 54 private int limit; 55 private FullTextQuery fullTextQuery; 56 private boolean includeRetired = false; 57 private boolean searchLastVersion = false; 58 private boolean annotateLinkFields = true; 59 private String styleHint; 60 private SqlGenerationContext sqlGenerationContext; 61 62 public Query(ValueExprList selectClause, PredicateExpr whereClause, FullTextQuery fullTextQuery, ValueExprList orderByClause, List sortOrders, int limit) { 63 this.selectClause = selectClause; 64 this.whereClause = whereClause; 65 this.orderByClause = orderByClause; 66 this.sortOrders = sortOrders; 67 this.limit = limit; 68 this.fullTextQuery = fullTextQuery; 69 70 if (selectClause == null) 71 throw new NullPointerException ("select clause is a required part of Query."); 72 if (whereClause == null && fullTextQuery == null) 73 throw new NullPointerException ("where clause is a required part of Query."); 74 } 75 76 public void prepare(QueryContext context) throws QueryException { 77 selectClause.prepare(context); 78 if (whereClause != null) 79 whereClause.prepare(context); 80 if (orderByClause != null) { 81 orderByClause.prepare(context); 82 ValueExpr[] valueExprs = orderByClause.getArray(); 83 for (int i = 0; i < valueExprs.length; i++) { 84 if (valueExprs[i].isMultiValue() || valueExprs[i].getValueType() == QValueType.UNDEFINED) 85 throw new QueryException("Sorting not possible on \"" + valueExprs[i].getExpression() + "\"."); 86 } 87 } 88 if (fullTextQuery != null) 89 fullTextQuery.prepare(context); 90 } 91 92 public boolean hasSql() { 93 return whereClause != null; 94 } 95 96 99 public String getSql(JdbcHelper jdbcHelper) throws QueryException { 100 if (whereClause == null) 101 throw new QueryException("This query has no SQL part."); 102 103 this.sqlGenerationContext = new SqlGenerationContext(jdbcHelper); 104 105 StringBuffer whereSql = new StringBuffer (1000); 106 whereClause.generateSql(whereSql, sqlGenerationContext); 107 108 StringBuffer sql = new StringBuffer (whereSql.length() + 5000); 109 sqlGenerationContext.appendDocIdSelectClause(sql); 110 sqlGenerationContext.appendFromClause(sql, searchLastVersion); 111 sql.append(" where "); 112 sql.append("("); 113 sql.append(whereSql); 114 sql.append(")"); 115 if (!includeRetired) 116 sql.append(" and document_variants.retired = ?"); 117 if (!searchLastVersion) 118 sql.append(" and document_variants.liveversion_id != -1"); 119 120 return sql.toString(); 121 } 122 123 public FullTextQuery getFullTextQuery() { 124 return fullTextQuery; 125 } 126 127 public void bindSql(PreparedStatement stmt, int bindPos, EvaluationContext evaluationContext) throws SQLException , QueryException { 128 if (whereClause == null) 129 throw new IllegalStateException ("This query has no SQL part."); 130 131 if (sqlGenerationContext == null) 132 throw new IllegalStateException ("SQL is not yet generated, can not yet be bound."); 133 134 bindPos = sqlGenerationContext.bindJoins(stmt, bindPos); 135 bindPos = whereClause.bindSql(stmt, bindPos, evaluationContext); 136 137 if (!includeRetired) 138 stmt.setBoolean(bindPos, false); 139 } 140 141 public ValueExpr[] getSelectValueExprs() { 142 return selectClause.getArray(); 143 } 144 145 public ValueExpr[] getOrderByValueExprs() { 146 if (orderByClause == null) 147 return null; 148 else 149 return orderByClause.getArray(); 150 } 151 152 public SortOrder[] getOrderBySortOrders() { 153 if (sortOrders == null) 154 return null; 155 else 156 return (SortOrder[])sortOrders.toArray(new SortOrder[sortOrders.size()]); 157 } 158 159 public int getLimit() { 160 return limit; 161 } 162 163 public void setIncludeRetired(boolean includeRetired) { 164 this.includeRetired = includeRetired; 165 } 166 167 public void setSearchLastVersion(boolean searchLastVersion) { 168 this.searchLastVersion = searchLastVersion; 169 } 170 171 public boolean getSearchLastVersion() { 172 return this.searchLastVersion; 173 } 174 175 public String getStyleHint() { 176 return styleHint; 177 } 178 179 public void setStyleHint(String styleHint) { 180 this.styleHint = styleHint; 181 } 182 183 public boolean getAnnotateLinkFields() { 184 return annotateLinkFields; 185 } 186 187 public void setAnnotateLinkFields(boolean annotateLinkFields) { 188 this.annotateLinkFields = annotateLinkFields; 189 } 190 191 public void setOption(String name, String value) { 192 if (name.equalsIgnoreCase("include_retired")) 193 setIncludeRetired(value.equalsIgnoreCase("true")); 194 else if (name.equalsIgnoreCase("search_last_version")) 195 setSearchLastVersion(value.equalsIgnoreCase("true")); 196 else if (name.equalsIgnoreCase("style_hint")) 197 setStyleHint(value); 198 else if (name.equalsIgnoreCase("annotate_link_fields")) 199 setAnnotateLinkFields(value.equalsIgnoreCase("true")); 200 else 201 throw new RuntimeException ("Unrecognized option: " + name); 202 } 203 204 public void setOptions(Map options) { 205 if (options.size() == 0) 206 return; 207 208 Iterator optionsIt = options.entrySet().iterator(); 209 while (optionsIt.hasNext()) { 210 Map.Entry entry = (Map.Entry )optionsIt.next(); 211 String name = (String )entry.getKey(); 212 String value = (String )entry.getValue(); 213 setOption(name, value); 214 } 215 } 216 217 220 public void mergeCondition(PredicateExpr predicateExpr) { 221 And and = new And(); 222 and.add(whereClause); 223 and.add(predicateExpr); 224 this.whereClause = and; 225 } 226 } 227 | Popular Tags |