1 package com.atlassian.activeobjects.backup;
2
3 import com.atlassian.activeobjects.osgi.ActiveObjectsServiceFactory;
4 import com.atlassian.dbexporter.CleanupMode;
5 import com.atlassian.dbexporter.ImportExportErrorService;
6 import com.atlassian.dbexporter.importer.DatabaseCleaner;
7 import net.java.ao.DatabaseProvider;
8 import net.java.ao.SchemaConfiguration;
9 import net.java.ao.schema.NameConverters;
10 import net.java.ao.schema.ddl.DDLAction;
11 import net.java.ao.schema.ddl.DDLTable;
12 import net.java.ao.schema.ddl.SQLAction;
13 import net.java.ao.schema.ddl.SchemaReader;
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
16
17 import java.sql.Connection;
18 import java.sql.SQLException;
19 import java.sql.Statement;
20
21 import static com.atlassian.activeobjects.backup.SqlUtils.executeUpdate;
22 import static com.atlassian.dbexporter.jdbc.JdbcUtils.closeQuietly;
23 import static com.google.common.base.Preconditions.checkNotNull;
24
25 final class ActiveObjectsDatabaseCleaner implements DatabaseCleaner {
26 private final Logger logger = LoggerFactory.getLogger(this.getClass());
27
28 private final ImportExportErrorService errorService;
29 private final NameConverters converters;
30 private final DatabaseProvider provider;
31 private final SchemaConfiguration schemaConfiguration;
32 private final ActiveObjectsServiceFactory aoServiceFactory;
33
34 public ActiveObjectsDatabaseCleaner(DatabaseProvider provider, NameConverters converters, SchemaConfiguration schemaConfiguration, ImportExportErrorService errorService, final ActiveObjectsServiceFactory aoServiceFactory) {
35 this.errorService = checkNotNull(errorService);
36 this.provider = checkNotNull(provider);
37 this.converters = checkNotNull(converters);
38 this.schemaConfiguration = checkNotNull(schemaConfiguration);
39 this.aoServiceFactory = checkNotNull(aoServiceFactory);
40 }
41
42 @Override
43 public void cleanup(CleanupMode cleanupMode) {
44 if (cleanupMode.equals(CleanupMode.CLEAN)) {
45 doCleanup();
46 } else {
47 logger.debug("Not cleaning up database before import. " +
48 "Any existing entity with the same name of entity being imported will make the import fail.");
49 }
50 }
51
52 private void doCleanup() {
53 Connection conn = null;
54 Statement stmt = null;
55 try {
56 aoServiceFactory.startCleaning();
57
58 final DDLTable[] readTables = SchemaReader.readSchema(provider, converters, schemaConfiguration);
59 final DDLAction[] actions = SchemaReader.sortTopologically(SchemaReader.diffSchema(provider.getTypeManager(), new DDLTable[]{}, readTables, provider.isCaseSensitive()));
60
61 conn = provider.getConnection();
62 stmt = conn.createStatement();
63
64 for (DDLAction a : actions) {
65 final Iterable<SQLAction> sqlActions = provider.renderAction(converters, a);
66 for (SQLAction sql : sqlActions) {
67 executeUpdate(errorService, tableName(a), stmt, sql.getStatement());
68 }
69 }
70 } catch (SQLException e) {
71 throw errorService.newImportExportSqlException(null, "", e);
72 } finally {
73 closeQuietly(stmt);
74 closeQuietly(conn);
75 aoServiceFactory.stopCleaning();
76 }
77 }
78
79 private String tableName(DDLAction a) {
80 if (a == null) {
81 return null;
82 }
83 if (a.getTable() == null) {
84 return null;
85 }
86 return a.getTable().getName();
87 }
88 }