View Javadoc

1   /**
2    * Copyright 2011 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
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  		// Preserve the start time
64  		long start = System.currentTimeMillis();
65  
66  		// get an instance of the database factory
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  			// build an instance of the liquibase database object
78  			Database database = databaseFactory.findCorrectDatabaseImplementation(new JdbcConnection(connection));
79  
80  			database.setDefaultCatalogName(null);
81  			database.setDefaultSchemaName(context.getSchemaName());
82  
83  			// Use Liquibase to snapshot the database
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  		// Preserve the start time
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 }