1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package liquibase.snapshot.ext;
27
28 import liquibase.database.Database;
29 import liquibase.database.jvm.JdbcConnection;
30 import liquibase.database.typeconversion.TypeConverterFactory;
31 import liquibase.database.core.MySQLDatabase;
32 import liquibase.database.structure.*;
33 import liquibase.diff.DiffStatusListener;
34 import liquibase.exception.DatabaseException;
35 import liquibase.executor.*;
36 import liquibase.snapshot.*;
37 import liquibase.servicelocator.ServiceLocator;
38 import liquibase.snapshot.DatabaseSnapshot;
39 import liquibase.sqlgenerator.SqlGenerator;
40 import liquibase.statement.core.GetViewDefinitionStatement;
41 import liquibase.statement.core.SelectSequencesStatement;
42 import liquibase.statement.SqlStatement;
43
44 import java.lang.reflect.ParameterizedType;
45 import java.lang.reflect.Type;
46 import java.lang.reflect.TypeVariable;
47 import java.math.BigInteger;
48 import java.sql.DatabaseMetaData;
49 import java.sql.ResultSet;
50 import java.sql.SQLException;
51 import java.sql.Statement;
52 import java.text.ParseException;
53 import java.util.ArrayList;
54 import java.util.HashMap;
55 import java.util.List;
56 import java.util.Map;
57 import java.util.Set;
58
59 import static liquibase.ext.Constants.EXTENSION_PRIORITY;
60
61
62
63
64
65
66 public class MySQLDatabaseSnapshotGenerator extends liquibase.snapshot.jvm.MySQLDatabaseSnapshotGenerator {
67
68 public int getPriority(Database database) {
69 return EXTENSION_PRIORITY;
70 }
71
72 protected View readView(final String name, final Database database) throws DatabaseException {
73 final String schemaName = convertFromDatabaseName(database.getDefaultSchemaName());
74 View view = new View();
75 view.setName(name);
76 view.setSchema(null);
77 view.setRawSchemaName(null);
78 view.setRawCatalogName(database.getDefaultCatalogName());
79 try {
80 view.setDefinition(database.getViewDefinition(schemaName, name));
81 } catch (DatabaseException e) {
82 throw new DatabaseException("Error getting " + database.getConnection().getURL() + " view with " + new GetViewDefinitionStatement(view.getSchema(), name), e);
83 }
84
85 return view;
86 }
87
88 protected void readViews(DatabaseSnapshot snapshot, String schema, DatabaseMetaData databaseMetaData) throws SQLException, DatabaseException {
89 Database database = snapshot.getDatabase();
90 updateListeners("Reading views for " + database.toString() + " ...");
91
92 ResultSet rs = databaseMetaData.getTables(database.convertRequestedSchemaToCatalog(schema), database.convertRequestedSchemaToSchema(schema), null, new String[]{"VIEW"});
93 try {
94 while (rs.next()) {
95 final String name = convertFromDatabaseName(rs.getString("TABLE_NAME"));
96 final View view = readView(name, database);
97 if (database.isSystemView(view.getRawCatalogName(), view.getRawSchemaName(), view.getName())) {
98 continue;
99 }
100
101 snapshot.getViews().add(view);
102 }
103 } finally {
104 try {
105 rs.close();
106 } catch (SQLException ignore) { }
107 }
108 }
109
110 protected void readSequences(final DatabaseSnapshot snapshot,
111 final String schema,
112 final DatabaseMetaData databaseMetaData) throws DatabaseException {
113 final Database database = snapshot.getDatabase();
114
115 updateListeners("Reading sequences for " + database.toString() + " ...");
116
117 final String convertedSchemaName = database.convertRequestedSchemaToSchema(schema);
118 try {
119 final ResultSet rs = databaseMetaData.getTables(null, convertedSchemaName, null, new String[] { "TABLE" });
120 while (rs.next()) {
121 final String sequenceName = rs.getString("TABLE_NAME");
122 if (isSequence(sequenceName, databaseMetaData)) {
123 final Sequence seq = new Sequence();
124 seq.setName(sequenceName.trim());
125
126 snapshot.getSequences().add(seq);
127 }
128 }
129 }
130 catch (SQLException sqle) {
131 throw new DatabaseException(sqle);
132 }
133 }
134
135 protected boolean isSequence(final String tableName, final DatabaseMetaData databaseMetaData) throws SQLException {
136 final ResultSet rs = databaseMetaData.getColumns(null, null, tableName, null);
137 Integer count = 0;
138 boolean hasId = false;
139 while (rs.next()) {
140 count++;
141 hasId = rs.getString("IS_AUTOINCREMENT").equalsIgnoreCase("yes");
142 }
143
144 return hasId && count == 1;
145 }
146
147 }