Beispiel #1
0
        /// <summary>
        /// Loads the most recent snapshot using the specified connection and aggregate identifier.
        /// </summary>
        /// <typeparam name="TKey">The type of aggregate identifier.</typeparam>
        /// <param name="connection">The <see cref="DbConnection">connection</see> used to load the snapshot.</param>
        /// <param name="aggregateId">The identifier of the aggregate to load the snapshot for.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken">token</see> that can be used to cancel the operation.</param>
        /// <returns>The <see cref="Task{TResult}">task</see> containing the loaded <see cref="SqlSnapshotDescriptor{TKey}">snapshot</see>
        /// or <c>null</c> if no match is found.</returns>
        public virtual async Task <SqlSnapshotDescriptor <TKey> > LoadSnapshot <TKey>(DbConnection connection, TKey aggregateId, CancellationToken cancellationToken)
        {
            Arg.NotNull(connection, nameof(connection));

            var snapshot = default(SqlSnapshotDescriptor <TKey>);

            using (var command = connection.CreateCommand())
            {
                var parameter = command.CreateParameter();

                parameter.ParameterName = "AggregateId";
                parameter.Value         = aggregateId;
                command.Parameters.Add(parameter);
                command.CommandText = Sql.Snapshots.Load;

                using (var reader = await command.ExecuteReaderAsync(SingleRow, cancellationToken).ConfigureAwait(false))
                {
                    if (await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
                    {
                        snapshot = new SqlSnapshotDescriptor <TKey>()
                        {
                            AggregateId  = aggregateId,
                            SnapshotType = reader.GetString(0),
                            Version      = reader.GetInt32(1),
                            Snapshot     = reader.GetStream(2),
                        };
                    }
                }
            }

            return(snapshot);
        }
Beispiel #2
0
        /// <summary>
        /// Saves the specified snapshot descriptor using the provided command.
        /// </summary>
        /// <typeparam name="TKey">The type of key.</typeparam>
        /// <param name="command">The <see cref="DbCommand">database command</see> used to save the snapshot.</param>
        /// <param name="snapshotDescriptor">The <see cref="EventDescriptor{TKey}">snapshot descriptor</see> that
        /// describes the snapshot being saved.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken">token</see> that can be used to cancel the operation.</param>
        /// <returns>A <see cref="Task">task</see> representing the asynchronous operation.</returns>
        public virtual Task SaveSnapshot <TKey>(DbCommand command, SqlSnapshotDescriptor <TKey> snapshotDescriptor, CancellationToken cancellationToken)
        {
            Arg.NotNull(command, nameof(command));
            Arg.NotNull(snapshotDescriptor, nameof(snapshotDescriptor));

            command.Parameters["AggregateId"].Value = snapshotDescriptor.AggregateId;
            command.Parameters["Version"].Value     = snapshotDescriptor.Version;
            command.Parameters["Type"].Value        = snapshotDescriptor.SnapshotType;
            command.Parameters["Snapshot"].Value    = snapshotDescriptor.Snapshot;

            return(command.ExecuteNonQueryAsync(cancellationToken));
        }
Beispiel #3
0
        /// <summary>
        /// Saves the specified snapshot descriptor.
        /// </summary>
        /// <typeparam name="TKey">The type of key.</typeparam>
        /// <param name="snapshotDescriptor">The <see cref="EventDescriptor{TKey}">snapshot descriptor</see> that
        /// describes the snapshot being saved.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken">token</see> that can be used to cancel the operation.</param>
        /// <returns>A <see cref="Task">task</see> representing the asynchronous operation.</returns>
        public virtual async Task SaveSnapshot <TKey>(SqlSnapshotDescriptor <TKey> snapshotDescriptor, CancellationToken cancellationToken)
        {
            Arg.NotNull(snapshotDescriptor, nameof(snapshotDescriptor));

            using (var connection = CreateConnection())
            {
                await connection.OpenAsync(cancellationToken).ConfigureAwait(false);

                using (var command = NewSaveEventCommand())
                {
                    command.Connection = connection;
                    await SaveSnapshot(command, snapshotDescriptor, cancellationToken).ConfigureAwait(false);
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Returns a new event stream that contains a snapshot using the specified descriptor.
        /// </summary>
        /// <param name="events">The <see cref="IEnumerable{T}">sequence</see> representing the <see cref="IEvent">event</see> stream.</param>
        /// <param name="snapshotDescriptor">The <see cref="SqlSnapshotDescriptor{TKey}">descriptor</see> describing the
        /// <see cref="ISnapshot{TKey}">snapshot</see> contained in the stream.</param>
        /// <returns>A new <see cref="IEnumerable{T}">sequence</see> of <see cref="IEvent">events</see> containing a
        /// <see cref="ISnapshot{TKey}">snapshot</see>.</returns>
        protected virtual IEnumerable <IEvent> NewEventStreamWithSnapshot(IEnumerable <IEvent> events, SqlSnapshotDescriptor <TKey> snapshotDescriptor)
        {
            Arg.NotNull(events, nameof(events));
            Arg.NotNull(snapshotDescriptor, nameof(snapshotDescriptor));
            Contract.Ensures(Contract.Result <IEnumerable <IEvent> >() != null);

            return(snapshotSerializer.Deserialize(events, snapshotDescriptor));
        }
        internal IEnumerable <IEvent> Deserialize <TKey>(IEnumerable <IEvent> events, SqlSnapshotDescriptor <TKey> snapshotDescriptor)
        {
            var abstractFactory = factories.GetOrAdd(snapshotDescriptor.SnapshotType, NewFactory);
            var deserialize     = abstractFactory.NewDeserializer(snapshotDescriptor.SnapshotType);

            return(deserialize(events, snapshotDescriptor.Snapshot));
        }