Exemple #1
0
        public override void Perform(SchemaChanges changes, IOutput output)
        {
            var pendingReorders = PendingReorderTableType.AllFrom(changes.Current);

            foreach (var desired in TableType.AllFrom(changes.Desired))
            {
                if (changes.Current.Contains(desired))
                {
                    continue;
                }

                var fields        = FieldType.ChildrenFrom(changes.Desired, desired.Identifier);
                var fieldCreation = from field in fields
                                    orderby field.State.OrdinalPosition
                                    select new FieldCreation(field.Name, field.State.DataType, field.State.IsNullable, field.State.IsSequencedPkey, field.State.SequenceName);

                changes.Put(changes.SchemaDriver.GetCreateTableSql(desired.Name, fieldCreation),
                            new ObjectState[] { desired }.Concat(fields));
            }
        }
Exemple #2
0
        public override void Perform(SchemaChanges changes, IOutput output)
        {
            if (changes.Options.TableDropBehavior == DropBehavior.SkipDrop)
            {
                return;
            }
            var errorResponse = changes.Options.TableDropBehavior == DropBehavior.TryDrop ? ErrorResponse.Ignore : ErrorResponse.Fail;

            foreach (var current in TableType.AllFrom(changes.Current))
            {
                if (changes.Desired.Contains(current))
                {
                    continue;
                }

                if (!changes.AllowDropWithPossibleDataLoss(current, changes.Options.TableDropBehavior))
                {
                    continue;
                }

                // Drop the table
                changes.Remove(changes.SchemaDriver.GetDropTableSql(current.Name), errorResponse, current);
            }
        }
Exemple #3
0
        private void createTempTables(SchemaChanges changes, IOutput output)
        {
            // For any tables with order-sensitivity and fields in different order between current and desired (ignoring fields that only exist in current),
            // Create a new table  "_nrdo_reorder" using "select (columns in correct order followed by columns to be dropped) from original table into newname"
            // Put the table, the fields (with nullability, datatype and identityness as current but in new order) and a PendingReorderTable into current
            // For any tables that need their fields reordered, create a copy of the table with the fields in the right order.
            foreach (var origTable in TableType.AllFrom(changes.Current))
            {
                // Tables that don't exist in desired state are to be dropped, they certainly don't need to be reordered!
                if (!changes.Desired.Contains(origTable))
                {
                    continue;
                }

                // Figure out whether a reorder is needed
                if (!FieldType.IsFieldReorderNeeded(changes, origTable.Identifier))
                {
                    continue;
                }

                // Put the fields in order.
                // At this point there may be extra fields that are to be dropped but haven't been yet. They need to stick around until
                // it's time to drop them, because before statements may rely on them. But we put those ones last (in the order they're currently in).
                var fieldsInOrder = from field in FieldType.ChildrenFrom(changes.Current, origTable.Identifier)
                                    let desired = changes.Desired.Get(field)
                                                  orderby
                                                  desired != null ? desired.State.OrdinalPosition : int.MaxValue,
                    field.State.OrdinalPosition
                select field;

                // Construct the state representation that will be used for the new table.
                // It inherits all before statements from the original table so that when it's renamed they'll still be there.
                // FIXME: This hardcodes the assumption that CreateTableAsSelect preserves field type, nullability and identity-ness, which may or may not be true on other DBs
                // FIXME: any other aspects of field state that we add support for (Default values, check constraints...) need to get dropped here.
                var tempTable       = TableType.Create(origTable.Name + "_nrdo_reorder");
                var pendingReorder  = PendingReorderTableType.Create(tempTable.Identifier, origTable.Name);
                var tempTableFields = from fi in fieldsInOrder.Select((field, index) => new { field, index })
                                      select fi.field
                                      .WithParent(tempTable.Identifier)
                                      .With(s => s.WithOrdinalPosition(fi.index));

                var tempTableBefores = from before in BeforeStatementType.ChildrenFrom(changes.Current, origTable.Identifier)
                                       select before.WithParent(tempTable.Identifier);

                // Gather all temporary objects into one list to put them into the database together
                var tempTableObjects =
                    new ObjectState[]
                {
                    tempTable,
                    pendingReorder
                }
                .Concat(tempTableFields)
                .Concat(tempTableBefores);

                var sql = changes.SchemaDriver.GetCreateTableAsSelectSql(tempTable.Name,
                                                                         string.Join(", ", from field in fieldsInOrder select changes.DbDriver.QuoteIdentifier(field.Name)),
                                                                         changes.DbDriver.QuoteSchemaIdentifier(origTable.Name));

                changes.Put(sql, tempTableObjects);
            }
        }