public void CreateWithCorrelation(BuildSqlVarient sqlVarient)
    {
        var saga = new SagaDefinition(
            name: "theSaga",
            tableSuffix: "theSaga",
            correlationProperty: new CorrelationProperty
            (
                name: "CorrelationProperty",
                type: CorrelationPropertyType.String
            )
        );

        var builder = new StringBuilder();
        using (var writer = new StringWriter(builder))
        {
            SagaScriptBuilder.BuildCreateScript(saga, sqlVarient, writer);
        }
        var script = builder.ToString();

        if (sqlVarient != BuildSqlVarient.MySql)
        {
            SqlValidator.Validate(script);
        }
        using (ApprovalResults.ForScenario(sqlVarient))
        {
            Approvals.Verify(script);
        }
    }
 public static string BuildCreateScript(SagaDefinition saga, BuildSqlVarient sqlVarient)
 {
     var stringBuilder = new StringBuilder();
     using (var stringWriter = new StringWriter(stringBuilder))
     {
         BuildCreateScript(saga, sqlVarient, stringWriter);
     }
     return stringBuilder.ToString();
 }
        public static void BuildDropScript(SagaDefinition saga, BuildSqlVariant sqlVariant, TextWriter writer)
        {
            var sqlVariantWriter = GetSqlVariantWriter(sqlVariant, writer, saga);

            WriteComment(writer, "TableNameVariable");
            sqlVariantWriter.WriteTableNameVariable();

            WriteComment(writer, "DropTable");
            sqlVariantWriter.WriteDropTable();
        }
        public static string BuildCreateScript(SagaDefinition saga, BuildSqlVariant sqlVariant)
        {
            var stringBuilder = new StringBuilder();

            using (var stringWriter = new StringWriter(stringBuilder))
            {
                BuildCreateScript(saga, sqlVariant, stringWriter);
            }
            return(stringBuilder.ToString());
        }
        public static string BuildDropScript(SagaDefinition saga, BuildSqlDialect sqlDialect)
        {
            var stringBuilder = new StringBuilder();

            using (var stringWriter = new StringWriter(stringBuilder))
            {
                BuildDropScript(saga, sqlDialect, stringWriter);
            }
            return(stringBuilder.ToString());
        }
        public static void BuildCreateScript(SagaDefinition saga, BuildSqlVariant sqlVariant, TextWriter writer)
        {
            Guard.AgainstNull(nameof(saga), saga);
            Guard.AgainstNull(nameof(writer), writer);

            SagaDefinitionValidator.ValidateSagaDefinition(
                correlationProperty: saga.CorrelationProperty?.Name,
                sagaName: saga.Name,
                tableSuffix: saga.TableSuffix,
                transitionalProperty: saga.TransitionalCorrelationProperty?.Name);

            var sqlVariantWriter = GetSqlVariantWriter(sqlVariant, writer, saga);

            WriteComment(writer, "TableNameVariable");
            sqlVariantWriter.WriteTableNameVariable();

            WriteComment(writer, "Initialize");
            sqlVariantWriter.Initialize();

            WriteComment(writer, "CreateTable");
            sqlVariantWriter.WriteCreateTable();
            if (saga.CorrelationProperty != null)
            {
                WriteComment(writer, $"AddProperty {saga.CorrelationProperty.Name}");
                sqlVariantWriter.AddProperty(saga.CorrelationProperty);

                WriteComment(writer, $"VerifyColumnType {saga.CorrelationProperty.Type}");
                sqlVariantWriter.VerifyColumnType(saga.CorrelationProperty);

                WriteComment(writer, $"WriteCreateIndex {saga.CorrelationProperty.Name}");
                sqlVariantWriter.WriteCreateIndex(saga.CorrelationProperty);
            }
            if (saga.TransitionalCorrelationProperty != null)
            {
                WriteComment(writer, $"AddProperty {saga.TransitionalCorrelationProperty.Name}");
                sqlVariantWriter.AddProperty(saga.TransitionalCorrelationProperty);

                WriteComment(writer, $"VerifyColumnType {saga.TransitionalCorrelationProperty.Type}");
                sqlVariantWriter.VerifyColumnType(saga.TransitionalCorrelationProperty);

                WriteComment(writer, $"CreateIndex {saga.TransitionalCorrelationProperty.Name}");
                sqlVariantWriter.WriteCreateIndex(saga.TransitionalCorrelationProperty);
            }
            WriteComment(writer, "PurgeObsoleteIndex");
            sqlVariantWriter.WritePurgeObsoleteIndex();

            WriteComment(writer, "PurgeObsoleteProperties");
            sqlVariantWriter.WritePurgeObsoleteProperties();

            WriteComment(writer, "CompleteSagaScript");
            sqlVariantWriter.CreateComplete();
        }
        static ISagaScriptWriter GetSqlVarientWriter(BuildSqlVarient sqlVarient, TextWriter textWriter, SagaDefinition saga)
        {
            if (sqlVarient == BuildSqlVarient.MsSqlServer)
            {
                return new MsSqlServerSagaScriptWriter(textWriter, saga);
            }
            if (sqlVarient == BuildSqlVarient.MySql)
            {
                return new MySqlSagaScriptWriter(textWriter, saga);
            }

            throw new Exception($"Unknown SqlVarient {sqlVarient}.");
        }
        public static void BuildCreateScript(SagaDefinition saga, BuildSqlVarient sqlVarient, TextWriter writer)
        {
            Guard.AgainstNull(nameof(saga), saga);
            Guard.AgainstNull(nameof(writer), writer);

            SagaDefinitionValidator.ValidateSagaDefinition(
                correlationProperty: saga.CorrelationProperty?.Name,
                sagaName: saga.Name,
                tableSuffix: saga.TableSuffix,
                transitionalProperty: saga.TransitionalCorrelationProperty?.Name);

            var sqlVarientWriter = GetSqlVarientWriter(sqlVarient, writer, saga);

            WriteComment(writer, "TableNameVariable");
            sqlVarientWriter.WriteTableNameVariable();

            WriteComment(writer, "CreateTable");
            sqlVarientWriter.WriteCreateTable();
            if (saga.CorrelationProperty != null)
            {
                WriteComment(writer, $"AddProperty {saga.CorrelationProperty.Name}");
                sqlVarientWriter.AddProperty(saga.CorrelationProperty);

                WriteComment(writer, $"VerifyColumnType {saga.CorrelationProperty.Type}");
                sqlVarientWriter.VerifyColumnType(saga.CorrelationProperty);

                WriteComment(writer, $"WriteCreateIndex {saga.CorrelationProperty.Name}");
                sqlVarientWriter.WriteCreateIndex(saga.CorrelationProperty);
            }
            if (saga.TransitionalCorrelationProperty != null)
            {
                WriteComment(writer, $"AddProperty {saga.TransitionalCorrelationProperty.Name}");
                sqlVarientWriter.AddProperty(saga.TransitionalCorrelationProperty);

                WriteComment(writer, $"VerifyColumnType {saga.TransitionalCorrelationProperty.Type}");
                sqlVarientWriter.VerifyColumnType(saga.TransitionalCorrelationProperty);

                WriteComment(writer, $"CreateIndex {saga.TransitionalCorrelationProperty.Name}");
                sqlVarientWriter.WriteCreateIndex(saga.TransitionalCorrelationProperty);
            }
            WriteComment(writer, "PurgeObsoleteIndex");
            sqlVarientWriter.WritePurgeObsoleteIndex();

            WriteComment(writer, "PurgeObsoleteProperties");
            sqlVarientWriter.WritePurgeObsoleteProperties();
        }
        public static void BuildDropScript(SagaDefinition saga, BuildSqlVarient sqlVarient, TextWriter writer)
        {
            var sqlVarientWriter = GetSqlVarientWriter(sqlVarient, writer, saga);

            WriteComment(writer, "TableNameVariable");
            sqlVarientWriter.WriteTableNameVariable();

            WriteComment(writer, "DropTable");
            sqlVarientWriter.WriteDropTable();
        }
 public MySqlSagaScriptWriter(TextWriter textWriter, SagaDefinition saga)
 {
     writer = textWriter;
     this.saga = saga;
 }
        static ISagaScriptWriter GetSqlVariantWriter(BuildSqlVariant sqlVariant, TextWriter textWriter, SagaDefinition saga)
        {
            if (sqlVariant == BuildSqlVariant.MsSqlServer)
            {
                return(new MsSqlServerSagaScriptWriter(textWriter, saga));
            }
            if (sqlVariant == BuildSqlVariant.MySql)
            {
                return(new MySqlSagaScriptWriter(textWriter, saga));
            }
            if (sqlVariant == BuildSqlVariant.Oracle)
            {
                return(new OracleSagaScriptWriter(textWriter, saga));
            }

            throw new Exception($"Unknown SqlVariant {sqlVariant}.");
        }
    public void BuildDropScript(BuildSqlVarient sqlVarient)
    {
        var builder = new StringBuilder();
        using (var writer = new StringWriter(builder))
        {
            var saga = new SagaDefinition(
                tableSuffix: "theSaga",
                name: "theSaga"
            );
            SagaScriptBuilder.BuildDropScript(saga, sqlVarient, writer);
        }
        var script = builder.ToString();
        if (sqlVarient == BuildSqlVarient.MsSqlServer)
        {
            SqlValidator.Validate(script);
        }

        using (ApprovalResults.ForScenario(sqlVarient))
        {
            Approvals.Verify(script);
        }
    }
    public static bool TryGetSqlSagaDefinition(TypeDefinition type, out SagaDefinition definition)
    {
        var typeFullName = type.FullName;
        var attribute = type.GetSingleAttribute("NServiceBus.Persistence.Sql.SqlSagaAttribute");
        if (attribute == null)
        {
            if (!type.IsAbstract && type.BaseType != null)
            {
                var baseTypeFullName = type.BaseType.FullName;
                if (baseTypeFullName.StartsWith("NServiceBus.Saga"))
                {
                    throw new ErrorsException($"The type '{typeFullName}' inherits from NServiceBus.Saga but is missing a [SqlSagaAttribute].");
                }
                if (baseTypeFullName.StartsWith("NServiceBus.Persistence.Sql.SqlSaga"))
                {
                    throw new ErrorsException($"The type '{typeFullName}' inherits from NServiceBus.Persistence.Sql.SqlSaga but is missing a [SqlSagaAttribute].");
                }
            }
            definition = null;
            return false;
        }
        if (type.HasGenericParameters)
        {
            throw new ErrorsException($"The type '{typeFullName}' has a [SqlSagaAttribute] but has generic parameters.");
        }
        if (type.IsAbstract)
        {
            throw new ErrorsException($"The type '{typeFullName}' has a [SqlSagaAttribute] but has is abstract.");
        }

        var arguments = attribute.ConstructorArguments;
        var correlation = (string)arguments[0].Value;
        var transitional = (string)arguments[1].Value;
        var tableSuffix = (string)arguments[2].Value;
        SagaDefinitionValidator.ValidateSagaDefinition(correlation, typeFullName, transitional, tableSuffix);
        
        if (tableSuffix == null)
        {
            tableSuffix = type.Name;
        }

        var sagaDataType = GetSagaDataTypeFromSagaType(type);

        definition = new SagaDefinition
        (
            correlationProperty: BuildConstraintProperty(sagaDataType, correlation),
            transitionalCorrelationProperty: BuildConstraintProperty(sagaDataType, transitional),
            tableSuffix: tableSuffix,
            name: type.FullName
        );
        return true;
    }