Exemple #1
0
        public void GenerateDifference(IDataReader source, IDataReader target, Table table, IDataWriter dataWriter, JobSettings settings)
        {
            if (source.FieldCount != target.FieldCount)
            {
                throw new MismatchedSchemaException($"Schema difference detected while importing {table.BasicName}. Please ensure the schemas match before syncing");
            }
            List <object>         sourceRecord    = ReadRecord(source);
            List <object>         targetRecord    = ReadRecord(target);
            List <object>         targetsToDelete = new List <object>();
            List <List <object> > recordsToInsert = new List <List <object> >();
            List <List <object> > recordsToUpdate = new List <List <object> >();

            while (true)
            {
                int?comparison;
                if (sourceRecord == null && targetRecord == null)
                {
                    break;
                }
                else if (sourceRecord == null)
                {
                    comparison = 1;
                }
                else if (targetRecord == null)
                {
                    comparison = -1;
                }
                else
                {
                    comparison = CompareObjects(source[table.PrimaryKey], target[table.PrimaryKey]);
                }

                if (sourceRecord != null)
                {
                    dataWriter.Entry(SerializeRecordAsDictionary(sourceRecord, table));
                }

                if (comparison == null)
                {
                    throw new NotSupportedKeyException($"Could not compare key {table.PrimaryKey} of {table.Name}. DbSync does not support comparison of keys of it's type");
                }
                bool consumeTarget = false;
                bool consumeSource = false;
                //record exists in both
                if (comparison == 0)
                {
                    var identical = true;
                    for (int i = 0; i < sourceRecord.Count; i++)
                    {
                        if (!table.Fields[i].IsAuditingColumn)
                        {
                            if (CompareObjects(sourceRecord[i], targetRecord[i]) != 0)
                            {
                                identical = false;
                            }
                        }
                    }
                    if (!identical)
                    {
                        dataWriter.Update(SerializeRecordAsDictionary(sourceRecord, table));
                    }
                    consumeSource = true;
                    consumeTarget = true;
                }
                //target contains a record not in source
                else if (comparison == 1)
                {
                    if ((table.MergeStrategy ?? settings.MergeStrategy) != Merge.Strategy.Override)
                    {
                        dataWriter.Delete(target[table.PrimaryKey]);
                    }
                    consumeTarget = true;
                }
                //source contains a record not in target
                else if (comparison == -1)
                {
                    dataWriter.Add(SerializeRecordAsDictionary(sourceRecord, table));
                    consumeSource = true;
                }
                if (consumeSource)
                {
                    sourceRecord = ReadRecord(source);
                }
                if (consumeTarget)
                {
                    targetRecord = ReadRecord(target);
                }
            }
        }