Beispiel #1
0
        /// <exception cref="NotSupportedException" />
        protected ComparsionIndex(Expression <Func <T, TProperty> > lambda, KeyValueComparer comparer)
            : base(comparer)
        {
            MemberName = lambda.Body.GetMemberName();

            _getKey = lambda.Body.CreateGetter <T, TProperty>();
        }
Beispiel #2
0
        /// <summary>
        /// If initializer is null, then every key initially maps to default(T).
        /// Otherwise every key k initially maps to initializer(k).
        ///
        /// If isThreadSafe = true, then reads / writes are protected by locks.
        /// Otherwise, reads are thread-safe as long as they are no intervening writes.
        /// </summary>
        public FixedDomMap(Set <S> keys, Func <S, T> initializer, bool isThreadSafe = false)
        {
            Contract.Requires(keys != null);
            keyValues    = new KeyValue[keys.Count];
            comparer     = keys.Comparer;
            kvComparer   = new KeyValueComparer(comparer);
            IsThreadSafe = isThreadSafe;

            int i = 0;

            if (initializer == null)
            {
                foreach (var k in keys)
                {
                    keyValues[i++] = new KeyValue(k, default(T));
                }
            }
            else
            {
                foreach (var k in keys)
                {
                    keyValues[i++] = new KeyValue(k, initializer(k));
                }
            }
        }
        public void TestKeyValueComparer()
        {
            KeyValueComparer <int, int> cmp = new KeyValueComparer <int, int>();

            Assert.IsTrue(ReferenceEquals(Comparer <int> .Default, cmp.Comparer));
            Assert.IsTrue(ReferenceEquals(Comparer <int> .Default, KeyValueComparer <int, int> .Default.Comparer));

            Assert.AreEqual(-1, cmp.Compare(new KeyValuePair <int, int>(1, 1), new KeyValuePair <int, int>(2, 1)));
            Assert.AreEqual(0, cmp.Compare(new KeyValuePair <int, int>(1, 1), new KeyValuePair <int, int>(1, 2)));
            Assert.AreEqual(1, cmp.Compare(new KeyValuePair <int, int>(2, 1), new KeyValuePair <int, int>(1, 1)));
        }
Beispiel #4
0
        /// <summary>
        /// Gets all data rows which match a given key value.
        /// </summary>
        /// <param name="keyFields">Fields in the key on which the data rows should match.</param>
        /// <param name="data">Data from which to get data rows which match the key value.</param>
        /// <param name="matchingKeyValue">The key value which the data rows should match.</param>
        /// <returns>Data rows which match the key value.</returns>
        public static IEnumerable <IEnumerable <IDataObjectBase> > GetDataRowsForKeyValue(IEnumerable <IField> keyFields, IEnumerable <IEnumerable <IDataObjectBase> > data, string matchingKeyValue)
        {
            if (keyFields == null)
            {
                throw new ArgumentNullException("keyFields");
            }
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (string.IsNullOrEmpty(matchingKeyValue))
            {
                throw new ArgumentNullException("matchingKeyValue");
            }
            var dataRows  = data as IList <IEnumerable <IDataObjectBase> > ?? new List <IEnumerable <IDataObjectBase> >(data);
            var keyValues = new List <string>(GetKeyValues(keyFields, dataRows, false));

            try
            {
                var keyValueComparer = new KeyValueComparer();
                var matchingDataRows = new List <IEnumerable <IDataObjectBase> >();
                for (var keyValueNo = 0; keyValueNo < keyValues.Count; keyValueNo++)
                {
                    if (keyValueComparer.Equals(keyValues.ElementAt(keyValueNo), matchingKeyValue))
                    {
                        matchingDataRows.Add(dataRows.ElementAt(keyValueNo));
                    }
                }
                return(matchingDataRows);
            }
            finally
            {
                while (keyValues.Count > 0)
                {
                    keyValues.Clear();
                }
            }
        }
Beispiel #5
0
        public static Dictionary <String, Object> DiffGlobInfos(Dictionary <String, Object> glob1, Dictionary <String, Object> glob2)
        {
            var unique   = new Dictionary <String, Object>();
            var comparer = new KeyValueComparer();

            var diff = ToDictionary(glob2.Except(glob1, comparer));

            foreach (var pair in glob2)
            {
                if (diff.ContainsKey(pair.Key) && pair.Value != null)
                {
                    if (pair.Value is Dictionary <String, Object> )
                    {
                        var subdiff = glob1.ContainsKey(pair.Key) ? DiffGlobInfos((Dictionary <String, Object>)glob1[pair.Key], (Dictionary <String, Object>)pair.Value) : (Dictionary <String, Object>)pair.Value;
                        if (subdiff.Count > 0)
                        {
                            //Debug.WriteLine("Replacing\n    {0}\nwith\n    {1}", _jss.Serialize(diff[pair.Key]), _jss.Serialize(subdiff));
                            diff[pair.Key] = subdiff;
                        }
                        else
                        {
                            //Debug.WriteLine("\nRemoving {0}\n", _jss.Serialize(pair.Key));
                            diff.Remove(pair.Key);
                        }
                    }
                    else if (pair.Value is IList)
                    {
                        if (glob1.ContainsKey(pair.Key) && ListEquality((IList)pair.Value, (IList)glob1[pair.Key]))
                        {
                            diff.Remove(pair.Key);
                        }
                    }
                }
            }

            return(diff);
        }
Beispiel #6
0
        /// <summary>
        /// Manipulates missing foreign key values for a given table.
        /// </summary>
        /// <param name="table">Tabel to manipulate data for missing foreign key values.</param>
        /// <param name="dataRepository">Data repository.</param>
        /// <param name="dataToManipulate">Data for the table where to manipulate data for missing foreign key values.</param>
        /// <returns>Manipulates data for the table.</returns>
        protected override IEnumerable <IEnumerable <IDataObjectBase> > Manipulate(ITable table, IDataRepository dataRepository, IList <IEnumerable <IDataObjectBase> > dataToManipulate)
        {
            var keyValueComparer = new KeyValueComparer();
            var foreignKeyFields = _foreignKeyFields.Select(m => DataRepositoryHelper.GetTableField(table, m)).ToArray();
            var foreignKeyValues = new List <string>(DataRepositoryHelper.GetKeyValues(foreignKeyFields, dataToManipulate, true).Distinct(keyValueComparer));

            try
            {
                if (foreignKeyValues.Count == 0)
                {
                    return(dataToManipulate);
                }
                // Try to manipulate using a data queryer.
                var dataQueryer = GetDataQueryer(dataRepository);
                if (dataQueryer != null)
                {
                    var dictionaryName    = GetDictionaryName(ForeignKeyTable.PrimaryKey);
                    var keyValueFromCache = new List <string>();
                    var keyValuesToClear  = new List <string>();
                    try
                    {
                        using (dataQueryer)
                        {
                            lock (SyncRoot)
                            {
                                if (DataCache.ContainsKey(dictionaryName) == false)
                                {
                                    DataCache.Add(dictionaryName, new Tuple <List <string>, List <string> >(new List <string>(), new List <string>()));
                                }
                                if (DataCache[dictionaryName].Item1.Contains(WorkerId) == false)
                                {
                                    DataCache[dictionaryName].Item1.Add(WorkerId);
                                }
                                keyValueFromCache.AddRange(DataCache[dictionaryName].Item2);
                            }
                            while (foreignKeyValues.Count > 0)
                            {
                                if (keyValueFromCache.Any(m => keyValueComparer.Equals(m, foreignKeyValues.ElementAt(0))))
                                {
                                    foreignKeyValues.RemoveAt(0);
                                    continue;
                                }
                                var dataObjects    = new List <IDataObjectBase>(DataRepositoryHelper.GetDataRowsForKeyValue(foreignKeyFields, dataToManipulate, foreignKeyValues.ElementAt(0)).First());
                                var extraCriterias = new List <KeyValuePair <string, object> >();
                                try
                                {
                                    for (var keyFieldNo = 0; keyFieldNo < Math.Min(foreignKeyFields.Count(), ForeignKeyTable.PrimaryKey.Fields.Count); keyFieldNo++)
                                    {
                                        var dataObject  = DataRepositoryHelper.GetDataObject(dataObjects, foreignKeyFields.ElementAt(keyFieldNo));
                                        var sourceValue = DataRepositoryHelper.GetSourceValue(dataObject);
                                        if (Equals(sourceValue, null))
                                        {
                                            continue;
                                        }
                                        var nameSource          = ForeignKeyTable.PrimaryKey.Fields.Select(m => m.Key).ElementAt(keyFieldNo).NameSource;
                                        var nameTarget          = ForeignKeyTable.PrimaryKey.Fields.Select(m => m.Key).ElementAt(keyFieldNo).NameTarget;
                                        var foreignKeyFieldName = ForeignKeyTable.Fields.Count(m => string.Compare(m.NameSource, nameSource, StringComparison.OrdinalIgnoreCase) == 0) > 1 ? nameTarget : nameSource;
                                        extraCriterias.Add(new KeyValuePair <string, object>(foreignKeyFieldName, sourceValue));
                                    }
                                    if (dataQueryer.GetNumberOfEqualKeyValues(ForeignKeyTable.PrimaryKey, extraCriterias, foreignKeyValues.ElementAt(0)) == 0)
                                    {
                                        keyValuesToClear.Add(foreignKeyValues.ElementAt(0));
                                        foreignKeyValues.RemoveAt(0);
                                        continue;
                                    }
                                    lock (SyncRoot)
                                    {
                                        if (DataCache.ContainsKey(dictionaryName) == false)
                                        {
                                            foreignKeyValues.RemoveAt(0);
                                            continue;
                                        }
                                        var dataInCache = DataCache.Select(m => m.Value.Item2).Where(m => m != null).ToArray();
                                        while (dataInCache.Sum(m => m.Count) >= MaxRowsInCache)
                                        {
                                            dataInCache.OrderByDescending(m => m.Count).First().RemoveAt(0);
                                        }
                                        DataCache[dictionaryName].Item2.Add(foreignKeyValues.ElementAt(0));
                                    }
                                }
                                finally
                                {
                                    while (extraCriterias.Count > 0)
                                    {
                                        extraCriterias.Clear();
                                    }
                                    while (dataObjects.Count > 0)
                                    {
                                        dataObjects.Clear();
                                    }
                                }
                                foreignKeyValues.RemoveAt(0);
                            }
                            dataQueryer.Dispose();
                        }
                        return(keyValuesToClear.Count == 0 ? dataToManipulate : ClearDataRows(table, dataToManipulate, keyValuesToClear, foreignKeyFields, keyValueComparer));
                    }
                    catch
                    {
                        RemoveFromCache(ForeignKeyTable.PrimaryKey);
                        throw;
                    }
                    finally
                    {
                        while (keyValuesToClear.Count > 0)
                        {
                            keyValuesToClear.Clear();
                        }
                        while (keyValueFromCache.Count > 0)
                        {
                            keyValueFromCache.Clear();
                        }
                    }
                }
                // Manipulated without a data queryer.
                try
                {
                    var primaryKeyValues = new List <string>(GetKeyValues(dataRepository, ForeignKeyTable.PrimaryKey, false));
                    try
                    {
                        var keyValuesToClear = new List <string>();
                        try
                        {
                            while (foreignKeyValues.Count > 0)
                            {
                                if (primaryKeyValues.Any(m => keyValueComparer.Equals(m, foreignKeyValues.ElementAt(0))) == false)
                                {
                                    keyValuesToClear.Add(foreignKeyValues.ElementAt(0));
                                }
                                foreignKeyValues.RemoveAt(0);
                            }
                            return(keyValuesToClear.Count == 0 ? dataToManipulate : ClearDataRows(table, dataToManipulate, keyValuesToClear, foreignKeyFields, keyValueComparer));
                        }
                        finally
                        {
                            while (keyValuesToClear.Count > 0)
                            {
                                keyValuesToClear.Clear();
                            }
                        }
                    }
                    finally
                    {
                        while (primaryKeyValues.Count > 0)
                        {
                            primaryKeyValues.Clear();
                        }
                    }
                }
                catch
                {
                    RemoveFromCache(ForeignKeyTable.PrimaryKey);
                    throw;
                }
            }
            finally
            {
                while (foreignKeyValues.Count > 0)
                {
                    foreignKeyValues.Clear();
                }
            }
        }
Beispiel #7
0
 /// <summary>
 /// Validates primary key on data for a target table.
 /// </summary>
 /// <param name="targetTable">Target table.</param>
 /// <param name="targetTableData">Data for the target table.</param>
 /// <param name="endOfData">Indicates whether this is the last data for the target table.</param>
 /// <param name="command">Command which to validate with.</param>
 protected override void ValidateData(ITable targetTable, IDictionary <ITable, IEnumerable <IEnumerable <IDataObjectBase> > > targetTableData, bool endOfData, ICommand command)
 {
     if (_disposed)
     {
         throw new ObjectDisposedException(GetType().Name);
     }
     foreach (var dataTable in targetTableData.Keys)
     {
         if (dataTable.CandidateKeys == null || dataTable.CandidateKeys.Count == 0)
         {
             throw new DeliveryEngineMetadataException(Resource.GetExceptionMessage(ExceptionMessage.MissingCandidateKeysOnTable, dataTable.NameSource), dataTable);
         }
         foreach (var candidateKey in dataTable.CandidateKeys)
         {
             if (candidateKey.Fields == null || candidateKey.Fields.Count == 0)
             {
                 throw new DeliveryEngineMetadataException(Resource.GetExceptionMessage(ExceptionMessage.MissingFieldsOnCandidateKey, candidateKey.NameSource, dataTable.NameSource), candidateKey);
             }
             var           keyValueComparer = new KeyValueComparer();
             List <string> primaryKeyValues;
             // Try to validate using a data queryer.
             var dataQueryer = GetDataQueryer(DataRepository);
             if (dataQueryer != null)
             {
                 using (dataQueryer)
                 {
                     primaryKeyValues = new List <string>(DataRepositoryHelper.GetKeyValues(candidateKey, targetTableData[dataTable], false));
                     try
                     {
                         for (var primaryKeyValueNo = 0; primaryKeyValueNo < primaryKeyValues.Count; primaryKeyValueNo++)
                         {
                             var dataRow = targetTableData[dataTable].ElementAt(primaryKeyValueNo);
                             RaiseOnValidationEvent(this, new DataValidatorEventArgs(dataRow));
                             if (endOfData)
                             {
                                 if (primaryKeyValues.Count(m => keyValueComparer.Equals(m, primaryKeyValues.ElementAt(primaryKeyValueNo))) == 1)
                                 {
                                     continue;
                                 }
                                 candidateKey.ValidateObjectData = dataRow;
                                 throw new DeliveryEngineValidateException(Resource.GetExceptionMessage(ExceptionMessage.UniqueConstraintViolationOnCandidateKey, candidateKey.NameSource), candidateKey);
                             }
                             var extraCriterias = GetExtraCriterias(candidateKey, new List <IDataObjectBase>(dataRow));
                             try
                             {
                                 if (dataQueryer.GetNumberOfEqualKeyValues(candidateKey, extraCriterias, primaryKeyValues.ElementAt(primaryKeyValueNo)) == 1)
                                 {
                                     continue;
                                 }
                                 candidateKey.ValidateObjectData = dataRow;
                                 throw new DeliveryEngineValidateException(Resource.GetExceptionMessage(ExceptionMessage.UniqueConstraintViolationOnCandidateKey, candidateKey.NameSource), candidateKey);
                             }
                             finally
                             {
                                 while (extraCriterias.Count > 0)
                                 {
                                     extraCriterias.Clear();
                                 }
                             }
                         }
                     }
                     finally
                     {
                         while (primaryKeyValues.Count > 0)
                         {
                             primaryKeyValues.Clear();
                         }
                     }
                     dataQueryer.Dispose();
                 }
                 continue;
             }
             // Validate without a data queryer.
             var dictionaryName = GetDictionaryName(candidateKey);
             lock (_syncRoot)
             {
                 if (_dataCache.TryGetValue(dictionaryName, out primaryKeyValues) == false)
                 {
                     primaryKeyValues = new List <string>();
                     _dataCache.Add(dictionaryName, primaryKeyValues);
                 }
             }
             var keyValues = new List <string>(DataRepositoryHelper.GetKeyValues(candidateKey, targetTableData[dataTable], false));
             try
             {
                 for (var keyValueNo = 0; keyValueNo < keyValues.Count; keyValueNo++)
                 {
                     RaiseOnValidationEvent(this, new DataValidatorEventArgs(targetTableData[dataTable].ElementAt(keyValueNo)));
                     if (primaryKeyValues.Count(m => keyValueComparer.Equals(keyValues.ElementAt(keyValueNo), m)) + keyValues.Count(m => keyValueComparer.Equals(keyValues.ElementAt(keyValueNo), m)) == 1)
                     {
                         continue;
                     }
                     candidateKey.ValidateObjectData = targetTableData[dataTable].ElementAt(keyValueNo);
                     throw new DeliveryEngineValidateException(Resource.GetExceptionMessage(ExceptionMessage.UniqueConstraintViolationOnCandidateKey, candidateKey.NameSource), candidateKey);
                 }
                 lock (_syncRoot)
                 {
                     _dataCache[dictionaryName].AddRange(keyValues);
                     if (!endOfData)
                     {
                         continue;
                     }
                     while (_dataCache[dictionaryName].Count > 0)
                     {
                         _dataCache[dictionaryName].Clear();
                     }
                     _dataCache.Remove(dictionaryName);
                 }
             }
             finally
             {
                 while (keyValues.Count > 0)
                 {
                     keyValues.Clear();
                 }
             }
         }
     }
 }
 /// <summary>
 /// Validates foreign keys on data for a target table.
 /// </summary>
 /// <param name="targetTable">Target table.</param>
 /// <param name="targetTableData">Data for the target table.</param>
 /// <param name="endOfData">Indicates whether this is the last data for the target table.</param>
 /// <param name="command">Command which to validate with.</param>
 protected override void ValidateData(ITable targetTable, IDictionary <ITable, IEnumerable <IEnumerable <IDataObjectBase> > > targetTableData, bool endOfData, IForeignKeysValidationCommand command)
 {
     if (_disposed)
     {
         throw new ObjectDisposedException(GetType().Name);
     }
     foreach (var dataTable in targetTableData.Select(m => m.Key).Where(m => m.ForeignKeys != null && m.ForeignKeys.Count > 0))
     {
         foreach (var foreignKey in dataTable.ForeignKeys)
         {
             if (foreignKey.CandidateKey == null)
             {
                 throw new DeliveryEngineMetadataException(Resource.GetExceptionMessage(ExceptionMessage.MissingCandidateKeyOnForeignKey, foreignKey.NameSource, dataTable.NameSource), foreignKey);
             }
             if (foreignKey.CandidateKey.Fields == null || foreignKey.Fields == null || foreignKey.CandidateKey.Fields.Count != foreignKey.Fields.Count)
             {
                 throw new DeliveryEngineMetadataException(Resource.GetExceptionMessage(ExceptionMessage.UnableToMatchFieldsOnForeignKey, foreignKey.CandidateKey.NameSource, foreignKey.NameSource, dataTable.NameSource), foreignKey);
             }
             var keyValueComparer = new KeyValueComparer();
             var foreignKeyValues = new List <string>(DataRepositoryHelper.GetKeyValues(foreignKey, targetTableData[dataTable], true).Distinct(keyValueComparer));
             if (foreignKeyValues.Count == 0)
             {
                 continue;
             }
             try
             {
                 var onRemove = new Action <ITable, List <IEnumerable <IDataObjectBase> > >((table, dataRowsToRemove) =>
                 {
                     var removeMethod = targetTableData[table].GetType().GetMethod("Remove");
                     if (removeMethod == null)
                     {
                         throw new DeliveryEngineSystemException(Resource.GetExceptionMessage(ExceptionMessage.MethodNotFoundOnType, "Remove", targetTableData[table].GetType().Name));
                     }
                     dataRowsToRemove.ForEach(dataRow => removeMethod.Invoke(targetTableData[table], new object[] { dataRow }));
                 });
                 // Try to validate using a data queryer.
                 var dataQueryer = GetDataQueryer(DataRepository);
                 if (dataQueryer != null)
                 {
                     using (dataQueryer)
                     {
                         var keyValuesFromCache = new List <string>();
                         try
                         {
                             var dictionaryName = GetDictionaryName(foreignKey);
                             lock (_syncRoot)
                             {
                                 List <string> dataInCache;
                                 if (_dataCache.TryGetValue(dictionaryName, out dataInCache))
                                 {
                                     while (_dataCache.ContainsKey(dictionaryName))
                                     {
                                         _dataCache.Remove(dictionaryName);
                                     }
                                     _dataCache.Add(dictionaryName, dataInCache);
                                 }
                                 else
                                 {
                                     _dataCache.Add(dictionaryName, new List <string>());
                                 }
                                 while (_dataCache.Count > 0 && _dataCache.Count >= command.NumberOfForeignTablesToCache && Equals(_dataCache.ElementAt(0).Key, dictionaryName) == false)
                                 {
                                     var keyName = _dataCache.ElementAt(0).Key;
                                     while (_dataCache[keyName].Count > 0)
                                     {
                                         _dataCache[keyName].Clear();
                                     }
                                     _dataCache.Remove(keyName);
                                 }
                                 keyValuesFromCache.AddRange(_dataCache[dictionaryName]);
                             }
                             while (foreignKeyValues.Count > 0)
                             {
                                 var dataRows = new List <IEnumerable <IDataObjectBase> >(DataRepositoryHelper.GetDataRowsForKeyValue(foreignKey, targetTableData[dataTable], foreignKeyValues.ElementAt(0)));
                                 try
                                 {
                                     dataRows.ForEach(dataRow => RaiseOnValidationEvent(this, new DataValidatorEventArgs(dataRow)));
                                     if (keyValuesFromCache.Any(m => keyValueComparer.Equals(m, foreignKeyValues.ElementAt(0))))
                                     {
                                         foreignKeyValues.RemoveAt(0);
                                         continue;
                                     }
                                     var extraCriterias = new List <KeyValuePair <string, object> >();
                                     try
                                     {
                                         for (var keyFieldNo = 0; keyFieldNo < Math.Min(foreignKey.Fields.Count, foreignKey.CandidateKey.Fields.Count); keyFieldNo++)
                                         {
                                             var dataObject  = DataRepositoryHelper.GetDataObject(dataRows[0].ToList(), foreignKey.Fields.ElementAt(keyFieldNo).Key);
                                             var sourceValue = DataRepositoryHelper.GetSourceValue(dataObject);
                                             if (Equals(sourceValue, null))
                                             {
                                                 continue;
                                             }
                                             var sourceName          = foreignKey.CandidateKey.Fields.ElementAt(keyFieldNo).Key.NameSource;
                                             var targetName          = foreignKey.CandidateKey.Fields.ElementAt(keyFieldNo).Key.NameTarget;
                                             var foreignKeyFieldName = foreignKey.CandidateKey.Table.Fields.Count(m => string.Compare(m.NameSource, sourceName, StringComparison.OrdinalIgnoreCase) == 0) > 1 ? targetName : sourceName;
                                             extraCriterias.Add(new KeyValuePair <string, object>(foreignKeyFieldName, sourceValue));
                                         }
                                         var equalPrimaryKeys = dataQueryer.GetNumberOfEqualKeyValues(foreignKey.CandidateKey, extraCriterias, foreignKeyValues.ElementAt(0));
                                         HandleEqualPrimaryKeysResult(equalPrimaryKeys, dataTable, foreignKey, dataRows, command, onRemove);
                                         if (equalPrimaryKeys == 1)
                                         {
                                             lock (_syncRoot)
                                             {
                                                 if (_dataCache.ContainsKey(dictionaryName) == false)
                                                 {
                                                     foreignKeyValues.RemoveAt(0);
                                                     continue;
                                                 }
                                                 while (_dataCache.Select(m => m.Value).Sum(m => m.Count) >= 8192)
                                                 {
                                                     _dataCache.Select(m => m.Value).Where(m => m.Count > 0).OrderByDescending(m => m.Count).First().RemoveAt(0);
                                                 }
                                                 _dataCache[dictionaryName].Add(foreignKeyValues.ElementAt(0));
                                             }
                                         }
                                     }
                                     finally
                                     {
                                         while (extraCriterias.Count > 0)
                                         {
                                             extraCriterias.Clear();
                                         }
                                     }
                                 }
                                 finally
                                 {
                                     while (dataRows.Count > 0)
                                     {
                                         dataRows.Clear();
                                     }
                                 }
                                 foreignKeyValues.RemoveAt(0);
                             }
                         }
                         finally
                         {
                             while (keyValuesFromCache.Count > 0)
                             {
                                 keyValuesFromCache.Clear();
                             }
                         }
                         dataQueryer.Dispose();
                     }
                     continue;
                 }
                 // Validate without a data queryer.
                 var primaryKeyValues = GetForeignKeyValues(foreignKey.CandidateKey, command.NumberOfForeignTablesToCache);
                 while (foreignKeyValues.Count > 0)
                 {
                     var dataRows = new List <IEnumerable <IDataObjectBase> >(DataRepositoryHelper.GetDataRowsForKeyValue(foreignKey, targetTableData[dataTable], foreignKeyValues.ElementAt(0)));
                     try
                     {
                         dataRows.ForEach(dataRow => RaiseOnValidationEvent(this, new DataValidatorEventArgs(dataRow)));
                         var equalPrimaryKeys = primaryKeyValues.Count(m => keyValueComparer.Equals(foreignKeyValues.ElementAt(0), m));
                         HandleEqualPrimaryKeysResult(equalPrimaryKeys, dataTable, foreignKey, dataRows, command, onRemove);
                     }
                     finally
                     {
                         while (dataRows.Count > 0)
                         {
                             dataRows.Clear();
                         }
                     }
                     foreignKeyValues.RemoveAt(0);
                 }
             }
             finally
             {
                 while (foreignKeyValues.Count > 0)
                 {
                     foreignKeyValues.Clear();
                 }
             }
         }
     }
 }
Beispiel #9
0
        /// <summary>
        /// Finalize missing foreign key values for a given table.
        /// </summary>
        /// <param name="table">Table to finalize data manipulation for missing foreign key values.</param>
        /// <param name="dataRepository">Data repository.</param>
        /// <param name="dataToManipulate">The last manipulated data which has been received.</param>
        /// <returns>Finalized and manipulated data for the table.</returns>
        protected override IEnumerable <IEnumerable <IDataObjectBase> > Finalize(ITable table, IDataRepository dataRepository, IList <IEnumerable <IDataObjectBase> > dataToManipulate)
        {
            var dictionaryName       = GetDictionaryName(table.PrimaryKey);
            var workerDictionaryName = string.Format("{0} - {1}", dictionaryName, WorkerId);
            var primaryKeyValues     = new List <string>();

            try
            {
                // Restore primary key values from the cache.
                lock (SyncRoot)
                {
                    if (DataCache.ContainsKey(workerDictionaryName) == false)
                    {
                        return(dataToManipulate);
                    }
                    primaryKeyValues.AddRange(DataCache[workerDictionaryName].Item1);
                    while (DataCache[workerDictionaryName].Item1.Count > 0)
                    {
                        DataCache[workerDictionaryName].Item1.Clear();
                    }
                    DataCache.Remove(workerDictionaryName);
                }
                // Add missing foreign key values.
                var clonedForeignKeyTable = GetForeignTableWithNotNullCriteria(ForeignKeyTable, _foreignKeyFields.Last());
                try
                {
                    var keyValueComparer = new KeyValueComparer();
                    var foreignKeyValues = new List <string>(DataRepositoryHelper.GetKeyValues(dataRepository, clonedForeignKeyTable, _foreignKeyFields, true).Distinct(keyValueComparer));
                    try
                    {
                        var keyValuesToCreate = new List <string>(foreignKeyValues.Where(m => primaryKeyValues.Count(n => keyValueComparer.Equals(m, n)) == 0));
                        try
                        {
                            AddMissingRows(table, dataToManipulate, keyValuesToCreate);
                        }
                        finally
                        {
                            while (keyValuesToCreate.Count > 0)
                            {
                                keyValuesToCreate.Clear();
                            }
                        }
                    }
                    finally
                    {
                        while (foreignKeyValues.Count > 0)
                        {
                            foreignKeyValues.Clear();
                        }
                    }
                    return(dataToManipulate);
                }
                finally
                {
                    clonedForeignKeyTable = null;
                    Debug.Assert(clonedForeignKeyTable == null);
                    GC.Collect();
                }
            }
            finally
            {
                while (primaryKeyValues.Count > 0)
                {
                    primaryKeyValues.Clear();
                }
                // Remove primary key values from the cache.
                lock (SyncRoot)
                {
                    while (DataCache.ContainsKey(workerDictionaryName))
                    {
                        while (DataCache[workerDictionaryName].Item1.Count > 0)
                        {
                            DataCache[workerDictionaryName].Item1.Clear();
                        }
                        DataCache.Remove(workerDictionaryName);
                    }
                }
                RemoveFromCache(table.PrimaryKey);
            }
        }
Beispiel #10
0
        /// <summary>
        /// Get the number of equal key values for a given key.
        /// </summary>
        /// <param name="key">Key on which to calculate equal number of key values.</param>
        /// <param name="extraCriterias">Extra criterias (field name and value) to put into the record filter when querying for number of equal key values.</param>
        /// <param name="matchingKeyValue">The key value on which to calculate the number of equal key values.</param>
        /// <returns>Number of equal key values for the key.</returns>
        public virtual int GetNumberOfEqualKeyValues(IKey key, IEnumerable <KeyValuePair <string, object> > extraCriterias, string matchingKeyValue)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            if (extraCriterias == null)
            {
                throw new ArgumentNullException("extraCriterias");
            }
            if (string.IsNullOrEmpty(matchingKeyValue))
            {
                throw new ArgumentNullException("matchingKeyValue");
            }

            var table = key.Table;

            if (table == null)
            {
                throw new DeliveryEngineMetadataException(Resource.GetExceptionMessage(ExceptionMessage.IllegalValue, table, "Table"), key);
            }

            var clonedTable  = (ITable)table.Clone();
            var addCriterias = new List <KeyValuePair <string, object> >(extraCriterias.ToList());

            try
            {
                foreach (var extraCriteria in addCriterias)
                {
                    var field = DataRepositoryHelper.GetTableField(clonedTable, extraCriteria.Key);
                    if (clonedTable.RecordFilters.Count == 0)
                    {
                        clonedTable.AddRecordFilter(new Filter());
                    }
                    foreach (var recordFilter in clonedTable.RecordFilters)
                    {
                        recordFilter.AddCriteria(DataRepositoryHelper.BuildEqualCriteria(field, extraCriteria.Value));
                    }
                }

                var selectCountForTable = SelectCountForTable(clonedTable);
                if (selectCountForTable == 1)
                {
                    return(selectCountForTable);
                }

                var numberOfEqualKeyValues = 0;
                GetData(clonedTable, (sender, eventArgs) =>
                {
                    if (eventArgs == null)
                    {
                        throw new ArgumentNullException("eventArgs");
                    }
                    var keyFields = new List <IField>(key.Fields.Select(m => m.Key).Select(keyField => DataRepositoryHelper.GetTableField(eventArgs.Table, keyField.NameTarget ?? keyField.NameSource)));
                    IList <string> keyValues;
                    var keyValueComparer = new KeyValueComparer();
                    if (_dataManipulators == null)
                    {
                        keyValues = new List <string>(DataRepositoryHelper.GetKeyValues(keyFields, eventArgs.Data, false));
                        try
                        {
                            numberOfEqualKeyValues += keyValues.Count(keyValue => keyValueComparer.Equals(keyValue, matchingKeyValue));
                        }
                        finally
                        {
                            while (keyValues.Count > 0)
                            {
                                keyValues.Clear();
                            }
                            keyValues = null;
                            Debug.Assert(keyValues == null);
                            while (keyFields.Count > 0)
                            {
                                keyFields.Clear();
                            }
                            keyFields = null;
                            Debug.Assert(keyFields == null);
                        }
                        return;
                    }
                    var manipulatedData    = eventArgs.Data;
                    var myDataManipulators = _dataManipulators.Where(m => (string.IsNullOrEmpty(eventArgs.Table.NameTarget) == false && m.IsManipulatingTable(eventArgs.Table.NameTarget)) || (string.IsNullOrEmpty(eventArgs.Table.NameSource) == false && m.IsManipulatingTable(eventArgs.Table.NameSource))).ToArray();
                    foreach (var dataManipulator in myDataManipulators)
                    {
                        if (keyFields.Any(keyField => (string.IsNullOrEmpty(keyField.NameTarget) == false && dataManipulator.IsManipulatingField(keyField.NameTarget)) || (string.IsNullOrEmpty(keyField.NameSource) == false && dataManipulator.IsManipulatingField(keyField.NameSource))) == false)
                        {
                            continue;
                        }
                        if (dataManipulator is IMissingForeignKeyHandler)
                        {
                            continue;
                        }
                        manipulatedData = dataManipulator.ManipulateData(eventArgs.Table, manipulatedData);
                        if (eventArgs.EndOfData)
                        {
                            manipulatedData = dataManipulator.FinalizeDataManipulation(eventArgs.Table, manipulatedData);
                        }
                    }
                    keyValues = new List <string>(DataRepositoryHelper.GetKeyValues(keyFields, manipulatedData, false));
                    try
                    {
                        numberOfEqualKeyValues += keyValues.Count(keyValue => keyValueComparer.Equals(keyValue, matchingKeyValue));
                        if (numberOfEqualKeyValues > 0 || eventArgs.EndOfData == false)
                        {
                            return;
                        }
                        // ReSharper disable LoopCanBeConvertedToQuery
                        foreach (var missingForeignKeyHandler in myDataManipulators.OfType <IMissingForeignKeyHandler>())
                        {
                            if (keyFields.Any(keyField => (string.IsNullOrEmpty(keyField.NameTarget) == false && missingForeignKeyHandler.IsManipulatingField(keyField.NameTarget)) || (string.IsNullOrEmpty(keyField.NameSource) == false && missingForeignKeyHandler.IsManipulatingField(keyField.NameSource))) == false)
                            {
                                continue;
                            }
                            if (missingForeignKeyHandler.Worker is IPrimaryKeyAdder)
                            {
                                numberOfEqualKeyValues += Convert.ToInt32(addCriterias.Any() == false);
                            }
                        }
                        // ReSharper restore LoopCanBeConvertedToQuery
                    }
                    finally
                    {
                        while (keyValues.Count > 0)
                        {
                            keyValues.Clear();
                        }
                        keyValues = null;
                        Debug.Assert(keyValues == null);
                        while (keyFields.Count > 0)
                        {
                            keyFields.Clear();
                        }
                        keyFields = null;
                        Debug.Assert(keyFields == null);
                    }
                });
                if (numberOfEqualKeyValues == 1 || addCriterias.Any() == false)
                {
                    return(numberOfEqualKeyValues);
                }

                var newCriterias = new List <KeyValuePair <string, object> >(addCriterias.GetRange(0, addCriterias.Count - 1));
                try
                {
                    if (_dataManipulators != null)
                    {
                        var tableNameTarget = key.Table.NameTarget;
                        var tableNameSource = key.Table.NameSource;
                        var retry           = _dataManipulators.Any(dataManipulator =>
                        {
                            if (string.IsNullOrEmpty(tableNameTarget) == false && dataManipulator.IsManipulatingTable(tableNameTarget))
                            {
                                return(dataManipulator.IsManipulatingField(addCriterias.Last().Key) || newCriterias.Select(newCriteria => newCriteria.Key).Any(dataManipulator.IsManipulatingField));
                            }
                            if (string.IsNullOrEmpty(tableNameSource) == false && dataManipulator.IsManipulatingTable(tableNameSource))
                            {
                                return(dataManipulator.IsManipulatingField(addCriterias.Last().Key) || newCriterias.Select(newCriteria => newCriteria.Key).Any(dataManipulator.IsManipulatingField));
                            }
                            return(false);
                        });
                        if (retry)
                        {
                            return(GetNumberOfEqualKeyValues(key, newCriterias, matchingKeyValue));
                        }
                    }
                    if (newCriterias.Count == 0 && clonedTable.RecordFilters.Any(recordFilter => recordFilter.Criterias.Take(recordFilter.Criterias.Count - 1).OfType <IFieldCriteria>().Any(criteria => criteria.Field != null && (string.Compare(addCriterias.Last().Key, criteria.Field.NameSource, StringComparison.OrdinalIgnoreCase) == 0 || string.Compare(addCriterias.Last().Key, criteria.Field.NameTarget, StringComparison.OrdinalIgnoreCase) == 0))))
                    {
                        return(numberOfEqualKeyValues);
                    }
                    return(newCriterias.Count == key.Fields.Count - 1 ? GetNumberOfEqualKeyValues(key, newCriterias, matchingKeyValue) : numberOfEqualKeyValues);
                }
                finally
                {
                    while (newCriterias.Count > 0)
                    {
                        newCriterias.Clear();
                    }
                    newCriterias = null;
                    Debug.Assert(newCriterias == null);
                }
            }
            finally
            {
                while (addCriterias.Count > 0)
                {
                    addCriterias.Clear();
                }
                clonedTable = null;
                Debug.Assert(clonedTable == null);
            }
        }