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