private SqlMigrationDocument FromReaderInternal(SqlReader reader, SqlTable table, SqlDatabase.Validator validator = null)
        {
            var document = new SqlMigrationDocument(table.Name);

            var id = table.NewName;

            if (table.IsEmbedded == false)
            {
                document.SetCollection(id);
            }

            for (var i = 0; i < reader.FieldCount; i++)
            {
                var columnName   = reader.GetName(i);
                var isPrimaryKey = table.PrimaryKeys.Contains(columnName);
                var isForeignKey = table.ForeignKeys.TryGetValue(columnName, out var foreignKeyTableName);

                object value;

                try
                {
                    value = reader[i];
                }
                catch (Exception e)
                {
                    if (!(e is PlatformNotSupportedException))
                    {
                        throw;
                    }

                    var isKey = isPrimaryKey || isForeignKey;

                    if (Options.SkipUnsupportedTypes == false)
                    {
                        var message = $"Cannot read column '{columnName}' in table '{table.Name}'. (Unsupported type: {reader.GetDataTypeName(i)}) Error: {e}";

                        if (validator != null)
                        {
                            validator.AddError(SqlMigrationImportResult.Error.ErrorType.UnsupportedType, message, table.Name, columnName);
                        }

                        else
                        {
                            throw new InvalidOperationException(message, e);
                        }
                    }

                    else if (isKey)
                    {
                        var message = $"Cannot skip unsupported KEY column '{columnName}' in table '{table.Name}'. (Unsupported type: {reader.GetDataTypeName(i)})";

                        if (validator != null)
                        {
                            validator.AddError(SqlMigrationImportResult.Error.ErrorType.UnsupportedType, message, table.Name, columnName);
                        }
                        else
                        {
                            throw new InvalidOperationException(message, e);
                        }
                    }

                    continue;
                }

                var isNullOrEmpty = value is DBNull || string.IsNullOrWhiteSpace(value.ToString());

                if (isPrimaryKey)
                {
                    id += $"/{value}";

                    if (isForeignKey == false && table.IsEmbedded == false)
                    {
                        continue;
                    }
                }

                if (Options.BinaryToAttachment && reader.GetFieldType(i) == typeof(byte[]))
                {
                    if (isNullOrEmpty == false)
                    {
                        _currentAttachments.Add($"{columnName}_{_currentAttachments.Count}", (byte[])value);
                    }
                }

                else
                {
                    if (isForeignKey && isNullOrEmpty == false && table.Database.TryGetNewName(foreignKeyTableName, out var newName))
                    {
                        value = $"{newName}/{value}";
                    }

                    document.Set(columnName, value, Options.TrimStrings);
                }
            }

            document.Id = id;

            if (validator == null)
            {
                SetEmbeddedDocuments(document, table);
            }

            return(document);
        }
Exemple #2
0
        private void SetTablesFromBlittableArray(List <SqlMigrationImportOperation.SqlMigrationTable> tablesToWrite, SqlTable parentTable = null)
        {
            foreach (var item in tablesToWrite)
            {
                SqlTable table;

                if (parentTable != null)
                {
                    table = new SqlEmbeddedTable(item.Name, item.Query, this, item.NewName, parentTable.Name);
                    parentTable.EmbeddedTables.Add((SqlEmbeddedTable)table);
                    EmbeddedTables.Add((SqlEmbeddedTable)table);
                }
                else
                {
                    table = new SqlParentTable(item.Name, item.Query, this, item.NewName, item.Patch);
                    ParentTables.Add((SqlParentTable)table);
                }

                if (item.EmbeddedTables != null)
                {
                    SetTablesFromBlittableArray(item.EmbeddedTables, table);
                }
            }
        }
        private void SetEmbeddedDocuments(SqlReader reader, SqlMigrationDocument document, SqlTable parentTable)
        {
            foreach (var childTable in parentTable.EmbeddedTables)
            {
                var parentValues = GetValuesFromColumns(reader, parentTable.PrimaryKeys); // values of referenced columns

                var childColumns = childTable.GetColumnsReferencingParentTable();         // values of referencing columns

                using (var childReader = GetChildReader(parentTable, childColumns, childTable, parentValues))
                {
                    if (childReader.HasValue() == false && childReader.Read() == false)
                    {
                        continue;
                    }

                    var continueLoop = false;

                    while (CompareValues(parentValues, GetValuesFromColumns(childReader, childColumns), out var isBigger) == false)
                    {
                        if (isBigger == false && childReader.Read())
                        {
                            continue;
                        }

                        continueLoop = true; // If parent value is greater than child value => childReader move to next. Otherwise => parentReader move to next
                        break;
                    }

                    if (continueLoop)
                    {
                        continue;
                    }

                    do
                    {
                        var innerDocument = FromReaderInternal(childReader, childTable);

                        document.Append(childTable.NewName, innerDocument);

                        if (childReader.Read() == false)
                        {
                            break;
                        }
                    } while (CompareValues(parentValues, GetValuesFromColumns(childReader, childColumns), out _));
                }
            }
        }