diff --git a/symmetric-android/src/main/java/org/jumpmind/symmetric/android/AndroidDatabasePlatform.java b/symmetric-android/src/main/java/org/jumpmind/symmetric/android/AndroidDatabasePlatform.java
index 847de33c58..19f6e87a38 100644
--- a/symmetric-android/src/main/java/org/jumpmind/symmetric/android/AndroidDatabasePlatform.java
+++ b/symmetric-android/src/main/java/org/jumpmind/symmetric/android/AndroidDatabasePlatform.java
@@ -22,8 +22,12 @@
import java.math.BigDecimal;
+import org.jumpmind.db.model.Database;
import org.jumpmind.db.platform.AbstractDatabasePlatform;
import org.jumpmind.db.platform.DatabaseNamesConstants;
+import org.jumpmind.db.platform.PermissionResult;
+import org.jumpmind.db.platform.PermissionType;
+import org.jumpmind.db.platform.PermissionResult.Status;
import org.jumpmind.db.platform.sqlite.SqliteDdlBuilder;
import org.jumpmind.db.platform.sqlite.SqliteDdlReader;
import org.jumpmind.db.sql.ISqlTemplate;
@@ -110,4 +114,27 @@ protected Object parseInteger(String value) {
}
}
+ @Override
+ public PermissionResult getCreateSymTablePermission(Database database) {
+ PermissionResult result = new PermissionResult(PermissionType.CREATE_TABLE, Status.UNIMPLEMENTED);
+ return result;
+ }
+
+ @Override
+ public PermissionResult getDropSymTablePermission() {
+ PermissionResult result = new PermissionResult(PermissionType.DROP_TABLE, Status.UNIMPLEMENTED);
+ return result;
+ }
+
+ @Override
+ public PermissionResult getAlterSymTablePermission(Database database) {
+ PermissionResult result = new PermissionResult(PermissionType.ALTER_TABLE, Status.UNIMPLEMENTED);
+ return result;
+ }
+
+ @Override
+ public PermissionResult getDropSymTriggerPermission() {
+ PermissionResult result = new PermissionResult(PermissionType.DROP_TRIGGER, Status.UNIMPLEMENTED);
+ return result;
+ }
}
diff --git a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/mssql/MsSqlSymmetricDialect.java b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/mssql/MsSqlSymmetricDialect.java
index 43e865902b..3ddf10837e 100644
--- a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/mssql/MsSqlSymmetricDialect.java
+++ b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/mssql/MsSqlSymmetricDialect.java
@@ -32,6 +32,7 @@
import org.jumpmind.db.model.Table;
import org.jumpmind.db.model.TypeMap;
import org.jumpmind.db.platform.IDatabasePlatform;
+import org.jumpmind.db.platform.PermissionType;
import org.jumpmind.db.sql.IConnectionCallback;
import org.jumpmind.db.sql.ISqlTemplate;
import org.jumpmind.db.sql.ISqlTransaction;
@@ -417,4 +418,9 @@ protected String getDbSpecificDataHasChangedCondition(Trigger trigger) {
return "$(anyNonBlobColumnChanged)";
}
+ @Override
+ public PermissionType[] getSymTablePermissions() {
+ PermissionType[] permissions = { PermissionType.CREATE_TABLE, PermissionType.DROP_TABLE, PermissionType.CREATE_TRIGGER, PermissionType.DROP_TRIGGER, PermissionType.CREATE_FUNCTION};
+ return permissions;
+ }
}
diff --git a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/mssql2000/MsSql2000SymmetricDialect.java b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/mssql2000/MsSql2000SymmetricDialect.java
index 808a6a1cd4..cace2413c9 100644
--- a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/mssql2000/MsSql2000SymmetricDialect.java
+++ b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/mssql2000/MsSql2000SymmetricDialect.java
@@ -1,120 +1,127 @@
-/**
- * Licensed to JumpMind Inc under one or more contributor
- * license agreements. See the NOTICE file distributed
- * with this work for additional information regarding
- * copyright ownership. JumpMind Inc licenses this file
- * to you under the GNU General Public License, version 3.0 (GPLv3)
- * (the "License"); you may not use this file except in compliance
- * with the License.
- *
- * You should have received a copy of the GNU General Public License,
- * version 3.0 (GPLv3) along with this library; if not, see
- * .
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.jumpmind.symmetric.db.mssql2000;
-
-import org.jumpmind.db.platform.IDatabasePlatform;
-import org.jumpmind.db.util.BinaryEncoding;
-import org.jumpmind.symmetric.db.mssql.MsSqlSymmetricDialect;
-import org.jumpmind.symmetric.service.IParameterService;
-
-public class MsSql2000SymmetricDialect extends MsSqlSymmetricDialect {
-
-
- public MsSql2000SymmetricDialect(IParameterService parameterService, IDatabasePlatform platform) {
- super(parameterService, platform);
- this.triggerTemplate = new MsSql2000TriggerTemplate(this);
- }
-
- @Override
- protected boolean alterLockEscalation() {
- return false;
- }
-
- @Override
- public void createRequiredDatabaseObjects() {
- String encode = this.parameterService.getTablePrefix() + "_" + "base64_encode";
- if (!installed(SQL_FUNCTION_INSTALLED, encode)) {
- String sql = " create function dbo.$(functionName) (\n" +
- " @binvalue varbinary(8000)) returns varchar(8000)\n" +
- " as \n" +
- " begin\n" +
- " declare @charvalue varchar(8000)\n" +
- " declare @i int\n" +
- " declare @length int\n" +
- " declare @hexstring char(16)\n" +
- "\n" +
- " select @charvalue = ''\n" +
- " select @i = 1\n" +
- " select @length = datalength(@binvalue)\n" +
- " select @hexstring = '0123456789abcdef'\n" +
- "\n" +
- " while (@i <= @length)\n" +
- " begin\n" +
- "\n" +
- " declare @tempint int\n" +
- " declare @firstint int\n" +
- " declare @secondint int\n" +
- "\n" +
- " select @tempint = convert(int, substring(@binvalue,@i,1))\n" +
- " select @firstint = floor(@tempint/16)\n" +
- " select @secondint = @tempint - (@firstint*16)\n" +
- "\n" +
- " select @charvalue = @charvalue +\n" +
- " substring(@hexstring, @firstint+1, 1) +\n" +
- " substring(@hexstring, @secondint+1, 1)\n" +
- "\n" +
- " select @i = @i + 1\n" +
- " end\n" +
- " return @charvalue\n" +
- " end";
- install(sql, encode);
- }
-
- String triggersDisabled = this.parameterService.getTablePrefix() + "_" + "triggers_disabled";
- if (!installed(SQL_FUNCTION_INSTALLED, triggersDisabled)) {
- String sql =
- "create function dbo.$(functionName)() returns smallint \n" +
- " begin \n" +
- " declare @disabled varchar(1);\n" +
- " declare @context_info varbinary(128); \n" +
- " SELECT @Context_Info = CONTEXT_INFO\n" +
- " FROM master.dbo.SYSPROCESSES \n" +
- " WHERE SPID = @@SPID \n" +
- " set @disabled = coalesce(replace(substring(cast(@context_info as varchar), 1, 1), 0x0, ''), ''); \n" +
- " if @disabled is null or @disabled != '1' \n" +
- " return 0; \n" +
- " return 1; \n" +
- " end ";
- install(sql, triggersDisabled);
- }
-
- String nodeDisabled = this.parameterService.getTablePrefix() + "_" + "node_disabled";
- if (!installed(SQL_FUNCTION_INSTALLED, nodeDisabled)) {
- String sql = "create function dbo.$(functionName)() returns varchar(50) \n" +
- " begin \n" +
- " declare @node varchar(50);\n" +
- " declare @context_info varbinary(128);\n" +
- " SELECT @context_info = CONTEXT_INFO\n" +
- " FROM master.dbo.SYSPROCESSES \n" +
- " WHERE SPID = @@SPID \n " +
- " SELECT @node = coalesce(replace(substring(cast(@context_info as varchar) collate SQL_Latin1_General_CP1_CI_AS, 2, 50), 0x0, ''), ''); \n " +
- " return @node; " +
- " end ";
- install(sql, nodeDisabled);
- }
-
- }
-
- @Override
- public BinaryEncoding getBinaryEncoding() {
- return BinaryEncoding.HEX;
- }
-}
+/**
+ * Licensed to JumpMind Inc under one or more contributor
+ * license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding
+ * copyright ownership. JumpMind Inc licenses this file
+ * to you under the GNU General Public License, version 3.0 (GPLv3)
+ * (the "License"); you may not use this file except in compliance
+ * with the License.
+ *
+ * You should have received a copy of the GNU General Public License,
+ * version 3.0 (GPLv3) along with this library; if not, see
+ * .
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jumpmind.symmetric.db.mssql2000;
+
+import org.jumpmind.db.platform.IDatabasePlatform;
+import org.jumpmind.db.platform.PermissionType;
+import org.jumpmind.db.util.BinaryEncoding;
+import org.jumpmind.symmetric.db.mssql.MsSqlSymmetricDialect;
+import org.jumpmind.symmetric.service.IParameterService;
+
+public class MsSql2000SymmetricDialect extends MsSqlSymmetricDialect {
+
+
+ public MsSql2000SymmetricDialect(IParameterService parameterService, IDatabasePlatform platform) {
+ super(parameterService, platform);
+ this.triggerTemplate = new MsSql2000TriggerTemplate(this);
+ }
+
+ @Override
+ protected boolean alterLockEscalation() {
+ return false;
+ }
+
+ @Override
+ public void createRequiredDatabaseObjects() {
+ String encode = this.parameterService.getTablePrefix() + "_" + "base64_encode";
+ if (!installed(SQL_FUNCTION_INSTALLED, encode)) {
+ String sql = " create function dbo.$(functionName) (\n" +
+ " @binvalue varbinary(8000)) returns varchar(8000)\n" +
+ " as \n" +
+ " begin\n" +
+ " declare @charvalue varchar(8000)\n" +
+ " declare @i int\n" +
+ " declare @length int\n" +
+ " declare @hexstring char(16)\n" +
+ "\n" +
+ " select @charvalue = ''\n" +
+ " select @i = 1\n" +
+ " select @length = datalength(@binvalue)\n" +
+ " select @hexstring = '0123456789abcdef'\n" +
+ "\n" +
+ " while (@i <= @length)\n" +
+ " begin\n" +
+ "\n" +
+ " declare @tempint int\n" +
+ " declare @firstint int\n" +
+ " declare @secondint int\n" +
+ "\n" +
+ " select @tempint = convert(int, substring(@binvalue,@i,1))\n" +
+ " select @firstint = floor(@tempint/16)\n" +
+ " select @secondint = @tempint - (@firstint*16)\n" +
+ "\n" +
+ " select @charvalue = @charvalue +\n" +
+ " substring(@hexstring, @firstint+1, 1) +\n" +
+ " substring(@hexstring, @secondint+1, 1)\n" +
+ "\n" +
+ " select @i = @i + 1\n" +
+ " end\n" +
+ " return @charvalue\n" +
+ " end";
+ install(sql, encode);
+ }
+
+ String triggersDisabled = this.parameterService.getTablePrefix() + "_" + "triggers_disabled";
+ if (!installed(SQL_FUNCTION_INSTALLED, triggersDisabled)) {
+ String sql =
+ "create function dbo.$(functionName)() returns smallint \n" +
+ " begin \n" +
+ " declare @disabled varchar(1);\n" +
+ " declare @context_info varbinary(128); \n" +
+ " SELECT @Context_Info = CONTEXT_INFO\n" +
+ " FROM master.dbo.SYSPROCESSES \n" +
+ " WHERE SPID = @@SPID \n" +
+ " set @disabled = coalesce(replace(substring(cast(@context_info as varchar), 1, 1), 0x0, ''), ''); \n" +
+ " if @disabled is null or @disabled != '1' \n" +
+ " return 0; \n" +
+ " return 1; \n" +
+ " end ";
+ install(sql, triggersDisabled);
+ }
+
+ String nodeDisabled = this.parameterService.getTablePrefix() + "_" + "node_disabled";
+ if (!installed(SQL_FUNCTION_INSTALLED, nodeDisabled)) {
+ String sql = "create function dbo.$(functionName)() returns varchar(50) \n" +
+ " begin \n" +
+ " declare @node varchar(50);\n" +
+ " declare @context_info varbinary(128);\n" +
+ " SELECT @context_info = CONTEXT_INFO\n" +
+ " FROM master.dbo.SYSPROCESSES \n" +
+ " WHERE SPID = @@SPID \n " +
+ " SELECT @node = coalesce(replace(substring(cast(@context_info as varchar) collate SQL_Latin1_General_CP1_CI_AS, 2, 50), 0x0, ''), ''); \n " +
+ " return @node; " +
+ " end ";
+ install(sql, nodeDisabled);
+ }
+
+ }
+
+ @Override
+ public BinaryEncoding getBinaryEncoding() {
+ return BinaryEncoding.HEX;
+ }
+
+ @Override
+ public PermissionType[] getSymTablePermissions() {
+ PermissionType[] permissions = { PermissionType.CREATE_TABLE, PermissionType.DROP_TABLE, PermissionType.CREATE_TRIGGER, PermissionType.DROP_TRIGGER, PermissionType.CREATE_FUNCTION};
+ return permissions;
+ }
+}
diff --git a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/mysql/MySqlSymmetricDialect.java b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/mysql/MySqlSymmetricDialect.java
index b5486fed5f..98df9d2ab8 100644
--- a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/mysql/MySqlSymmetricDialect.java
+++ b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/mysql/MySqlSymmetricDialect.java
@@ -24,6 +24,7 @@
import java.sql.SQLException;
import org.jumpmind.db.platform.IDatabasePlatform;
+import org.jumpmind.db.platform.PermissionType;
import org.jumpmind.db.sql.ISqlTransaction;
import org.jumpmind.db.sql.JdbcSqlTransaction;
import org.jumpmind.db.sql.SqlException;
@@ -228,4 +229,10 @@ public BinaryEncoding getBinaryEncoding() {
protected String getDbSpecificDataHasChangedCondition(Trigger trigger) {
return "var_old_data is null or var_row_data != var_old_data";
}
+
+ @Override
+ public PermissionType[] getSymTablePermissions() {
+ PermissionType[] permissions = { PermissionType.CREATE_TABLE, PermissionType.DROP_TABLE, PermissionType.CREATE_TRIGGER, PermissionType.DROP_TRIGGER, PermissionType.CREATE_ROUTINE};
+ return permissions;
+ }
}
diff --git a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/oracle/OracleSymmetricDialect.java b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/oracle/OracleSymmetricDialect.java
index 454e6a308a..02d181f5d3 100644
--- a/symmetric-client/src/main/java/org/jumpmind/symmetric/db/oracle/OracleSymmetricDialect.java
+++ b/symmetric-client/src/main/java/org/jumpmind/symmetric/db/oracle/OracleSymmetricDialect.java
@@ -27,6 +27,7 @@
import org.apache.commons.lang.time.DateUtils;
import org.jumpmind.db.model.Table;
import org.jumpmind.db.platform.IDatabasePlatform;
+import org.jumpmind.db.platform.PermissionType;
import org.jumpmind.db.sql.ISqlTransaction;
import org.jumpmind.db.sql.SqlException;
import org.jumpmind.db.util.BinaryEncoding;
@@ -358,4 +359,10 @@ protected String getDbSpecificDataHasChangedCondition(Trigger trigger) {
public String getTemplateNumberPrecisionSpec() {
return parameterService.getString(ParameterConstants.DBDIALECT_ORACLE_TEMPLATE_NUMBER_SPEC,"30,10");
}
+
+ @Override
+ public PermissionType[] getSymTablePermissions() {
+ PermissionType[] permissions = { PermissionType.CREATE_TABLE, PermissionType.DROP_TABLE, PermissionType.CREATE_TRIGGER, PermissionType.DROP_TRIGGER, PermissionType.EXECUTE};
+ return permissions;
+ }
}
diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractSymmetricDialect.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractSymmetricDialect.java
index 79869791b0..f77987a2f8 100644
--- a/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractSymmetricDialect.java
+++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/db/AbstractSymmetricDialect.java
@@ -38,6 +38,7 @@
import org.jumpmind.db.platform.IAlterDatabaseInterceptor;
import org.jumpmind.db.platform.IDatabasePlatform;
import org.jumpmind.db.platform.IDdlBuilder;
+import org.jumpmind.db.platform.PermissionType;
import org.jumpmind.db.sql.ISqlResultsListener;
import org.jumpmind.db.sql.ISqlTemplate;
import org.jumpmind.db.sql.ISqlTransaction;
@@ -815,4 +816,9 @@ public IParameterService getParameterService() {
public void setExtensionService(IExtensionService extensionService) {
this.extensionService = extensionService;
}
+
+ public PermissionType[] getSymTablePermissions() {
+ PermissionType[] permissions = { PermissionType.CREATE_TABLE, PermissionType.DROP_TABLE, PermissionType.CREATE_TRIGGER, PermissionType.DROP_TRIGGER };
+ return permissions;
+ }
}
diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/db/ISymmetricDialect.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/db/ISymmetricDialect.java
index 96c88dcb71..f22dd6852a 100644
--- a/symmetric-core/src/main/java/org/jumpmind/symmetric/db/ISymmetricDialect.java
+++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/db/ISymmetricDialect.java
@@ -1,203 +1,204 @@
-/**
- * Licensed to JumpMind Inc under one or more contributor
- * license agreements. See the NOTICE file distributed
- * with this work for additional information regarding
- * copyright ownership. JumpMind Inc licenses this file
- * to you under the GNU General Public License, version 3.0 (GPLv3)
- * (the "License"); you may not use this file except in compliance
- * with the License.
- *
- * You should have received a copy of the GNU General Public License,
- * version 3.0 (GPLv3) along with this library; if not, see
- * .
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.jumpmind.symmetric.db;
-
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.jumpmind.db.model.Column;
-import org.jumpmind.db.model.Database;
-import org.jumpmind.db.model.Table;
-import org.jumpmind.db.platform.IDatabasePlatform;
-import org.jumpmind.db.sql.ISqlTransaction;
-import org.jumpmind.db.util.BinaryEncoding;
-import org.jumpmind.symmetric.io.data.DataEventType;
-import org.jumpmind.symmetric.model.Channel;
-import org.jumpmind.symmetric.model.Node;
-import org.jumpmind.symmetric.model.Trigger;
-import org.jumpmind.symmetric.model.TriggerHistory;
-import org.jumpmind.symmetric.model.TriggerRouter;
-import org.jumpmind.symmetric.service.IExtensionService;
-import org.jumpmind.symmetric.service.IParameterService;
-import org.jumpmind.symmetric.service.impl.TransformService.TransformTableNodeGroupLink;
-
+/**
+ * Licensed to JumpMind Inc under one or more contributor
+ * license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding
+ * copyright ownership. JumpMind Inc licenses this file
+ * to you under the GNU General Public License, version 3.0 (GPLv3)
+ * (the "License"); you may not use this file except in compliance
+ * with the License.
+ *
+ * You should have received a copy of the GNU General Public License,
+ * version 3.0 (GPLv3) along with this library; if not, see
+ * .
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jumpmind.symmetric.db;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.jumpmind.db.model.Column;
+import org.jumpmind.db.model.Database;
+import org.jumpmind.db.model.Table;
+import org.jumpmind.db.platform.IDatabasePlatform;
+import org.jumpmind.db.platform.PermissionType;
+import org.jumpmind.db.sql.ISqlTransaction;
+import org.jumpmind.db.util.BinaryEncoding;
+import org.jumpmind.symmetric.io.data.DataEventType;
+import org.jumpmind.symmetric.model.Channel;
+import org.jumpmind.symmetric.model.Node;
+import org.jumpmind.symmetric.model.Trigger;
+import org.jumpmind.symmetric.model.TriggerHistory;
+import org.jumpmind.symmetric.model.TriggerRouter;
+import org.jumpmind.symmetric.service.IExtensionService;
+import org.jumpmind.symmetric.service.IParameterService;
+import org.jumpmind.symmetric.service.impl.TransformService.TransformTableNodeGroupLink;
+
/*
* A dialect is the interface that insulates SymmetricDS from database implementation specifics.
*/
-public interface ISymmetricDialect {
-
+public interface ISymmetricDialect {
+
public void createTrigger(StringBuilder sqlBuffer, DataEventType dml,
- Trigger trigger, TriggerHistory hist, Channel channel,
- String tablePrefix, Table table);
-
- /*
- * Get the name of this symmetric instance. This can be set in
- * symmetric.properties using the symmetric.runtime.engine.name property.
- */
- public String getEngineName();
-
- public void removeTrigger(StringBuilder sqlBuffer, String catalogName, String schemaName, String triggerName,
- String tableName);
-
+ Trigger trigger, TriggerHistory hist, Channel channel,
+ String tablePrefix, Table table);
+
+ /*
+ * Get the name of this symmetric instance. This can be set in
+ * symmetric.properties using the symmetric.runtime.engine.name property.
+ */
+ public String getEngineName();
+
+ public void removeTrigger(StringBuilder sqlBuffer, String catalogName, String schemaName, String triggerName,
+ String tableName);
+
public boolean doesTriggerExist(String catalogName, String schema, String tableName, String triggerName);
- public void verifyDatabaseIsCompatible();
-
+ public void verifyDatabaseIsCompatible();
+
public void initTablesAndDatabaseObjects();
public void dropTablesAndDatabaseObjects();
- public boolean createOrAlterTablesIfNecessary(String... tables);
-
- public void dropRequiredDatabaseObjects();
-
- public void createRequiredDatabaseObjects();
-
- public IDatabasePlatform getPlatform();
-
- public String getName();
-
- public String getVersion();
-
- public int getMajorVersion();
-
- public int getMinorVersion();
-
- public String getProductVersion();
-
+ public boolean createOrAlterTablesIfNecessary(String... tables);
+
+ public void dropRequiredDatabaseObjects();
+
+ public void createRequiredDatabaseObjects();
+
+ public IDatabasePlatform getPlatform();
+
+ public String getName();
+
+ public String getVersion();
+
+ public int getMajorVersion();
+
+ public int getMinorVersion();
+
+ public String getProductVersion();
+
public BinaryEncoding getBinaryEncoding();
- public String getTransactionTriggerExpression(String defaultCatalog, String defaultSchema, Trigger trigger);
-
+ public String getTransactionTriggerExpression(String defaultCatalog, String defaultSchema, Trigger trigger);
+
public String createInitialLoadSqlFor(Node node, TriggerRouter trigger, Table table, TriggerHistory triggerHistory, Channel channel, String overrideSelectSql);
-
- public String createPurgeSqlFor(Node node, TriggerRouter triggerRouter, TriggerHistory triggerHistory);
-
- public String createPurgeSqlFor(Node node, TriggerRouter triggerRouter, TriggerHistory triggerHistory, List transforms);
-
- public String createPurgeSqlFor(Node node, TriggerRouter triggerRouter, TriggerHistory triggerHistory, List transforms, String deleteSql);
-
- public String createCsvDataSql(Trigger trigger, TriggerHistory triggerHistory, Channel channel, String whereClause);
-
- public String createCsvPrimaryKeySql(Trigger trigger, TriggerHistory triggerHistory, Channel channel, String whereClause);
-
- /*
- * Get the maximum size the name of a trigger can be for the database
- * platform. If the generated symmetric trigger name is greater than the max
- * trigger name, symmetric will truncate the name, then log a warning
- * suggesting that you might want to provide your own name.
- */
- public int getMaxTriggerNameLength();
-
+
+ public String createPurgeSqlFor(Node node, TriggerRouter triggerRouter, TriggerHistory triggerHistory);
+
+ public String createPurgeSqlFor(Node node, TriggerRouter triggerRouter, TriggerHistory triggerHistory, List transforms);
+
+ public String createPurgeSqlFor(Node node, TriggerRouter triggerRouter, TriggerHistory triggerHistory, List transforms, String deleteSql);
+
+ public String createCsvDataSql(Trigger trigger, TriggerHistory triggerHistory, Channel channel, String whereClause);
+
+ public String createCsvPrimaryKeySql(Trigger trigger, TriggerHistory triggerHistory, Channel channel, String whereClause);
+
+ /*
+ * Get the maximum size the name of a trigger can be for the database
+ * platform. If the generated symmetric trigger name is greater than the max
+ * trigger name, symmetric will truncate the name, then log a warning
+ * suggesting that you might want to provide your own name.
+ */
+ public int getMaxTriggerNameLength();
+
public boolean supportsTransactionId();
- /*
- * Use this call to check to see if the implemented database dialect supports
- * a way to check on pending database transactions.
- */
- public boolean supportsTransactionViews();
-
- /*
- * Indicates if this dialect supports subselects in delete statements.
- */
- public boolean supportsSubselectsInDelete();
-
- /*
- * Indicates if this dialect supports subselects in update statements.
- */
- public boolean supportsSubselectsInUpdate();
-
- /*
- * Implement this if the database has some type of cleanup functionality
- * that needs to be run when dropping database objects. An example is
- * Oracle's 'purge recyclebin'
- */
- public void cleanDatabase();
-
- public void disableSyncTriggers(ISqlTransaction transaction);
-
- public void disableSyncTriggers(ISqlTransaction transaction, String nodeId);
-
- public void enableSyncTriggers(ISqlTransaction transaction);
-
- public String getSyncTriggersExpression();
-
- public String getSourceNodeExpression();
-
- public String getCreateSymmetricDDL();
-
- public boolean isBlobSyncSupported();
-
- public boolean isClobSyncSupported();
-
- /*
- * An indicator as to whether the ability to override the default
- * transaction id provided by the dialect can be overridden in the trigger
- * configuration.
- */
- public boolean isTransactionIdOverrideSupported();
-
- public Table getTable(TriggerHistory triggerHistory, boolean useCache);
-
+ /*
+ * Use this call to check to see if the implemented database dialect supports
+ * a way to check on pending database transactions.
+ */
+ public boolean supportsTransactionViews();
+
+ /*
+ * Indicates if this dialect supports subselects in delete statements.
+ */
+ public boolean supportsSubselectsInDelete();
+
+ /*
+ * Indicates if this dialect supports subselects in update statements.
+ */
+ public boolean supportsSubselectsInUpdate();
+
+ /*
+ * Implement this if the database has some type of cleanup functionality
+ * that needs to be run when dropping database objects. An example is
+ * Oracle's 'purge recyclebin'
+ */
+ public void cleanDatabase();
+
+ public void disableSyncTriggers(ISqlTransaction transaction);
+
+ public void disableSyncTriggers(ISqlTransaction transaction, String nodeId);
+
+ public void enableSyncTriggers(ISqlTransaction transaction);
+
+ public String getSyncTriggersExpression();
+
+ public String getSourceNodeExpression();
+
+ public String getCreateSymmetricDDL();
+
+ public boolean isBlobSyncSupported();
+
+ public boolean isClobSyncSupported();
+
+ /*
+ * An indicator as to whether the ability to override the default
+ * transaction id provided by the dialect can be overridden in the trigger
+ * configuration.
+ */
+ public boolean isTransactionIdOverrideSupported();
+
+ public Table getTable(TriggerHistory triggerHistory, boolean useCache);
+
public long insertWithGeneratedKey(final String sql, final SequenceIdentifier sequenceId);
- public long insertWithGeneratedKey(final String sql, final SequenceIdentifier identifier, Object... args);
-
- @Deprecated
- public Column[] orderColumns(String[] columnNames, Table table);
-
- public boolean supportsOpenCursorsAcrossCommit();
-
- /*
- * Retrieves a list of keywords for the database.
- */
- public Set getSqlKeywords();
-
- public String getInitialLoadTableAlias();
-
- public String preProcessTriggerSqlClause(String sqlClause);
-
- public void truncateTable(String tableName);
-
- public long getDatabaseTime();
-
- public boolean areDatabaseTransactionsPendingSince(long time);
-
- public Date getEarliestTransactionStartTime();
-
- /*
- * Returns true if the trigger select lob data back from the original table.
- */
- public boolean needsToSelectLobData();
-
- /*
- * This is a SQL clause that compares the old data to the new data in a trigger.
- */
- public String getDataHasChangedCondition(Trigger trigger);
-
- /*
- * Indicates whether captured data can contain gaps.
- */
+ public long insertWithGeneratedKey(final String sql, final SequenceIdentifier identifier, Object... args);
+
+ @Deprecated
+ public Column[] orderColumns(String[] columnNames, Table table);
+
+ public boolean supportsOpenCursorsAcrossCommit();
+
+ /*
+ * Retrieves a list of keywords for the database.
+ */
+ public Set getSqlKeywords();
+
+ public String getInitialLoadTableAlias();
+
+ public String preProcessTriggerSqlClause(String sqlClause);
+
+ public void truncateTable(String tableName);
+
+ public long getDatabaseTime();
+
+ public boolean areDatabaseTransactionsPendingSince(long time);
+
+ public Date getEarliestTransactionStartTime();
+
+ /*
+ * Returns true if the trigger select lob data back from the original table.
+ */
+ public boolean needsToSelectLobData();
+
+ /*
+ * This is a SQL clause that compares the old data to the new data in a trigger.
+ */
+ public String getDataHasChangedCondition(Trigger trigger);
+
+ /*
+ * Indicates whether captured data can contain gaps.
+ */
public boolean canGapsOccurInCapturedDataIds();
public String massageDataExtractionSql(String sql, Channel channel);
@@ -231,14 +232,16 @@ public void removeTrigger(StringBuilder sqlBuffer, String catalogName, String sc
public String getTemplateNumberPrecisionSpec();
- public Map getSqlReplacementTokens();
-
+ public Map getSqlReplacementTokens();
+
public int getSqlTypeForIds();
-
- public AbstractTriggerTemplate getTriggerTemplate();
-
- public IParameterService getParameterService();
-
- public void setExtensionService(IExtensionService extensionService);
+
+ public AbstractTriggerTemplate getTriggerTemplate();
+
+ public IParameterService getParameterService();
+
+ public void setExtensionService(IExtensionService extensionService);
+
+ public PermissionType[] getSymTablePermissions();
}
diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataLoaderService.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataLoaderService.java
index acdce37b93..5c91b3b935 100644
--- a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataLoaderService.java
+++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataLoaderService.java
@@ -913,7 +913,7 @@ public void end(final DataContext ctx, final Batch batch, final IStagedResource
Callable loadBatchFromStage = new Callable() {
public IncomingBatch call() throws Exception {
IncomingBatch incomingBatch = null;
- if (!isError) {
+ if (!isError && resource != null && resource.exists()) {
try {
processInfo.setStatus(ProcessInfo.Status.LOADING);
@@ -949,6 +949,11 @@ protected IDataWriter chooseDataWriter(Batch batch) {
}
resource.setState(State.DONE);
}
+ } else {
+ log.info("The batch {} was missing in staging. Setting status to resend", batch.getNodeBatchId());
+ incomingBatch = new IncomingBatch(batch);
+ incomingBatch.setStatus(Status.RS);
+ incomingBatchService.updateIncomingBatch(incomingBatch);
}
return incomingBatch;
}
diff --git a/symmetric-db/src/main/java/org/jumpmind/db/platform/AbstractDatabasePlatform.java b/symmetric-db/src/main/java/org/jumpmind/db/platform/AbstractDatabasePlatform.java
index 8e979f5bea..dab445f535 100644
--- a/symmetric-db/src/main/java/org/jumpmind/db/platform/AbstractDatabasePlatform.java
+++ b/symmetric-db/src/main/java/org/jumpmind/db/platform/AbstractDatabasePlatform.java
@@ -1,921 +1,1078 @@
-package org.jumpmind.db.platform;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import static org.apache.commons.lang.StringUtils.isNotBlank;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.sql.Array;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TimeZone;
-import java.util.regex.Pattern;
-
-import org.apache.commons.codec.DecoderException;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.binary.Hex;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.time.DateUtils;
-import org.jumpmind.db.io.DatabaseXmlUtil;
-import org.jumpmind.db.model.Column;
-import org.jumpmind.db.model.ColumnTypes;
-import org.jumpmind.db.model.Database;
-import org.jumpmind.db.model.ForeignKey;
-import org.jumpmind.db.model.IIndex;
-import org.jumpmind.db.model.IndexColumn;
-import org.jumpmind.db.model.Reference;
-import org.jumpmind.db.model.Table;
-import org.jumpmind.db.model.TypeMap;
-import org.jumpmind.db.sql.DmlStatement;
-import org.jumpmind.db.sql.DmlStatement.DmlType;
-import org.jumpmind.db.sql.ISqlTemplate;
-import org.jumpmind.db.sql.Row;
-import org.jumpmind.db.sql.SqlScript;
-import org.jumpmind.db.util.BinaryEncoding;
-import org.jumpmind.exception.IoException;
-import org.jumpmind.util.FormatUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/*
- * Base class for platform implementations.
- */
-public abstract class AbstractDatabasePlatform implements IDatabasePlatform {
-
- /* The log for this platform. */
- protected final Logger log = LoggerFactory.getLogger(getClass());
-
- public static final String REQUIRED_FIELD_NULL_SUBSTITUTE = " ";
-
- /* The default name for models read from the database, if no name as given. */
- protected static final String MODEL_DEFAULT_NAME = "default";
-
- /* The model reader for this platform. */
- protected IDdlReader ddlReader;
-
- protected IDdlBuilder ddlBuilder;
-
- protected Map tableCache = new HashMap();
-
- private long lastTimeCachedModelClearedInMs = System.currentTimeMillis();
-
- protected long clearCacheModelTimeoutInMs = DateUtils.MILLIS_PER_HOUR;
-
- protected String defaultSchema;
-
- protected String defaultCatalog;
-
- protected Boolean storesUpperCaseIdentifiers;
-
- protected Boolean storesLowerCaseIdentifiers;
-
- protected Boolean storesMixedCaseIdentifiers;
-
- protected boolean metadataIgnoreCase = true;
-
- public AbstractDatabasePlatform() {
- }
-
- public DatabaseInfo getDatabaseInfo() {
- return getDdlBuilder().getDatabaseInfo();
- }
-
- abstract public ISqlTemplate getSqlTemplate();
-
- abstract public ISqlTemplate getSqlTemplateDirty();
-
- public DmlStatement createDmlStatement(DmlType dmlType, Table table, String textColumnExpression) {
-
- return createDmlStatement(dmlType, table.getCatalog(), table.getSchema(), table.getName(),
- table.getPrimaryKeyColumns(), table.getColumns(), null, textColumnExpression);
- }
-
- public DmlStatement createDmlStatement(DmlType dmlType, String catalogName, String schemaName,
- String tableName, Column[] keys, Column[] columns, boolean[] nullKeyValues, String textColumnExpression) {
-
- return DmlStatementFactory.createDmlStatement(getName(), dmlType, catalogName, schemaName,
- tableName, keys, columns, nullKeyValues, getDdlBuilder(), textColumnExpression);
- }
-
- public DmlStatement createDmlStatement(DmlType dmlType, String catalogName, String schemaName,
- String tableName, Column[] keys, Column[] columns, boolean[] nullKeyValues, String textColumnExpression,
- boolean namedParameters) {
-
- return DmlStatementFactory.createDmlStatement(getName(), dmlType, catalogName, schemaName,
- tableName, keys, columns, nullKeyValues, getDdlBuilder(), textColumnExpression,
- namedParameters);
-
- }
-
-
- public IDdlReader getDdlReader() {
- return ddlReader;
- }
-
- public IDdlBuilder getDdlBuilder() {
- return ddlBuilder;
- }
-
- public void setClearCacheModelTimeoutInMs(long clearCacheModelTimeoutInMs) {
- this.clearCacheModelTimeoutInMs = clearCacheModelTimeoutInMs;
- }
-
- public long getClearCacheModelTimeoutInMs() {
- return clearCacheModelTimeoutInMs;
- }
-
- public void dropTables(boolean continueOnError, Table...tables) {
- Database db = new Database();
- for (Table table : tables) {
- db.addTable(table);
- }
- dropDatabase(db, continueOnError);
- }
-
- public void dropDatabase(Database database, boolean continueOnError) {
- String sql = ddlBuilder.dropTables(database);
- new SqlScript(sql, getSqlTemplate(), !continueOnError, null).execute(getDatabaseInfo().isRequiresAutoCommitForDdl());
- }
-
- public void createTables(boolean dropTablesFirst, boolean continueOnError, Table... tables) {
- Database database = new Database();
- database.addTables(tables);
- createDatabase(database, dropTablesFirst, continueOnError);
- }
-
- public void createDatabase(Database targetDatabase, boolean dropTablesFirst,
- boolean continueOnError) {
- if (dropTablesFirst) {
- dropDatabase(targetDatabase, true);
- }
-
- String createSql = ddlBuilder.createTables(targetDatabase, false);
-
- if (log.isDebugEnabled()) {
- log.debug("Generated create sql: \n{}", createSql);
- }
-
- String delimiter = getDdlBuilder().getDatabaseInfo().getSqlCommandDelimiter();
- new SqlScript(createSql, getSqlTemplate(), !continueOnError, false, false, delimiter, null).execute(getDatabaseInfo().isRequiresAutoCommitForDdl());
- }
-
- public void alterDatabase(Database desiredDatabase, boolean continueOnError) {
- alterTables(continueOnError, desiredDatabase.getTables());
- }
-
- public void alterTables(boolean continueOnError, Table... desiredTables) {
- Database currentDatabase = new Database();
- Database desiredDatabase = new Database();
- StringBuilder tablesProcessed = new StringBuilder();
- for (Table table : desiredTables) {
- tablesProcessed.append(table.getFullyQualifiedTableName());
- tablesProcessed.append(", ");
- desiredDatabase.addTable(table);
- Table currentTable = ddlReader.readTable(table.getCatalog(), table.getSchema(),
- table.getName());
- if (currentTable != null) {
- currentDatabase.addTable(currentTable);
- }
- }
-
- if (tablesProcessed.length() > 1) {
- tablesProcessed.replace(tablesProcessed.length() - 2, tablesProcessed.length(), "");
- }
-
- String alterSql = ddlBuilder.alterDatabase(currentDatabase, desiredDatabase);
-
- if (StringUtils.isNotBlank(alterSql.trim())) {
- log.info("Running alter sql:\n{}", alterSql);
- String delimiter = getDdlBuilder().getDatabaseInfo().getSqlCommandDelimiter();
- new SqlScript(alterSql, getSqlTemplate(), !continueOnError, false, false, delimiter, null).execute(getDatabaseInfo().isRequiresAutoCommitForDdl());
- } else {
- log.info("Tables up to date. No alters found for {}", tablesProcessed);
- }
-
- }
-
- public Database readDatabase(String catalog, String schema, String[] tableTypes) {
- Database model = ddlReader.readTables(catalog, schema, tableTypes);
- if ((model.getName() == null) || (model.getName().length() == 0)) {
- model.setName(MODEL_DEFAULT_NAME);
- }
- return model;
- }
-
-
- public Database readFromDatabase(Table... tables) {
- Database fromDb = new Database();
- for (Table tableFromXml : tables) {
- Table tableFromDatabase = getTableFromCache(tableFromXml.getCatalog(),
- tableFromXml.getSchema(), tableFromXml.getName(), true);
- if (tableFromDatabase != null) {
- fromDb.addTable(tableFromDatabase);
- }
- }
- fromDb.initialize();
- return fromDb;
- }
-
- public Table readTableFromDatabase(String catalogName, String schemaName, String tableName) {
- String originalFullyQualifiedName = Table.getFullyQualifiedTableName(catalogName,
- schemaName, tableName);
- String defaultedCatalogName = catalogName == null ? getDefaultCatalog() : catalogName;
- String defaultedSchemaName = schemaName == null ? getDefaultSchema() : schemaName;
-
- Table table = ddlReader.readTable(defaultedCatalogName, defaultedSchemaName, tableName);
- if (table == null && metadataIgnoreCase) {
-
- IDdlReader reader = getDdlReader();
-
- if (isNotBlank(catalogName)) {
- List catalogNames = reader.getCatalogNames();
- if (catalogNames != null) {
- for (String name : catalogNames) {
- if (name != null && name.equalsIgnoreCase(catalogName)) {
- defaultedCatalogName = name;
- break;
- }
- }
- }
- }
-
- if (isNotBlank(schemaName)) {
- List schemaNames = reader.getSchemaNames(catalogName);
- if (schemaNames != null) {
- for (String name : schemaNames) {
- if (name != null && name.equalsIgnoreCase(schemaName)) {
- defaultedSchemaName = name;
- break;
- }
- }
- }
- }
-
-
- List tableNames = reader.getTableNames(defaultedCatalogName, defaultedSchemaName, null);
- if (tableNames != null) {
- for (String name : tableNames) {
- if (name != null && name.equalsIgnoreCase(tableName)) {
- tableName = name;
- break;
- }
- }
- }
-
- if (!originalFullyQualifiedName.equals(Table.getFullyQualifiedTableName(
- defaultedCatalogName, defaultedSchemaName, tableName))) {
- table = ddlReader.readTable(defaultedCatalogName, defaultedSchemaName, tableName);
- }
-
- }
-
- if (table != null && log.isDebugEnabled()) {
- log.debug("Just read table: \n{}", table.toVerboseString());
- }
- return table;
- }
-
- public void resetCachedTableModel() {
- synchronized (this.getClass()) {
- this.tableCache = new HashMap();
- lastTimeCachedModelClearedInMs = System.currentTimeMillis();
- }
- }
-
- public Table getTableFromCache(String tableName, boolean forceReread) {
- return getTableFromCache(getDefaultCatalog(), getDefaultSchema(), tableName, forceReread);
- }
-
- public Table getTableFromCache(String catalogName, String schemaName, String tableName,
- boolean forceReread) {
- if (System.currentTimeMillis() - lastTimeCachedModelClearedInMs > clearCacheModelTimeoutInMs) {
- resetCachedTableModel();
- }
- Map model = tableCache;
- String key = Table.getFullyQualifiedTableName(catalogName, schemaName, tableName);
- Table retTable = model != null ? model.get(key) : null;
- if (retTable == null || forceReread) {
- synchronized (this.getClass()) {
- try {
- Table table = readTableFromDatabase(catalogName, schemaName, tableName);
- tableCache.put(key, table);
- retTable = table;
- } catch (RuntimeException ex) {
- throw ex;
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
- }
- return retTable;
- }
-
- public Object[] getObjectValues(BinaryEncoding encoding, Table table, String[] columnNames,
- String[] values) {
- Column[] metaData = Table.orderColumns(columnNames, table);
- return getObjectValues(encoding, values, metaData);
- }
-
- public Object[] getObjectValues(BinaryEncoding encoding, Table table, String[] columnNames,
- String[] values, boolean useVariableDates, boolean fitToColumn) {
- Column[] metaData = Table.orderColumns(columnNames, table);
- return getObjectValues(encoding, values, metaData, useVariableDates, fitToColumn);
- }
-
- public Object[] getObjectValues(BinaryEncoding encoding, String[] values,
- Column[] orderedMetaData) {
- return getObjectValues(encoding, values, orderedMetaData, false, false);
- }
-
- public Object[] getObjectValues(BinaryEncoding encoding, String[] values,
- Column[] orderedMetaData, boolean useVariableDates, boolean fitToColumn) {
- if (values != null) {
- List