/// <summary>
        /// Appends the current property name, e.g. <c>"Item.MyValue"</c>, to the attribute buffer.
        /// </summary>
        /// <param name="attribute">The current attribute</param>
        /// <param name="tblAlias">An alias to qualify the property name with.</param>
        /// <param name="propName">A name to suffix the property name with.</param>
        /// <returns>A new attribute containing the appended buffer.</returns>
        public static IProjectionAttribute Prop(this IProjectionAttribute attribute, string tblAlias = null, string propName = null)
        {
            if (attribute.Metadata.HasFlag(RelationMetadataFlags.Model) && (propName == null || attribute.Data != null))
            {
                throw ProjectionException.PropertyNotFound(attribute.Metadata);
            }

            if (attribute.Data != null)
            {
                ColumnBinding binding = new ColumnBinding(attribute.Data.Output);

                propName = attribute.Context.Domain.Dialect.Identifier(binding.ColumnName);

                return(attribute.Append(propName).Append(binding));
            }
            else
            {
                string fullName = attribute.Metadata.Identity.Name;

                if (propName != null)
                {
                    fullName = attribute.Identity.Schema.Notation.Combine(fullName, propName);
                }

                if (tblAlias != null)
                {
                    attribute = attribute.Append(attribute.Context.Domain.Dialect.Identifier(tblAlias));
                    attribute = attribute.Append(attribute.Context.Domain.Dialect.Qualifier);
                }

                return(attribute.Append(attribute.Context.Domain.Dialect.Identifier(fullName)));
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Appends the current parameter name and value, e.g. <c>@P0</c>, to the attribute buffer.
        /// </summary>
        /// <param name="attribute">The current attribute.</param>
        /// <returns>A new attribute containing the appended buffer.</returns>
        public static IProjectionAttribute Par(this IProjectionAttribute attribute)
        {
            if (!attribute.Context.Domain.Dialect.Support.HasFlag(DialectSupport.InputParameters))
            {
                throw ProjectionException.FromProjection(attribute, $"Dialect '{attribute.Context.Domain.Dialect.GetType().Name}' does not support input parameters.");
            }

            IField value = attribute.Field?.Invoke();

            if (value != null)
            {
                string paramName   = attribute.Context.Lookup.Parameter(attribute.Identity, value);
                string dialectName = attribute.Context.Domain.Dialect.Parameter(paramName);

                Parameter param = new Parameter(paramName, value);

                IProjectionAttribute result = attribute.Append(dialectName).Append(param);

                if (attribute.Metadata.HasFlag(ProjectionMetadataFlags.Output) && attribute.Context.Domain.Dialect.Support.HasFlag(DialectSupport.OutputParameters))
                {
                    ParameterBinding binding = new ParameterBinding(param);

                    result = result.Append(binding);
                }

                return(result);
            }
            else
            {
                string paramName   = attribute.Context.Lookup.Parameter(attribute.Identity, attribute.Metadata.Identity);
                string dialectName = attribute.Context.Domain.Dialect.Parameter(paramName);

                return(attribute.Append(dialectName));
            }
        }
Ejemplo n.º 3
0
        public static IProjectionValues <TModel> Vals <TModel>(this IProjection <TModel> projection, int batchIndex = -1)
        {
            if (projection.Data == null)
            {
                throw ProjectionException.ValueNotFound(projection.Metadata);
            }
            else if (projection.Data.Source.Snapshot == null)
            {
                IEnumerable <IProjection <TModel> > emptyItems = Array.Empty <IProjection <TModel> >();

                return(new ProjectionValues <TModel>(projection.Context, projection.Identity, emptyItems, batchIndex));
            }

            IProjectionMetadata[]  header = new[] { projection.Metadata }.Concat(projection.Header.Select(a => a.Metadata)).ToArray();
            IProjectionAttribute[] attributes = header.Skip(1).Select(m => new ProjectionAttribute(projection.Identity, projection.Context, m, data: null)).ToArray();

            return(new ProjectionValues <TModel>(projection.Context, projection.Identity, innerReader(), batchIndex));

            IEnumerable <IProjection <TModel> > innerReader()
            {
                using ProjectionReader reader = new ProjectionReader(projection.Data.Source, header);

                while (reader.Read())
                {
                    IProjectionData[] dataSet = reader.GetData().ToArray();

                    if (dataSet[0].Source.Snapshot != null)
                    {
                        IEnumerable <IProjectionAttribute> valueHeader = attributes.Zip(dataSet.Skip(1)).Select(t => t.First.With(data: t.Second));

                        yield return(projection.With(data: dataSet[0], header: valueHeader));
                    }
                }
            }
        }
Ejemplo n.º 4
0
        public static IProjectionAttribute ValList(this IProjection projection, Func <IProjectionAttribute, IProjectionAttribute> itemFactory)
        {
            if (projection.Data == null)
            {
                throw ProjectionException.ValueNotFound(projection.Metadata);
            }

            IProjectionMetadata itemMetadata = projection.Metadata?.Item ?? projection.Metadata;

            using ProjectionReader reader = new ProjectionReader(projection.Data.Source, new[] { itemMetadata });

            IProjectionAttribute attribute = new ProjectionAttribute(projection.Identity, projection.Context, itemMetadata, data: null);

            if (reader.Read())
            {
                IProjectionData data = reader.GetData().First();

                attribute = itemFactory(attribute.With(data: data));
            }

            while (reader.Read())
            {
                IProjectionData data = reader.GetData().First();

                attribute = attribute.Append(", ");
                attribute = itemFactory(attribute.With(data: data));
            }

            return(attribute);
        }
        private NHibernate.ExceptionResolution OnNonTransientException(ProjectionException exception)
        {
            if (exception.TransactionBatch.Count > 1)
            {
                // If we have more than one transition, let's try to run them one by one to trace down the one that really fails.
                return(NHibernate.ExceptionResolution.RetryIndividual);
            }
            else
            {
                // So we found the failing transaction. So let's mark it as corrupt and ignore the transaction.
                Console.WriteLine(exception.Message);

                using (var session = sessionFactory())
                {
                    string failingStreamId = exception.TransactionBatch.Single().StreamId;
                    if (failingStreamId != null)
                    {
                        var projection = session.Query <DocumentCountProjection>().SingleOrDefault(x => x.Id == failingStreamId);
                        if (projection != null)
                        {
                            projection.Corrupt = true;
                            cache.Clear();
                            session.Flush();
                        }
                    }
                }

                return(NHibernate.ExceptionResolution.Ignore);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Appends the current property name, e.g. <c>"Item.MyValue"</c>, to the attribute buffer.
        /// </summary>
        /// <param name="attribute">The current attribute</param>
        /// <param name="tblAlias">An alias to qualify the property name with.</param>
        /// <param name="propName">A name to suffix the property name with.</param>
        /// <returns>A new attribute containing the appended buffer.</returns>
        public static IProjectionAttribute Prop(this IProjectionAttribute attribute, string tblAlias = null, string propName = null)
        {
            if ((propName == null || attribute.Field != null) && attribute.Metadata.HasFlag(RelationMetadataFlags.Model))
            {
                throw ProjectionException.FromProjection(attribute, "Cannot reference model directly.");
            }

            if (attribute.Field != null)
            {
                IField field = attribute.Field();

                ColumnBinding binding = new ColumnBinding(field.Identity.Name, field);

                propName = attribute.Context.Domain.Dialect.Identifier(binding.ColumnName);

                return(attribute.Append(propName).Append(binding));
            }
            else
            {
                string fullName = attribute.Metadata.Identity.Name;

                if (propName != null)
                {
                    fullName = attribute.Identity.Schema.Notation.Combine(fullName, propName);
                }

                if (tblAlias != null)
                {
                    attribute = attribute.Append(attribute.Context.Domain.Dialect.Identifier(tblAlias));
                    attribute = attribute.Append(attribute.Context.Domain.Dialect.Qualifier);
                }

                return(attribute.Append(attribute.Context.Domain.Dialect.Identifier(fullName)));
            }
        }
Ejemplo n.º 7
0
        private async Task ProjectTransactionBatch(IList <Transaction> batch)
        {
            try
            {
                using (IAsyncDocumentSession session = sessionFactory())
                {
                    foreach (Transaction transaction in batch)
                    {
                        await ProjectTransaction(transaction, session).ConfigureAwait(false);
                    }

                    await StoreLastCheckpoint(session, batch.Last()).ConfigureAwait(false);

                    await session.SaveChangesAsync().ConfigureAwait(false);
                }
            }
            catch (ProjectionException projectionException)
            {
                projectionException.Projector = typeof(TProjection).ToString();
                projectionException.SetTransactionBatch(batch);
                throw;
            }
            catch (Exception exception)
            {
                var projectionException = new ProjectionException("Projector failed to project transaction batch.", exception)
                {
                    Projector = typeof(TProjection).ToString()
                };

                projectionException.SetTransactionBatch(batch);
                throw projectionException;
            }
        }
Ejemplo n.º 8
0
        public static IProjectionMetadata GetPreferredTvpMetadata(IProjection projection)
        {
            if (projection.Metadata.List == null && projection.Metadata.Item == null)
            {
                throw ProjectionException.FromProjection(projection, "No table information found.");
            }

            return(projection.Metadata.List ?? projection.Metadata.Item?.List);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Navigates the current projection to its default item target.
        /// </summary>
        /// <param name="projection">The current projection.</param>
        /// <returns>A new projection of the item target.</returns>
        public static IProjection Open(this IProjection projection)
        {
            if (!projection.Metadata.HasFlag(RelationMetadataFlags.List))
            {
                throw ProjectionException.FromProjection(projection, "No metadata list contract found.");
            }

            return(projection.With(metadata: projection.Metadata.Item));
        }
Ejemplo n.º 10
0
        public static IField GetFieldValue(IProjectionAttribute attribute)
        {
            if (attribute.Field == null)
            {
                throw ProjectionException.ValueNotFound(attribute);
            }

            return(attribute.Field());
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Navigates the current projection to its default item target.
        /// </summary>
        /// <param name="projection">The current projection.</param>
        /// <returns>A new projection of the item target.</returns>
        public static IProjection Open(this IProjection projection)
        {
            if (!projection.Metadata.HasFlag(RelationMetadataFlags.List))
            {
                throw ProjectionException.InvalidProjection(projection.Metadata, "Attribute is not a list.");
            }

            return(projection.With(metadata: projection.Metadata.Item));
        }
 private async Task <NHibernate.ExceptionResolution> OnException(ProjectionException exception, int attempts, CancellationToken cancellationToken)
 {
     if (IsTransient(attempts))
     {
         return(await OnTransientException(attempts));
     }
     else
     {
         return(OnNonTransientException(exception));
     }
 }
Ejemplo n.º 13
0
        public static IProjection Val(this IProjection projection)
        {
            IProjection value = projection.Vals().FirstOrDefault();

            if (value == null)
            {
                throw ProjectionException.ValueNotFound(projection);
            }

            return(value);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Appends mappings between the current qualified columns and their properties, e.g. <c>T0."MyColumn" AS "Item.MyValue"</c>, to the projection buffer. Identical to calling <c>Cols().As().Props()</c>.
        /// </summary>
        /// <param name="projection">The current projection</param>
        /// <param name="tblAlias">The table alias to qualify each column name with.</param>
        /// <returns>A new projection containing the appended buffer.</returns>
        public static IProjection Star(this IProjection projection, string tblAlias = null)
        {
            if (!projection.Any())
            {
                throw ProjectionException.AttributesNotFound(projection.Metadata);
            }

            IProjectionMetadata metadata = ProjectionHelper.GetPreferredTableMetadata(projection.Metadata);

            return(projection.With(metadata).Cols(tblAlias).As().Props());
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Appends mappings between the current qualified columns and their properties, e.g. <c>T0."MyColumn" AS "Item.MyValue"</c>, to the projection buffer. Identical to calling <c>Cols().As().Props()</c>.
        /// </summary>
        /// <param name="projection">The current projection</param>
        /// <returns>A new projection containing the appended buffer.</returns>
        public static IProjection Star(this IProjection projection)
        {
            if (!projection.Any())
            {
                throw ProjectionException.FromProjection(projection, "No attributes found.");
            }

            IProjectionMetadata metadata = ProjectionHelper.GetPreferredTableMetadata(projection).Identity.GetMetadata <IProjectionMetadata>();

            return(projection.With(metadata).Cols().As().Props());
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Appends the current variable name, e.g. <c>@V0</c>, to the attribute buffer.
        /// </summary>
        /// <param name="attribute">The current attribute.</param>
        /// <returns>A new attribute containing the appended buffer.</returns>
        public static IProjectionAttribute Var(this IProjectionAttribute attribute)
        {
            if (attribute.Data == null)
            {
                throw ProjectionException.ValueNotFound(attribute.Metadata);
            }

            string variableName = attribute.Context.Lookup.Variable(attribute.Identity, attribute.Data.Input);
            string dialectName  = attribute.Context.Domain.Dialect.Variable(variableName);

            return(attribute.Append(dialectName));
        }
Ejemplo n.º 17
0
        public static ITableMetadata GetPreferredColumnMetadata(IProjectionAttribute attribute)
        {
            if (attribute.Metadata.HasFlag(TableMetadataFlags.Column))
            {
                return(attribute.Metadata.Table);
            }
            else if (attribute.Metadata.Item != null && attribute.Metadata.Item.HasFlag(TableMetadataFlags.Column))
            {
                return(attribute.Metadata.Item.Table);
            }

            throw ProjectionException.FromProjection(attribute, "No column information found.");
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Appends the current JSON path literal, e.g. <c>'$.my.value'</c>, to the attribute buffer.
        /// </summary>
        /// <param name="attribute">The current attribute.</param>
        /// <returns>A new attribute containing the appended buffer.</returns>
        public static IProjectionAttribute JsonPath(this IProjectionAttribute attribute)
        {
            IJsonMetadata metadata = attribute.Metadata.Identity.GetMetadata <IJsonMetadata>();

            if (metadata == null)
            {
                throw ProjectionException.FromProjection(attribute, "JSON metadata not found.");
            }

            string literal = attribute.Context.Domain.Dialect.String(metadata.Path);

            return(attribute.Append(literal));
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Appends the current variable name, e.g. <c>@V0</c>, to the attribute buffer.
        /// </summary>
        /// <param name="attribute">The current attribute.</param>
        /// <returns>A new attribute containing the appended buffer.</returns>
        public static IProjectionAttribute Var(this IProjectionAttribute attribute)
        {
            if (attribute.Field == null)
            {
                throw ProjectionException.ValueNotFound(attribute);
            }

            IField field = ProjectionHelper.GetFieldValue(attribute);

            string variableName = attribute.Context.Lookup.Variable(attribute.Identity, field);
            string dialectName  = attribute.Context.Domain.Dialect.Variable(variableName);

            return(attribute.Append(dialectName));
        }
Ejemplo n.º 20
0
        public static IProjection Val(this IProjection projection)
        {
            if (projection.Data == null)
            {
                throw ProjectionException.ValueNotFound(projection.Metadata);
            }

            IProjectionData newData = ProjectionData.Resolve(projection.Data, projection.Metadata);

            if (newData.Source.Snapshot == null)
            {
                throw ProjectionException.ValueNotFound(newData.Source);
            }

            return(projection.With(data: newData));
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Appends a table-valued parameter from the current values, e.g. <c>@TP0</c>, to the projection buffer.
        /// </summary>
        /// <param name="projection">The current projection.</param>
        /// <returns>A new attribute containing the appended buffer.</returns>
        public static IProjectionAttribute TvpName(this IProjection projection)
        {
            if (projection.Source == null)
            {
                throw ProjectionException.ValueNotFound(projection);
            }
            else if (!projection.Attributes.Any())
            {
                throw ProjectionException.FromProjection(projection, "No attributes found.");
            }

            Relation relation = new Relation(projection.Source, projection.Attributes.Select(a => a.Metadata.Identity));

            string paramName   = projection.Context.Lookup.Custom("TP", projection.Identity, field: projection.Source);
            string dialectName = projection.Context.Domain.Dialect.Parameter(paramName);

            return(projection.Attr().Append(dialectName).Append(new TableValuedParameter(paramName, relation)));
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Appends the current parameter name and value, e.g. <c>@P0</c>, to the attribute buffer.
        /// </summary>
        /// <param name="attribute">The current attribute.</param>
        /// <returns>A new attribute containing the appended buffer.</returns>
        public static IProjectionAttribute Par(this IProjectionAttribute attribute)
        {
            if (!attribute.Context.Domain.Dialect.Support.HasFlag(DialectSupport.InputParameters))
            {
                throw ProjectionException.ParametersNotSupported(attribute);
            }

            if (attribute.Data?.Input != null)
            {
                string paramName   = attribute.Context.Lookup.Parameter(attribute.Identity, attribute.Data.Input);
                string dialectName = attribute.Context.Domain.Dialect.Parameter(paramName);

                Parameter param = new Parameter(paramName, attribute.Data.Input);

                IProjectionAttribute result = attribute.Append(dialectName).Append(param);

                if (attribute.Metadata.HasFlag(ProjectionMetadataFlags.Output))
                {
                    if (attribute.Context.Domain.Dialect.Support.HasFlag(DialectSupport.OutputParameters))
                    {
                        ParameterBinding binding = new ParameterBinding(attribute.Data.Output, param.Name);

                        result = result.Append(binding);
                    }

                    if (attribute.Metadata.HasAnyFlag(ProjectionMetadataFlags.Cascade))
                    {
                        CascadeBinding binding = new CascadeBinding(attribute.Data.Output, attribute.Data.Input);

                        result = result.Append(binding);
                    }
                }

                return(result);
            }
            else
            {
                string paramName   = attribute.Context.Lookup.Parameter(attribute.Identity, attribute.Metadata.Identity);
                string dialectName = attribute.Context.Domain.Dialect.Parameter(paramName);

                return(attribute.Append(dialectName));
            }
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Appends a call to <c>JSON_VALUE</c> from the current column and JSON path, e.g. <c>JSON_VALUE(T0."MyJson", '$.my.value')</c>, to the attribute buffer.
        /// </summary>
        /// <param name="attribute">The current attribute.</param>
        /// <returns>A new attribute containing the appended buffer.</returns>
        public static IProjectionAttribute Json(this IProjectionAttribute attribute)
        {
            IJsonMetadata json = ProjectionHelper.GetJsonMetadata(attribute);

            IProjectionMetadata metadata     = attribute.Metadata;
            IProjectionMetadata rootMetadata = json.MemberOf.Identity.GetMetadata <IProjectionMetadata>();

            attribute = attribute.Append("JSON_VALUE(");
            try
            {
                attribute = attribute.With(metadata: rootMetadata).Col();
            }
            catch (ProjectionException ex)
            {
                throw ProjectionException.FromProjection(attribute, "JSON value requires a column to read from.", innerException: ex);
            }
            attribute = attribute.Append(",");
            attribute = attribute.With(metadata: metadata).JsonPath();
            attribute = attribute.Append(")");

            return(attribute);
        }
Ejemplo n.º 24
0
            public When_serialized_and_deserialized()
            {
                Given(() =>
                {
                    UseThe(new BinaryFormatter());
                });

                When(() =>
                {
                    byte[] serializedException;

                    using (var stream = new MemoryStream())
                    {
                        The <BinaryFormatter>().Serialize(stream, Subject);
                        serializedException = stream.ToArray();
                    }

                    using (var stream = new MemoryStream(serializedException))
                    {
                        result = (ProjectionException)The <BinaryFormatter>().Deserialize(stream);
                    }
                });
            }
Ejemplo n.º 25
0
        /// <summary>
        /// Appends a table-valued parameter from the current values, e.g. <c>@TP0</c>, to the projection buffer.
        /// </summary>
        /// <param name="projection">The current projection.</param>
        /// <returns>A new attribute containing the appended buffer.</returns>
        public static IProjectionAttribute TvpName(this IProjection projection)
        {
            if (projection.Source == null)
            {
                throw ProjectionException.ValueNotFound(projection);
            }
            else if (!projection.Attributes.Any())
            {
                throw ProjectionException.FromProjection(projection, "No attributes found.");
            }

            IProjectionMetadata metadata = TvpHelper.GetPreferredTvpMetadata(projection);
            IField source = new Relation(projection.Source, metadata.Identity.Name).Scalar();

            RelationIdentity identity = new RelationIdentity(metadata.Identity.Schema, projection.Attributes.Select(a => a.Metadata.Identity));

            IBindingParameterContract contract = TvpCache.GetParameterContract(identity);

            string paramName   = projection.Context.Lookup.Custom("TP", projection.Identity, field: source);
            string dialectName = projection.Context.Domain.Dialect.Parameter(paramName);

            return(projection.Attr().Append(dialectName).Append(new Parameter(paramName, source, contract)));
        }
Ejemplo n.º 26
0
        public static IProjectionAttribute ValList(this IProjection projection, Func <IProjectionAttribute, IProjectionAttribute> itemFactory)
        {
            if (projection.Source == null)
            {
                throw ProjectionException.ValueNotFound(projection);
            }

            IField[]             items     = new Relation(projection.Source, projection.Metadata.Identity.Name).Column().ToArray();
            IProjectionAttribute attribute = projection.Attr();

            if (items.Length == 0)
            {
                return(attribute);
            }

            attribute = itemFactory(attribute.With(metadata: attribute.Metadata, field: () => items[0]));

            foreach (IField item in items.Skip(1))
            {
                attribute = itemFactory(attribute.With(field: () => item).Append(", "));
            }

            return(attribute);
        }
Ejemplo n.º 27
0
        public static IProjectionMetadata GetMetadataFromRelativeLambda(IProjection projection, LambdaExpression expression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }

            string name     = projection.Metadata.Identity.Notation.Lambda(expression);
            string fullName = projection.Metadata.Identity.Notation.Combine(projection.Metadata.Identity.Name, name);

            return(projection.Metadata.Identity.Schema.GetMetadata <IProjectionMetadata>(fullName) ?? throw ProjectionException.FromProjection(projection, "Metadata not found."));
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Returns the identity attribute of the current projection.
        /// </summary>
        /// <param name="projection">The current projection</param>
        /// <returns>The identity attribute, or throw a <see cref="ProjectionException">ProjectionException</see> if none are found.</returns>
        public static IProjectionAttribute Id(this IProjection projection)
        {
            IProjectionAttribute identity = projection.Header.FirstOrDefault(a => a.Metadata.HasFlag(ProjectionMetadataFlags.Identity));

            return(identity ?? throw ProjectionException.IdentityNotFound(projection.Metadata));
        }
Ejemplo n.º 29
0
 public static IJsonMetadata GetJsonMetadata(IProjectionAttribute attribute) => attribute.Metadata.Identity.GetMetadata <IJsonMetadata>() ??
 throw ProjectionException.FromProjection(attribute, "JSON metadata not found.");
        protected virtual async Task <bool> ShouldRetry(ProjectionException exception, int attempts)
        {
            await Task.Delay((int)Math.Pow(2d, attempts));

            return(attempts < 3);
        }