/*
 * Copyright 2020, TeamDev. All rights reserved.
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package io.spine.server.aggregate;

import io.spine.query.RecordQuery;
import io.spine.server.storage.MessageRecordSpec;
import io.spine.server.storage.MessageStorage;
import io.spine.server.storage.StorageFactory;

import java.util.Iterator;

/**
 * Storage of events for each {@link Aggregate}.
 */
public class AggregateEventStorage
        extends MessageStorage<AggregateEventRecordId, AggregateEventRecord> {

    @SuppressWarnings("ConstantConditions")     // Protobuf getters return non-{@code null} values.
    private static final MessageRecordSpec<AggregateEventRecordId, AggregateEventRecord> spec =
            new MessageRecordSpec<>(
                    AggregateEventRecordId.class,
                    AggregateEventRecord.class,
                    AggregateEventRecord::getId,
                    AggregateEventRecordColumn.definitions()
            );

    public AggregateEventStorage(StorageFactory factory, boolean multitenant) {
        super(factory.createRecordStorage(spec, multitenant));
    }

    /**
     * {@inheritDoc}
     *
     * <p>Overrides to expose this method as a part of storage's package-level API.
     */
    @Override
    protected Iterator<AggregateEventRecord>
    readAll(RecordQuery<AggregateEventRecordId, AggregateEventRecord> query) {
        return super.readAll(query);
    }

    /**
     * {@inheritDoc}
     *
     * <p>Overrides to expose this method as a part of storage's package-level API.
     */
    @Override
    protected boolean delete(AggregateEventRecordId id) {
        return super.delete(id);
    }

    /**
     * {@inheritDoc}
     *
     * <p>Overrides to expose this method as a part of storage's package-level API.
     */
    @Override
    protected void deleteAll(Iterable<AggregateEventRecordId> ids) {
        super.deleteAll(ids);
    }
}

@@ -1422,16 +1422,106 @@
 ord%3E %7B%0A%0A
+    /**%0A     * A specification on how to store the event records of an aggregate.%0A     */%0A
     @Sup
@@ -1969,16 +1969,436 @@
     );%0A%0A
+    /**%0A     * Creates a new storage.%0A     *%0A     * %3Cp%3EUses the passed factory to create a %7B@code RecordStorage%7D delegate, and configures it with%0A     * the columns stored for the %7B@link AggregateEventRecord%7D.%0A     *%0A     * @param factory%0A     *         the storage factory to use when creating a record storage delegate%0A     * @param multitenant%0A     *         tells whether this storage should be multi-tenant%0A     */%0A
     publ

Improve the documentation.