1 | |
package liquibase.snapshot.jvm; |
2 | |
|
3 | |
import liquibase.database.Database; |
4 | |
import liquibase.database.jvm.JdbcConnection; |
5 | |
import liquibase.database.structure.ForeignKeyInfo; |
6 | |
import liquibase.database.typeconversion.TypeConverterFactory; |
7 | |
import liquibase.database.core.MySQLDatabase; |
8 | |
import liquibase.database.structure.Column; |
9 | |
import liquibase.exception.DatabaseException; |
10 | |
|
11 | |
import java.sql.ResultSet; |
12 | |
import java.sql.SQLException; |
13 | |
import java.sql.Statement; |
14 | |
import java.text.ParseException; |
15 | |
import java.util.ArrayList; |
16 | |
import java.util.HashMap; |
17 | |
import java.util.List; |
18 | |
import java.util.Map; |
19 | |
|
20 | 0 | public class MySQLDatabaseSnapshotGenerator extends JdbcDatabaseSnapshotGenerator { |
21 | |
|
22 | |
|
23 | |
|
24 | |
|
25 | 0 | private static Map<String, Map<String, List<String>>> schemaCache = new HashMap<String, Map<String, List<String>>>(); |
26 | |
|
27 | |
public int getPriority(Database database) { |
28 | 0 | return PRIORITY_DATABASE; |
29 | |
} |
30 | |
|
31 | |
public boolean supports(Database database) { |
32 | 0 | return database instanceof MySQLDatabase; |
33 | |
} |
34 | |
|
35 | |
|
36 | |
|
37 | |
|
38 | |
@Override |
39 | |
protected void getColumnTypeAndDefValue(Column columnInfo, ResultSet rs, Database database) throws SQLException, |
40 | |
DatabaseException { |
41 | |
|
42 | 0 | String columnTypeName = rs.getString("TYPE_NAME"); |
43 | 0 | String columnName = rs.getString("COLUMN_NAME"); |
44 | 0 | String tableName = rs.getString("TABLE_NAME"); |
45 | 0 | String schemaName = rs.getString("TABLE_CAT"); |
46 | |
|
47 | 0 | Map<String, List<String>> tableSchema = new HashMap<String, List<String>>(); |
48 | |
|
49 | 0 | if (!schemaCache.containsKey(tableName)) { |
50 | |
|
51 | 0 | Statement selectStatement = null; |
52 | 0 | ResultSet rsColumnType = null; |
53 | |
try { |
54 | 0 | selectStatement = ((JdbcConnection) database.getConnection()).getUnderlyingConnection() |
55 | |
.createStatement(); |
56 | 0 | rsColumnType = selectStatement.executeQuery("DESC " + database.escapeTableName(schemaName, tableName)); |
57 | |
|
58 | 0 | while (rsColumnType.next()) { |
59 | 0 | List<String> colSchema = new ArrayList<String>(); |
60 | 0 | colSchema.add(rsColumnType.getString("Type")); |
61 | 0 | colSchema.add(rsColumnType.getString("Default")); |
62 | 0 | tableSchema.put(rsColumnType.getString("Field"), colSchema); |
63 | 0 | } |
64 | |
} finally { |
65 | 0 | if (rsColumnType != null) { |
66 | |
try { |
67 | 0 | rsColumnType.close(); |
68 | 0 | } catch (SQLException ignore) { |
69 | 0 | } |
70 | |
} |
71 | 0 | if (selectStatement != null) { |
72 | |
try { |
73 | 0 | selectStatement.close(); |
74 | 0 | } catch (SQLException ignore) { |
75 | 0 | } |
76 | |
} |
77 | |
} |
78 | |
|
79 | 0 | schemaCache.put(tableName, tableSchema); |
80 | |
|
81 | |
} |
82 | |
|
83 | 0 | tableSchema = schemaCache.get(tableName); |
84 | |
|
85 | |
|
86 | 0 | if (columnTypeName.toLowerCase().startsWith("enum") || columnTypeName.toLowerCase().startsWith("set")) { |
87 | |
|
88 | 0 | columnInfo.setTypeName(tableSchema.get(columnName).get(0)); |
89 | |
try { |
90 | 0 | String tmpDefaultValue = (String) TypeConverterFactory |
91 | |
.getInstance() |
92 | |
.findTypeConverter(database) |
93 | |
.convertDatabaseValueToObject(tableSchema.get(columnName).get(1), columnInfo.getDataType(), |
94 | |
columnInfo.getColumnSize(), columnInfo.getDecimalDigits(), database); |
95 | 0 | if ("".equals(tmpDefaultValue)) { |
96 | 0 | columnInfo.setDefaultValue(null); |
97 | |
} else { |
98 | 0 | columnInfo.setDefaultValue(tmpDefaultValue); |
99 | |
} |
100 | 0 | } catch (ParseException e) { |
101 | 0 | throw new DatabaseException(e); |
102 | 0 | } |
103 | |
|
104 | |
|
105 | 0 | } else if (columnTypeName.toLowerCase().equals("text") || columnTypeName.toLowerCase().equals("blob")) { |
106 | 0 | columnInfo.setTypeName(columnTypeName); |
107 | 0 | columnInfo.setDefaultValue(null); |
108 | |
|
109 | |
|
110 | |
|
111 | 0 | } else if (columnTypeName.toLowerCase().equals("timestamp") |
112 | |
&& !"CURRENT_TIMESTAMP".equals(tableSchema.get(columnName).get(1))) { |
113 | 0 | columnInfo.setTypeName(columnTypeName); |
114 | 0 | columnInfo.setDefaultValue(tableSchema.get(columnName).get(1)); |
115 | |
} else { |
116 | 0 | super.getColumnTypeAndDefValue(columnInfo, rs, database); |
117 | |
} |
118 | 0 | } |
119 | |
|
120 | |
@Override |
121 | |
protected String convertPrimaryKeyName(String pkName) throws SQLException { |
122 | 0 | if (pkName.equals("PRIMARY")) { |
123 | 0 | return null; |
124 | |
} else { |
125 | 0 | return pkName; |
126 | |
} |
127 | |
} |
128 | |
|
129 | |
@Override |
130 | |
protected ForeignKeyInfo fillForeignKeyInfo(ResultSet rs) throws DatabaseException, SQLException { |
131 | 0 | ForeignKeyInfo fkinfo = super.fillForeignKeyInfo(rs); |
132 | |
|
133 | 0 | fkinfo.setPkTableSchema(convertFromDatabaseName(rs.getString("PKTABLE_CAT"))); |
134 | 0 | fkinfo.setFkSchema(convertFromDatabaseName(rs.getString("FKTABLE_CAT"))); |
135 | 0 | return fkinfo; |
136 | |
} |
137 | |
|
138 | |
} |