/// <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); }
/// <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)); }
/// <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); } } }
/// <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)); }