/// <summary> /// Utility function that configures a CE provider /// </summary> /// <param name="sqlCeConnection"></param> /// <returns></returns> public SqlCeSyncProvider ConfigureCESyncProvider(SqlCeConnection sqlCeConnection) { SqlCeSyncProvider provider = new SqlCeSyncProvider(); //Set the scope name provider.ScopeName = SyncUtils.ScopeName; //Set the connection. provider.Connection = sqlCeConnection; //Register event handlers //1. Register the BeginSnapshotInitialization event handler. Called when a CE peer pointing to an uninitialized // snapshot database is about to being initialization. provider.BeginSnapshotInitialization += new EventHandler <DbBeginSnapshotInitializationEventArgs>(provider_BeginSnapshotInitialization); //2. Register the EndSnapshotInitialization event handler. Called when a CE peer pointing to an uninitialized // snapshot database has been initialized for the given scope. provider.EndSnapshotInitialization += new EventHandler <DbEndSnapshotInitializationEventArgs>(provider_EndSnapshotInitialization); //3. 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); //Thats it. We are done configuring the CE provider. return(provider); }
//<snippetOCSv2_CS_Peer_Cleanup_ConfigureCeSyncProvider> public SqlCeSyncProvider ConfigureCeSyncProvider(string sqlCeConnString) { SqlCeSyncProvider sampleCeProvider = new SqlCeSyncProvider(); //Set the scope name sampleCeProvider.ScopeName = "Sales"; //Set the connection sampleCeProvider.Connection = new SqlCeConnection(sqlCeConnString); return(sampleCeProvider); }
//For Compact databases that are not initialized with a snapshot, //get the schema and initial data from a server database. //<snippetOCSv2_CS_Basic_PeerWithCe_CheckIfProviderNeedsSchema> private void CheckIfProviderNeedsSchema(SqlCeSyncProvider providerToCheck, DbSyncProvider providerWithSchema) { //If one of the providers is a SqlCeSyncProvider and it needs //to be initialized, retrieve the schema from the other provider //if that provider is a DbSyncProvider; otherwise configure a //DbSyncProvider, connect to the server, and retrieve the schema. if (providerToCheck != null) { SqlCeSyncScopeProvisioning ceConfig = new SqlCeSyncScopeProvisioning(); SqlCeConnection ceConn = (SqlCeConnection)providerToCheck.Connection; string scopeName = providerToCheck.ScopeName; if (!ceConfig.ScopeExists(scopeName, ceConn)) { DbSyncScopeDescription scopeDesc = providerWithSchema.GetScopeDescription(); ceConfig.ScopeDescription = scopeDesc; ceConfig.Apply(ceConn); } } }
private void ReadTableValuesForSelectedTab() { TabPage tabPage = this.peerTabsControl.SelectedTab; SqlCeSyncProvider ceProvider = providersCollection[tabPage.Text] as SqlCeSyncProvider; if (ceProvider != null) { SqlCeConnection ceConn = (SqlCeConnection)ceProvider.Connection; SqlCeSyncScopeProvisioning ceConfig = new SqlCeSyncScopeProvisioning(ceConn); string scopeName = ceProvider.ScopeName; if (!ceConfig.ScopeExists(scopeName)) { MessageBox.Show(string.Format("Client '{0}' does not contain schema. Synchronize this client with the server to retrieve data.", tabPage.Text), "UnInitialized Client Database"); } } RefreshTables(providersCollection[tabPage.Text].Connection, (TablesViewControl)this.peerTabsControl.SelectedTab.Controls["TablesViewCtrl"]); }
public static RelationalSyncProvider CreateProvider(DbConnection conn, string scopeName) { RelationalSyncProvider serverProvider; if (conn is SqlCeConnection) { serverProvider = new SqlCeSyncProvider(scopeName, conn as SqlCeConnection, prefix); } else if (conn is SqlConnection) { serverProvider = new SqlSyncProvider(scopeName, conn as SqlConnection, prefix); } else { throw new ArgumentOutOfRangeException(); } return(serverProvider); }
/// <summary> /// Check to see if the passed in CE provider needs Schema from server. /// If it does, we'll need to do some extra manipulating of the DbSyncScopeDescription given from the Oracle provider, before /// we apply it to CE. /// </summary> /// <param name="localProvider"></param> private void CheckIfProviderNeedsSchema(SqlCeSyncProvider localProvider) { if (localProvider != null) { SqlCeSyncScopeProvisioning ceConfig = new SqlCeSyncScopeProvisioning(); SqlCeConnection ceConn = (SqlCeConnection)localProvider.Connection; string scopeName = localProvider.ScopeName; if (!ceConfig.ScopeExists(scopeName, ceConn)) { DbSyncScopeDescription scopeDesc = ((DbSyncProvider)ceSharingForm.providersCollection["Server"]).GetScopeDescription(); // We have to manually fix up the Oracle types on the DbSyncColumnDescriptions. Alternatively we could just construct the DbScopeDescription // from scratch. for (int i = 0; i < scopeDesc.Tables.Count; i++) { for (int j = 0; j < scopeDesc.Tables[i].Columns.Count; j++) { // When grabbing the Oracle schema table the type field gets set to the index of that type in the OracleType enumeration. // We will have to change it to the actual name instead of the index. scopeDesc.Tables[i].Columns[j].Type = ((OracleType)Int32.Parse(scopeDesc.Tables[i].Columns[j].Type)).ToString().ToLower(); // We also have to convert number to a decimal for CE if (scopeDesc.Tables[i].Columns[j].Type == "number") { scopeDesc.Tables[i].Columns[j].Type = "decimal"; } // Because the DbSyncColumnDescription only had a number for the Type (which it does not understand), it could not // auto-fill in the required attributes for that field type. So in the case of a string field, we have to manually // set the length ourselves. If we wanted to set scale and precision for the previous decimal field we need to do the same. if (scopeDesc.Tables[i].Columns[j].Type == "nvarchar") { scopeDesc.Tables[i].Columns[j].Size = "100"; } } } ceConfig.PopulateFromScopeDescription(scopeDesc); ceConfig.Apply(ceConn); } } }
//<snippetOCSv2_CS_Basic_PeerWithCe_ConfigureCeSyncProvider> public SqlCeSyncProvider ConfigureCeSyncProvider(string sqlCeConnString) { SqlCeSyncProvider sampleCeProvider = new SqlCeSyncProvider(); //Set the scope name sampleCeProvider.ScopeName = "Sales"; //Set the connection sampleCeProvider.Connection = new SqlCeConnection(sqlCeConnString); //Register event handlers //Register the BeginSnapshotInitialization event handler. //It is called when snapshot initialization is about to begin //for a particular scope in a Compact database. sampleCeProvider.BeginSnapshotInitialization += new EventHandler <DbBeginSnapshotInitializationEventArgs>(sampleCeProvider_BeginSnapshotInitialization); //Register the EndSnapshotInitialization event handler. //It is called when snapshot initialization has completed //for a particular scope in a Compact database. sampleCeProvider.EndSnapshotInitialization += new EventHandler <DbEndSnapshotInitializationEventArgs>(sampleCeProvider_EndSnapshotInitialization); return(sampleCeProvider); }
private void addCEBtn_Click(object sender, EventArgs e) { ceCreationWizard = new NewCEClientCreationWizard(); //Create a new client CEDatabase client = new CEDatabase(); if (ceCreationWizard.ShowDialog(this) == DialogResult.OK) { //Creation mode is based on the option the user picked in the new ce creation wizard client.CreationMode = (ceCreationWizard.fullInitRadioBtn.Checked) ? CEDatabaseCreationMode.FullInitialization : CEDatabaseCreationMode.SnapshotInitialization; //Database location is based on mode. switch (client.CreationMode) { case CEDatabaseCreationMode.FullInitialization: client.Location = ceCreationWizard.fullInitDbLocation.Text; try { SynchronizationHelper.CheckAndCreateCEDatabase(client); } catch (Exception e1) { MessageBox.Show(e1.ToString(), "Error in creating CE database", MessageBoxButtons.OK); return; } break; case CEDatabaseCreationMode.SnapshotInitialization: client.Location = ceCreationWizard.snapshotDestLocation.Text; //Export the source SDF file first. ExportClientDatabase(new SqlCeConnection("Data Source=\"" + ceCreationWizard.snapshotSrcLocation.Text + "\""), client.Location); break; } //Provide our client a unique name client.Name = "Client " + (clientsMapping.Keys.Count + 1); //Add this client info to our mapping so it can be retrieved clientsMapping.Add(client.Name, client); //Create a SqlCeSyncProvider for the new client that is being added SqlCeSyncProvider clientProvider = synchronizationHelper.ConfigureCESyncProvider(client.Connection); providersCollection.Add(client.Name, clientProvider); //Now add a new tab to the peer tabs TabPage tab = new TabPage(client.Name); tab.Padding = new Padding(8); tab.Tag = client; TablesViewControl control = new TablesViewControl(client.Name); control.Name = "TablesViewCtrl"; control.Dock = DockStyle.Fill; tab.Controls.Add(control); this.peerTabsControl.TabPages.Add(tab); tab.BackColor = Color.Transparent; tab.UseVisualStyleBackColor = true; // Add the name of the file to the bottom Label labelFileName = new Label(); labelFileName.Text = "SqlCe Filename: " + ceCreationWizard.fullInitDbLocation.Text; labelFileName.Dock = DockStyle.Bottom; labelFileName.Padding = new System.Windows.Forms.Padding(4); tab.Controls.Add(labelFileName); //Add the client name to the list of providers available for synchronization this.srcProviderComboBox.Items.Add(client.Name); this.destProviderComboBox.Items.Add(client.Name); this.destProviderComboBox.SelectedIndex = destProviderComboBox.Items.Count - 1; this.synchronizeBtn.Enabled = this.providersCollection.Count > 1; } }
static void Main(string[] args) { //The Utility class handles all functionality that is not //directly related to synchronization, such as holding peerConnection //string information and making changes to the server database. Utility util = new Utility(); util.RecreateCePeerDatabase(util.Ce1ConnString); util.RecreateCePeerDatabase(util.Ce2ConnString); //<snippetOCSv2_CS_Basic_PeerWithCe_Synchronize> //The SampleStats class handles information from the SyncStatistics //object that the Synchronize method returns. SampleStats sampleStats = new SampleStats(); try { //Initial synchronization. Instantiate the SyncOrchestrator //and call Synchronize. SampleSyncProvider sampleSyncProvider = new SampleSyncProvider(); SyncOrchestrator sampleSyncAgent; SyncOperationStatistics syncStatistics; //First session: Synchronize two databases by using two instances //of DbSyncProvider. sampleSyncAgent = new SampleSyncAgent( sampleSyncProvider.ConfigureDbSyncProvider(util.Peer1ConnString), sampleSyncProvider.ConfigureDbSyncProvider(util.Peer2ConnString)); syncStatistics = sampleSyncAgent.Synchronize(); sampleStats.DisplayStats(syncStatistics, "initial"); //<snippetOCSv2_CS_Basic_PeerWithCe_SnapshotInit> //Second session: Synchronize two databases by using one instance of //DbSyncProvider and one instance of SqlCeSyncProvider. After the Compact //database is initialized, it is copied by using GenerateSnapshot and then //used for the third session. SqlCeSyncProvider sqlCeSyncProvider1 = sampleSyncProvider.ConfigureCeSyncProvider(util.Ce1ConnString); sampleSyncAgent = new SampleSyncAgent( sampleSyncProvider.ConfigureDbSyncProvider(util.Peer1ConnString), sqlCeSyncProvider1); syncStatistics = sampleSyncAgent.Synchronize(); sampleStats.DisplayStats(syncStatistics, "initial"); //Copy the Compact database and save it as SyncSampleCe2.sdf. SqlCeSyncStoreSnapshotInitialization snapshotInit = new SqlCeSyncStoreSnapshotInitialization(); snapshotInit.GenerateSnapshot(new SqlCeConnection(util.Ce1ConnString), "SyncSampleCe2.sdf"); //Make a change that is synchronized during the third session. util.MakeDataChangesOnPeer(util.Peer1ConnString, "Customer"); //Third session: Synchronize the new Compact database. The five rows //from SyncSampleCe1.sdf are already in SyncSampleCe2.sdf. The new //change is now downloaded to bring SyncSampleCe2.sdf up to date. //SyncSampleCe2.sdf will get this row during the next round of //synchronization sessions. sampleSyncAgent = new SampleSyncAgent( sampleSyncProvider.ConfigureDbSyncProvider(util.Peer1ConnString), sampleSyncProvider.ConfigureCeSyncProvider(util.Ce2ConnString)); syncStatistics = sampleSyncAgent.Synchronize(); sampleStats.DisplayStats(syncStatistics, "initial"); //</snippetOCSv2_CS_Basic_PeerWithCe_SnapshotInit> } catch (DbOutdatedSyncException ex) { Console.WriteLine("Outdated Knowledge: " + ex.OutdatedPeerSyncKnowledge.ToString() + " Clean up knowledge: " + ex.MissingCleanupKnowledge.ToString()); } catch (Exception ex) { Console.WriteLine(ex.Message); } //</snippetOCSv2_CS_Basic_PeerWithCe_Synchronize> //Make a change in one of the databases. util.MakeDataChangesOnPeer(util.Peer2ConnString, "Customer"); try { //Subsequent synchronization. Changes are now synchronized between all //nodes. SampleSyncProvider sampleSyncProvider = new SampleSyncProvider(); SyncOrchestrator sampleSyncAgent; SyncOperationStatistics syncStatistics; sampleSyncAgent = new SampleSyncAgent( sampleSyncProvider.ConfigureDbSyncProvider(util.Peer1ConnString), sampleSyncProvider.ConfigureDbSyncProvider(util.Peer2ConnString)); syncStatistics = sampleSyncAgent.Synchronize(); sampleStats.DisplayStats(syncStatistics, "subsequent"); sampleSyncAgent = new SampleSyncAgent( sampleSyncProvider.ConfigureDbSyncProvider(util.Peer1ConnString), sampleSyncProvider.ConfigureCeSyncProvider(util.Ce1ConnString)); syncStatistics = sampleSyncAgent.Synchronize(); sampleStats.DisplayStats(syncStatistics, "subsequent"); sampleSyncAgent = new SampleSyncAgent( sampleSyncProvider.ConfigureDbSyncProvider(util.Peer1ConnString), sampleSyncProvider.ConfigureCeSyncProvider(util.Ce2ConnString)); syncStatistics = sampleSyncAgent.Synchronize(); sampleStats.DisplayStats(syncStatistics, "subsequent"); } catch (DbOutdatedSyncException ex) { Console.WriteLine("Outdated Knowledge: " + ex.OutdatedPeerSyncKnowledge.ToString() + " Clean up knowledge: " + ex.MissingCleanupKnowledge.ToString()); } catch (Exception ex) { Console.WriteLine(ex.Message); } //Return data back to its original state. util.CleanUpPeer(util.Peer1ConnString); util.CleanUpPeer(util.Peer2ConnString); //Exit. Console.Write("\nPress Enter to close the window."); Console.ReadLine(); }