//////////////////////////////////////////////////////////////////////// public void CopyFromDataSet(DataSet ds) { foreach (DataTable table in CContexteDonnee.GetTablesOrderInsert(ds)) { Merge(table, false, MissingSchemaAction.Add); } }
/// <summary> /// ///////////////////////////////////////////////////////////////////////////////// /// </summary> /// <param name="table"></param> /// <param name="result"></param> /// private static CResultAErreur TraitementAvantSauvegardeExterne(CContexteDonnee contexte, Hashtable tableData) { CResultAErreur result = CResultAErreur.True; ///Stef 22/07/08 : l'appel à shouldDeclenche peut ///nécessiter GetValeurChamp (si conditions sur des champs). Or, si un élément n'a pas ///de valeur pour un champ, l'appli va aller chercher la valeur par défaut de ce ///champ, si le champ n'est pas chargé, l'appli va le lire. Comme on est souvent ///dans un contexte sans gestion par tables complètes, on est mal, parce que ///ça va génerer une requête par champ. ///Donc, on lit tous les champs custom avant de commencer CListeObjetsDonnees listeChamps = new CListeObjetsDonnees(contexte, typeof(CChampCustom)); listeChamps.PreserveChanges = true; //Pour ne pas modifier les champs modifiés listeChamps.AssureLectureFaite(); DateTime dt = DateTime.Now; CTraitementApresSauvegarde traitement = new CTraitementApresSauvegarde( ); ArrayList lstTables = CContexteDonnee.GetTablesOrderInsert(contexte); //Pour empêcher de regarder deux fois les évenements d'un même objet //Type->Dictionnaire des ids vus Dictionary <Type, Dictionary <int, bool> > elementsVus = new Dictionary <Type, Dictionary <int, bool> >(); DataRowChangeEventHandler handlerRedo = new DataRowChangeEventHandler(table_RowChanged); Dictionary <string, Dictionary <int, bool> > listeElementsARepasser = null; if (!m_listeElementsARepasser.TryGetValue(contexte, out listeElementsARepasser)) { listeElementsARepasser = new Dictionary <string, Dictionary <int, bool> >(); m_listeElementsARepasser[contexte] = listeElementsARepasser; } bool bFirstPasse = true; int nLimiteurPasses = 0; while ((bFirstPasse | listeElementsARepasser.Count > 0) && nLimiteurPasses < 5) { nLimiteurPasses++; foreach (DataTable table in lstTables) { if (table.Rows.Count > 0 && table.PrimaryKey.Length == 1) { string strChampCle = table.PrimaryKey[0].ColumnName; Type tpObjets = CContexteDonnee.GetTypeForTable(table.TableName); if (!typeof(CObjetDonneeAIdNumerique).IsAssignableFrom(tpObjets)) { continue; } Type typeOriginal = tpObjets; //Lors de la modif de champs custom, l'élement parent n'est pas forcement modifié //Mais le champ peut l'être if (tpObjets.IsSubclassOf(typeof(CRelationElementAChamp_ChampCustom))) { int nLigne = 0; bool bGoOut = false; while (table.Rows.Count > nLigne && !bGoOut) { if (table.Rows[nLigne].RowState != DataRowState.Deleted) { CRelationElementAChamp_ChampCustom rel = (CRelationElementAChamp_ChampCustom)contexte.GetNewObjetForRow(table.Rows[nLigne]); tpObjets = rel.ElementAChamps.GetType(); strChampCle = ((CObjetDonnee)rel.ElementAChamps).GetChampsId()[0]; bGoOut = true; } nLigne++; } } //Les objets qui n'ont pas de relationTypeId ne peuvent pas avoir d'évenements if (tpObjets.GetCustomAttributes(typeof(NoRelationTypeIdAttribute), true).Length > 0) { continue; } ArrayList lstEvenements = GetListeEvenementsAutoSur(tpObjets, contexte.IdVersionDeTravail); //Id des éléments modifiés List <int> listeIdsElementsAVerifierHandlers = new List <int>(); string strPrimaryKey = ""; if (table.PrimaryKey.Length == 1 && table.PrimaryKey[0].DataType == typeof(int)) { strPrimaryKey = table.PrimaryKey[0].ColumnName; } Dictionary <int, bool> tableIdsVues = null; if (!elementsVus.TryGetValue(tpObjets, out tableIdsVues)) { tableIdsVues = new Dictionary <int, bool>(); elementsVus[tpObjets] = tableIdsVues; } Dictionary <int, bool> listeARepasserPourTable = null; if (!listeElementsARepasser.TryGetValue(table.TableName, out listeARepasserPourTable)) { listeARepasserPourTable = null; } List <CObjetDonnee> lstObjetsAvecEvenementsSpecifiques = new List <CObjetDonnee>(); //Stef 16/11/2012 : //Si c'est un élément à champs, il est consideré comme modifié //si un de ses champs custom est modifiés //Ca a été fait parce que les handlers d'évenement n'étaient //Pas pris en compte sur modif de champ custom //On n'enlève pas pour autant l'ancienne méthode qui consiste //à considérer l'élément modifié losrqu'on passe sur la table des //valeurs de champs custom if (typeof(IObjetDonneeAChamps).IsAssignableFrom(typeOriginal) && table.Rows.Count > 0) { //Regarde s'il y a des relations IObjetDonneeAChamps objAChamp = contexte.GetNewObjetForRow(table.Rows[0]) as IObjetDonneeAChamps; string strTableChamps = objAChamp.GetNomTableRelationToChamps(); //Trouve la relation à la table DataTable tableChamps = contexte.Tables[strTableChamps]; if (tableChamps != null)//Si la table champs n'est pas là, c'est //qu'elle n'a pas été modifiée !! c'est logique çà { DataRelation rel = null; foreach (DataRelation relTest in tableChamps.ParentRelations) { if (relTest.ParentTable.TableName == table.TableName) { rel = relTest; break; } } if (rel != null)//On peut vérifier ! { foreach (DataRow row in new ArrayList(table.Rows)) { if (row.RowState == DataRowState.Unchanged)//sinon, ce n'est pas la peine { DataRow[] rowsChamps = row.GetChildRows(rel); foreach (DataRow rowChamp in rowsChamps) { if (rowChamp.RowState != DataRowState.Unchanged) { //Aloue l'objet pour s'assurer que la ligne est bien pleine CObjetDonnee objTmp = contexte.GetNewObjetForRow(row); objTmp.AssureData(); row.SetModified(); string strOldContexte = (string)row[CObjetDonnee.c_champContexteModification]; if (strOldContexte.Length == 0) { row[CObjetDonnee.c_champContexteModification] = rowChamp[CObjetDonnee.c_champContexteModification, rowChamp.RowState == DataRowState.Deleted ? DataRowVersion.Original : DataRowVersion.Current] as string; } break; } } } } } } } foreach (DataRow row in new ArrayList(table.Rows)) { CObjetDonneeAIdNumerique objet = null; if (lstEvenements.Count > 0) { if (row.RowState == DataRowState.Added || row.RowState == DataRowState.Modified || row.RowState == DataRowState.Deleted) { objet = (CObjetDonneeAIdNumerique)((CContexteDonnee)table.DataSet).GetNewObjetForRow(row); if (objet.Row.RowState == DataRowState.Deleted) { objet.VersionToReturn = DataRowVersion.Original; } if (objet.Row.RowState != DataRowState.Deleted && EvenementAttribute.HasEventsSpecifiques(objet)) { lstObjetsAvecEvenementsSpecifiques.Add(objet); } if (typeof(CRelationElementAChamp_ChampCustom).IsAssignableFrom(typeOriginal)) { CRelationElementAChamp_ChampCustom rel = objet as CRelationElementAChamp_ChampCustom; objet = (CObjetDonneeAIdNumerique)((CRelationElementAChamp_ChampCustom)objet).ElementAChamps; if (objet.Row.RowState == DataRowState.Unchanged) { objet.Row.Row.SetModified(); } if (objet.Row.RowState == DataRowState.Deleted) { objet.VersionToReturn = DataRowVersion.Original; } if (rel.ContexteDeModification.Length != 0 && objet.ContexteDeModification.Length == 0) { objet.ContexteDeModification = rel.ContexteDeModification; } } if (!tableIdsVues.ContainsKey(objet.Id) || ( listeARepasserPourTable != null && listeARepasserPourTable.ContainsKey(objet.Id))) { tableIdsVues[objet.Id] = true; foreach (CEvenement evt in lstEvenements) { if (!traitement.ContainsCouple(evt, (CObjetDonneeAIdNumerique)objet)) { //Attention, si c'est une valeur de champ custom, envoie la valeur, //c'est elle qui sera testée. CInfoDeclencheurProcess infoDeclencheur = null; if (evt.ShouldDeclenche((CObjetDonneeAIdNumerique)objet, ref infoDeclencheur)) { infoDeclencheur.DbKeyEvenementDeclencheur = evt.DbKey; infoDeclencheur.Info = evt.Libelle; traitement.AddCoupleEvenementObjet(evt, (CObjetDonneeAIdNumerique)objet, infoDeclencheur); } } } } } } //Regarde les handle d'évenement sur l'objet if (strPrimaryKey != "" && (row.RowState == DataRowState.Modified)) { listeIdsElementsAVerifierHandlers.Add((int)row[strPrimaryKey]); } } if (listeARepasserPourTable != null) { listeARepasserPourTable.Clear(); } if (listeIdsElementsAVerifierHandlers.Count > 0 && bFirstPasse) { //traitement par paquet de 500 for (int nIndexLot = 0; nIndexLot < listeIdsElementsAVerifierHandlers.Count; nIndexLot += 500) { int nMin = Math.Min(nIndexLot + 500, listeIdsElementsAVerifierHandlers.Count); StringBuilder bl = new StringBuilder(); for (int nIndex = nIndexLot; nIndex < nMin; nIndex++) { bl.Append(listeIdsElementsAVerifierHandlers[nIndex].ToString()); bl.Append(","); } string strIdsElementsAVerifierHandlers = bl.ToString().Substring(0, bl.ToString().Length - 1); //Recherche tous les handlers d'évenement pour les objets concernés CListeObjetsDonnees listeHandler = new CListeObjetsDonnees(contexte, typeof(CHandlerEvenement)); listeHandler.Filtre = new CFiltreData( CHandlerEvenement.c_champIdCible + " in (" + strIdsElementsAVerifierHandlers + ") and " + CHandlerEvenement.c_champTypeCible + "=@1 and " + CHandlerEvenement.c_champTypeEvenement + "=@2", tpObjets.ToString(), (int)TypeEvenement.Modification); listeHandler.PreserveChanges = true; foreach (CHandlerEvenement handler in listeHandler) { if (handler.Row.RowState != DataRowState.Deleted) { CObjetDonneeAIdNumerique objetTmp = (CObjetDonneeAIdNumerique)Activator.CreateInstance(tpObjets, new object[] { contexte }); if (objetTmp.ReadIfExists(handler.IdElementCible)) { CInfoDeclencheurProcess infoDeclencheur = null; if (handler.ShoulDeclenche(objetTmp, ref infoDeclencheur)) { if (infoDeclencheur != null && handler.EvenementLie != null) { infoDeclencheur.Info = handler.EvenementLie.Libelle; } traitement.AddCoupleHandlerObjet(handler, (CObjetDonneeAIdNumerique)objetTmp, infoDeclencheur); } } } } } } //Annule les évenements spécifiques, ils ont été traités ! foreach (CObjetDonnee objet in lstObjetsAvecEvenementsSpecifiques) { EvenementAttribute.ClearEvenements(objet); } } } //Execute ce qui peut être executé tout de suite foreach (DataTable table in contexte.Tables) { table.RowChanged += handlerRedo; } listeElementsARepasser.Clear(); foreach (CTraitementApresSauvegarde.CCoupleDeclencheurObjet couple in traitement.CouplesEvenementOuHandlerObjet) { if (couple.Objet is CObjetDonneeAIdNumerique && couple.PeutEtreExecuteSurLePosteClient) { result = couple.OnDeclencheSurClient(); if (!result) { return(result); } } } foreach (DataTable table in contexte.Tables) { table.RowChanged -= handlerRedo; } bFirstPasse = false; } if (traitement.CouplesEvenementOuHandlerObjet.Count != 0) { tableData[c_cleDonneeListeTraitements] = traitement; } m_listeElementsARepasser.Remove(contexte); return(result); }
/// //////////////////////////////////////////////////////// protected override CResultAErreur MyExecute(CContexteExecutionAction contexte) { CResultAErreur result = CResultAErreur.True; List <Type> lstTypesAVerifier = new List <Type>(); //Trouve tous les types héritant de CMappableTimos foreach (Assembly ass in sc2i.common.CGestionnaireAssemblies.GetAssemblies()) { foreach (Type tp in ass.GetTypes()) { if (typeof(IObjetSPVAvecObjetTimos).IsAssignableFrom(tp)) { lstTypesAVerifier.Add(tp); } } } List <string> lstTablesDansOrdre = new List <string>(); using (CContexteDonnee ctxTmp = new CContexteDonnee(contexte.IdSession, true, false)) { foreach (Type tp in lstTypesAVerifier) { string strTable = CContexteDonnee.GetNomTableForType(tp); if (strTable != null) { ctxTmp.GetTableSafe(strTable); } } foreach (DataTable table in ctxTmp.GetTablesOrderInsert()) { lstTablesDansOrdre.Add(table.TableName); } } foreach (string strNomTable in lstTablesDansOrdre) { Type tp = CContexteDonnee.GetTypeForTable(strNomTable); Type tpParent = tp; Type[] generics = new Type[0]; while (tpParent != null && generics.Length == 0) { if (tpParent.IsGenericType && tpParent.GetGenericTypeDefinition() == typeof(CMappableAvecTimos <,>)) { generics = tpParent.GetGenericArguments(); } tpParent = tpParent.BaseType; } if (generics.Length == 0) { continue; } IObjetSPVAvecObjetTimos obj = Activator.CreateInstance(tp, new object[] { contexte.ContexteDonnee }) as IObjetSPVAvecObjetTimos; Type typeTimos = obj.GetTypeObjetsTimos(); //Lit tous les objets TIMOS CListeObjetsDonnees lstObjetsTimos = new CListeObjetsDonnees(contexte.ContexteDonnee, typeTimos); lstObjetsTimos.AssureLectureFaite(); CListeObjetsDonnees lstObjetsSpv = new CListeObjetsDonnees(contexte.ContexteDonnee, obj.GetType()); lstObjetsSpv.AssureLectureFaite(); string strIdObjetTimosInObjetSpv = obj.GetChampIdObjetTimos(); Type tpMappable = typeof(CMappeurTimos <,>).MakeGenericType(generics); IMappeurTimosNonGenerique mappeur = Activator.CreateInstance(tpMappable) as IMappeurTimosNonGenerique; foreach (CObjetDonneeAIdNumerique objTimos in (CObjetDonneeAIdNumerique[])lstObjetsTimos.ToArray(typeof(CObjetDonneeAIdNumerique))) { CObjetDonneeAIdNumerique objSpv = Activator.CreateInstance(tp, new object[] { contexte.ContexteDonnee }) as CObjetDonneeAIdNumerique; if (!objSpv.ReadIfExists(new CFiltreData(strIdObjetTimosInObjetSpv + "=@1", objTimos.Id), false)) { mappeur.GetObjetSpvFromObjetTimosAvecCreationSansGenerique(objTimos); } } } return(result); }
//----------------------------------------------------------------------- private CResultAErreur TraiteModifiesFromSecondaire(CContexteDonnee ctxSecondaire) { CResultAErreur result = CResultAErreur.True; CUtilSynchronisation utilSync = new CUtilSynchronisation(IdSession); int nIdSyncSessionEnCours = utilSync.IdSyncSession; ArrayList lstTables = ctxSecondaire.GetTablesOrderInsert(); DataTable tableLogsSynchroFromSecondaire = ctxSecondaire.Tables[CEntreeLogSynchronisation.c_nomTable]; if (tableLogsSynchroFromSecondaire == null) { result.EmpileErreur(I.T("Synchro table missing|20003")); return(result); } foreach (DataTable tableSource in lstTables) { Type tpObjet = CContexteDonnee.GetTypeForTable(tableSource.TableName); if ( tableSource.PrimaryKey.Length == 1 && m_mappeurTablesToClass.IsSynchronisable(tableSource.TableName) && tpObjet != null) { DataTable tableDest = GetTableSafe(tableSource.TableName); string strPrimKey = tableDest.PrimaryKey[0].ColumnName; ArrayList lstRows = new ArrayList(tableSource.Rows); foreach (DataRow rowSource in lstRows) { //S'assure que la rowSource a bien été modifiée if (rowSource.RowState == DataRowState.Modified) { DataRow rowDest = tableDest.Rows.Find(rowSource[strPrimKey]); if (rowDest == null) { CObjetDonneeAIdNumerique objet = Activator.CreateInstance(tpObjet, new object[] { this }) as CObjetDonneeAIdNumerique; if (objet != null) { if (!objet.ReadIfExists((int)rowSource[strPrimKey])) { objet = null; } else { rowDest = objet.Row.Row; } } } else { CObjetDonneeAIdNumerique objet = Activator.CreateInstance(tpObjet, new object[] { rowDest }) as CObjetDonneeAIdNumerique; //S'assure de la lecture de la ligne DataRow rowTmp = objet.Row.Row; } if (rowDest != null)//sinon, c'est bizarre, ça //veut dire que la ligne aurait été supprimée dans la base principale { foreach (DataColumn col in tableSource.Columns) { if (rowDest.Table.Columns.Contains(col.ColumnName) && col.ColumnName != strPrimKey) { rowDest[col.ColumnName] = rowSource[col.ColumnName]; } } rowDest[CSc2iDataConst.c_champIdSynchro] = nIdSyncSessionEnCours; } } } } } return(result); }
//----------------------------------------------------------------------- private CResultAErreur AjouteNouveauxFromSecondaire(CContexteDonnee ctxDonnee) { CUtilSynchronisation utilSync = new CUtilSynchronisation(IdSession); int nIdSyncSessionEnCours = utilSync.IdSyncSession; CResultAErreur result = CResultAErreur.True; DataTable tableLogsSynchroFromSecondaire = ctxDonnee.Tables[CEntreeLogSynchronisation.c_nomTable]; if (tableLogsSynchroFromSecondaire == null) { result.EmpileErreur(I.T("Synchro table missing|20003")); return(result); } Dictionary <CIdentifiantElement, int> dicNewIds = new Dictionary <CIdentifiantElement, int>(); ArrayList lstTables = ctxDonnee.GetTablesOrderInsert(); foreach (DataTable tableSource in lstTables) { if (tableSource.PrimaryKey.Length == 1 && m_mappeurTablesToClass.IsSynchronisable(tableSource.TableName)) { DataTable tableDest = GetTableSafe(tableSource.TableName); string strPrimKey = tableDest.PrimaryKey[0].ColumnName; //Identifie tous les ajouts DataRow[] rowsLogAjout = tableLogsSynchroFromSecondaire.Select( CEntreeLogSynchronisation.c_champTable + "='" + tableSource.TableName + "' and " + CEntreeLogSynchronisation.c_champType + "=" + (int)CEntreeLogSynchronisation.TypeModifLogSynchro.tAdd); foreach (DataRow rowLogAjout in rowsLogAjout) { //Cherche la DataRow dans la table source DataRow rowSource = tableSource.Rows.Find(rowLogAjout[CEntreeLogSynchronisation.c_champIdElement]); if (rowSource != null) { //Création d'une nouvelle ligne DataRow rowDest = tableDest.NewRow(); //copie de la ligne foreach (DataColumn col in tableSource.Columns) { if (rowDest.Table.Columns.Contains(col.ColumnName) && col.ColumnName != strPrimKey) { rowDest[col.ColumnName] = rowSource[col.ColumnName]; } } rowDest[CSc2iDataConst.c_champIdSynchro] = nIdSyncSessionEnCours; tableDest.Rows.Add(rowDest); m_mapRowsFromSecondaireToMain[rowSource] = rowDest; m_mapOldRowToOldId[rowSource] = (int)rowSource[strPrimKey]; dicNewIds[new CIdentifiantElement(tableDest.TableName, (int)rowSource[strPrimKey])] = (int)rowDest[strPrimKey]; //Change l'id dans la rowSource pour qu'il soit //répercuté sur les dépendances rowSource[strPrimKey] = rowDest[strPrimKey]; } } } } //change tous les anciens identifiants par les nouveaux foreach (KeyValuePair <CIdentifiantElement, int> kv in dicNewIds) { CIdentifiantElement ident = kv.Key; int nNewId = kv.Value; foreach (CInfoRelation relation in CContexteDonnee.GetListeRelationsTable(ident.TableName)) { if (relation.TableParente == ident.TableName) { DataTable tableThis = Tables[relation.TableFille]; if (tableThis != null) { DataRow[] rows = tableThis.Select(relation.ChampsFille[0] + "=" + ident.IdElement); foreach (DataRow row in rows) { row[relation.ChampsFille[0]] = nNewId; } } DataTable tableSource = ctxDonnee.Tables[relation.TableFille]; if (tableSource != null) { DataRow[] rows = tableSource.Select(relation.ChampsFille[0] + "=" + ident.IdElement); foreach (DataRow row in rows) { row[relation.ChampsFille[0]] = nNewId; } } } } Type tp = CContexteDonnee.GetTypeForTable(ident.TableName); //Change les ids des relation typeid foreach (RelationTypeIdAttribute rel in RelationsTypeIds) { DataTable tableThis = Tables[rel.TableFille]; if (tableThis != null) { DataRow[] rows = tableThis.Select(rel.ChampId + "=" + ident.IdElement + " and " + rel.ChampType + "='" + tp.ToString() + "'"); foreach (DataRow row in rows) { row[rel.ChampId] = nNewId; } } DataTable tableSource = ctxDonnee.Tables[rel.TableFille]; if (tableSource != null) { DataRow[] rows = tableSource.Select(rel.ChampId + "=" + ident.IdElement + " and " + rel.ChampType + "='" + tp.ToString() + "'"); foreach (DataRow row in rows) { row[rel.ChampId] = nNewId; } } } } return(result); }
/// ////////////////////////////////////////// ///<summary> ///Charge les données de la table qui vont devoir être mise à jour ///à partir des données modifiées dans la table source ///</summary> public CResultAErreur ChargeDonneesAMettreAJour(DataSet donneesSources) { CResultAErreur result = CResultAErreur.True; ArrayList lstTables = CContexteDonnee.GetTablesOrderInsert(donneesSources); foreach (DataTable table in lstTables) { DataTable tableDest = null; //S'assure que la table est bien chargée try { tableDest = GetTableSafe(table.TableName); } catch { //La table n'existe pas } if (tableDest != null && m_mappeurTablesToClass.IsSynchronisable(table.TableName) && table.Rows.Count != 0) { IObjetServeur serveur = CContexteDonnee.GetTableLoader(tableDest.TableName, null, IdSession); string strNomTableInDb = CContexteDonnee.GetNomTableInDbForNomTable(tableDest.TableName); if (serveur.CountRecords(strNomTableInDb, new CFiltreData("1=1")) != 0) //Première maj : copie complète { string strColPrim = table.PrimaryKey[0].ColumnName; string strFiltre = ""; foreach (DataRow row in table.Rows) { strFiltre += row[strColPrim].ToString() + ","; } if (strFiltre.Length != 0) { //Supprime la dernière virgule; strFiltre = strFiltre.Substring(0, strFiltre.Length - 1); strFiltre = strColPrim += " in (" + strFiltre + ")"; IObjetServeur loader = GetTableLoader(table.TableName); DataTable tableNew = loader.Read(new CFiltreData(strFiltre)); if (table == null) { result.EmpileErreur(I.T("Error while reading table @1|128", table.TableName)); return(result); } IntegreTable(tableNew, false); } } } } //Charge les éléments à supprimer CContexteDonnee contexteForListe = new CContexteDonnee(IdSession, true, false); DataTable tableSync = donneesSources.Tables[CEntreeLogSynchronisation.c_nomTable]; DataTable tableCopie = CUtilDataSet.AddTableCopie(donneesSources.Tables[CEntreeLogSynchronisation.c_nomTable], contexteForListe); foreach (DataRow row in tableSync.Rows) { tableCopie.ImportRow(row); } CListeObjetsDonnees liste = new CListeObjetsDonnees(contexteForListe, typeof(CEntreeLogSynchronisation)); liste.InterditLectureInDB = true; liste.Filtre = new CFiltreData(CEntreeLogSynchronisation.c_champType + "=@1", (int)CEntreeLogSynchronisation.TypeModifLogSynchro.tDelete); foreach (CEntreeLogSynchronisation entree in liste) { DataTable table = GetTableSafe(entree.TableConcernee); CObjetDonneeAIdNumerique objet = (CObjetDonneeAIdNumerique)GetNewObjetForTable(table); objet.ReadIfExists(entree.IdElement); } return(result); }