1 10 11 package mondrian.rolap.aggmatcher; 12 13 import mondrian.olap.*; 14 import mondrian.rolap.*; 15 import mondrian.recorder.*; 16 import mondrian.resource.MondrianResource; 17 18 import org.apache.log4j.Logger; 19 import org.eigenbase.util.property.*; 20 import org.eigenbase.util.property.Property; 21 22 import javax.sql.DataSource ; 23 import java.util.*; 24 import java.sql.SQLException ; 25 26 44 public class AggTableManager { 45 private static final Logger LOGGER = 46 Logger.getLogger(AggTableManager.class); 47 48 private final RolapSchema schema; 49 50 private static final MondrianResource mres = MondrianResource.instance(); 51 52 56 private Trigger[] triggers; 57 58 public AggTableManager(final RolapSchema schema) { 59 this.schema = schema; 60 } 61 62 67 public void finalCleanUp() { 68 removeJdbcSchema(); 69 deregisterTriggers(MondrianProperties.instance()); 70 71 if (getLogger().isDebugEnabled()) { 72 StringBuilder buf = new StringBuilder (100); 73 buf.append("AggTableManager.finalCleanUp: schema="); 74 buf.append(schema.getName()); 75 getLogger().debug(buf.toString()); 76 } 77 } 78 79 82 public Logger getLogger() { 83 return LOGGER; 84 } 85 86 91 public void initialize() { 92 if (MondrianProperties.instance().ReadAggregates.get()) { 93 try { 94 loadRolapStarAggregates(); 95 96 } catch (SQLException ex) { 97 throw mres.AggLoadingError.ex(ex); 98 } 99 } 100 registerTriggers(); 101 printResults(); 102 } 103 private void printResults() { 104 127 if (getLogger().isDebugEnabled()) { 128 StringBuilder buf = new StringBuilder (4096); 131 buf.append(Util.nl); 132 for (RolapStar star : getStars()) { 133 buf.append(star.toString()); 134 buf.append(Util.nl); 135 } 136 getLogger().debug(buf.toString()); 137 } 138 } 139 private void reLoadRolapStarAggregates() { 140 if (MondrianProperties.instance().ReadAggregates.get()) { 141 try { 142 clearJdbcSchema(); 143 loadRolapStarAggregates(); 144 printResults(); 145 146 } catch (SQLException ex) { 147 throw mres.AggLoadingError.ex(ex); 148 } 149 } 150 } 151 152 private JdbcSchema getJdbcSchema() { 153 DataSource dataSource = schema.getInternalConnection().getDataSource(); 154 155 return JdbcSchema.makeDB(dataSource); 158 } 159 160 163 private void clearJdbcSchema() { 164 DataSource dataSource = schema.getInternalConnection().getDataSource(); 165 JdbcSchema.clearDB(dataSource); 166 } 167 168 171 private void removeJdbcSchema() { 172 DataSource dataSource = schema.getInternalConnection().getDataSource(); 173 JdbcSchema.removeDB(dataSource); 174 } 175 176 177 187 private void loadRolapStarAggregates() throws SQLException { 188 ListRecorder msgRecorder = new ListRecorder(); 189 try { 190 191 DefaultRules rules = DefaultRules.getInstance(); 192 JdbcSchema db = getJdbcSchema(); 193 db.load(); 195 196 loop: 197 for (RolapStar star : getStars()) { 198 star.prepareToLoadAggregates(); 201 202 List<ExplicitRules.Group> aggGroups = getAggGroups(star); 203 for (ExplicitRules.Group group : aggGroups) { 204 group.validate(msgRecorder); 205 } 206 207 208 String factTableName = star.getFactTable().getAlias(); 209 210 JdbcSchema.Table dbFactTable = db.getTable(factTableName); 211 if (dbFactTable == null) { 212 msgRecorder.reportWarning("No Table found for fact name=" 213 +factTableName); 214 215 continue loop; 216 } 217 218 bindToStar(dbFactTable, star, msgRecorder); 221 String schema = dbFactTable.table.schema; 222 223 for (JdbcSchema.Table dbTable : db.getTables()) { 227 String name = dbTable.getName(); 228 229 if (ExplicitRules.excludeTable(name, aggGroups)) { 232 continue; 233 } 234 235 ExplicitRules.TableDef tableDef = 243 ExplicitRules.getIncludeByTableDef(name, aggGroups); 244 245 boolean makeAggStar = false; 246 if (tableDef != null) { 248 dbTable.load(); 250 makeAggStar = tableDef.columnsOK(star, 251 dbFactTable, 252 dbTable, 253 msgRecorder); 254 } 255 if (! makeAggStar) { 256 if (rules.matchesTableName(factTableName, name)) { 258 dbTable.load(); 260 makeAggStar = rules.columnsOK(star, 261 dbFactTable, 262 dbTable, 263 msgRecorder); 264 } 265 } 266 267 268 if (makeAggStar) { 269 dbTable.setTableUsageType(JdbcSchema.TableUsageType.AGG); 270 String alias = null; 271 dbTable.table = new MondrianDef.Table(schema, 272 name, 273 alias); 274 AggStar aggStar = AggStar.makeAggStar(star, 275 dbTable, 276 msgRecorder); 277 if (aggStar.getSize() > 0) { 278 star.addAggStar(aggStar); 279 } else { 280 String msg = mres.AggTableZeroSize.str( 281 aggStar.getFactTable().getName(), 282 factTableName); 283 getLogger().warn(msg); 284 } 285 } 286 } 292 } 293 294 } catch (RecorderException ex) { 295 throw new MondrianException(ex); 296 297 } finally { 298 msgRecorder.logInfoMessage(getLogger()); 299 msgRecorder.logWarningMessage(getLogger()); 300 msgRecorder.logErrorMessage(getLogger()); 301 if (msgRecorder.hasErrors()) { 302 throw mres.AggLoadingExceededErrorCount.ex( 303 msgRecorder.getErrorCount()); 304 } 305 } 306 } 307 private boolean runTrigger() { 308 if (RolapSchema.cacheContains(schema)) { 309 return true; 310 } else { 311 deregisterTriggers(MondrianProperties.instance()); 313 314 return false; 315 } 316 317 } 318 319 328 private void registerTriggers() { 329 final MondrianProperties properties = MondrianProperties.instance(); 330 triggers = new Trigger[] { 331 332 new Trigger() { 337 public boolean isPersistent() { 338 return false; 339 } 340 public int phase() { 341 return Trigger.SECONDARY_PHASE; 342 } 343 public void execute(Property property, String value) { 344 if (AggTableManager.this.runTrigger()) { 345 reOrderAggStarList(); 346 } 347 } 348 }, 349 350 new Trigger() { 356 public boolean isPersistent() { 357 return false; 358 } 359 public int phase() { 360 return Trigger.SECONDARY_PHASE; 361 } 362 public void execute(Property property, String value) { 363 if (AggTableManager.this.runTrigger()) { 364 reLoadRolapStarAggregates(); 365 } 366 } 367 }, 368 369 new Trigger() { 374 public boolean isPersistent() { 375 return false; 376 } 377 public int phase() { 378 return Trigger.SECONDARY_PHASE; 379 } 380 public void execute(Property property, String value) { 381 if (AggTableManager.this.runTrigger()) { 382 reLoadRolapStarAggregates(); 383 } 384 } 385 } 386 }; 387 388 properties.ChooseAggregateByVolume.addTrigger(triggers[0]); 394 properties.AggregateRules.addTrigger(triggers[1]); 395 properties.AggregateRuleTag.addTrigger(triggers[1]); 396 properties.ReadAggregates.addTrigger(triggers[2]); 397 } 398 399 private void deregisterTriggers(final MondrianProperties properties) { 400 properties.ChooseAggregateByVolume.removeTrigger(triggers[0]); 402 properties.AggregateRules.removeTrigger(triggers[1]); 403 properties.AggregateRuleTag.removeTrigger(triggers[1]); 404 properties.ReadAggregates.removeTrigger(triggers[2]); 405 } 406 407 private Collection<RolapStar> getStars() { 408 return schema.getStars(); 409 } 410 411 private void reOrderAggStarList() { 412 for (RolapStar star : getStars()) { 413 star.reOrderAggStarList(); 414 } 415 } 416 417 422 protected List<ExplicitRules.Group> getAggGroups(RolapStar star) { 423 List<ExplicitRules.Group> aggGroups = 424 new ArrayList<ExplicitRules.Group>(); 425 for (RolapCube cube : schema.getCubesWithStar(star)) { 426 if (cube.hasAggGroup() && cube.getAggGroup().hasRules()) { 427 aggGroups.add(cube.getAggGroup()); 428 } 429 } 430 return aggGroups; 431 } 432 433 444 void bindToStar(final JdbcSchema.Table dbFactTable, 445 final RolapStar star, 446 final MessageRecorder msgRecorder) throws SQLException { 447 msgRecorder.pushContextName("AggTableManager.bindToStar"); 448 try { 449 dbFactTable.load(); 451 452 dbFactTable.setTableUsageType(JdbcSchema.TableUsageType.FACT); 453 454 MondrianDef.Relation relation = star.getFactTable().getRelation(); 455 String schema = null; 456 if (relation instanceof MondrianDef.Table) { 457 schema = ((MondrianDef.Table) relation).schema; 458 } 459 String tableName = dbFactTable.getName(); 460 String alias = null; 461 dbFactTable.table = new MondrianDef.Table(schema, tableName, alias); 462 463 for (JdbcSchema.Table.Column factColumn : dbFactTable.getColumns()) { 464 String cname = factColumn.getName(); 465 RolapStar.Column[] rcs = 466 star.getFactTable().lookupColumns(cname); 467 468 for (RolapStar.Column rc : rcs) { 469 if (rc instanceof RolapStar.Measure) { 471 RolapStar.Measure rm = (RolapStar.Measure) rc; 472 JdbcSchema.Table.Column.Usage usage = 473 factColumn.newUsage(JdbcSchema.UsageType.MEASURE); 474 usage.setSymbolicName(rm.getName()); 475 476 usage.setAggregator(rm.getAggregator()); 477 usage.rMeasure = rm; 478 } 479 } 480 481 RolapStar.Table rTable = 483 star.getFactTable().findTableWithLeftJoinCondition(cname); 484 if (rTable != null) { 485 JdbcSchema.Table.Column.Usage usage = 486 factColumn.newUsage(JdbcSchema.UsageType.FOREIGN_KEY); 487 usage.setSymbolicName("FOREIGN_KEY"); 488 usage.rTable = rTable; 489 } else { 490 RolapStar.Column rColumn = 491 star.getFactTable().lookupColumn(cname); 492 if ((rColumn != null) && 493 !(rColumn instanceof RolapStar.Measure)) { 494 JdbcSchema.Table.Column.Usage usage = 499 factColumn.newUsage(JdbcSchema.UsageType.FOREIGN_KEY); 500 usage.setSymbolicName("FOREIGN_KEY"); 501 usage.rColumn = rColumn; 502 } 503 } 504 505 if (!factColumn.hasUsage() && getLogger().isDebugEnabled()) { 507 String msg = mres.UnknownFactTableColumn.str( 508 msgRecorder.getContext(), 509 dbFactTable.getName(), 510 factColumn.getName()); 511 getLogger().debug(msg); 512 } 513 } 514 } finally { 515 msgRecorder.popContextName(); 516 } 517 } 518 } 519 520 | Popular Tags |