View Javadoc
1   package com.atlassian.dbexporter.importer;
2   
3   import com.atlassian.dbexporter.Column;
4   import com.atlassian.dbexporter.Context;
5   import com.atlassian.dbexporter.DatabaseInformation;
6   import com.atlassian.dbexporter.EntityNameProcessor;
7   import com.atlassian.dbexporter.ForeignKey;
8   import com.atlassian.dbexporter.ImportExportErrorService;
9   import com.atlassian.dbexporter.Table;
10  import com.atlassian.dbexporter.node.NodeParser;
11  import com.atlassian.dbexporter.progress.ProgressMonitor;
12  import com.google.common.collect.Lists;
13  
14  import java.util.Collection;
15  import java.util.List;
16  
17  import static com.atlassian.dbexporter.importer.ImporterUtils.checkEndNode;
18  import static com.atlassian.dbexporter.importer.ImporterUtils.checkStartNode;
19  import static com.atlassian.dbexporter.importer.ImporterUtils.isNodeNotClosed;
20  import static com.atlassian.dbexporter.importer.TableDefinitionImporter.DatabaseCleanerAroundImporter.newCleaner;
21  import static com.atlassian.dbexporter.node.NodeBackup.ColumnDefinitionNode;
22  import static com.atlassian.dbexporter.node.NodeBackup.ForeignKeyDefinitionNode;
23  import static com.atlassian.dbexporter.node.NodeBackup.TableDefinitionNode;
24  import static com.atlassian.dbexporter.progress.ProgressMonitor.Task;
25  import static com.google.common.base.Preconditions.checkNotNull;
26  import static com.google.common.collect.Lists.newArrayList;
27  
28  public final class TableDefinitionImporter extends AbstractSingleNodeImporter {
29      private final TableCreator tableCreator;
30  
31      public TableDefinitionImporter(ImportExportErrorService errorService, TableCreator tableCreator, final DatabaseCleaner databaseCleaner) {
32          super(errorService, Lists.<AroundImporter>newArrayList(newCleaner(databaseCleaner)));
33          this.tableCreator = checkNotNull(tableCreator);
34      }
35  
36      @Override
37      protected void doImportNode(NodeParser node, ImportConfiguration configuration, Context context) {
38          final ProgressMonitor monitor = configuration.getProgressMonitor();
39          monitor.begin(Task.TABLE_DEFINITION);
40  
41          final List<Table> tables = newArrayList();
42          while (isNodeNotClosed(node, getNodeName())) {
43              tables.add(readTable(node, configuration.getEntityNameProcessor()));
44          }
45  
46          monitor.end(Task.TABLE_DEFINITION);
47          monitor.totalNumberOfTables(tables.size());
48  
49          DatabaseInformation databaseInformation = context.get(DatabaseInformation.class);
50          tableCreator.create(databaseInformation, tables, configuration.getEntityNameProcessor(), monitor);
51          context.putAll(tables); // add the parsed tables to the context
52      }
53  
54      private Table readTable(NodeParser node, EntityNameProcessor entityNameProcessor) {
55          checkStartNode(node, TableDefinitionNode.NAME);
56  
57          final String tableName = entityNameProcessor.tableName(TableDefinitionNode.getName(node));
58          node.getNextNode();
59  
60          final List<Column> columns = readColumns(node, entityNameProcessor);
61          final Collection<ForeignKey> foreignKeys = readForeignKeys(node);
62  
63          checkEndNode(node, TableDefinitionNode.NAME);
64  
65          node.getNextNode(); // get to the next node, that table has been imported!
66  
67          return new Table(tableName, columns, foreignKeys);
68      }
69  
70      private List<Column> readColumns(NodeParser node, EntityNameProcessor entityNameProcessor) {
71          final List<Column> columns = newArrayList();
72          while (node.getName().equals(ColumnDefinitionNode.NAME)) {
73              columns.add(readColumn(node, entityNameProcessor));
74          }
75          return columns;
76      }
77  
78      private Column readColumn(NodeParser node, EntityNameProcessor entityNameProcessor) {
79          checkStartNode(node, ColumnDefinitionNode.NAME);
80  
81          final String columnName = entityNameProcessor.columnName(ColumnDefinitionNode.getName(node));
82          final boolean isPk = ColumnDefinitionNode.isPrimaryKey(node);
83          final boolean isAi = ColumnDefinitionNode.isAutoIncrement(node);
84          final int sqlType = ColumnDefinitionNode.getSqlType(node);
85          final Integer precision = ColumnDefinitionNode.getPrecision(node);
86          final Integer scale = ColumnDefinitionNode.getScale(node);
87  
88          checkEndNode(node.getNextNode(), ColumnDefinitionNode.NAME);
89          node.getNextNode(); // get to the next node, that column has been imported!
90          return new Column(columnName, sqlType, isPk, isAi, precision, scale);
91      }
92  
93      private Collection<ForeignKey> readForeignKeys(NodeParser node) {
94          final Collection<ForeignKey> fks = newArrayList();
95          while (node.getName().equals(ForeignKeyDefinitionNode.NAME)) {
96              fks.add(readForeignKey(node));
97          }
98          return fks;
99      }
100 
101     private ForeignKey readForeignKey(NodeParser node) {
102         checkStartNode(node, ForeignKeyDefinitionNode.NAME);
103 
104         final String fromTable = ForeignKeyDefinitionNode.getFromTable(node);
105         final String fromColumn = ForeignKeyDefinitionNode.getFromColumn(node);
106         final String toTable = ForeignKeyDefinitionNode.getToTable(node);
107         final String toColumn = ForeignKeyDefinitionNode.getToColumn(node);
108 
109         checkEndNode(node.getNextNode(), ForeignKeyDefinitionNode.NAME);
110         node.getNextNode(); // get to the next node, that column has been imported!
111         return new ForeignKey(fromTable, fromColumn, toTable, toColumn);
112     }
113 
114     @Override
115     protected String getNodeName() {
116         return TableDefinitionNode.NAME;
117     }
118 
119     static final class DatabaseCleanerAroundImporter extends NoOpAroundImporter {
120         private final DatabaseCleaner databaseCleaner;
121 
122         private DatabaseCleanerAroundImporter(DatabaseCleaner databaseCleaner) {
123             this.databaseCleaner = checkNotNull(databaseCleaner);
124         }
125 
126         @Override
127         public void before(NodeParser node, ImportConfiguration configuration, Context context) {
128             databaseCleaner.cleanup(configuration.getCleanupMode());
129         }
130 
131         static DatabaseCleanerAroundImporter newCleaner(DatabaseCleaner cleaner) {
132             return new DatabaseCleanerAroundImporter(cleaner);
133         }
134     }
135 }