public void VerifyColumnType(CorrelationProperty correlationProperty)
    {
        var columnType = MySqlCorrelationPropertyTypeConverter.GetColumnType(correlationProperty.Type);
        var name       = correlationProperty.Name;

        writer.Write($@"
set @column_type_{name} = (
  select concat(column_type,' character set ', character_set_name)
  from information_schema.columns
  where
    table_schema = database() and
    table_name = @tableNameNonQuoted and
    column_name = 'Correlation_{name}'
);

set @query = IF(
    @column_type_{name} <> '{columnType}',
    'call sqlpersistence_raiseerror(concat(\'Incorrect data type for Correlation_{name}. Expected {columnType} got \', @column_type_{name}, \'.\'));',
    'select \'Column Type OK\' status');

prepare script from @query;
execute script;
deallocate prepare script;
");
    }
Exemplo n.º 2
0
    static void TrySetCorrelationPropertyValue(ISagaData newSagaData, CorrelationProperty correlationProperty, object body, ITransactionContext transactionContext)
    {
        try
        {
            if (IgnoredProperties.Contains(correlationProperty.PropertyName))
            {
                return;
            }

            var correlationPropertyInfo = newSagaData.GetType().GetProperty(correlationProperty.PropertyName);

            if (correlationPropertyInfo == null)
            {
                return;
            }

            var valueFromMessage = correlationProperty.ValueFromMessage(new MessageContext(transactionContext), body);

            correlationPropertyInfo.SetValue(newSagaData, valueFromMessage);
        }
        catch (Exception)
        {
            // if this fails it might be because the property is not settable.... just leave it to the programmer in the other end to set it
        }
    }
    public void VerifyColumnType(CorrelationProperty correlationProperty)
    {
        string columnType;

        if (correlationProperty.Type == CorrelationPropertyType.String)
        {
            columnType = "character varying";
        }
        else
        {
            columnType = PostgreSqlCorrelationPropertyTypeConverter.GetColumnType(correlationProperty.Type);
        }

        var name = correlationProperty.Name;

        writer.Write($@"
        columnType := (
            select data_type
            from information_schema.columns
            where
            table_schema = schema and
            table_name = tableNameNonQuoted and
            column_name = 'Correlation_{name}'
        );
        if columnType <> '{columnType}' then
            raise exception 'Incorrect data type for Correlation_{name}. Expected ""{columnType}"" got ""%""', columnType;
        end if;
");
    }
Exemplo n.º 4
0
    public void VerifyColumnType(CorrelationProperty correlationProperty)
    {
        var columnType = OracleCorrelationPropertyTypeConverter.GetColumnType(correlationProperty.Type);
        var name       = OracleCorrelationPropertyName(correlationProperty);

        writer.Write($@"
select data_type ||
  case when char_length > 0 then
    '(' || char_length || ')'
  else
    case when data_precision is not null then
      '(' || data_precision ||
        case when data_scale is not null and data_scale > 0 then
          ',' || data_scale
        end || ')'
    end
  end into dataType
from all_tab_columns
where table_name = '{tableName}' and column_name = '{name}' and owner = currentSchema;

if(dataType <> '{columnType}')
then
  raise_application_error(-20000, 'Incorrect data type for Correlation_{name}.  Expected ""{columnType}"" got ""' || dataType || '"".');
end if;
");
    }
Exemplo n.º 5
0
    public void VerifyColumnType(CorrelationProperty correlationProperty)
    {
        string columnType;
        if (correlationProperty.Type == CorrelationPropertyType.String)
        {
            columnType = "nvarchar";
        }
        else
        {
            columnType = MsSqlServerCorrelationPropertyTypeConverter.GetColumnType(correlationProperty.Type);
        }
        var name = correlationProperty.Name;
        writer.Write($@"
declare @dataType_{name} nvarchar(max);
set @dataType_{name} = (
  select data_type
  from INFORMATION_SCHEMA.COLUMNS
  where
    table_name = @tableNameWithoutSchema and
    table_schema = @schema and
    column_name = 'Correlation_{name}'
);
if (@dataType_{name} <> '{columnType}')
  begin
    declare @error_{name} nvarchar(max) = N'Incorrect data type for Correlation_{name}. Expected {columnType} got ' + @dataType_{name} + '.';
    throw 50000, @error_{name}, 0
  end
");
    }
    public void WriteCreateIndex(CorrelationProperty correlationProperty)
    {
        var indexName = CreateSagaIndexName(saga.TableSuffix, correlationProperty.Name);

        writer.Write($@"
        script = 'create unique index if not exists ""' || tablePrefix || '{indexName}"" on ""' || schema || '"".""' || tableNameNonQuoted || '"" using btree (""Correlation_{correlationProperty.Name}"" asc);';
        execute script;"
                     );
    }
 public SagaDefinition(string tableSuffix, string name, CorrelationProperty correlationProperty = null, CorrelationProperty transitionalCorrelationProperty = null)
 {
     Guard.AgainstNullAndEmpty(nameof(tableSuffix), tableSuffix);
     Guard.AgainstNullAndEmpty(nameof(name), name);
     TableSuffix                     = tableSuffix;
     Name                            = name;
     CorrelationProperty             = correlationProperty;
     TransitionalCorrelationProperty = transitionalCorrelationProperty;
 }
 public SagaDefinition(string tableSuffix, string name, CorrelationProperty correlationProperty = null, CorrelationProperty transitionalCorrelationProperty = null)
 {
     Guard.AgainstNullAndEmpty(nameof(tableSuffix), tableSuffix);
     Guard.AgainstNullAndEmpty(nameof(name), name);
     TableSuffix = tableSuffix;
     Name = name;
     CorrelationProperty = correlationProperty;
     TransitionalCorrelationProperty = transitionalCorrelationProperty;
 }
Exemplo n.º 9
0
    string OracleCorrelationPropertyName(CorrelationProperty property)
    {
        var name = "CORR_" + property.Name.ToUpper();

        if (name.Length > 30)
        {
            name = name.Substring(0, 30);
        }
        return(name);
    }
    public void AddProperty(CorrelationProperty correlationProperty)
    {
        var columnType = PostgreSqlCorrelationPropertyTypeConverter.GetColumnType(correlationProperty.Type);
        var name       = correlationProperty.Name;

        writer.Write($@"
        script = 'alter table ""' || schema || '"".""' || tableNameNonQuoted || '"" add column if not exists ""Correlation_{name}"" {columnType}';
        execute script;
");
    }
Exemplo n.º 11
0
    public void WriteCreateIndex(CorrelationProperty correlationProperty)
    {
        var columnName = OracleCorrelationPropertyName(correlationProperty);
        var indexName  = CreateSagaIndexName(tableName, correlationProperty.Name);

        writer.Write($@"
select count(*) into n from user_indexes where table_name = '{tableName}' and index_name = '{indexName}';
if(n = 0)
then
  sqlStatement := 'create unique index ""{indexName}"" on ""{tableName}"" ({columnName} ASC)';

  execute immediate sqlStatement;
end if;
");
    }
Exemplo n.º 12
0
    public void AddProperty(CorrelationProperty correlationProperty)
    {
        var columnType = OracleCorrelationPropertyTypeConverter.GetColumnType(correlationProperty.Type);
        var name       = OracleCorrelationPropertyName(correlationProperty);

        writer.Write($@"
select count(*) into n from all_tab_columns where table_name = '{tableName}' and column_name = '{name}' and owner = currentSchema;
if(n = 0)
then
  sqlStatement := 'alter table ""{tableName}"" add ( {name} {columnType} )';

  execute immediate sqlStatement;
end if;
");
    }
    public static SagaDefinition GetSagaDefinition(Type sagaType, BuildSqlDialect sqlDialect)
    {
        if (SagaTypeHasIntermediateBaseClass(sagaType))
        {
            throw new Exception("Saga implementations must inherit from either Saga<T> or SqlSaga<T> directly. Deep class hierarchies are not supported.");
        }

        var saga   = (Saga)FormatterServices.GetUninitializedObject(sagaType);
        var mapper = new ConfigureHowToFindSagaWithMessage();

        methodInfo.Invoke(saga, new object[]
        {
            mapper
        });
        CorrelationProperty correlationProperty = null;

        if (mapper.CorrelationType != null)
        {
            correlationProperty = new CorrelationProperty(
                name: mapper.CorrelationProperty,
                type: CorrelationPropertyTypeReader.GetCorrelationPropertyType(mapper.CorrelationType));
        }

        var transitionalCorrelationPropertyName = GetSagaMetadataProperty(sagaType, saga, "TransitionalCorrelationPropertyName", att => att.TransitionalCorrelationProperty);

        CorrelationProperty transitional = null;

        if (transitionalCorrelationPropertyName != null)
        {
            var sagaDataType         = sagaType.BaseType.GetGenericArguments()[0];
            var transitionalProperty = sagaDataType.GetProperty(transitionalCorrelationPropertyName, AnyInstanceMember);
            transitional = new CorrelationProperty(transitionalCorrelationPropertyName, CorrelationPropertyTypeReader.GetCorrelationPropertyType(transitionalProperty.PropertyType));
        }

        var tableSuffixOverride = GetSagaMetadataProperty(sagaType, saga, "TableSuffix", att => att.TableSuffix);
        var tableSuffix         = tableSuffixOverride ?? sagaType.Name;

        if (sqlDialect == BuildSqlDialect.Oracle)
        {
            tableSuffix = tableSuffix.Substring(0, Math.Min(27, tableSuffix.Length));
        }

        return(new SagaDefinition(
                   tableSuffix: tableSuffix,
                   name: sagaType.FullName,
                   correlationProperty: correlationProperty,
                   transitionalCorrelationProperty: transitional));
    }
    public static SagaDefinition GetSagaDefinition(Type sagaType, BuildSqlDialect sqlDialect)
    {
        var saga   = (Saga)FormatterServices.GetUninitializedObject(sagaType);
        var mapper = new ConfigureHowToFindSagaWithMessage();

        methodInfo.Invoke(saga, new object[]
        {
            mapper
        });
        CorrelationProperty correlationProperty = null;

        if (mapper.CorrelationType != null)
        {
            correlationProperty = new CorrelationProperty(
                name: mapper.CorrelationProperty,
                type: CorrelationPropertyTypeReader.GetCorrelationPropertyType(mapper.CorrelationType));
        }
        var transitionalCorrelationPropertyName = (string)sagaType
                                                  .GetProperty("TransitionalCorrelationPropertyName", AnyInstanceMember)
                                                  .GetValue(saga);


        CorrelationProperty transitional = null;

        if (transitionalCorrelationPropertyName != null)
        {
            var sagaDataType         = sagaType.BaseType.GetGenericArguments()[0];
            var transitionalProperty = sagaDataType.GetProperty(transitionalCorrelationPropertyName, AnyInstanceMember);
            transitional = new CorrelationProperty(transitionalCorrelationPropertyName, CorrelationPropertyTypeReader.GetCorrelationPropertyType(transitionalProperty.PropertyType));
        }

        var tableSuffixOverride = (string)sagaType.GetProperty("TableSuffix", AnyInstanceMember).GetValue(saga);
        var tableSuffix         = tableSuffixOverride ?? sagaType.Name;

        if (sqlDialect == BuildSqlDialect.Oracle)
        {
            tableSuffix = tableSuffix.Substring(0, Math.Min(27, tableSuffix.Length));
        }

        return(new SagaDefinition(
                   tableSuffix: tableSuffix,
                   name: sagaType.FullName,
                   correlationProperty: correlationProperty,
                   transitionalCorrelationProperty: transitional));
    }
Exemplo n.º 15
0
    public void AddProperty(CorrelationProperty correlationProperty)
    {
        var columnType = MsSqlServerCorrelationPropertyTypeConverter.GetColumnType(correlationProperty.Type);
        var name = correlationProperty.Name;
        writer.Write($@"
if not exists
(
  select * from sys.columns
  where
    name = N'Correlation_{name}' and
    object_id = object_id(@tableName)
)
begin
  declare @createColumn_{name} nvarchar(max);
  set @createColumn_{name} = '
  alter table ' + @tableName + N'
    add Correlation_{name} {columnType};';
  exec(@createColumn_{name});
end
");
    }
    public void VerifyColumnType(CorrelationProperty correlationProperty)
    {
        var columnType = MsSqlServerCorrelationPropertyTypeConverter.GetColumnType(correlationProperty.Type);
        var name       = correlationProperty.Name;

        writer.Write($@"
declare @dataType_{name} nvarchar(max);
set @dataType_{name} = (
  select data_type
  from information_schema.columns
  where
    table_name = ' + @tableName + N' and
    column_name = 'Correlation_{name}'
);
if (@dataType_{name} <> '{columnType}')
  begin
    declare @error_{name} nvarchar(max) = N'Incorrect data type for Correlation_{name}. Expected {columnType} got ' + @dataType_{name} + '.';
    throw 50000, @error_{name}, 0
  end
");
    }
    public void AddProperty(CorrelationProperty correlationProperty)
    {
        var columnType = MySqlCorrelationPropertyTypeConverter.GetColumnType(correlationProperty.Type);
        var name       = correlationProperty.Name;

        writer.Write($@"
select count(*)
into @exist
from information_schema.columns
where table_schema = database() and
      column_name = 'Correlation_{name}' and
      table_name = @tableNameNonQuoted;

set @query = IF(
    @exist <= 0,
    concat('alter table ', @tableNameQuoted, ' add column Correlation_{name} {columnType}'), 'select \'Column Exists\' status');

prepare script from @query;
execute script;
deallocate prepare script;
");
    }
Exemplo n.º 18
0
    public void WriteCreateIndex(CorrelationProperty correlationProperty)
    {
        var name = correlationProperty.Name;
        writer.Write($@"
if not exists
(
    select *
    from sys.indexes
    where
        name = N'Index_Correlation_{name}' and
        object_id = object_id(@tableName)
)
begin
  declare @createIndex_{name} nvarchar(max);
  set @createIndex_{name} = N'
  create unique index Index_Correlation_{name}
  on ' + @tableName + N'(Correlation_{name})
  where Correlation_{name} is not null;';
  exec(@createIndex_{name});
end
");
    }
    public void WriteCreateIndex(CorrelationProperty correlationProperty)
    {
        var name = correlationProperty.Name;

        writer.Write($@"
select count(*)
into @exist
from information_schema.statistics
where
    table_schema = database() and
    index_name = 'Index_Correlation_{name}' and
    table_name = @tableNameNonQuoted;

set @query = IF(
    @exist <= 0,
    concat('create unique index Index_Correlation_{name} on ', @tableNameQuoted, '(Correlation_{name})'), 'select \'Index Exists\' status');

prepare script from @query;
execute script;
deallocate prepare script;
");
    }
Exemplo n.º 20
0
        private static void ValidateCorrelation(ICollection <CorrelationProperty> initializerProperties, ICollection <CorrelationProperty> followerProperties, string memberName, Activity activity)
        {
            if (followerProperties == null && initializerProperties == null)
            {
                return;
            }

            if (followerProperties == null || initializerProperties == null)
            {
                throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationViolationException, memberName, activity.QualifiedName));
            }

            if (initializerProperties.Count != followerProperties.Count)
            {
                throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationViolationException, memberName, activity.QualifiedName));
            }

            IEnumerator <CorrelationProperty> initializerValues = initializerProperties.GetEnumerator();
            IEnumerator <CorrelationProperty> followerValues    = followerProperties.GetEnumerator();

            while (initializerValues.MoveNext() && followerValues.MoveNext())
            {
                IComparable initializerValue = initializerValues.Current.Value as IComparable;
                object      followerValue    = followerValues.Current.Value;

                //



                if (!initializerValues.Current.Name.Equals(followerValues.Current.Name, StringComparison.OrdinalIgnoreCase))
                {
                    CorrelationProperty followerProperty = null;
                    IEnumerator <CorrelationProperty> followerEnumerator = followerProperties.GetEnumerator();
                    while (followerEnumerator.MoveNext())
                    {
                        // We don't need to be concerned with culture here because the names we are comparing
                        // are parameter names on methods in an interface.
                        if (initializerValues.Current.Name.Equals(followerEnumerator.Current.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            // We found a matching Name in the follower collection.
                            // Saving the followerProperty rather than followerEnumerator.Current.Value here
                            // because the latter could be null and still be correct. I need something
                            // that indicates that we actually found a matching CorrelationProperty in the
                            // collection. So instead of having a separate bool, I just have a reference
                            // to the matching CorrelationProperty.
                            followerProperty = followerEnumerator.Current;
                            break;
                        }
                        // If we get here, the name of the parameter doesn't match, so just move to the next element in the
                        // followerEnumerator.
                    }
                    // If we found a followerProperty with a matching name, use it.
                    // In the highly, possibly impossible, event that we didn't find an element in the
                    // followerProperties collection with a matching name, we fall thru with
                    // followerValue = followerValues.Current.Value, which is exactly what the previous
                    // code had, and we act just like we did before.
                    if (followerProperty != null)
                    {
                        followerValue = followerProperty.Value;
                    }
                }

                if (initializerValue != null && (initializerValue.CompareTo(followerValue) != 0))
                {
                    throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationViolationException, memberName, activity.QualifiedName));
                }
                else if (initializerValues.Current.Value == null && followerValue == null)
                {
                    return;
                }
                else if (initializerValue == null && followerValue != null && !followerValue.Equals(initializerValues.Current.Value))
                {
                    throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationViolationException, memberName, activity.QualifiedName));
                }
            }
        }
        private static void ValidateCorrelation(ICollection <CorrelationProperty> initializerProperties, ICollection <CorrelationProperty> followerProperties, string memberName, Activity activity)
        {
            if (followerProperties == null && initializerProperties == null)
            {
                return;
            }

            if (followerProperties == null || initializerProperties == null)
            {
                throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationViolationException, memberName, activity.QualifiedName));
            }

            if (initializerProperties.Count != followerProperties.Count)
            {
                throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationViolationException, memberName, activity.QualifiedName));
            }

            IEnumerator <CorrelationProperty> initializerValues = initializerProperties.GetEnumerator();
            IEnumerator <CorrelationProperty> followerValues    = followerProperties.GetEnumerator();

            while (initializerValues.MoveNext() && followerValues.MoveNext())
            {
                IComparable initializerValue = initializerValues.Current.Value as IComparable;
                object      followerValue    = followerValues.Current.Value;

                // Bug DevDiv2\DevDiv 552322 - http://vstfdevdiv.redmond.corp.microsoft.com:8080/DevDiv2/DevDiv/_workitems#_a=edit&id=552322
                // Reflection does not guarantee ordering, so the two collections (arrays) of
                // CorrelationProperties may not be in the same order, based on Name. So we need to check all the
                // elements of the followerProperties for the Name of the current initializerValue.
                // The collections MIGHT be in the same order. Before searching the followerProperties collection for an element with a matching
                // name, see if the current element in the initializerValues and followerValues enumerators have a matching name.
                // If they do match, just fall thru because followerValue is already set to followerValues.Current.Value;
                if (!initializerValues.Current.Name.Equals(followerValues.Current.Name, StringComparison.OrdinalIgnoreCase))
                {
                    CorrelationProperty followerProperty = null;
                    IEnumerator <CorrelationProperty> followerEnumerator = followerProperties.GetEnumerator();
                    while (followerEnumerator.MoveNext())
                    {
                        // We don't need to be concerned with culture here because the names we are comparing
                        // are parameter names on methods in an interface.
                        if (initializerValues.Current.Name.Equals(followerEnumerator.Current.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            // We found a matching Name in the follower collection.
                            // Saving the followerProperty rather than followerEnumerator.Current.Value here
                            // because the latter could be null and still be correct. I need something
                            // that indicates that we actually found a matching CorrelationProperty in the
                            // collection. So instead of having a separate bool, I just have a reference
                            // to the matching CorrelationProperty.
                            followerProperty = followerEnumerator.Current;
                            break;
                        }
                        // If we get here, the name of the parameter doesn't match, so just move to the next element in the
                        // followerEnumerator.
                    }
                    // If we found a followerProperty with a matching name, use it.
                    // In the highly, possibly impossible, event that we didn't find an element in the
                    // followerProperties collection with a matching name, we fall thru with
                    // followerValue = followerValues.Current.Value, which is exactly what the previous
                    // code had, and we act just like we did before.
                    if (followerProperty != null)
                    {
                        followerValue = followerProperty.Value;
                    }
                }

                if (initializerValue != null && (initializerValue.CompareTo(followerValue) != 0))
                {
                    throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationViolationException, memberName, activity.QualifiedName));
                }
                else if (initializerValues.Current.Value == null && followerValue == null)
                {
                    return;
                }
                else if (initializerValue == null && followerValue != null && !followerValue.Equals(initializerValues.Current.Value))
                {
                    throw new InvalidOperationException(SR.GetString(SR.Error_CorrelationViolationException, memberName, activity.QualifiedName));
                }
            }
        }
Exemplo n.º 22
0
 public Task Store(ISagaData data, CorrelationProperty correlationProperty, CancellationToken cancellationToken) =>
 throw new NotSupportedException(SR.NoConfiguredSagaStorage);
        public Task Configure(CancellationToken cancellationToken = default)
        {
            var variant           = (SqlTestVariant)Variant.Values[0];
            var dialect           = variant.Dialect;
            var buildDialect      = variant.BuildDialect;
            var connectionFactory = variant.ConnectionFactory;
            var pessimisticMode   = variant.UsePessimisticMode;

            if (SessionTimeout.HasValue)
            {
                dialect = new TimeoutSettingDialect(dialect, (int)SessionTimeout.Value.TotalSeconds);
            }

            var infoCache = new SagaInfoCache(
                null,
                Serializer.JsonSerializer,
                reader => new JsonTextReader(reader),
                writer => new JsonTextWriter(writer),
                "PersistenceTests_",
                dialect,
                SagaMetadataCollection,
                name => ShortenSagaName(name));

            var connectionManager = new ConnectionManager(connectionFactory);

            SagaIdGenerator                = new DefaultSagaIdGenerator();
            SagaStorage                    = new SagaPersister(infoCache, dialect);
            SynchronizedStorage            = new SynchronizedStorage(connectionManager, infoCache, null);
            SynchronizedStorageAdapter     = new StorageAdapter(connectionManager, infoCache, dialect, null);
            OutboxStorage                  = CreateOutboxPersister(connectionManager, dialect, false, false);
            SupportsPessimisticConcurrency = pessimisticMode;

            GetContextBagForSagaStorage = () =>
            {
                var contextBag = new ContextBag();
                contextBag.Set(new IncomingMessage("MessageId", new Dictionary <string, string>(), new byte[0]));
                return(contextBag);
            };

            GetContextBagForOutbox = () =>
            {
                var contextBag = new ContextBag();
                contextBag.Set(new IncomingMessage("MessageId", new Dictionary <string, string>(), new byte[0]));
                return(contextBag);
            };

            using (var connection = connectionFactory())
            {
                connection.Open();

                foreach (var saga in SagaMetadataCollection)
                {
                    CorrelationProperty correlationProperty = null;
                    if (saga.TryGetCorrelationProperty(out var propertyMetadata))
                    {
                        correlationProperty = new CorrelationProperty(propertyMetadata.Name, CorrelationPropertyType.String);
                    }

                    var tableName  = ShortenSagaName(saga.SagaType.Name);
                    var definition = new SagaDefinition(tableName, saga.EntityName, correlationProperty);

                    connection.ExecuteCommand(SagaScriptBuilder.BuildDropScript(definition, buildDialect), "PersistenceTests");
                    connection.ExecuteCommand(SagaScriptBuilder.BuildCreateScript(definition, buildDialect), "PersistenceTests");
                }

                connection.ExecuteCommand(OutboxScriptBuilder.BuildDropScript(buildDialect), "PersistenceTests");
                connection.ExecuteCommand(OutboxScriptBuilder.BuildCreateScript(buildDialect), "PersistenceTests");
            }
            return(Task.CompletedTask);
        }