1 10 11 package com.triactive.jdo.store; 12 13 import java.util.ArrayList ; 14 import java.util.HashMap ; 15 import java.util.Iterator ; 16 import javax.jdo.JDOFatalInternalException; 17 18 19 public class QueryStatement 20 { 21 protected final StoreManager storeMgr; 22 protected final DatabaseAdapter dba; 23 protected final SQLIdentifier defaultRangeVar; 24 protected final TableExpression initialTableExpr; 25 26 protected HashMap tableExprsByRangeVar = new HashMap (); 27 protected boolean distinctResults = false; 28 protected ArrayList selected = new ArrayList (); 29 protected ArrayList joins = new ArrayList (); 30 protected BooleanExpression whereExpr = null; 31 protected StatementText orderByList = null; 32 protected StatementText stmtText = null; 33 34 public QueryStatement(Table initialTable) 35 { 36 this.storeMgr = initialTable.getStoreManager(); 37 this.dba = storeMgr.getDatabaseAdapter(); 38 39 defaultRangeVar = new TableIdentifier(dba, "this"); 40 41 initialTableExpr = newTableExpression(initialTable, defaultRangeVar); 42 tableExprsByRangeVar.put(defaultRangeVar, initialTableExpr); 43 } 44 45 public QueryStatement(Table initialTable, SQLIdentifier initialRangeVar) 46 { 47 this.storeMgr = initialTable.getStoreManager(); 48 this.dba = storeMgr.getDatabaseAdapter(); 49 50 defaultRangeVar = new TableIdentifier(dba, "this"); 51 52 initialTableExpr = newTableExpression(initialTable, initialRangeVar); 53 tableExprsByRangeVar.put(initialRangeVar, initialTableExpr); 54 } 55 56 protected void assertNotFrozen() 57 { 58 if (stmtText != null) 59 throw new JDOFatalInternalException("A query statement cannot be modified after being output"); 60 } 61 62 public StoreManager getStoreManager() 63 { 64 return storeMgr; 65 } 66 67 public TableExpression getTableExpression(SQLIdentifier rangeVar) 68 { 69 return (TableExpression)tableExprsByRangeVar.get(rangeVar); 70 } 71 72 public TableExpression getDefaultTableExpression() 73 { 74 return getTableExpression(defaultRangeVar); 75 } 76 77 public TableExpression newTableExpression(Table mainTable, SQLIdentifier rangeVar) 78 { 79 assertNotFrozen(); 80 81 TableExpression te = (TableExpression)tableExprsByRangeVar.get(rangeVar); 82 83 if (te == null) 84 { 85 te = dba.newTableExpression(this, mainTable, rangeVar); 86 87 tableExprsByRangeVar.put(rangeVar, te); 88 } 89 else 90 { 91 if (!te.getMainTable().equals(mainTable)) 92 throw new JDOFatalInternalException("Range variable " + rangeVar + " already in use in query: " + this); 93 } 94 95 return te; 96 } 97 98 public boolean getDistinctResults() 99 { 100 return distinctResults; 101 } 102 103 public void setDistinctResults(boolean distinctResults) 104 { 105 assertNotFrozen(); 106 107 this.distinctResults = distinctResults; 108 } 109 110 public int select(Column col) 111 { 112 return select(defaultRangeVar, col); 113 } 114 115 public int select(SQLIdentifier rangeVar, Column col) 116 { 117 assertNotFrozen(); 118 119 String columnID = getColumn(rangeVar, col).toString(); 120 121 if (!selected.contains(columnID)) 122 selected.add(columnID); 123 124 return selected.indexOf(columnID) + 1; 125 } 126 127 public int columnsSelected() 128 { 129 return selected.size(); 130 } 131 132 public QueryColumn getColumn(Column col) 133 { 134 return getColumn(defaultRangeVar, col); 135 } 136 137 public QueryColumn getColumn(SQLIdentifier rangeVar, Column col) 138 { 139 TableExpression te = (TableExpression)tableExprsByRangeVar.get(rangeVar); 140 141 if (te == null) 142 throw new JDOFatalInternalException("No such range variable: " + rangeVar); 143 144 return getColumn(te, col); 145 } 146 147 public QueryColumn getColumn(TableExpression te, Column col) 148 { 149 return new QueryColumn(te, col); 150 } 151 152 public void innerJoin(QueryColumn from, QueryColumn to) 153 { 154 assertNotFrozen(); 155 156 joins.add(new Join("INNER JOIN", from, to)); 157 } 158 159 public void leftOuterJoin(QueryColumn from, QueryColumn to) 160 { 161 assertNotFrozen(); 162 163 joins.add(new Join("LEFT OUTER JOIN", from, to)); 164 } 165 166 public void rightOuterJoin(QueryColumn from, QueryColumn to) 167 { 168 assertNotFrozen(); 169 170 joins.add(new Join("RIGHT OUTER JOIN", from, to)); 171 } 172 173 public void andCondition(BooleanExpression condition) 174 { 175 assertNotFrozen(); 176 177 if (whereExpr == null) 178 whereExpr = condition; 179 else 180 whereExpr = whereExpr.and(condition); 181 } 182 183 public void setOrdering(SQLExpression[] exprs, boolean[] descending) 184 { 185 assertNotFrozen(); 186 187 boolean needsSelect = dba.includeOrderByColumnsInSelect(); 188 189 orderByList = new StatementText(); 190 191 for (int i = 0; i < exprs.length; ++i) 192 { 193 if (i > 0) 194 orderByList.append(','); 195 196 orderByList.append(exprs[i]); 197 198 if (descending[i]) 199 orderByList.append(" DESC"); 200 201 if (needsSelect) 202 { 203 Iterator j = exprs[i].toStatementText().getReferencedColumns().iterator(); 204 205 while (j.hasNext()) 206 { 207 String columnRef = j.next().toString(); 208 209 if (!selected.contains(columnRef)) 210 selected.add(columnRef); 211 } 212 } 213 } 214 } 215 216 public StatementText toStatementText() 217 { 218 if (stmtText == null) 219 { 220 stmtText = new StatementText("SELECT "); 221 222 if (distinctResults) 223 stmtText.append("DISTINCT "); 224 225 Iterator i = selected.iterator(); 226 227 while (i.hasNext()) 228 { 229 stmtText.append(i.next()); 230 231 if (i.hasNext()) 232 stmtText.append(','); 233 } 234 235 stmtText.append(" FROM ").append(initialTableExpr); 236 237 i = joins.iterator(); 238 239 while (i.hasNext()) 240 stmtText.append(' ').append(i.next()); 241 242 if (whereExpr != null) 243 stmtText.append(" WHERE ").append(whereExpr); 244 245 if (orderByList != null) 246 stmtText.append(" ORDER BY ").append(orderByList); 247 } 248 249 return stmtText; 250 } 251 252 public String toString() 253 { 254 return toStatementText().toString(); 255 } 256 257 protected static class Join 258 { 259 private final String type; 260 private final TableExpression te; 261 private final String condition; 262 263 public Join(String type, QueryColumn from, QueryColumn to) 264 { 265 this.type = type; 266 267 281 te = to.te; 282 condition = from + " = " + to; 283 } 284 285 public String toString() 286 { 287 return type + " " + te + " ON " + condition; 288 } 289 } 290 291 public class QueryColumn 292 { 293 public final TableExpression te; 294 public final Column column; 295 296 private QueryColumn(TableExpression te, Column column) 297 { 298 this.te = te; 299 this.column = column; 300 } 301 302 public QueryStatement getQueryStatement() 303 { 304 return QueryStatement.this; 305 } 306 307 public int hashCode() 308 { 309 return te.hashCode() ^ column.hashCode(); 310 } 311 312 public boolean equals(Object o) 313 { 314 if (o == this) 315 return true; 316 317 if (!(o instanceof QueryColumn)) 318 return false; 319 320 QueryColumn qsc = (QueryColumn)o; 321 322 return te.equals(qsc.te) && column.equals(qsc.column); 323 } 324 325 public String toString() 326 { 327 return te.referenceColumn(column); 328 } 329 } 330 } 331
| Popular Tags
|