/// ////////////////////////////////////////// public CResultAErreur Update(CContexteDonneesSynchroSecondaire donneesSecondaires) { CResultAErreur result = CResultAErreur.True; //Met à jour les tables; foreach (DataTable tableSecondaire in donneesSecondaires.Tables) { if (m_mappeurTablesToClass.IsSynchronisable(tableSecondaire.TableName)) { DataTable tableDest = Tables[tableSecondaire.TableName]; string strPrimKey = tableDest.PrimaryKey[0].ColumnName; foreach (DataRow rowSecondaire in tableSecondaire.Rows) { object obj = rowSecondaire[CSc2iDataConst.c_champIdSynchro]; if (m_tableAjouts[tableSecondaire.TableName + "_" + rowSecondaire[strPrimKey].ToString()] == null) //Ce n'est pas un élément ajouté { if (obj is int && ((int)obj) >= donneesSecondaires.IdSynchro) { DataRow rowToUpdate = tableDest.Rows.Find(rowSecondaire[strPrimKey]); if (rowToUpdate != null) { DataRow rowDest = rowToUpdate; CopyRow(rowSecondaire, rowDest, false); } } } } } } return(result); }
/// ////////////////////////////////////////// ///<summary> ///Ajoute les nouveaux éléments à partir du domaine Secondaire ///</summary> public CResultAErreur AjouteNouveaux(CContexteDonneesSynchroSecondaire donneesSecondaires) { CResultAErreur result = CResultAErreur.True; ArrayList lst = donneesSecondaires.GetTablesOrderInsert(); DataTable tableEntreesLog = donneesSecondaires.GetTableSafe(CEntreeLogSynchronisation.c_nomTable); foreach (DataTable table in lst) { if (m_mappeurTablesToClass.IsSynchronisable(table.TableName)) { //int nIdMaxInSecondaire = (int)table.ExtendedProperties[CContexteDonneesSynchroSecondaire.c_extMaxIdInBase]; //int nIdMaxInMain = (int)table.ExtendedProperties[CContexteDonneesSynchroSecondaire.c_extMaxIdInBase]; int nNextId = 0; //Math.Max(nIdMaxInMain, nIdMaxInSecondaire)+1; DataTable tableDest = Tables[table.TableName]; DataView view = new DataView(tableEntreesLog); string strFiltre = CEntreeLogSynchronisation.c_champTable + "='" + table.TableName + "'"; view.RowFilter = strFiltre; foreach (DataRowView row in view) { CEntreeLogSynchronisation entree = new CEntreeLogSynchronisation(row.Row); if (entree.TypeModif == CEntreeLogSynchronisation.TypeModifLogSynchro.tAdd) { CObjetDonneeAIdNumerique obj = entree.GetObjet(); DataRow newRow = CopieToNew(obj.Row, tableDest, nNextId); nNextId++; m_mapOldRowToNewRow[obj.Row.Row] = newRow; m_tableAjouts[table.TableName + "_" + obj.Id] = ""; } } } } return(result); }
/// ////////////////////////////////////////// public CResultAErreur Delete(CContexteDonneesSynchroSecondaire donneesSecondaires) { CResultAErreur result = CResultAErreur.True; ArrayList lst = donneesSecondaires.GetTablesOrderDelete(); DataTable tableEntreesLog = donneesSecondaires.GetTableSafe(CEntreeLogSynchronisation.c_nomTable); foreach (DataTable table in lst) { if (m_mappeurTablesToClass.IsSynchronisable(table.TableName)) { DataTable tableDest = Tables[table.TableName]; DataView view = new DataView(tableEntreesLog); string strFiltre = CEntreeLogSynchronisation.c_champTable + "='" + table.TableName + "'"; view.RowFilter = strFiltre; string strCleMain = tableDest.PrimaryKey[0].ColumnName; foreach (DataRowView row in view) { CEntreeLogSynchronisation entree = new CEntreeLogSynchronisation(row.Row); if (entree.TypeModif == CEntreeLogSynchronisation.TypeModifLogSynchro.tDelete) { DataRow rowDest = tableDest.Rows.Find(entree.IdElement); if (rowDest != null) { rowDest.Delete(); } } } } } return(result); }
/// //////////////////////////////////////////////////////////////////////////////////// public CResultAErreur WriteChanges(CContexteDonneesSynchroSecondaire donneesSecondaires) { CResultAErreur result = base.SaveAll(true); if (!result) { return(result); } //Crée une table des conversions d'id par table Hashtable mapTablesOldToNew = new Hashtable(); Hashtable mapTablesNewToOld = new Hashtable(); Hashtable mapMaxParTable = new Hashtable(); FillMapsId(mapTablesOldToNew, mapTablesNewToOld, mapMaxParTable); ChangeOldIdParNew(donneesSecondaires, mapTablesOldToNew, mapTablesNewToOld, mapMaxParTable); return(result); }
/// ////////////////////////////////////////////////////////////////// //le result du dataset contient le dataset à appliquer à la base secondaire public CResultAErreur PutSecondaryIntoMain(CContexteDonneesSynchroSecondaire dsSecondaire) { CResultAErreur result = CResultAErreur.True; //Répercute les modifs de la base secondaire sur la base primaire using (CContexteDonneesSynchroMain donneesMain = new CContexteDonneesSynchroMain(IdSession, true)) { IDatabaseConnexionSynchronisable connexionMain; connexionMain = (IDatabaseConnexionSynchronisable)CSc2iDataServer.GetInstance().GetDatabaseConnexion(IdSession, m_strIdConnexion); int nIdSyncMain = connexionMain.IdSyncSession; result = donneesMain.ChargeDonneesAMettreAJour(dsSecondaire); if (result) { result = donneesMain.AjouteNouveaux(dsSecondaire); } if (result) { result = donneesMain.Update(dsSecondaire); } if (result) { result = donneesMain.Delete(dsSecondaire); } try { connexionMain.BeginTrans(); } catch (Exception e) { result.EmpileErreur(new CErreurException(e)); result.EmpileErreur(I.T("Error while data synchronization|208")); return(result); } if (result) { result = donneesMain.WriteChanges(dsSecondaire); } //Augmente d'un le numéro de version de la base principale if (result) { while (connexionMain.IdSyncSession < nIdSyncMain + 2) { connexionMain.IncrementeSyncSession(); } result = connexionMain.CommitTrans(); result.Data = dsSecondaire; } else { connexionMain.RollbackTrans(); } } return(result); }
/// ////////////////////////////////////////////////////////////////// public CResultAErreur PutMainIntoSecondary(CContexteDonneesSynchro ctxMain) { CResultAErreur result = CResultAErreur.True; IDatabaseConnexionSynchronisable connexionSecondaire = (IDatabaseConnexionSynchronisable)CSc2iDataServer.GetInstance().GetDatabaseConnexion(IdSession, m_strIdConnexion); //Toutes les modifs apportées sur la base secondaire doivent porter l'id de synchro //Initial de la base secondaire, sinon les modifs font du //ping pong entre secondaire et main, //Ces modifs ne doivent surtout pas apparaitre //lors d'une synchro de sec->main ! connexionSecondaire.LockSyncSessionLocalTo(connexionSecondaire.LastSyncIdPutInBasePrincipale); //Répercute les modifs de la base secondaire sur la base primaire using (CContexteDonneesSynchroSecondaire donneeSec = new CContexteDonneesSynchroSecondaire(IdSession, true)) { result = donneeSec.ChargeDonneesAMettreAJour(ctxMain); donneeSec.EnforceConstraints = false; if (result) { result = donneeSec.AjouteNouveaux(ctxMain); } if (result) { result = donneeSec.Update(ctxMain); } if (result) { result = donneeSec.Delete(ctxMain); } donneeSec.EnforceConstraints = true; try { connexionSecondaire.BeginTrans(); } catch (Exception e) { result.EmpileErreur(new CErreurException(e)); result.EmpileErreur(I.T("Error while data synchronization|208")); return(result); } if (result) { result = donneeSec.WriteChanges(ctxMain); } if (result) { if (connexionSecondaire.LastSyncIdPutInBasePrincipale == -1) { connexionSecondaire.LastSyncIdPutInBasePrincipale = connexionSecondaire.IdSyncSession; } connexionSecondaire.UnlockSyncSessionLocal(); while (connexionSecondaire.IdSyncSession < ctxMain.IdSynchro) { connexionSecondaire.IncrementeSyncSession(); } connexionSecondaire.LastSyncIdVueDeBasePrincipale = ctxMain.IdSynchro == -1?0:ctxMain.IdSynchro; connexionSecondaire.CommitTrans(); } if (!result) { connexionSecondaire.RollbackTrans(); } } return(result); }
/// //////////////////////////////////////////////////////////////////////////////////// private void ChangeOldIdParNew(CContexteDonneesSynchroSecondaire donneesSecondaires, Hashtable mapTablesOldToNew, Hashtable mapTablesNewToOld, Hashtable mapMaxParTable) { ArrayList lst = donneesSecondaires.GetTablesOrderInsert(); CListeObjetsDonnees listeEntreesLog = new CListeObjetsDonnees(donneesSecondaires, typeof(CEntreeLogSynchronisation)); listeEntreesLog.InterditLectureInDB = true; foreach (DataTable table in lst) { string strTable = table.TableName; if (mapMaxParTable[strTable] != null) { //DataTable table = donneesSecondaires.Tables[strTable]; string strPrim = table.PrimaryKey[0].ColumnName; int nIndice = (int)mapMaxParTable[strTable] + 1; Hashtable tableOldToNew = (Hashtable)mapTablesOldToNew[strTable]; Hashtable tableIdOriginauxDansSecondaire = new Hashtable(); //Commence par renumeroter les indices des nouveaux éléments //pour être sur de ne pas affecter à un élément un id déjà existant foreach (DataRow row in tableOldToNew.Keys) { tableIdOriginauxDansSecondaire[row] = row[strPrim]; row[strPrim] = nIndice; nIndice++; } foreach (DataRow row in tableOldToNew.Keys) { DataRow newRowPrim = (DataRow)tableOldToNew[row]; int nNewId = (int)newRowPrim[strPrim]; int nIdOriginalDansSecondaire = (int)tableIdOriginauxDansSecondaire[row]; if (nNewId != nIdOriginalDansSecondaire) /*L'élement a changé d'id. On va donc en créer * un nouveau avec le nouvel id, modifier les liens fils * et supprimer l'ancien * */ { //Crée la nouvelle ligne (avec le bon id) (copie de la ligne d'origine) DataRow newRowSec = table.NewRow(); CopyRow(newRowPrim, newRowSec); table.Rows.Add(newRowSec); //Change l'info de log synchro listeEntreesLog.Filtre = new CFiltreData( CEntreeLogSynchronisation.c_champTable + "=@1 and " + CEntreeLogSynchronisation.c_champIdElement + "=@2 and " + CEntreeLogSynchronisation.c_champType + "=@3", strTable, nIdOriginalDansSecondaire, (int)CEntreeLogSynchronisation.TypeModifLogSynchro.tAdd); if (listeEntreesLog.Count > 0) { CEntreeLogSynchronisation entree = (CEntreeLogSynchronisation)listeEntreesLog[0]; entree.IdElement = nNewId; } //Change toutes les liaisons filles sur le nouvel élément foreach (DataRelation rel in table.ChildRelations) { if (rel.ParentColumns.Length == 1 && rel.ParentColumns[0].ColumnName == strPrim) { foreach (DataRow childRow in row.GetChildRows(rel)) { childRow[rel.ChildColumns[0].ColumnName] = nNewId; } } } //Supprime l'ancien élément row.Delete(); } else { row[strPrim] = nIdOriginalDansSecondaire; } } } } }