Skip to content

Commit

Permalink
Fixing flyway#687 - flyway fails to clean tables that have Flashback …
Browse files Browse the repository at this point in the history
…enabled

Added test case (once launched it will prevent any schema cleanup) and code that disables flasback during cleanup.
  • Loading branch information
awal11 committed Feb 3, 2014
1 parent ab86670 commit 16354b0
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 0 deletions.
Expand Up @@ -83,6 +83,10 @@ protected void doClean() throws SQLException {
jdbcTemplate.execute(statement);
}

for (String statement : generateAlterStatementsForFlashbackTables()) {
jdbcTemplate.execute(statement);
}

for (String statement : generateDropStatementsForObjectType("TRIGGER", "")) {
jdbcTemplate.execute(statement);
}
Expand Down Expand Up @@ -128,6 +132,41 @@ protected void doClean() throws SQLException {
}
}

/**
* Generates the ALTER statements for all tables that have Flashback enabled.
*
* @return The complete alter statements, ready to execute.
* @throws SQLException when the statements could not be generated.
*/
private List<String> generateAlterStatementsForFlashbackTables() throws SQLException {
List<String> alterStatements = new ArrayList<String>();

if (!flashbackAvailable()) {
LOG.debug("Oracle DBA_FLASHBACK_ARCHIVE_TABLES not available. No cleaning of Flashback tables.");
return alterStatements;
}
List<String> objectNames =
jdbcTemplate.queryForStringList("SELECT table_name " +
"FROM DBA_FLASHBACK_ARCHIVE_TABLES WHERE owner_name = ?", name);
for (String objectName : objectNames) {
alterStatements.add("ALTER TABLE " + dbSupport.quote(name, objectName) + " NO FLASHBACK ARCHIVE");
}
return alterStatements;
}

/**
* Checks whether Oracle DBA_FLASHBACK_ARCHIVE_TABLES are available or not.
*
* @return {@code true} if they are available, {@code false} if not.
* @throws SQLException when checking availability of the feature failed.
*/
private boolean flashbackAvailable() throws SQLException {
return jdbcTemplate.queryForInt("select count(*) " +
"from all_objects " +
"where object_name like 'DBA_FLASHBACK_ARCHIVE_TABLES'") > 0;
}


/**
* Generates the drop statements for all xml tables.
*
Expand Down
Expand Up @@ -270,6 +270,19 @@ public void xml() throws FlywayException {
flyway.migrate();
}

/**
* Tests support for cleaning of tables with Flashback/Total Recall enabled.
* Schema containing such tables has to be first cleaned by disabling flashback on each table;
*/
@Ignore("Disabled due to missing flashback functionality in Oracle XE.")
@Test
public void flashback() throws FlywayException {
flyway.setLocations("migration/dbsupport/oracle/sql/flashback");
flyway.migrate();
flyway.clean();
flyway.migrate();
}

/**
* Tests support for reference partitioned tables.
*/
Expand Down
@@ -0,0 +1,44 @@
--
-- Copyright 2010-2014 Axel Fontaine and the many contributors.
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--

CREATE TABLE test (
id number(10) not null,
name varchar(20),
primary key (id)
);

CREATE TABLE table1(
id number,
name varchar2(20),
test_id number(10) not null,
foreign key (test_id) references test(id)
);

-- unfortunately you need to specify archive name, but I do not have the permissions to create it in my environment
-- so I will not even try to write it properly, with creating the archive from scratch
alter table table1 flashback archive fda_trac;
alter table test flashback archive fda_trac;
--from now on you will be unable to delete the tables with plain DROP command

insert into test values (1,'aaa');
insert into test values (2,'aaa');
insert into test values (3,'aac');

update test set name = 'cccc';

insert into table1 values (1,'daa', 1);

commit;

0 comments on commit 16354b0

Please sign in to comment.