View Javadoc

1   /*
2    * SymmetricDS is an open source database synchronization solution.
3    *   
4    * Copyright (C) Chris Henson <chenson42@users.sourceforge.net>
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 3 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, see
18   * <http://www.gnu.org/licenses/>.
19   */
20  
21  package org.jumpmind.symmetric.db.oracle;
22  
23  import java.net.URL;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.jumpmind.symmetric.db.AbstractDbDialect;
28  import org.jumpmind.symmetric.db.BinaryEncoding;
29  import org.jumpmind.symmetric.db.IDbDialect;
30  import org.jumpmind.symmetric.db.SequenceIdentifier;
31  import org.jumpmind.symmetric.db.SqlScript;
32  import org.jumpmind.symmetric.model.Trigger;
33  import org.jumpmind.symmetric.model.TriggerHistory;
34  
35  public class OracleDbDialect extends AbstractDbDialect implements IDbDialect {
36  
37      static final Log logger = LogFactory.getLog(OracleDbDialect.class);
38  
39      static final String TRANSACTION_ID_FUNCTION_NAME = "fn_transaction_id";
40  
41      static final String PACKAGE = "pack_symmetric";
42  
43      static final String ORACLE_OBJECT_TYPE = "FUNCTION";
44  
45      @Override
46      protected void initForSpecificDialect() {
47          try {
48              if (!isPackageUpToDate(PACKAGE)) {
49                  logger.info("Creating package " + PACKAGE);
50                  new SqlScript(getSqlScriptUrl(), getPlatform().getDataSource(), '/').execute();
51              }
52          } catch (Exception ex) {
53              logger.error("Error while initializing Oracle.", ex);
54          }
55      }
56  
57      private URL getSqlScriptUrl() {
58          return getClass().getResource("/dialects/oracle.sql");
59      }
60  
61      private boolean isPackageUpToDate(String name) throws Exception {
62          return jdbcTemplate.queryForInt("select count(*) from user_objects where object_name= upper(?) ",
63                  new Object[] { name }) > 0;
64      }
65  
66      public BinaryEncoding getBinaryEncoding() {
67          return BinaryEncoding.BASE64;
68      }
69  
70      public boolean isCharSpacePadded() {
71          return true;
72      }
73  
74      public boolean isCharSpaceTrimmed() {
75          return false;
76      }
77  
78      public boolean isEmptyStringNulled() {
79          return true;
80      }
81  
82      public boolean isBlobOverrideToBinary() {
83          return true;
84      }
85  
86      public boolean isDateOverrideToTimestamp() {
87          return true;
88      }
89  
90      public void removeTrigger(String schemaName, String triggerName) {
91          schemaName = schemaName == null ? "" : (schemaName + ".");
92          triggerName = schemaName + triggerName;
93          try {            
94              jdbcTemplate.update("drop trigger " + triggerName);
95              logger.info("Removed trigger " + triggerName);
96          } catch (Exception e) {
97              logger.warn("Trigger " + triggerName + " could not be removed.  It does not exist");
98          }
99      }
100 
101     public void removeTrigger(String catalogName, String schemaName, String triggerName, String tableName, TriggerHistory oldHistory) {
102         removeTrigger(schemaName, triggerName);
103     }
104 
105     public String getTransactionTriggerExpression(Trigger trigger) {
106         return TRANSACTION_ID_FUNCTION_NAME + "()";
107     }
108 
109     @Override
110     public boolean supportsTransactionId() {
111         return true;
112     }
113     
114     @Override
115     protected String getSequenceName(SequenceIdentifier identifier) {
116         switch (identifier) {
117         case OUTGOING_BATCH:
118             return "SEQ_SYM_OUTGOIN_BATCH_BATCH_ID";
119         case DATA:
120             return "SEQ_SYM_DATA_DATA_ID";
121         case TRIGGER_HIST:
122             return "SEQ_SYM_TRIGGER_RIGGER_HIST_ID";
123         }
124         return null;
125     }
126 
127     public String getSelectLastInsertIdSql(String sequenceName) {
128         return "select " + sequenceName + ".currval from dual";
129     }
130 
131     @Override
132     protected boolean doesTriggerExistOnPlatform(String catalog, String schema, String tableName, String triggerName) {
133         return jdbcTemplate.queryForInt(
134                 "select count(*) from user_triggers where trigger_name like upper(?) and table_name like upper(?)",
135                 new Object[] { triggerName, tableName }) > 0;
136     }
137 
138     public boolean storesUpperCaseNamesInCatalog() {
139         return true;
140     }
141 
142     public void purge() {
143         jdbcTemplate.update("purge recyclebin");
144     }
145 
146     public void disableSyncTriggers(String nodeId) {
147         jdbcTemplate.update("call pack_symmetric.setValue(1)");
148         if (nodeId != null) {
149             jdbcTemplate.update("call pack_symmetric.setNodeValue('" + nodeId + "')");
150         }
151     }
152 
153     public void enableSyncTriggers() {
154         jdbcTemplate.update("call pack_symmetric.setValue(null)");
155         jdbcTemplate.update("call pack_symmetric.setNodeValue(null)");
156     }
157 
158     public String getSyncTriggersExpression() {
159         return "fn_trigger_disabled() is null";
160     }
161 
162     public String getDefaultCatalog() {
163         return null;
164     }
165 
166     public String getDefaultSchema() {
167         return (String) jdbcTemplate.queryForObject("SELECT sys_context('USERENV', 'CURRENT_SCHEMA') FROM dual",
168                 String.class);
169     }
170     
171     
172 
173 }