Skip to content

Repository

alexstaeding edited this page Mar 5, 2020 · 1 revision

A Repository has direct access to a specific datastore. For example, a MongoRepository is responsible all transactions with the connected MongoDB instance. It is recommended to create one concrete class per datastore type.

In this example, we'll create a TicketRepository with the responsibility of performing atomic operations on the current datastore. The first step is to create the TicketRepository interface:

package org.anvilpowered.simpletickets.api.ticket.repository;

import org.anvilpowered.anvil.api.repository.Repository;
import org.anvilpowered.simpletickets.api.model.ticket.Ticket;

import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

public interface TicketRepository<TKey, TDataStore> extends Repository<TKey, Ticket<TKey>, TDataStore> {
    
    CompletableFuture<Optional<Ticket<TKey>>> create(UUID userUUID, String description);

    CompletableFuture<Boolean> close(UUID userUUID);
}

The type parameters TKey and TDataStore are necessary because we need type-safe access to them when we create the datastore-specific repositories such as MongoTicketRepository or XodusTicketRepository.

The next step is to create a common implementation for this:

package org.anvilpowered.simpletickets.common.ticket.repository;

import org.anvilpowered.anvil.api.datastore.DataStoreContext;
import org.anvilpowered.anvil.base.repository.BaseRepository;
import org.anvilpowered.simpletickets.api.model.ticket.Ticket;
import org.anvilpowered.simpletickets.api.ticket.repository.TicketRepository;

import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

public abstract class CommonTicketRepository<
    TKey,
    TDataStore>
    extends BaseRepository<TKey, Ticket<TKey>, TDataStore>
    implements TicketRepository<TKey, TDataStore> {

    protected CommonTicketRepository(DataStoreContext<TKey, TDataStore> dataStoreContext) {
        super(dataStoreContext);
    }

    @Override
    @SuppressWarnings("unchecked")
    public Class<Ticket<TKey>> getTClass() {
        return (Class<Ticket<TKey>>) getDataStoreContext().getEntityClassUnsafe("ticket");
    }

    @Override
    public CompletableFuture<Optional<Ticket<TKey>>> create(UUID userUUID, String description) {
        Ticket<TKey> ticket = generateEmpty();
        ticket.setUserUUID(userUUID);
        ticket.setDescription(description);
        return insertOne(ticket);
    }
}

Default implementations of classes that you should extend are located in anvil-base. While not strictly necessary, it is recommended that you use these instead of directly implementing the API (for those classes that have a "base" version). To use these default implementations, add anvil-base to your gradle dependencies (for more info, look at Project Structure)