1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.jumpmind.symmetric.db.mysql;
22
23 import java.sql.Connection;
24 import java.sql.SQLException;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.jumpmind.symmetric.Version;
29 import org.jumpmind.symmetric.db.AbstractDbDialect;
30 import org.jumpmind.symmetric.db.BinaryEncoding;
31 import org.jumpmind.symmetric.db.IDbDialect;
32 import org.jumpmind.symmetric.model.Trigger;
33
34 public class MySqlDbDialect extends AbstractDbDialect implements IDbDialect {
35
36 static final Log logger = LogFactory.getLog(MySqlDbDialect.class);
37
38 static final String TRANSACTION_ID_FUNCTION_NAME = "fn_transaction_id";
39
40 static final String SYNC_TRIGGERS_DISABLED_USER_VARIABLE = "@sync_triggers_disabled";
41
42 private boolean supportsTransactionId = false;
43
44 protected void initForSpecificDialect() {
45 int[] versions = Version.parseVersion(getProductVersion());
46 if (getMajorVersion() == 5
47 && (getMinorVersion() == 0 || (getMinorVersion() == 1 && versions[2] < 23))) {
48 logger.info("Enabling transaction ID support");
49 supportsTransactionId = true;
50 }
51 }
52
53 @Override
54 protected void createRequiredFunctions() {
55 String[] functions = sqlTemplate.getFunctionsToInstall();
56 for (String funcName : functions) {
57 if (! funcName.equals("fn_transaction_id") || supportsTransactionId) {
58 if (jdbcTemplate.queryForInt(sqlTemplate.getFunctionInstalledSql(funcName)) == 0) {
59 jdbcTemplate.update(sqlTemplate.getFunctionSql(funcName));
60 logger.info("Just installed " + funcName);
61 }
62 }
63 }
64 }
65
66 @Override
67 protected boolean doesTriggerExistOnPlatform(String catalog, String schema, String tableName, String triggerName) {
68 catalog = catalog == null ? (getDefaultCatalog() == null ? null : getDefaultCatalog()) : catalog;
69 String checkCatalogSql = (catalog != null && catalog.length() > 0) ? " and trigger_schema='" + catalog + "'"
70 : "";
71 return jdbcTemplate.queryForInt(
72 "select count(*) from information_schema.triggers where trigger_name like ? and event_object_table like ?"
73 + checkCatalogSql, new Object[] { triggerName, tableName }) > 0;
74 }
75
76
77 public void removeTrigger(String catalogName, String schemaName, String triggerName, String tableName) {
78 catalogName = catalogName == null ? "" : (catalogName + ".");
79 try {
80 jdbcTemplate.update("drop trigger " + catalogName + triggerName);
81 } catch (Exception e) {
82 logger.warn("Trigger does not exist");
83 }
84 }
85
86 public void disableSyncTriggers() {
87 jdbcTemplate.update("set " + SYNC_TRIGGERS_DISABLED_USER_VARIABLE + "=1");
88 }
89
90 public void enableSyncTriggers() {
91 jdbcTemplate.update("set " + SYNC_TRIGGERS_DISABLED_USER_VARIABLE + "=null");
92 }
93
94 public String getSyncTriggersExpression() {
95 return SYNC_TRIGGERS_DISABLED_USER_VARIABLE + " is null";
96 }
97
98
99 public String getTransactionTriggerExpression(Trigger trigger) {
100 if (supportsTransactionId) {
101 String defaultCatalog = "";
102 if (trigger.getSourceCatalogName() != null) {
103 defaultCatalog = this.getDefaultCatalog() + ".";
104 }
105 return defaultCatalog + TRANSACTION_ID_FUNCTION_NAME + "()";
106 }
107 return "null";
108 }
109
110 public boolean supportsTransactionId() {
111 return supportsTransactionId;
112 }
113
114 public String getSelectLastInsertIdSql(String sequenceName) {
115 return "select last_insert_id()";
116 }
117
118 public boolean isCharSpacePadded() {
119 return false;
120 }
121
122 public boolean isCharSpaceTrimmed() {
123 return true;
124 }
125
126 public boolean isEmptyStringNulled() {
127 return false;
128 }
129
130 public void purge() {
131 }
132
133 public String getDefaultSchema() {
134 return null;
135 }
136
137 public String getDefaultCatalog() {
138 return (String) jdbcTemplate.queryForObject("select database()", String.class);
139 }
140
141 protected String switchCatalogForTriggerInstall(String catalog, Connection c) throws SQLException {
142 if (catalog != null) {
143 String previousCatalog = c.getCatalog();
144 c.setCatalog(catalog);
145 return previousCatalog;
146 } else {
147 return null;
148 }
149 }
150
151 /***
152 * According to the documentation (and experience) the jdbc driver for mysql
153 * requires the fetch size to be as follows.
154 */
155 @Override
156 public int getStreamingResultsFetchSize() {
157 return Integer.MIN_VALUE;
158 }
159
160 public BinaryEncoding getBinaryEncoding() {
161 return BinaryEncoding.HEX;
162 }
163
164 public String getIdentifierQuoteString()
165 {
166 return "";
167 }
168
169 }