public static bool TryGetSqlSagaDefinition(TypeDefinition type, out SagaDefinition definition)
    {
        ValidateIsNotDirectSaga(type);
        if (!IsSqlSaga(type))
        {
            definition = null;
            return(false);
        }
        CheckIsValidSaga(type);

        var correlation  = GetCorrelationPropertyName(type);
        var transitional = GetTransitionalCorrelationPropertyName(type);
        var tableSuffix  = GetTableSuffix(type);

        SagaDefinitionValidator.ValidateSagaDefinition(correlation, type.FullName, 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);
    }
    public void WithTransitionalAndNoCorrelation()
    {
        var errorsException = Assert.Throws <ErrorsException>(() => SagaDefinitionValidator.ValidateSagaDefinition(null, "saga1", "Transitional", "tableSuffix"));

        Assert.IsNotNull(errorsException.Message);
        Approver.Verify(errorsException.Message);
    }
    public void WithInvalidSuffixTick()
    {
        var errorsException = Assert.Throws <ErrorsException>(() => SagaDefinitionValidator.ValidateSagaDefinition("Correlation", "saga1", "Transitional", "table`Suffix"));

        Assert.IsNotNull(errorsException.Message);
#if NET452
        Approvals.Verify(errorsException.Message);
#endif
    }
        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 bool TryGetCoreSagaDefinition(TypeDefinition type, out SagaDefinition definition)
    {
        var baseType = type.BaseType as GenericInstanceType;

        definition = null;

        // Class must directly inherit from NServiceBus.Saga<T> so that no tricks can be pulled from an intermediate class
        if (baseType == null || !baseType.FullName.StartsWith("NServiceBus.Saga") || baseType.GenericArguments.Count != 1)
        {
            return(false);
        }

        CheckIsValidSaga(type);

        string correlationId  = null;
        string transitionalId = null;
        string tableSuffix    = null;

        var attribute = type.GetSingleAttribute("NServiceBus.Persistence.Sql.SqlSagaAttribute");

        if (attribute != null)
        {
            var args = attribute.ConstructorArguments;
            correlationId  = (string)args[0].Value;
            transitionalId = (string)args[1].Value;
            tableSuffix    = (string)args[2].Value;
        }

        var sagaDataType = GetSagaDataTypeFromSagaType(type);

        if (correlationId == null)
        {
            correlationId = GetCoreSagaCorrelationId(type, sagaDataType);
        }

        SagaDefinitionValidator.ValidateSagaDefinition(correlationId, type.FullName, transitionalId, tableSuffix);

        if (tableSuffix == null)
        {
            tableSuffix = type.Name;
        }

        definition = new SagaDefinition
                     (
            correlationProperty: BuildConstraintProperty(sagaDataType, correlationId),
            transitionalCorrelationProperty: BuildConstraintProperty(sagaDataType, transitionalId),
            tableSuffix: tableSuffix,
            name: type.FullName
                     );
        return(true);
    }
    static bool TryGetSqlSagaDefinition(TypeDefinition type, out SagaDefinition definition)
    {
        if (!IsSqlSaga(type))
        {
            definition = null;
            return(false);
        }
        CheckIsValidSaga(type);

        if (type.GetSingleAttribute("NServiceBus.Persistence.Sql.SqlSagaAttribute") != null)
        {
            throw new Exception("[SqlSaga] attribute is invalid on a class inheriting SqlSaga<T>. To provide CorrelationId, TransitionalCorrelationId, or TableSuffix override the corresponding properties on the SqlSaga<T> base class instead.");
        }

        var correlation  = GetCorrelationPropertyName(type);
        var transitional = GetTransitionalCorrelationPropertyName(type);
        var tableSuffix  = GetSqlSagaTableSuffix(type);

        SagaDefinitionValidator.ValidateSagaDefinition(correlation, type.FullName, 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);
    }
 public void WithNoTransitionalCorrelation()
 {
     SagaDefinitionValidator.ValidateSagaDefinition("Correlation", "saga1", null, "tableSuffix");
 }
 public void WithNoCorrelation()
 {
     SagaDefinitionValidator.ValidateSagaDefinition(null, "saga1", null, "tableSuffix");
 }
 public void Simple()
 {
     SagaDefinitionValidator.ValidateSagaDefinition("Correlation", "saga1", "Transitional", "tableSuffix");
 }
    public void WithInvalidSuffixRight()
    {
        var errorsException = Assert.Throws <ErrorsException>(() => SagaDefinitionValidator.ValidateSagaDefinition("Correlation", "saga1", "Transitional", "table]Suffix"));

        Approvals.Verify(errorsException.Message);
    }
    public void WithMatchingIds()
    {
        var errorsException = Assert.Throws <ErrorsException>(() => SagaDefinitionValidator.ValidateSagaDefinition("Transitional", "saga1", "Transitional", "tableSuffix"));

        Approvals.Verify(errorsException.Message);
    }