public override void ColumnDefinition(
            string schema, 
            string table, 
            string name, 
            string type, 
            bool nullable, 
            object defaultValue, 
            string defaultValueSql,
            string computedColumnSql, 
            IAnnotatable annotatable, 
            IModel model, 
            SqlBatchBuilder builder)
        {
            base.ColumnDefinition(
                schema, table, name, type, nullable, 
                defaultValue, defaultValueSql, computedColumnSql, annotatable, model, builder);

            var columnAnnotation = annotatable as Annotatable;
            var inlinePk = columnAnnotation?.FindAnnotation(SqliteAnnotationNames.Prefix + SqliteAnnotationNames.InlinePrimaryKey);

            if (inlinePk != null
                && (bool)inlinePk.Value)
            {
                builder.Append(" PRIMARY KEY");
                var autoincrement = columnAnnotation.FindAnnotation(SqliteAnnotationNames.Prefix + SqliteAnnotationNames.Autoincrement);
                if (autoincrement != null
                    && (bool)autoincrement.Value)
                {
                    builder.Append(" AUTOINCREMENT");
                }
            }
        }
        public void SqlBatchBuilder_correctly_produces_multiple_batches()
        {
            var batchBuilder = new SqlBatchBuilder();
            batchBuilder.AppendLine("Statement1");
            batchBuilder.EndBatch();
            batchBuilder.AppendLine("Statement2");
            batchBuilder.AppendLine("Statement3");
            batchBuilder.EndBatch();
            batchBuilder.AppendLine("Statement4");
            batchBuilder.AppendLine("Statement5");
            batchBuilder.AppendLine("Statement6");
            batchBuilder.EndBatch();

            Assert.Equal(3, batchBuilder.SqlBatches.Count);

            Assert.Equal(
                @"Statement1
", batchBuilder.SqlBatches[0].Sql);

            Assert.Equal(
                @"Statement2
Statement3
", batchBuilder.SqlBatches[1].Sql);

            Assert.Equal(
                @"Statement4
Statement5
Statement6
", batchBuilder.SqlBatches[2].Sql);
        }
        public override void Generate(RenameSequenceOperation operation, IModel model, SqlBatchBuilder builder)
        {
            Check.NotNull(operation, nameof(operation));
            Check.NotNull(builder, nameof(builder));

            var separate = false;
            var name = operation.Name;
            if (operation.NewName != null)
            {
                var qualifiedName = new StringBuilder();
                if (operation.Schema != null)
                {
                    qualifiedName
                        .Append(operation.Schema)
                        .Append(".");
                }
                qualifiedName.Append(operation.Name);

                Rename(qualifiedName.ToString(), operation.NewName, builder);

                separate = true;
                name = operation.NewName;
            }

            if (operation.NewSchema != null)
            {
                if (separate)
                {
                    builder.AppendLine(_sql.BatchCommandSeparator);
                }

                Transfer(operation.NewSchema, operation.Schema, name, builder);
            }
        }
        public override void Generate(DropIndexOperation operation, IModel model, SqlBatchBuilder builder)
        {
            Check.NotNull(operation, nameof(operation));
            Check.NotNull(builder, nameof(builder));

            builder
                .Append("DROP INDEX ")
                .Append(_sql.DelimitIdentifier(operation.Name));
        }
        public override void Generate(RenameTableOperation operation, IModel model, SqlBatchBuilder builder)
        {
            Check.NotNull(operation, nameof(operation));
            Check.NotNull(builder, nameof(builder));

            if (operation.NewName != null)
            {
                builder
                    .Append("ALTER TABLE ")
                    .Append(_sql.DelimitIdentifier(operation.Name))
                    .Append(" RENAME TO ")
                    .Append(_sql.DelimitIdentifier(operation.NewName));
            }
        }
        public void SqlBatchBuilder_correctly_groups_multiple_statements_into_one_batch()
        {
            var batchBuilder = new SqlBatchBuilder();
            batchBuilder.AppendLine("Statement1");
            batchBuilder.AppendLine("Statement2");
            batchBuilder.AppendLine("Statement3");
            batchBuilder.EndBatch();

            Assert.Equal(1, batchBuilder.SqlBatches.Count);
            Assert.Equal(
                @"Statement1
Statement2
Statement3
", batchBuilder.SqlBatches[0].Sql);
        }
        public override void Generate(CreateTableOperation operation, IModel model, SqlBatchBuilder builder)
        {
            // Lifts a primary key definition into the typename.
            // This handles the quirks of creating integer primary keys using autoincrement, not default rowid behavior.
            if (operation.PrimaryKey?.Columns.Length == 1)
            {
                var columnOp = operation.Columns?.FirstOrDefault(o => o.Name == operation.PrimaryKey.Columns[0]);
                if (columnOp != null)
                {
                    columnOp.AddAnnotation(SqliteAnnotationNames.Prefix + SqliteAnnotationNames.InlinePrimaryKey, true);
                    operation.PrimaryKey = null;
                }
            }

            base.Generate(operation, model, builder);
        }
        public virtual IReadOnlyList<SqlBatch> Generate(
            IReadOnlyList<MigrationOperation> operations,
            IModel model = null)
        {
            Check.NotNull(operations, nameof(operations));

            var builder = new SqlBatchBuilder();
            foreach (var operation in operations)
            {
                Generate(operation, model, builder);
                builder.AppendLine(Sql.BatchCommandSeparator);
            }

            builder.EndBatch();

            return builder.SqlBatches;
        }
        protected override void Generate(MigrationOperation operation, IModel model, SqlBatchBuilder builder)
        {
            Check.NotNull(operation, nameof(operation));
            Check.NotNull(builder, nameof(builder));

            var createDatabaseOperation = operation as CreateDatabaseOperation;
            var dropDatabaseOperation = operation as DropDatabaseOperation;
            if (createDatabaseOperation != null)
            {
                Generate(createDatabaseOperation, model, builder);
            }
            else if (dropDatabaseOperation != null)
            {
                Generate(dropDatabaseOperation, model, builder);
            }
            else
            {
                base.Generate(operation, model, builder);
            }
        }
        public void SqlBatchBuilder_ignores_empty_batches()
        {
            var batchBuilder = new SqlBatchBuilder();
            batchBuilder.AppendLine("Statement1");
            batchBuilder.EndBatch();
            batchBuilder.EndBatch();
            batchBuilder.EndBatch();
            batchBuilder.AppendLine("Statement2");
            batchBuilder.AppendLine("Statement3");
            batchBuilder.EndBatch();
            batchBuilder.EndBatch();

            Assert.Equal(2, batchBuilder.SqlBatches.Count);

            Assert.Equal(
                @"Statement1
", batchBuilder.SqlBatches[0].Sql);

            Assert.Equal(
                @"Statement2
Statement3
", batchBuilder.SqlBatches[1].Sql);
        }
        protected override void ColumnDefinition(
            string schema,
            string table,
            string name,
            Type clrType,
            string type,
            bool nullable,
            object defaultValue,
            string defaultValueSql,
            string computedColumnSql,
            IAnnotatable annotatable,
            IModel model,
            SqlBatchBuilder builder)
        {
            base.ColumnDefinition(
                schema, table, name, clrType, type, nullable,
                defaultValue, defaultValueSql, computedColumnSql, annotatable, model, builder);

            var inlinePk = annotatable[SqliteAnnotationNames.Prefix + SqliteAnnotationNames.InlinePrimaryKey] as bool?;
            if (inlinePk == true)
            {
                var inlinePkName = annotatable[
                    SqliteAnnotationNames.Prefix + SqliteAnnotationNames.InlinePrimaryKeyName] as string;
                if (!string.IsNullOrEmpty(inlinePkName))
                {
                    builder
                        .Append(" CONSTRAINT ")
                        .Append(Sql.DelimitIdentifier(inlinePkName));
                }
                builder.Append(" PRIMARY KEY");
                var autoincrement = annotatable[SqliteAnnotationNames.Prefix + SqliteAnnotationNames.Autoincrement] as bool?;
                if (autoincrement == true)
                {
                    builder.Append(" AUTOINCREMENT");
                }
            }
        }
 public override void Generate(DropSequenceOperation operation, IModel model, SqlBatchBuilder builder)
 {
     throw new NotSupportedException(Strings.SequencesNotSupported);
 }
 public override void Generate(CreateSchemaOperation operation, IModel model, SqlBatchBuilder builder)
 {
     throw new NotSupportedException(Strings.SchemasNotSupported);
 }
 public override void Generate(AlterColumnOperation operation, IModel model, SqlBatchBuilder builder)
 {
     throw new NotSupportedException(Strings.InvalidMigrationOperation);
 }
 public override void Generate(DropUniqueConstraintOperation operation, IModel model, SqlBatchBuilder builder)
 {
     throw new NotSupportedException(Strings.InvalidMigrationOperation);
 }
 protected override void Generate(AlterColumnOperation operation, IModel model, SqlBatchBuilder builder)
 {
 }
        protected override void Generate(EnsureSchemaOperation operation, IModel model, SqlBatchBuilder builder)
        {
            Check.NotNull(operation, nameof(operation));
            Check.NotNull(builder, nameof(builder));

            if (string.Equals(operation.Name, "DBO", StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            builder
                .Append("IF SCHEMA_ID(N")
                .Append(Sql.GenerateLiteral(operation.Name))
                .Append(") IS NULL EXEC(N'CREATE SCHEMA ")
                .Append(Sql.DelimitIdentifier(operation.Name))
                .Append("')");
        }
 protected override void Generate(RenameIndexOperation operation, IModel model, SqlBatchBuilder builder)
 {
     throw new NotSupportedException(Strings.InvalidMigrationOperation);
 }
        protected override void ForeignKeyAction(ReferentialAction referentialAction, SqlBatchBuilder builder)
        {
            Check.NotNull(builder, nameof(builder));

            if (referentialAction == ReferentialAction.Restrict)
            {
                builder.Append("NO ACTION");
            }
            else
            {
                base.ForeignKeyAction(referentialAction, builder);
            }
        }
        protected override void IndexTraits(MigrationOperation operation, IModel model, SqlBatchBuilder builder)
        {
            Check.NotNull(operation, nameof(operation));
            Check.NotNull(builder, nameof(builder));

            var clustered = operation[SqlServerAnnotationNames.Prefix + SqlServerAnnotationNames.Clustered] as bool?;
            if (clustered.HasValue)
            {
                builder.Append(clustered.Value ? "CLUSTERED " : "NONCLUSTERED ");
            }
        }
        protected override void ColumnDefinition(
            string schema,
            string table,
            string name,
            Type clrType,
            string type,
            bool nullable,
            object defaultValue,
            string defaultValueSql,
            string computedColumnSql,
            IAnnotatable annotatable,
            IModel model,
            SqlBatchBuilder builder)
        {
            Check.NotEmpty(name, nameof(name));
            Check.NotNull(clrType, nameof(clrType));
            Check.NotNull(annotatable, nameof(annotatable));
            Check.NotNull(builder, nameof(builder));

            if (computedColumnSql != null)
            {
                builder
                    .Append(Sql.DelimitIdentifier(name))
                    .Append(" AS ")
                    .Append(computedColumnSql);

                return;
            }

            base.ColumnDefinition(
                schema,
                table,
                name,
                clrType,
                type,
                nullable,
                defaultValue,
                defaultValueSql,
                computedColumnSql,
                annotatable,
                model,
                builder);

            var valueGenerationStrategy = annotatable[
                SqlServerAnnotationNames.Prefix + SqlServerAnnotationNames.ValueGenerationStrategy] as SqlServerIdentityStrategy?;
            if (valueGenerationStrategy == SqlServerIdentityStrategy.IdentityColumn)
            {
                builder.Append(" IDENTITY");
            }
        }
        public void SqlBatchBuilder_correctly_splits_statements_to_multiple_batches_when_transaction_is_suppressed()
        {
            var batchBuilder = new SqlBatchBuilder();
            batchBuilder.AppendLine("Statement1");
            batchBuilder.AppendLine("Statement2");
            batchBuilder.AppendLine("Statement3", suppressTransaction: true);
            batchBuilder.AppendLine("Statement4");
            batchBuilder.AppendLine("Statement5");
            batchBuilder.AppendLine("Statement6", suppressTransaction: true);
            batchBuilder.AppendLine("Statement7", suppressTransaction: true);
            batchBuilder.EndBatch();

            Assert.Equal(2, batchBuilder.SqlBatches.Count);
            Assert.False(batchBuilder.SqlBatches[0].SuppressTransaction);
            Assert.Equal(
                @"Statement1
Statement2
", batchBuilder.SqlBatches[0].Sql);

            Assert.True(batchBuilder.SqlBatches[1].SuppressTransaction);
            Assert.Equal(
                @"Statement3
Statement4
Statement5
Statement6
Statement7
", batchBuilder.SqlBatches[1].Sql);
        }
 protected override void Generate(EnsureSchemaOperation operation, IModel model, SqlBatchBuilder builder)
 {
 }
 protected override void Generate(RenameIndexOperation operation, IModel model, SqlBatchBuilder builder)
 {
 }
 protected override void Generate(RenameSequenceOperation operation, IModel model, SqlBatchBuilder builder)
 {
     throw new NotSupportedException(Strings.SequencesNotSupported);
 }
        public override void IndexTraits(MigrationOperation operation, IModel model, SqlBatchBuilder builder)
        {
            Check.NotNull(operation, nameof(operation));
            Check.NotNull(builder, nameof(builder));

            var clustered = (string)operation[SqlServerAnnotationNames.Prefix + SqlServerAnnotationNames.Clustered];
            if (clustered != null)
            {
                builder.Append(clustered == "True" ? "CLUSTERED " : "NONCLUSTERED ");
            }
        }