/// <summary>
 /// Executes the changeset. Operation is persisting changes to database.
 /// </summary>
 /// <param name="changeset">The changeset that is persisted.</param>
 public override void ExecuteChangeset(DBXml changeset)
 {
     if (this.executionMode == 1)
     {
         repository.ExecuteOperations(changeset);
     }
     else
     {
         DBXml   xml = new DBXml();
         DBTable tab = xml.AddTable(this.MainObjectTag);
         foreach (var valuation in changeset.Table(this.MainObjectTag).Rows)
         {
             Guid?savepointName = null;
             var  row           = tab.AddRow(valuation);
             try
             {
                 savepointName = Guid.NewGuid();
                 this.repository.CreateSavepoint(savepointName.ToString());
                 repository.ExecuteOperations(xml);
             }
             catch (SqlException)
             {
                 if (savepointName.HasValue)
                 {
                     this.repository.RollbackToSavepoint(savepointName.ToString());
                 }
             }
             row.Remove();
         }
     }
 }
Exemple #2
0
        /// <summary>
        /// Executes the changeset. Operation is persisting changes to database.
        /// </summary>
        /// <param name="changeset">The changeset that is persisted.</param>
        public override void ExecuteChangeset(Makolab.Fractus.Communication.DBLayer.DBXml changeset)
        {
            //remove valuations that link to lines marked as deleted
            if (changeset.Table("warehouseDocumentValuation") != null && changeset.Table("warehouseDocumentLine") != null)
            {
                List <DBRow> deletedValuations = new List <DBRow>();
                foreach (var line in changeset.Table("warehouseDocumentLine").Rows.Where(l => l.Action == DBRowState.Delete))
                {
                    foreach (var valuation in changeset.Table("warehouseDocumentValuation").Rows)
                    {
                        if (valuation.Element("incomeWarehouseDocumentLineId").Value.Equals(line.Element("id").Value, StringComparison.OrdinalIgnoreCase) ||
                            valuation.Element("outcomeWarehouseDocumentLineId").Value.Equals(line.Element("id").Value, StringComparison.OrdinalIgnoreCase))
                        {
                            deletedValuations.Add(valuation);
                        }
                    }
                }
                deletedValuations.ForEach(v => v.Remove());
            }


            //TODO kod dodany by wykorzystywac mechanizm savepointow, ale dziwia warunki na korekte pz/wz
            //TODO nalezy sprawdzi czy zmiana wycen rusza wersje obiektu glownego bo wyglda na to ze nie
            var docType = Makolab.Fractus.Kernel.Mappers.DictionaryMapper.Instance.GetDocumentType(
                new Guid(this.CurrentPackage.Table(this.MainObjectTag).FirstRow().Element("documentTypeId").Value));

            if ((docType.DocumentCategory == Makolab.Fractus.Kernel.Enums.DocumentCategory.IncomeWarehouseCorrection ||
                 docType.DocumentCategory == Makolab.Fractus.Kernel.Enums.DocumentCategory.OutcomeWarehouseCorrection) &&
                changeset.Table("warehouseDocumentValuation") != null)
            {
                var warehouseValuationTable = changeset.Table("warehouseDocumentValuation");
                warehouseValuationTable.Remove();
                DBXml valuationXml = new DBXml();
                valuationXml.AddTable(warehouseValuationTable);

                this.Repository.ExecuteOperations(changeset);

                WarehouseDocumentValuation valuationProcessor = new WarehouseDocumentValuation(this.UnitOfWork, this.ExecutionController, this.IsHeadquarter);
                valuationProcessor.Log = this.Log;
                valuationProcessor.LocalTransactionId = this.LocalTransactionId;
                CommunicationPackage valuationPackage = new CommunicationPackage(new XmlTransferObject()
                {
                    Content = valuationXml.Xml.ToString(SaveOptions.DisableFormatting)
                });
                valuationPackage.DatabaseId = this.package.DatabaseId;
                valuationPackage.XmlData.LocalTransactionId    = this.package.XmlData.LocalTransactionId;
                valuationPackage.XmlData.DeferredTransactionId = this.package.XmlData.DeferredTransactionId;
                valuationProcessor.ExecutePackage(valuationPackage, 0);
            }
            else
            {
                this.Repository.ExecuteOperations(changeset);
            }
        }
Exemple #3
0
        /// <summary>
        /// Process communication package persisting it's data to database.
        /// </summary>
        /// <param name="communicationPackage">The communication package to execute.</param>
        /// <returns>
        ///     <c>true</c> if execution succeeded; otherwise, <c>false</c>
        /// </returns>
        public override bool ExecutePackage(ICommunicationPackage communicationPackage)
        {
            SessionManager.VolatileElements.DeferredTransactionId = communicationPackage.XmlData.DeferredTransactionId;
            SessionManager.VolatileElements.LocalTransactionId    = this.LocalTransactionId;

            this.CurrentPackage = new DBXml(XDocument.Parse(communicationPackage.XmlData.Content));

            //Guid mainObjectId = new Guid(this.CurrentPackage.Table(MainObjectTag).Row().Element("id").Value);
            //DBXml dbSnapshot = GetCurrentSnapshot(mainObjectId);

            DBXml dbSnapshot        = new DBXml();
            Guid  currentConGrMemId = Guid.Empty;
            var   dbTables          = new List <DBTable>();

            try
            {
                var groupsAlreadyRemoved = new List <DBRow>();
                foreach (var conGrMem in this.CurrentPackage.Table(MainObjectTag).Rows)
                {
                    currentConGrMemId = new Guid(conGrMem.Element("id").Value);
                    DBXml currentDBSnapshot = GetCurrentSnapshot(currentConGrMemId);

                    if (conGrMem.Action == DBRowState.Delete && currentDBSnapshot == null)
                    {
                        groupsAlreadyRemoved.Add(conGrMem);
                    }

                    // TODO conflict detection & resolution
                    //if (ValidateVersion(conGrMem, currentDBSnapshot) == false)
                    //{
                    //    throw new ConflictException("Conflict detected while changing " + this.MainObjectTag + " id: " + currentConGrMemId);
                    //}

                    if (conGrMem.Element("_object1from") != null)
                    {
                        DBXml contractor = repository.FindContractorSnapshot(new Guid(conGrMem.Element("contractorId").Value));
                        if (contractor != null && contractor.Table("contractor").FirstRow().Element("version").Value.Equals(conGrMem.Element("_object1from").Value) == false)
                        {
                            this.Log.Error("ItemGroupMembershipScript: Wystapil konflikt wersji towaru " + conGrMem.Element("contractorId").Value + " oczekiwano " +
                                           conGrMem.Element("_object1from").Value +
                                           " otrzymano " + contractor.Table("contractor").FirstRow().Element("version").Value);

                            conGrMem.Element("_object1from").Value = contractor.Table("contractor").FirstRow().Element("version").Value;
                        }
                    }

                    if (currentDBSnapshot != null)
                    {
                        dbTables.Add(currentDBSnapshot.Table(this.MainObjectTag));
                    }
                }
                dbSnapshot.AddTable(dbTables);

                DBXml changeset = GenerateChangeset(CurrentPackage, dbSnapshot);
                ExecuteChangeset(changeset);
            }
            catch (SqlException e)
            {
                if (e.Number == 50012) // Conflict detection
                {
                    throw new ConflictException("Conflict detected while changing " + this.MainObjectTag + " id: " + currentConGrMemId.ToString());
                }
                else
                {
                    this.Log.Error("SnapshotScript:ExecutePackage " + e.ToString());
                    return(false);
                }
            }

            return(true);
        }
Exemple #4
0
        /// <summary>
        /// Generates the changeset - diff beetween two snapshots.
        /// </summary>
        /// <param name="commSnapshot">The snapshot from other branch.</param>
        /// <param name="dbSnapshot">The snapshot created from database.</param>
        /// <returns>Generated xml changeset.</returns>
        public virtual DBXml GenerateChangeset(DBXml commSnapshot, DBXml dbSnapshot)
        {
            DBXml result = new DBXml(commSnapshot);
            Dictionary <string, string> previousVersion = GetPreviousVersion(result);

            RemovePreviousVersion(result);

            IEnumerable <DBRow> resultEntries = result.Tables.SelectMany(table => table.Rows);

            if (dbSnapshot == null)
            {
                var eTables = new List <DBTable>();
                foreach (var table in result.Tables)
                {
                    if (table.HasRows == false)
                    {
                        eTables.Add(table);
                    }
                }
                foreach (var table in eTables)
                {
                    table.Remove();
                }

                return(MarkAsInserted(resultEntries).First().Table.Document);
            }

            IEnumerable <DBRow> dbEntries = dbSnapshot.Tables.SelectMany(table => table.Rows).Where(row => row.HasAction == false);

            List <DBRow> unmodifiedEntries = new List <DBRow>();

            foreach (DBRow entry in resultEntries)
            {
                DBRow match = dbSnapshot.FindRow(entry);

                if (match != null)
                {
                    //entry.Action != DBRowState.Delete - niestety musialem dolozyc ten warunek gdyz ciezko jest dogadac sie z chlopakami
                    // by entry przy delete tez zawieraly wersje
                    if (entry.Action != DBRowState.Delete && entry.IsTheSameAs(match))
                    {
                        if (entry.Action == null)
                        {
                            unmodifiedEntries.Add(entry);
                        }
                        else if (entry.Action == DBRowState.Insert)
                        {
                            entry.SetAction(DBRowState.Update);
                        }
                    }
                    else if (entry.Action == null)
                    {
                        entry.Element("version").Name = "_version";
                        entry.SetAction(DBRowState.Update);
                    }

                    match.Remove();
                }
                else if (entry.Action == null)
                {
                    entry.SetAction(DBRowState.Insert);
                }
            }

            if (previousVersion != null) // && result.Table(MainObjectTag).FirstRow().Element("version") == null
            {
                SetPreviousVersion(result, previousVersion);
                //result.Table(MainObjectTag).FirstRow().AddElement("version", previousVersion);
            }

            // remove unmodified entries from result
            unmodifiedEntries.ForEach(entry => entry.Remove());

            foreach (DBRow entry in dbEntries)
            {
                entry.SetAction(DBRowState.Delete);
            }

            result.AddTable(from table in dbSnapshot.Tables where table.HasRows select table);

            var emptyTables = new List <DBTable>();

            foreach (var table in result.Tables)
            {
                if (table.HasRows == false)
                {
                    emptyTables.Add(table);
                }
            }
            foreach (var table in emptyTables)
            {
                table.Remove();
            }

            return(result);
        }
Exemple #5
0
        /// <summary>
        /// Process communication package persisting it's data to database.
        /// </summary>
        /// <param name="communicationPackage">The communication package to execute.</param>
        /// <returns>
        ///     <c>true</c> if execution succeeded; otherwise, <c>false</c>
        /// </returns>
        public override bool ExecutePackage(ICommunicationPackage communicationPackage)
        {
            try
            {
                SessionManager.VolatileElements.DeferredTransactionId = communicationPackage.XmlData.DeferredTransactionId;
                SessionManager.VolatileElements.LocalTransactionId    = this.LocalTransactionId;

                bool result = base.ExecutePackage(communicationPackage);
                if (result == false)
                {
                    return(false);
                }

                //skip local shift documents
                if (IsLocal(this.CurrentPackage) == true)
                {
                    return(true);
                }

                using (var wrapper = this.UnitOfWork.ConnectionManager.SynchronizeConnection())
                {
                    SqlConnectionManager.Instance.SetConnection(wrapper.Connection, this.UnitOfWork.Transaction as SqlTransaction);
                }

                bool isOutcomeshift = IsOutcomeshift(this.CurrentPackage);
                bool isIncomeShift  = IsIncomeshift(this.CurrentPackage);
                bool isTargetBranch = IsTargetBranch(this.CurrentPackage);
                bool isSourceBranch = IsSourceBranch(this.CurrentPackage);

                if (isOutcomeshift == true)
                {
                    if (isTargetBranch == true)
                    {
                        if (this.IsHeadquarter == false)
                        {
                            DBXml series = new DBXml();
                            series.AddTable(this.CurrentPackage.Table("series"));

                            SeriesScript seriesProcessor = new SeriesScript(this.UnitOfWork, this.ExecutionController);
                            seriesProcessor.Log = this.Log;
                            seriesProcessor.LocalTransactionId = this.LocalTransactionId;
                            CommunicationPackage seriesPackage = new CommunicationPackage(new XmlTransferObject()
                            {
                                Content = series.Xml.ToString(SaveOptions.DisableFormatting)
                            });
                            seriesPackage.DatabaseId = communicationPackage.DatabaseId;
                            seriesPackage.XmlData.LocalTransactionId    = communicationPackage.XmlData.LocalTransactionId;
                            seriesPackage.XmlData.DeferredTransactionId = communicationPackage.XmlData.DeferredTransactionId;
                            seriesProcessor.ExecutePackage(seriesPackage);
                        }

                        this.ExecutionController.ExecuteCommand(() => ExecuteOutcomeShift());
                        if (this.CurrentPackage.Xml.Root.Attribute("skipPackage") == null)
                        {
                            this.CurrentPackage.Xml.Root.Add(new XAttribute("skipPackage", true));
                        }
                    }

                    if (this.IsHeadquarter && isTargetBranch == false)
                    {
                        DBXml series = this.Repository.FindSeries(new Guid(this.CurrentPackage.Table("warehouseDocumentHeader").FirstRow().Element("seriesId").Value));
                        this.CurrentPackage.AddTable(series.Table("series"));
                    }
                    if (this.IsHeadquarter == false && isTargetBranch == false && isSourceBranch == false)
                    {
                        throw new InvalidOperationException("ShiftDocumentSnapshot is in invalid branch.");
                    }
                }
                else if (isIncomeShift == true && this.IsHeadquarter == true && (isTargetBranch || IsNewOrChanged(this.CurrentPackage, this.previousDocument)))
                {
                    this.ExecutionController.ExecuteCommand(() => ExecuteIncomeShift());
                }
                communicationPackage.XmlData.Content = this.CurrentPackage.Xml.ToString(SaveOptions.DisableFormatting);
                return(result);
            }
            catch (SqlException e)
            {
                if (e.Number == 50012) // Conflict detection
                {
                    throw new ConflictException("Conflict detected while changing " + this.MainObjectTag);
                }
                else
                {
                    this.Log.Error("ShiftDocumentSnapshot:ExecutePackage " + e.ToString());
                    return(false);
                }
            }
        }