View Javadoc
1   package com.atlassian.activeobjects.backup;
2   
3   import com.atlassian.dbexporter.Column;
4   import com.atlassian.dbexporter.DatabaseInformation;
5   import com.atlassian.dbexporter.EntityNameProcessor;
6   import com.atlassian.dbexporter.ForeignKey;
7   import com.atlassian.dbexporter.ImportExportErrorService;
8   import com.atlassian.dbexporter.Table;
9   import com.atlassian.dbexporter.exporter.TableReader;
10  import com.google.common.base.Function;
11  import com.google.common.collect.Collections2;
12  import com.google.common.collect.Lists;
13  import net.java.ao.DatabaseProvider;
14  import net.java.ao.SchemaConfiguration;
15  import net.java.ao.schema.NameConverters;
16  import net.java.ao.schema.ddl.DDLField;
17  import net.java.ao.schema.ddl.DDLForeignKey;
18  import net.java.ao.schema.ddl.DDLTable;
19  import net.java.ao.schema.ddl.SchemaReader;
20  
21  import java.sql.Connection;
22  import java.sql.SQLException;
23  import java.util.Collection;
24  import java.util.List;
25  
26  import static com.google.common.base.Preconditions.checkNotNull;
27  import static com.google.common.collect.Lists.newArrayList;
28  import static net.java.ao.sql.SqlUtils.closeQuietly;
29  
30  public final class ActiveObjectsTableReader implements TableReader {
31      private final ImportExportErrorService errorService;
32      private final DatabaseProvider provider;
33      private final NameConverters converters;
34      private final SchemaConfiguration schemaConfiguration;
35  
36      public ActiveObjectsTableReader(ImportExportErrorService errorService, NameConverters converters, DatabaseProvider provider, SchemaConfiguration schemaConfiguration) {
37          this.converters = checkNotNull(converters);
38          this.errorService = checkNotNull(errorService);
39          this.provider = checkNotNull(provider);
40          this.schemaConfiguration = checkNotNull(schemaConfiguration);
41      }
42  
43      @Override
44      public Iterable<Table> read(DatabaseInformation databaseInformation, EntityNameProcessor entityNameProcessor) {
45          final List<Table> tables = newArrayList();
46          final DDLTable[] ddlTables;
47          Connection connection = null;
48          try {
49              connection = getConnection();
50              ddlTables = SchemaReader.readSchema(connection, provider, converters, schemaConfiguration, true);
51          } catch (SQLException e) {
52              throw errorService.newImportExportSqlException(null, "An error occurred reading schema information from database", e);
53          } finally {
54              closeQuietly(connection);
55          }
56          for (DDLTable ddlTable : ddlTables) {
57              tables.add(readTable(ddlTable, entityNameProcessor));
58          }
59          return tables;
60      }
61  
62      private Connection getConnection() {
63          try {
64              return provider.getConnection();
65          } catch (SQLException e) {
66              throw errorService.newImportExportSqlException(null, "Could not get connection from provider", e);
67          }
68      }
69  
70      private Table readTable(DDLTable ddlTable, EntityNameProcessor processor) {
71          final String name = processor.tableName(ddlTable.getName());
72          return new Table(name, readColumns(ddlTable.getFields(), processor), readForeignKeys(ddlTable.getForeignKeys()));
73      }
74  
75      private List<Column> readColumns(DDLField[] fields, final EntityNameProcessor processor) {
76          return Lists.transform(newArrayList(fields), new Function<DDLField, Column>() {
77              @Override
78              public Column apply(DDLField field) {
79                  return readColumn(field, processor);
80              }
81          });
82      }
83  
84      private Column readColumn(DDLField field, EntityNameProcessor processor) {
85          final String name = processor.columnName(field.getName());
86          return
87                  new Column(name, getType(field), field.isPrimaryKey(), field.isAutoIncrement(),
88                          getPrecision(field), getScale(field));
89      }
90  
91      private int getType(DDLField field) {
92          return field.getJdbcType();
93      }
94  
95      private Integer getScale(DDLField field) {
96          return field.getType().getQualifiers().getScale();
97      }
98  
99      private Integer getPrecision(DDLField field) {
100         Integer precision = field.getType().getQualifiers().getPrecision();
101         return precision != null ? precision : field.getType().getQualifiers().getStringLength();
102     }
103 
104     private Collection<ForeignKey> readForeignKeys(DDLForeignKey[] foreignKeys) {
105         return Collections2.transform(newArrayList(foreignKeys), new Function<DDLForeignKey, ForeignKey>() {
106             public ForeignKey apply(DDLForeignKey fk) {
107                 return readForeignKey(fk);
108             }
109         });
110     }
111 
112     private ForeignKey readForeignKey(DDLForeignKey fk) {
113         return new ForeignKey(fk.getDomesticTable(), fk.getField(), fk.getTable(), fk.getForeignField());
114     }
115 }