1 package org.apache.ojb.broker.accesslayer.sql; 2 3 17 18 import java.util.ArrayList ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Map ; 22 import java.util.Set ; 23 import java.lang.ref.WeakReference ; 24 25 import org.apache.commons.collections.set.ListOrderedSet; 26 import org.apache.ojb.broker.metadata.ClassDescriptor; 27 import org.apache.ojb.broker.metadata.DescriptorRepository; 28 import org.apache.ojb.broker.metadata.FieldDescriptor; 29 import org.apache.ojb.broker.metadata.JdbcType; 30 import org.apache.ojb.broker.platforms.Platform; 31 import org.apache.ojb.broker.query.Criteria; 32 import org.apache.ojb.broker.query.Query; 33 import org.apache.ojb.broker.query.ReportQuery; 34 import org.apache.ojb.broker.query.ReportQueryByCriteria; 35 import org.apache.ojb.broker.util.SqlHelper; 36 import org.apache.ojb.broker.util.logging.Logger; 37 38 44 public class SqlSelectStatement extends SqlQueryStatement implements SelectStatement 45 { 46 private WeakReference fieldsForSelect; 47 48 56 public SqlSelectStatement(Platform pf, ClassDescriptor cld, Query query, Logger logger) 57 { 58 super(pf, cld, query, logger); 59 } 60 61 70 public SqlSelectStatement(SqlQueryStatement parent, Platform pf, ClassDescriptor cld, Query query, Logger logger) 71 { 72 super(parent, pf, cld, query, logger); 73 } 74 75 81 protected void appendColumn(TableAlias anAlias, FieldDescriptor field, StringBuffer buf) 82 { 83 buf.append(anAlias.alias); 84 buf.append("."); 85 buf.append(field.getColumnName()); 86 } 87 88 98 protected List appendListOfColumnsForSelect(StringBuffer buf) 99 { 100 FieldDescriptor[] fieldDescriptors = getFieldsForSelect(); 101 ArrayList columnList = new ArrayList (); 102 TableAlias searchAlias = getSearchTable(); 103 104 for (int i = 0; i < fieldDescriptors.length; i++) 105 { 106 FieldDescriptor field = fieldDescriptors[i]; 107 TableAlias alias = getTableAliasForClassDescriptor(field.getClassDescriptor()); 108 if (alias == null) 109 { 110 alias = searchAlias; 111 } 112 if (i > 0) 113 { 114 buf.append(","); 115 } 116 appendColumn(alias, field, buf); 117 columnList.add(field.getAttributeName()); 118 } 119 120 appendClazzColumnForSelect(buf); 121 return columnList; 122 } 123 124 128 private ClassDescriptor[] getMultiJoinedClassDescriptors(ClassDescriptor cld) 129 { 130 DescriptorRepository repository = cld.getRepository(); 131 Class [] multiJoinedClasses = repository.getSubClassesMultipleJoinedTables(cld, true); 132 ClassDescriptor[] result = new ClassDescriptor[multiJoinedClasses.length]; 133 134 for (int i = 0 ; i < multiJoinedClasses.length; i++) 135 { 136 result[i] = repository.getDescriptorFor(multiJoinedClasses[i]); 137 } 138 139 return result; 140 } 141 142 147 private void appendClazzColumnForSelect(StringBuffer buf) 148 { 149 ClassDescriptor cld = getSearchClassDescriptor(); 150 ClassDescriptor[] clds = getMultiJoinedClassDescriptors(cld); 151 152 if (clds.length == 0) 153 { 154 return; 155 } 156 157 buf.append(",CASE"); 158 159 for (int i = clds.length; i > 0; i--) 160 { 161 buf.append(" WHEN "); 162 163 ClassDescriptor subCld = clds[i - 1]; 164 FieldDescriptor[] fieldDescriptors = subCld.getPkFields(); 165 166 TableAlias alias = getTableAliasForClassDescriptor(subCld); 167 for (int j = 0; j < fieldDescriptors.length; j++) 168 { 169 FieldDescriptor field = fieldDescriptors[j]; 170 if (j > 0) 171 { 172 buf.append(" AND "); 173 } 174 appendColumn(alias, field, buf); 175 buf.append(" IS NOT NULL"); 176 } 177 buf.append(" THEN '").append(subCld.getClassNameOfObject()).append("'"); 178 } 179 buf.append(" ELSE '").append(cld.getClassNameOfObject()).append("'"); 180 buf.append(" END AS " + SqlHelper.OJB_CLASS_COLUMN); 181 } 182 183 188 protected FieldDescriptor[] getFieldsForSelect() 189 { 190 if (fieldsForSelect == null || fieldsForSelect.get() == null) 191 { 192 fieldsForSelect = new WeakReference (buildFieldsForSelect(getSearchClassDescriptor())); 193 } 194 return (FieldDescriptor[]) fieldsForSelect.get(); 195 } 196 197 203 protected FieldDescriptor[] buildFieldsForSelect(ClassDescriptor cld) 204 { 205 DescriptorRepository repository = cld.getRepository(); 206 Set fields = new ListOrderedSet(); 208 FieldDescriptor fds[] = repository.getFieldDescriptorsForMultiMappedTable(cld); 213 for (int i = 0; i < fds.length; i++) 214 { 215 fields.add(fds[i]); 216 } 217 218 fds = cld.getFieldDescriptor(true); 220 for (int i = 0; i < fds.length; i++) 221 { 222 fields.add(fds[i]); 223 } 224 225 Class [] multiJoinedClasses = repository.getSubClassesMultipleJoinedTables(cld, true); 227 for (int c = 0; c < multiJoinedClasses.length; c++) 228 { 229 ClassDescriptor subCld = repository.getDescriptorFor(multiJoinedClasses[c]); 230 fds = subCld.getFieldDescriptions(); 231 for (int i = 0; i < fds.length; i++) 232 { 233 fields.add(fds[i]); 234 } 235 } 236 237 FieldDescriptor[] result = new FieldDescriptor[fields.size()]; 238 fields.toArray(result); 239 return result; 240 } 241 242 248 protected List appendListOfColumns(String [] columns, StringBuffer buf) 249 { 250 ArrayList columnList = new ArrayList (); 251 252 for (int i = 0; i < columns.length; i++) 253 { 254 if (i > 0) 255 { 256 buf.append(","); 257 } 258 appendColName(columns[i], false, null, buf); 259 columnList.add(columns[i]); 260 } 261 return columnList; 262 } 263 264 267 protected String buildStatement() 268 { 269 StringBuffer stmt = new StringBuffer (1024); 270 Query query = getQuery(); 271 boolean first = true; 272 List orderByFields = null; 273 String [] attributes = null; 274 String [] joinAttributes = null; 275 Iterator it = getJoinTreeToCriteria().entrySet().iterator(); 276 List columnList = new ArrayList (); 277 278 if (query instanceof ReportQuery) 279 { 280 attributes = ((ReportQuery) query).getAttributes(); 281 joinAttributes = ((ReportQuery) query).getJoinAttributes(); 282 } 283 284 while (it.hasNext()) 285 { 286 Map.Entry entry = (Map.Entry ) it.next(); 287 Criteria whereCrit = (Criteria) entry.getValue(); 288 Criteria havingCrit = query.getHavingCriteria(); 289 StringBuffer where = new StringBuffer (); 290 StringBuffer having = new StringBuffer (); 291 List groupByFields; 292 293 setRoot((TableAlias) entry.getKey()); 295 296 if (whereCrit != null && whereCrit.isEmpty()) 297 { 298 whereCrit = null; 299 } 300 301 if (havingCrit != null && havingCrit.isEmpty()) 302 { 303 havingCrit = null; 304 } 305 306 if (first) 307 { 308 first = false; 309 } 310 else 311 { 312 stmt.append(" UNION "); 313 } 314 315 stmt.append("SELECT "); 316 if (query.isDistinct()) 317 { 318 stmt.append("DISTINCT "); 319 } 320 321 if (attributes == null || attributes.length == 0) 322 { 323 329 columnList.addAll(appendListOfColumnsForSelect(stmt)); 330 } 331 else 332 { 333 columnList.addAll(appendListOfColumns(attributes, stmt)); 334 } 335 336 if (joinAttributes != null && joinAttributes.length > 0) 342 { 343 for (int i = 0; i < joinAttributes.length; i++) 344 { 345 getAttributeInfo(joinAttributes[i], false, null, getQuery().getPathClasses()); 346 } 347 } 348 349 groupByFields = query.getGroupBy(); 350 ensureColumns(groupByFields, columnList); 351 352 orderByFields = query.getOrderBy(); 353 columnList = ensureColumns(orderByFields, columnList, stmt); 354 358 362 ClassDescriptor cld = getBaseClassDescriptor(); 363 ClassDescriptor cldSuper = null; 364 if (cld.getSuperClass() != null) 365 { 366 cldSuper = cld.getRepository().getDescriptorFor(cld.getSuperClass()); 368 appendSuperClassColumns(cldSuper, stmt); 369 } 370 371 stmt.append(" FROM "); 372 appendTableWithJoins(getRoot(), where, stmt); 373 374 if (cld.getSuperClass() != null) 375 { 376 appendSuperClassJoin(cld, cldSuper, stmt, where); 377 } 378 379 appendWhereClause(where, whereCrit, stmt); 380 appendGroupByClause(groupByFields, stmt); 381 appendHavingClause(having, havingCrit, stmt); 382 } 383 384 appendOrderByClause(orderByFields, columnList, stmt); 385 386 if (query instanceof ReportQueryByCriteria) 387 { 388 ((ReportQueryByCriteria) query).setAttributeFieldDescriptors(m_attrToFld); 389 } 390 391 return stmt.toString(); 392 } 393 394 398 private void appendSuperClassJoin(ClassDescriptor cld, ClassDescriptor cldSuper, StringBuffer stmt, StringBuffer where) 399 { 400 stmt.append(","); 401 appendTable(cldSuper, stmt); 402 403 if (where != null) 404 { 405 if (where.length() > 0) 406 { 407 where.append(" AND "); 408 } 409 410 int superFieldRef = cld.getSuperClassFieldRef(); 413 FieldDescriptor refField = cld.getFieldDescriptorByIndex(superFieldRef); 414 415 appendTable(cldSuper, where); 416 where.append("."); 417 appendField(cldSuper.getAutoIncrementFields()[0], where); 418 where.append(" = "); 419 appendTable(cld, where); 420 where.append("."); 421 appendField(refField, where); 422 } 423 } 424 425 private void appendSuperClassColumns(ClassDescriptor cldSuper, StringBuffer buf) 426 { 427 FieldDescriptor[] fields = cldSuper.getFieldDescriptions(); 428 for (int i = 0; i < fields.length; i++) 429 { 430 FieldDescriptor field = fields[i]; 431 if (i > 0) 432 { 433 buf.append(","); 434 } 435 buf.append(cldSuper.getFullTableName()); 436 buf.append("."); 437 buf.append(field.getColumnName()); 438 } 439 } 440 441 444 protected void appendTable(ClassDescriptor cld, StringBuffer buf) 445 { 446 buf.append(cld.getFullTableName()); 447 } 448 449 452 protected void appendField(FieldDescriptor fld, StringBuffer buf) 453 { 454 buf.append(fld.getColumnName()); 455 } 456 457 public Query getQueryInstance() 458 { 459 return getQuery(); 460 } 461 462 public int getColumnIndex(FieldDescriptor fld) 463 { 464 int index = JdbcType.MIN_INT; 465 FieldDescriptor[] fields = getFieldsForSelect(); 466 if (fields != null) 467 { 468 for (int i = 0; i < fields.length; i++) 469 { 470 if (fields[i].equals(fld)) 471 { 472 index = i + 1; break; 474 } 475 } 476 } 477 return index; 478 } 479 } 480 | Popular Tags |