001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb.plugins.cmp.jdbc;
023:
024: import java.sql.Connection;
025: import java.sql.DatabaseMetaData;
026: import java.sql.ResultSet;
027: import java.sql.Statement;
028: import java.sql.SQLException;
029: import javax.sql.DataSource;
030: import javax.transaction.Transaction;
031: import javax.transaction.TransactionManager;
032:
033: import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractCMRFieldBridge;
034: import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractEntityBridge;
035: import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCEntityMetaData;
036: import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationMetaData;
037: import org.jboss.logging.Logger;
038:
039: /**
040: * JDBCStopCommand drops the table for this entity if specified in the xml.
041: *
042: * @author <a href="mailto:dain@daingroup.com">Dain Sundstrom</a>
043: * @author <a href="mailto:rickard.oberg@telkel.com">Rickard Öberg</a>
044: * @author <a href="mailto:justin@j-m-f.demon.co.uk">Justin Forder</a>
045: * @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a>
046: * @version $Revision: 57209 $
047: */
048: public final class JDBCStopCommand {
049: private final JDBCEntityPersistenceStore manager;
050: private final JDBCAbstractEntityBridge entity;
051: private final JDBCEntityMetaData entityMetaData;
052: private final Logger log;
053:
054: public JDBCStopCommand(JDBCEntityPersistenceStore manager) {
055: this .manager = manager;
056: entity = manager.getEntityBridge();
057: entityMetaData = entity.getMetaData();
058:
059: // Create the Log
060: log = Logger.getLogger(this .getClass().getName() + "."
061: + manager.getMetaData().getName());
062: }
063:
064: public boolean execute() {
065: boolean success = true;
066:
067: // drop relation tables
068: JDBCAbstractCMRFieldBridge[] cmrFields = entity.getCMRFields();
069: for (int i = 0; i < cmrFields.length; ++i) {
070: JDBCAbstractCMRFieldBridge cmrField = cmrFields[i];
071: JDBCRelationMetaData relationMetaData = cmrField
072: .getMetaData().getRelationMetaData();
073: if (relationMetaData.isTableMappingStyle()
074: && !relationMetaData.isTableDropped()) {
075: if (relationMetaData.getRemoveTable()) {
076: final boolean dropped = dropTable(relationMetaData
077: .getDataSource(), cmrField
078: .getQualifiedTableName());
079: if (!dropped) {
080: success = false;
081: } else {
082: relationMetaData.setTableDropped();
083: }
084: }
085: }
086: }
087:
088: if (entityMetaData.getRemoveTable()) {
089: boolean dropped = dropTable(entity.getDataSource(), entity
090: .getQualifiedTableName());
091: if (!dropped) {
092: success = false;
093: }
094: }
095:
096: return success;
097: }
098:
099: private boolean dropTable(DataSource dataSource,
100: String qualifiedTableName) {
101: boolean success;
102: Connection con = null;
103: ResultSet rs = null;
104:
105: String schema = SQLUtil.getSchema(qualifiedTableName);
106: String tableName = schema != null ? SQLUtil
107: .getTableNameWithoutSchema(qualifiedTableName)
108: : qualifiedTableName;
109:
110: // was the table already delete?
111: try {
112: con = dataSource.getConnection();
113: DatabaseMetaData dmd = con.getMetaData();
114: rs = dmd.getTables(con.getCatalog(), schema, tableName,
115: null);
116: if (!rs.next()) {
117: return true;
118: }
119: } catch (SQLException e) {
120: log.debug(
121: "Error getting database metadata for DROP TABLE command. "
122: + " DROP TABLE will not be executed. ", e);
123: return true;
124: } finally {
125: JDBCUtil.safeClose(rs);
126: JDBCUtil.safeClose(con);
127: }
128:
129: // since we use the pools, we have to do this within a transaction
130:
131: // suspend the current transaction
132: TransactionManager tm = manager.getContainer()
133: .getTransactionManager();
134: Transaction oldTransaction = null;
135: try {
136: oldTransaction = tm.suspend();
137: } catch (Exception e) {
138: log.error(
139: "Could not suspend current transaction before drop table. "
140: + "'" + qualifiedTableName
141: + "' will not be dropped.", e);
142: }
143:
144: try {
145: Statement statement = null;
146: try {
147: con = dataSource.getConnection();
148: statement = con.createStatement();
149:
150: // execute sql
151: String sql = SQLUtil.DROP_TABLE + qualifiedTableName;
152: log.debug("Executing SQL: " + sql);
153: statement.executeUpdate(sql);
154: success = true;
155: } finally {
156: JDBCUtil.safeClose(statement);
157: JDBCUtil.safeClose(con);
158: }
159: } catch (Exception e) {
160: log.debug("Could not drop table " + qualifiedTableName
161: + ": " + e.getMessage());
162: success = false;
163: } finally {
164: try {
165: // resume the old transaction
166: if (oldTransaction != null) {
167: tm.resume(oldTransaction);
168: }
169: } catch (Exception e) {
170: log
171: .error("Could not reattach original transaction after drop table");
172: }
173: }
174:
175: return success;
176: }
177: }
|