001
002 /*
003 * Copyright (C) 2011 Archie L. Cobbs. All rights reserved.
004 *
005 * $Id: UpdatingDataSource.java 268 2012-02-01 20:24:34Z archie.cobbs $
006 */
007
008 package org.dellroad.stuff.schema;
009
010 import java.sql.Connection;
011 import java.sql.SQLException;
012
013 import javax.sql.DataSource;
014
015 /**
016 * A {@link DataSource} that wraps an inner {@link DataSource} and automatically applies a configured
017 * {@link SQLCommandList} on first access.
018 *
019 * @see SQLCommandList
020 */
021 public class UpdatingDataSource extends AbstractUpdatingDataSource {
022
023 private SQLCommandList action;
024 private boolean transactional = true;
025
026 /**
027 * Configure the {@link SQLCommandList} to be applied to the database on first access. Required property.
028 */
029 public void setSQLCommandList(SQLCommandList action) {
030 this.action = action;
031 }
032
033 /**
034 * Configure whether the {@link SQLCommandList} is applied transactionally or not.
035 * Default is {@code true}.
036 */
037 public void setTransactional(boolean transactional) {
038 this.transactional = transactional;
039 }
040
041 @Override
042 protected void updateDataSource(DataSource dataSource) throws SQLException {
043
044 // Sanity check
045 if (this.action == null)
046 throw new IllegalArgumentException("no SQLCommandList configured");
047
048 // Get connection
049 Connection c = dataSource.getConnection();
050 boolean tx = this.transactional;
051 try {
052 try {
053
054 // Open transaction if so configured
055 if (tx) {
056 c.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
057 c.setAutoCommit(false);
058 }
059
060 // Apply SQL command(s)
061 this.action.apply(c);
062
063 // Commit transaction
064 if (tx)
065 c.commit();
066 tx = false;
067 } finally {
068 if (tx)
069 c.rollback();
070 }
071 } finally {
072 c.close();
073 }
074 }
075 }
076