1 56 57 package org.objectstyle.cayenne.access; 58 59 import java.sql.CallableStatement ; 60 import java.sql.Connection ; 61 import java.sql.ResultSet ; 62 import java.sql.SQLException ; 63 import java.util.Collection ; 64 import java.util.Collections ; 65 import java.util.HashMap ; 66 import java.util.Iterator ; 67 import java.util.Map ; 68 69 import javax.sql.DataSource ; 70 71 import org.apache.log4j.Level; 72 import org.objectstyle.cayenne.CayenneException; 73 import org.objectstyle.cayenne.CayenneRuntimeException; 74 import org.objectstyle.cayenne.access.jdbc.BatchAction; 75 import org.objectstyle.cayenne.access.jdbc.ProcedureAction; 76 import org.objectstyle.cayenne.access.jdbc.RowDescriptor; 77 import org.objectstyle.cayenne.access.jdbc.SelectAction; 78 import org.objectstyle.cayenne.access.jdbc.UpdateAction; 79 import org.objectstyle.cayenne.access.trans.BatchQueryBuilder; 80 import org.objectstyle.cayenne.conn.PoolManager; 81 import org.objectstyle.cayenne.dba.DbAdapter; 82 import org.objectstyle.cayenne.dba.JdbcAdapter; 83 import org.objectstyle.cayenne.map.AshwoodEntitySorter; 84 import org.objectstyle.cayenne.map.DataMap; 85 import org.objectstyle.cayenne.map.EntityResolver; 86 import org.objectstyle.cayenne.map.EntitySorter; 87 import org.objectstyle.cayenne.query.BatchQuery; 88 import org.objectstyle.cayenne.query.GenericSelectQuery; 89 import org.objectstyle.cayenne.query.ProcedureQuery; 90 import org.objectstyle.cayenne.query.Query; 91 import org.objectstyle.cayenne.query.SelectQuery; 92 93 104 public class DataNode implements QueryEngine { 105 106 public static final Class DEFAULT_ADAPTER_CLASS = JdbcAdapter.class; 107 108 protected String name; 109 protected DataSource dataSource; 110 protected DbAdapter adapter; 111 protected String dataSourceLocation; 112 protected String dataSourceFactory; 113 protected EntityResolver entityResolver; 114 protected EntitySorter entitySorter; 115 116 protected Map dataMaps = new HashMap (); 120 private Collection dataMapsValuesRef = Collections.unmodifiableCollection(dataMaps 121 .values()); 122 123 126 public DataNode() { 127 this(null); 128 } 129 130 133 public DataNode(String name) { 134 this.name = name; 135 136 this.entitySorter = new AshwoodEntitySorter(Collections.EMPTY_LIST); 140 } 141 142 143 public String getName() { 144 return name; 145 } 146 147 public void setName(String name) { 148 this.name = name; 149 } 150 151 152 public String getDataSourceLocation() { 153 return dataSourceLocation; 154 } 155 156 public void setDataSourceLocation(String dataSourceLocation) { 157 this.dataSourceLocation = dataSourceLocation; 158 } 159 160 161 public String getDataSourceFactory() { 162 return dataSourceFactory; 163 } 164 165 public void setDataSourceFactory(String dataSourceFactory) { 166 this.dataSourceFactory = dataSourceFactory; 167 } 168 169 172 public Collection getDataMaps() { 173 return dataMapsValuesRef; 174 } 175 176 public void setDataMaps(Collection dataMaps) { 177 Iterator it = dataMaps.iterator(); 178 while (it.hasNext()) { 179 DataMap map = (DataMap) it.next(); 180 this.dataMaps.put(map.getName(), map); 181 } 182 183 entitySorter.setDataMaps(dataMaps); 184 } 185 186 189 public void addDataMap(DataMap map) { 190 this.dataMaps.put(map.getName(), map); 191 192 entitySorter.setDataMaps(getDataMaps()); 193 } 194 195 public void removeDataMap(String mapName) { 196 DataMap map = (DataMap) dataMaps.remove(mapName); 197 if (map != null) { 198 entitySorter.setDataMaps(getDataMaps()); 199 } 200 } 201 202 205 public DataSource getDataSource() { 206 return dataSource; 207 } 208 209 public void setDataSource(DataSource dataSource) { 210 this.dataSource = dataSource; 211 } 212 213 217 public DbAdapter getAdapter() { 218 return adapter; 219 } 220 221 public void setAdapter(DbAdapter adapter) { 222 this.adapter = adapter; 223 } 224 225 230 public DataNode lookupDataNode(DataMap dataMap) { 231 return this; 233 } 234 235 239 public void performQueries(Collection queries, OperationObserver observer) { 240 Transaction transaction = Transaction.internalTransaction(null); 241 transaction.performQueries(this, queries, observer); 242 } 243 244 250 public void performQueries( 251 Collection queries, 252 OperationObserver resultConsumer, 253 Transaction transaction) { 254 255 Level logLevel = resultConsumer.getLoggingLevel(); 256 257 int listSize = queries.size(); 258 if (listSize == 0) { 259 return; 260 } 261 QueryLogger.logQueryStart(logLevel, listSize); 262 263 if (transaction == null) { 265 throw new CayenneRuntimeException( 266 "No transaction associated with the queries."); 267 } 268 269 Connection connection = null; 270 271 try { 272 if (resultConsumer.isIteratedResult() && listSize > 1) { 274 throw new CayenneException( 275 "Iterated queries are not allowed in a batch. Batch size: " 276 + listSize); 277 } 278 279 connection = this.getDataSource().getConnection(); 281 transaction.addConnection(connection); 282 } 283 catch (Exception globalEx) { 285 QueryLogger.logQueryError(logLevel, globalEx); 286 287 if (connection != null) { 288 transaction.setRollbackOnly(); 290 } 291 292 resultConsumer.nextGlobalException(globalEx); 293 return; 294 } 295 296 DataNodeQueryAction queryRunner = new DataNodeQueryAction(this, resultConsumer); 297 Iterator it = queries.iterator(); 298 while (it.hasNext()) { 299 Query nextQuery = (Query) it.next(); 300 301 try { 303 queryRunner.runQuery(connection, nextQuery); 304 } 305 catch (Exception queryEx) { 306 QueryLogger.logQueryError(logLevel, queryEx); 307 308 resultConsumer.nextQueryException(nextQuery, queryEx); 311 312 transaction.setRollbackOnly(); 314 break; 315 } 316 } 317 } 318 319 324 protected void runSelect( 325 Connection connection, 326 Query query, 327 OperationObserver observer) throws SQLException , Exception { 328 329 new SelectAction((SelectQuery) query, getAdapter(), getEntityResolver()) 330 .performAction(connection, observer); 331 } 332 333 338 protected void runUpdate(Connection con, Query query, OperationObserver delegate) 339 throws SQLException , Exception { 340 341 new UpdateAction(query, getAdapter(), getEntityResolver()).performAction(con, 342 delegate); 343 } 344 345 350 protected void runBatchUpdate( 351 Connection connection, 352 BatchQuery query, 353 OperationObserver observer) throws SQLException , Exception { 354 355 357 boolean useOptimisticLock = query.isUsingOptimisticLocking(); 359 360 boolean runningAsBatch = !useOptimisticLock && adapter.supportsBatchUpdates(); 361 BatchAction action = new BatchAction(query, getAdapter(), getEntityResolver()); 362 action.setBatch(runningAsBatch); 363 action.performAction(connection, observer); 364 } 365 366 371 protected void runBatchUpdateAsBatch( 372 Connection con, 373 BatchQuery query, 374 BatchQueryBuilder queryBuilder, 375 OperationObserver delegate) throws SQLException , Exception { 376 new TempBatchAction(query, true).runAsBatch(con, queryBuilder, delegate); 377 } 378 379 385 protected void runBatchUpdateAsIndividualQueries( 386 Connection con, 387 BatchQuery query, 388 BatchQueryBuilder queryBuilder, 389 OperationObserver delegate) throws SQLException , Exception { 390 391 new TempBatchAction(query, false).runAsBatch(con, queryBuilder, delegate); 392 } 393 394 397 protected void runStoredProcedure( 398 Connection con, 399 Query query, 400 OperationObserver delegate) throws SQLException , Exception { 401 402 new ProcedureAction((ProcedureQuery) query, getAdapter(), getEntityResolver()) 403 .performAction(con, delegate); 404 } 405 406 411 protected void readStoredProcedureOutParameters( 412 CallableStatement statement, 413 org.objectstyle.cayenne.access.util.ResultDescriptor descriptor, 414 Query query, 415 OperationObserver delegate) throws SQLException , Exception { 416 417 new TempProcedureAction((ProcedureQuery) query) 419 .readProcedureOutParameters(statement, delegate); 420 } 421 422 427 protected void readResultSet( 428 ResultSet resultSet, 429 org.objectstyle.cayenne.access.util.ResultDescriptor descriptor, 430 GenericSelectQuery query, 431 OperationObserver delegate) throws SQLException , Exception { 432 433 RowDescriptor rowDescriptor = new RowDescriptor(resultSet, getAdapter() 435 .getExtendedTypes()); 436 new TempProcedureAction((ProcedureQuery) query).readResultSet(resultSet, 437 rowDescriptor, 438 query, 439 delegate); 440 } 441 442 445 public EntityResolver getEntityResolver() { 446 return entityResolver; 447 } 448 449 456 public void setEntityResolver( 457 org.objectstyle.cayenne.map.EntityResolver entityResolver) { 458 this.entityResolver = entityResolver; 459 } 460 461 464 public EntitySorter getEntitySorter() { 465 return entitySorter; 466 } 467 468 471 public synchronized void shutdown() { 472 DataSource ds = getDataSource(); 473 try { 474 if (ds instanceof PoolManager) { 478 ((PoolManager) ds).dispose(); 479 } 480 } 481 catch (SQLException ex) { 482 } 483 } 484 485 final class TempProcedureAction extends ProcedureAction { 489 490 public TempProcedureAction(ProcedureQuery query) { 491 super(query, DataNode.this.adapter, DataNode.this.entityResolver); 492 } 493 494 public void readProcedureOutParameters( 496 CallableStatement statement, 497 OperationObserver delegate) throws SQLException , Exception { 498 super.readProcedureOutParameters(statement, delegate); 499 } 500 501 public void readResultSet( 503 ResultSet resultSet, 504 RowDescriptor descriptor, 505 GenericSelectQuery query, 506 OperationObserver delegate) throws SQLException , Exception { 507 super.readResultSet(resultSet, descriptor, query, delegate); 508 } 509 } 510 511 final class TempBatchAction extends BatchAction { 515 516 public TempBatchAction(BatchQuery batchQuery, boolean runningAsBatch) { 517 super(batchQuery, DataNode.this.adapter, DataNode.this.entityResolver); 518 setBatch(runningAsBatch); 519 } 520 521 protected void runAsBatch( 523 Connection con, 524 BatchQueryBuilder queryBuilder, 525 OperationObserver delegate) throws SQLException , Exception { 526 super.runAsBatch(con, queryBuilder, delegate); 527 } 528 529 public void runAsIndividualQueries( 531 Connection con, 532 BatchQueryBuilder queryBuilder, 533 OperationObserver delegate) throws SQLException , Exception { 534 super.runAsIndividualQueries(con, queryBuilder, delegate, false); 535 } 536 } 537 538 } | Popular Tags |