private void RefreshServerProvider() { //Configure the SQL Server sync provider OracleDbSyncProvider serverSyncProvider = synchronizationHelper.ConfigureDBSyncProvider(this.oracleConnectionString); //Add the server provider to the collection providersCollection["Server"] = serverSyncProvider; }
/// <summary> /// Configure the Oracle DbSyncprovider. Usual configuration similar to OCS V2 samples. /// </summary> /// <param name="connectionString"></param> /// <returns></returns> public OracleDbSyncProvider ConfigureDBSyncProvider(string connectionString) { OracleDbSyncProvider provider = new OracleDbSyncProvider(); provider.ScopeName = SyncUtils.ScopeName; provider.Connection = new OracleConnection(); provider.Connection.ConnectionString = connectionString; for (int i = 0; i < SyncUtils.SyncAdapterTables.Length; i++) { //Add each table as a DbSyncAdapter to the provider DbSyncAdapter adapter = new DbSyncAdapter(SyncUtils.SyncAdapterTables[i]); adapter.RowIdColumns.Add(SyncUtils.SyncAdapterTablePrimaryKeys[i]); // select incremental changes command OracleCommand chgsOrdersCmd = new OracleCommand(); chgsOrdersCmd.CommandType = CommandType.StoredProcedure; chgsOrdersCmd.CommandText = "sp_" + SyncUtils.SyncAdapterTables[i] + "_selectchanges"; chgsOrdersCmd.Parameters.Add(DbSyncSession.SyncMetadataOnly, OracleType.Int32); chgsOrdersCmd.Parameters.Add(DbSyncSession.SyncMinTimestamp, OracleType.Number); chgsOrdersCmd.Parameters.Add(DbSyncSession.SyncScopeLocalId, OracleType.Int32); chgsOrdersCmd.Parameters.Add("sync_changes", OracleType.Cursor).Direction = ParameterDirection.Output; adapter.SelectIncrementalChangesCommand = chgsOrdersCmd; // insert row command OracleCommand insOrdersCmd = new OracleCommand(); insOrdersCmd.CommandType = CommandType.StoredProcedure; insOrdersCmd.CommandText = "sp_" + SyncUtils.SyncAdapterTables[i] + "_applyinsert"; insOrdersCmd.Parameters.Add(SyncUtils.SyncAdapterTablePrimaryKeys[i], OracleType.Int32); if (SyncUtils.SyncAdapterTables[i] == "orders") { insOrdersCmd.Parameters.Add("order_date", OracleType.DateTime); } else { insOrdersCmd.Parameters.Add("product", OracleType.NVarChar, 100); insOrdersCmd.Parameters.Add("quantity", OracleType.Int32); insOrdersCmd.Parameters.Add("order_id", OracleType.Int32); } insOrdersCmd.Parameters.Add(DbSyncSession.SyncRowCount, OracleType.Int32).Direction = ParameterDirection.Output; adapter.InsertCommand = insOrdersCmd; // update row command OracleCommand updOrdersCmd = new OracleCommand(); updOrdersCmd.CommandType = CommandType.StoredProcedure; updOrdersCmd.CommandText = "sp_" + SyncUtils.SyncAdapterTables[i] + "_applyupdate"; updOrdersCmd.Parameters.Add(SyncUtils.SyncAdapterTablePrimaryKeys[i], OracleType.Int32); if (SyncUtils.SyncAdapterTables[i] == "orders") { updOrdersCmd.Parameters.Add("order_date", OracleType.DateTime); } else { updOrdersCmd.Parameters.Add("product", OracleType.NVarChar, 100); updOrdersCmd.Parameters.Add("quantity", OracleType.Int32); updOrdersCmd.Parameters.Add("order_id", OracleType.Int32); } updOrdersCmd.Parameters.Add(DbSyncSession.SyncMinTimestamp, OracleType.Number); updOrdersCmd.Parameters.Add(DbSyncSession.SyncRowCount, OracleType.Int32).Direction = ParameterDirection.Output; updOrdersCmd.Parameters.Add(DbSyncSession.SyncForceWrite, OracleType.Int32); adapter.UpdateCommand = updOrdersCmd; // delete row command OracleCommand delOrdersCmd = new OracleCommand(); delOrdersCmd.CommandType = CommandType.StoredProcedure; delOrdersCmd.CommandText = "sp_" + SyncUtils.SyncAdapterTables[i] + "_applydelete"; delOrdersCmd.Parameters.Add(SyncUtils.SyncAdapterTablePrimaryKeys[i], OracleType.Int32); delOrdersCmd.Parameters.Add(DbSyncSession.SyncMinTimestamp, OracleType.Number); delOrdersCmd.Parameters.Add(DbSyncSession.SyncRowCount, OracleType.Int32).Direction = ParameterDirection.Output; delOrdersCmd.Parameters.Add(DbSyncSession.SyncForceWrite, OracleType.Int32); adapter.DeleteCommand = delOrdersCmd; // get row command OracleCommand selRowOrdersCmd = new OracleCommand(); selRowOrdersCmd.CommandType = CommandType.StoredProcedure; selRowOrdersCmd.CommandText = "sp_" + SyncUtils.SyncAdapterTables[i] + "_selectrow"; selRowOrdersCmd.Parameters.Add(SyncUtils.SyncAdapterTablePrimaryKeys[i], OracleType.Int32); selRowOrdersCmd.Parameters.Add(DbSyncSession.SyncScopeLocalId, OracleType.Int32); selRowOrdersCmd.Parameters.Add("selectedRow", OracleType.Cursor).Direction = ParameterDirection.Output; adapter.SelectRowCommand = selRowOrdersCmd; // insert row metadata command OracleCommand insMetadataOrdersCmd = new OracleCommand(); insMetadataOrdersCmd.CommandType = CommandType.StoredProcedure; insMetadataOrdersCmd.CommandText = "sp_" + SyncUtils.SyncAdapterTables[i] + "_insert_md"; insMetadataOrdersCmd.Parameters.Add(SyncUtils.SyncAdapterTablePrimaryKeys[i], OracleType.Int32); insMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncScopeLocalId, OracleType.Int32); insMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncRowTimestamp, OracleType.Number); insMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncCreatePeerKey, OracleType.Int32); insMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncCreatePeerTimestamp, OracleType.Number); insMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncUpdatePeerKey, OracleType.Int32); insMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncUpdatePeerTimestamp, OracleType.Number); insMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncRowIsTombstone, OracleType.Int32); insMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncCheckConcurrency, OracleType.Int32); insMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncRowCount, OracleType.Int32).Direction = ParameterDirection.Output; adapter.InsertMetadataCommand = insMetadataOrdersCmd; // update row metadata command OracleCommand updMetadataOrdersCmd = new OracleCommand(); updMetadataOrdersCmd.CommandType = CommandType.StoredProcedure; updMetadataOrdersCmd.CommandText = "sp_" + SyncUtils.SyncAdapterTables[i] + "_update_md"; updMetadataOrdersCmd.Parameters.Add(SyncUtils.SyncAdapterTablePrimaryKeys[i], OracleType.Int32); updMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncScopeLocalId, OracleType.Int32); updMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncRowTimestamp, OracleType.Number); updMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncCreatePeerKey, OracleType.Int32); updMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncCreatePeerTimestamp, OracleType.Number); updMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncUpdatePeerKey, OracleType.Int32); updMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncUpdatePeerTimestamp, OracleType.Number); updMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncRowIsTombstone, OracleType.Int32); updMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncCheckConcurrency, OracleType.Int32); updMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncRowCount, OracleType.Int32).Direction = ParameterDirection.Output; adapter.UpdateMetadataCommand = (IDbCommand)updMetadataOrdersCmd.Clone(); // delete row metadata command OracleCommand delMetadataOrdersCmd = new OracleCommand(); delMetadataOrdersCmd.CommandType = CommandType.StoredProcedure; delMetadataOrdersCmd.CommandText = "sp_" + SyncUtils.SyncAdapterTables[i] + "_delete_md"; delMetadataOrdersCmd.Parameters.Add(SyncUtils.SyncAdapterTablePrimaryKeys[i], OracleType.Int32); delMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncCheckConcurrency, OracleType.Int32); delMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncRowTimestamp, OracleType.Number); delMetadataOrdersCmd.Parameters.Add(DbSyncSession.SyncRowCount, OracleType.Int32).Direction = ParameterDirection.Output; adapter.DeleteMetadataCommand = delMetadataOrdersCmd; // get tombstones for cleanup OracleCommand selTombstonesOrdersCmd = new OracleCommand(); selTombstonesOrdersCmd.CommandType = CommandType.StoredProcedure; selTombstonesOrdersCmd.CommandText = "sp_" + SyncUtils.SyncAdapterTables[i] + "_select_ts"; selTombstonesOrdersCmd.Parameters.Add("tombstone_aging_in_hours", OracleType.Int32).Value = SyncUtils.TombstoneAgingInHours; selTombstonesOrdersCmd.Parameters.Add("sync_scope_local_id", OracleType.Int32); adapter.SelectMetadataForCleanupCommand = selTombstonesOrdersCmd; provider.SyncAdapters.Add(adapter); } // 2. Setup provider wide commands // There are few commands on the provider itself and not on a table sync adapter: // SelectNewTimestampCommand: Returns the new high watermark for current sync // SelectScopeInfoCommand: Returns sync knowledge, cleanup knowledge and scope version (timestamp) // UpdateScopeInfoCommand: Sets the new values for sync knowledge and cleanup knowledge // OracleCommand anchorCmd = new OracleCommand(); anchorCmd.CommandType = CommandType.StoredProcedure; anchorCmd.CommandText = "SP_GET_TIMESTAMP"; // for SQL Server 2005 SP2, use "min_active_rowversion() - 1" anchorCmd.Parameters.Add(DbSyncSession.SyncNewTimestamp, OracleType.UInt32).Direction = ParameterDirection.Output; provider.SelectNewTimestampCommand = anchorCmd; // // Select local replica info // OracleCommand selReplicaInfoCmd = new OracleCommand(); selReplicaInfoCmd.CommandType = CommandType.Text; selReplicaInfoCmd.CommandText = "select " + "scope_id, " + "scope_local_id, " + "scope_sync_knowledge, " + "scope_forgotten_knowledge, " + "scope_timestamp " + "from scope_info " + "where scope_name = :" + DbSyncSession.SyncScopeName; selReplicaInfoCmd.Parameters.Clear(); selReplicaInfoCmd.Parameters.Add(DbSyncSession.SyncScopeName, OracleType.NVarChar).Direction = ParameterDirection.Input; provider.SelectScopeInfoCommand = selReplicaInfoCmd; // // Update local replica info // OracleCommand updReplicaInfoCmd = new OracleCommand(); updReplicaInfoCmd.CommandType = CommandType.Text; updReplicaInfoCmd.CommandText = "begin update scope_info set " + "scope_sync_knowledge = :" + DbSyncSession.SyncScopeKnowledge + ", " + "scope_id = :" + DbSyncSession.SyncScopeId + ", " + "scope_forgotten_knowledge = :" + DbSyncSession.SyncScopeCleanupKnowledge + " " + "where scope_name = :" + DbSyncSession.SyncScopeName + " and " + " ( :" + DbSyncSession.SyncCheckConcurrency + " = 0 or scope_timestamp = :" + DbSyncSession.SyncScopeTimestamp + "); " + ":" + DbSyncSession.SyncRowCount + " := sql%rowcount; End;"; updReplicaInfoCmd.Parameters.Add(DbSyncSession.SyncScopeKnowledge, OracleType.Raw, 10000); updReplicaInfoCmd.Parameters.Add(DbSyncSession.SyncScopeCleanupKnowledge, OracleType.Raw, 10000); updReplicaInfoCmd.Parameters.Add(DbSyncSession.SyncScopeName, OracleType.NVarChar, 100); updReplicaInfoCmd.Parameters.Add(DbSyncSession.SyncCheckConcurrency, OracleType.Int32); updReplicaInfoCmd.Parameters.Add(DbSyncSession.SyncScopeId, OracleType.Raw); updReplicaInfoCmd.Parameters.Add(DbSyncSession.SyncScopeTimestamp, OracleType.Number); updReplicaInfoCmd.Parameters.Add(DbSyncSession.SyncRowCount, OracleType.Int32).Direction = ParameterDirection.Output; provider.UpdateScopeInfoCommand = updReplicaInfoCmd; // // Select overlapping scopes // // get tombstones for cleanup OracleCommand overlappingScopesCmd = new OracleCommand(); overlappingScopesCmd.CommandType = CommandType.StoredProcedure; overlappingScopesCmd.CommandText = "sp_select_shared_scopes"; overlappingScopesCmd.Parameters.Add(":" + DbSyncSession.SyncScopeName, OracleType.NVarChar, 100); provider.SelectOverlappingScopesCommand = overlappingScopesCmd; // // Update table cleanup info // OracleCommand updScopeCleanupInfoCmd = new OracleCommand(); updScopeCleanupInfoCmd.CommandType = CommandType.Text; updScopeCleanupInfoCmd.CommandText = "update scope_info set " + "scope_cleanup_timestamp = :" + DbSyncSession.SyncScopeCleanupTimestamp + " " + "where scope_name = :" + DbSyncSession.SyncScopeName + " and " + "(scope_cleanup_timestamp is null or scope_cleanup_timestamp < :" + DbSyncSession.SyncScopeCleanupTimestamp + ");" + "set :" + DbSyncSession.SyncRowCount + " = ::rowcount"; updScopeCleanupInfoCmd.Parameters.Add(":" + DbSyncSession.SyncScopeCleanupTimestamp, OracleType.Number); updScopeCleanupInfoCmd.Parameters.Add(":" + DbSyncSession.SyncScopeName, OracleType.NVarChar, 100); updScopeCleanupInfoCmd.Parameters.Add(":" + DbSyncSession.SyncRowCount, OracleType.Int32).Direction = ParameterDirection.Output; provider.UpdateScopeCleanupTimestampCommand = updScopeCleanupInfoCmd; //Register the BatchSpooled and BatchApplied events. These are fired when a provider is either enumerating or applying changes in batches. provider.BatchApplied += new EventHandler <DbBatchAppliedEventArgs>(provider_BatchApplied); provider.BatchSpooled += new EventHandler <DbBatchSpooledEventArgs>(provider_BatchSpooled); return(provider); }