1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.common.impex.schema.service.impl.liquibase;
17
18 import java.sql.Connection;
19 import java.sql.SQLException;
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import liquibase.database.Database;
24 import liquibase.database.DatabaseFactory;
25 import liquibase.database.jvm.JdbcConnection;
26 import liquibase.exception.DatabaseException;
27 import liquibase.snapshot.DatabaseSnapshot;
28 import liquibase.snapshot.InvalidExampleException;
29 import liquibase.snapshot.SnapshotControl;
30 import liquibase.snapshot.SnapshotGeneratorFactory;
31
32 import org.kuali.common.impex.model.ForeignKey;
33 import org.kuali.common.impex.model.Schema;
34 import org.kuali.common.impex.model.Sequence;
35 import org.kuali.common.impex.model.Table;
36 import org.kuali.common.impex.model.View;
37 import org.kuali.common.impex.schema.service.ExtractSchemaContext;
38 import org.kuali.common.impex.schema.service.ExtractSchemaService;
39 import org.kuali.common.jdbc.JdbcUtils;
40 import org.kuali.common.util.FormatUtils;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 public class LiquibaseSchemaExtractionService implements ExtractSchemaService {
45
46 private static final Logger log = LoggerFactory.getLogger(LiquibaseSchemaExtractionService.class);
47
48 @Override
49 public Schema getSchema(ExtractSchemaContext context) {
50 try {
51 DatabaseSnapshot snapshot = getDatabaseSnapshot(context);
52 LiquibaseSchemaProvider schemaProvider = getSchemaProvider(snapshot, context);
53
54 return schemaProvider.buildSchema();
55 } catch (Exception e) {
56 log.error("Exception occurred when extracting database schema: " + e.getMessage(), e);
57 throw new RuntimeException(e);
58 }
59 }
60
61 protected DatabaseSnapshot getDatabaseSnapshot(ExtractSchemaContext context) throws DatabaseException, InvalidExampleException, SQLException {
62
63
64 long start = System.currentTimeMillis();
65
66
67 DatabaseFactory databaseFactory = DatabaseFactory.getInstance();
68
69 Connection connection = null;
70 DatabaseSnapshot snapshot = null;
71 try {
72
73 log.info("Creating Liquibase snapshot for schema {}", context.getSchemaName());
74
75 connection = context.getDataSource().getConnection();
76
77
78 Database database = databaseFactory.findCorrectDatabaseImplementation(new JdbcConnection(connection));
79
80 database.setDefaultCatalogName(null);
81 database.setDefaultSchemaName(context.getSchemaName());
82
83
84 SnapshotGeneratorFactory factory = SnapshotGeneratorFactory.getInstance();
85 snapshot = factory.createSnapshot(database.getDefaultSchema(), database, new SnapshotControl());
86
87 log.info("Liquibase snapshot created - Time: {}", FormatUtils.getTime(System.currentTimeMillis() - start));
88
89 } finally {
90 JdbcUtils.closeQuietly(context.getDataSource(), connection);
91 }
92
93 return snapshot;
94 }
95
96 protected LiquibaseSchemaProvider getSchemaProvider(DatabaseSnapshot snapshot, ExtractSchemaContext context) throws SQLException {
97 log.info("Creating LiquibaseModelProvider");
98
99
100 long start = System.currentTimeMillis();
101
102 LiquibaseSchemaProvider modelProvider = new LiquibaseSchemaProvider(snapshot, context.getSequenceFinder(), context.getDataSource());
103 modelProvider.setSchemaName(context.getSchemaName());
104 modelProvider.setNameFilter(context.getNameFilter());
105
106 log.info("LiquibaseModelProvider created - Time: {}", FormatUtils.getTime(System.currentTimeMillis() - start));
107
108 return modelProvider;
109 }
110
111 @Override
112 public List<Table> extractTables(List<String> tableNames, ExtractSchemaContext context) throws SQLException {
113 Schema schema = getSchema(context);
114
115 List<Table> result = new ArrayList<Table>(tableNames.size());
116 for (Table table : schema.getTables()) {
117 if (tableNames.contains(table.getName())) {
118 result.add(table);
119 }
120 }
121
122 return result;
123 }
124
125 @Override
126 public List<View> extractViews(ExtractSchemaContext context) throws SQLException {
127 Schema schema = getSchema(context);
128
129 return schema.getViews();
130 }
131
132 @Override
133 public List<Sequence> extractSequences(ExtractSchemaContext context) throws SQLException {
134 Schema schema = getSchema(context);
135
136 return schema.getSequences();
137 }
138
139 @Override
140 public List<ForeignKey> extractForeignKeys(List<String> tableNames, ExtractSchemaContext context) throws SQLException {
141 Schema schema = getSchema(context);
142
143 List<ForeignKey> result = new ArrayList<ForeignKey>(tableNames.size());
144 for (ForeignKey foreignKey : schema.getForeignKeys()) {
145 if (tableNames.contains(foreignKey.getLocalTableName())) {
146 result.add(foreignKey);
147 }
148 }
149
150 return result;
151 }
152 }