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.postgresql;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.jumpmind.symmetric.db.AbstractDbDialect;
26 import org.jumpmind.symmetric.db.BinaryEncoding;
27 import org.jumpmind.symmetric.db.IDbDialect;
28 import org.jumpmind.symmetric.model.Trigger;
29 import org.jumpmind.symmetric.model.TriggerHistory;
30
31 public class PostgreSqlDbDialect extends AbstractDbDialect implements IDbDialect {
32
33 static final Log logger = LogFactory.getLog(PostgreSqlDbDialect.class);
34
35 static final String TRANSACTION_ID_EXPRESSION = "txid_current()";
36
37 static final String SYNC_TRIGGERS_DISABLED_VARIABLE = "symmetric.triggers_disabled";
38
39 static final String SYNC_NODE_DISABLED_VARIABLE = "symmetric.node_disabled";
40
41 private boolean supportsTransactionId = false;
42
43 private String transactionIdExpression = "null";
44
45 protected String defaultSchema;
46
47 protected void initForSpecificDialect() {
48 if (getMajorVersion() >= 8 && getMinorVersion() >= 3) {
49 logger.info("Enabling transaction ID support");
50 supportsTransactionId = true;
51 transactionIdExpression = TRANSACTION_ID_EXPRESSION;
52 }
53 try {
54 enableSyncTriggers();
55 } catch (Exception e) {
56 logger.error("Please add \"custom_variable_classes = 'symmetric'\" to your postgresql.conf file");
57 throw new RuntimeException("Missing custom variable class 'symmetric'", e);
58 }
59 defaultSchema = (String) jdbcTemplate.queryForObject("select current_schema()", String.class);
60 }
61
62 @Override
63 protected boolean doesTriggerExistOnPlatform(String catalogName, String schema, String tableName, String triggerName) {
64 return jdbcTemplate.queryForInt(
65 "select count(*) from information_schema.triggers where trigger_name = ? " +
66 "and event_object_table = ? and trigger_schema = ?",
67 new Object[] { triggerName.toLowerCase(), tableName.toLowerCase(), schema == null ? defaultSchema : schema }) > 0;
68 }
69
70 public void removeTrigger(String schemaName, String triggerName) {
71 throw new RuntimeException("Not implemented. Use removeTrigger(schema, trigger, table) instead.");
72 }
73
74 public void removeTrigger(String catalogName, String schemaName, String triggerName, String tableName, TriggerHistory oldHistory) {
75 schemaName = schemaName == null ? "" : (schemaName + ".");
76 try {
77 jdbcTemplate.update("drop trigger " + triggerName + " on " + schemaName + tableName);
78 jdbcTemplate.update("drop function " + schemaName + "f" + triggerName + "()");
79 } catch (Exception e) {
80 logger.warn("Trigger does not exist");
81 }
82 }
83
84 public void disableSyncTriggers(String nodeId) {
85 jdbcTemplate.queryForList("select set_config('" + SYNC_TRIGGERS_DISABLED_VARIABLE + "', '1', false)");
86 if (nodeId == null) {
87 nodeId = "";
88 }
89 jdbcTemplate.queryForList("select set_config('" + SYNC_NODE_DISABLED_VARIABLE + "', '" + nodeId + "', false)");
90 }
91
92 public void enableSyncTriggers() {
93 jdbcTemplate.queryForList("select set_config('" + SYNC_TRIGGERS_DISABLED_VARIABLE + "', '', false)");
94 jdbcTemplate.queryForList("select set_config('" + SYNC_NODE_DISABLED_VARIABLE + "', '', false)");
95 }
96
97 public String getSyncTriggersExpression() {
98 return "fn_sym_triggers_disabled() = 0";
99 }
100
101 public String getTransactionTriggerExpression(Trigger trigger) {
102 return transactionIdExpression;
103 }
104
105 public String getSelectLastInsertIdSql(String sequenceName) {
106 return "select currval('" + sequenceName + "_seq')";
107 }
108
109 public boolean requiresSavepointForFallback() {
110 return true;
111 }
112
113 public boolean isCharSpacePadded() {
114 return true;
115 }
116
117 public boolean isCharSpaceTrimmed() {
118 return false;
119 }
120
121 public boolean isEmptyStringNulled() {
122 return false;
123 }
124
125 public boolean storesLowerCaseNamesInCatalog() {
126 return true;
127 }
128
129 protected boolean allowsNullForIdentityColumn() {
130 return false;
131 }
132
133 public boolean supportsTransactionId() {
134 return supportsTransactionId;
135 }
136
137 public void purge() {
138 }
139
140 public String getDefaultCatalog() {
141 return null;
142 }
143
144 public String getDefaultSchema() {
145 return defaultSchema;
146 }
147
148 public BinaryEncoding getBinaryEncoding() {
149 return BinaryEncoding.BASE64;
150 }
151
152 }