All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.distelli.persistence.Index Maven / Gradle / Ivy

There is a newer version: 3.8.16
Show newest version
package com.distelli.persistence;

import java.net.URI;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityNotFoundException;
import javax.persistence.RollbackException;
import com.distelli.cred.CredProvider;
import com.distelli.crypto.KeyProvider;

public interface Index {
    public interface Builder {
        /**
         * URI format:
         *    DynamoDB (always connects over SSL):
         *
         *       ddb://<region|endpoint>/
         *
         *    MySQL (always connects over SSL):
         *
         *       mysql://<host>:<port>/
         *
         * @param endpoint is the endpoint to use.
         *
         * @return this
         */
        public Builder withEndpoint(URI endpoint);

        /**
         * @param convertMarker is used for generating the PageIterator marker
         *        when performing queryItems() call.
         *
         * @return this
         */
        public Builder withConvertMarker(ConvertMarker convertMarker);

        /**
         * Source the following fields from the TableDescription:
         *
         *   - hashKeyName
         *   - rangeKeyName
         *   - otherKeyNames
         *   - convertMarker
         *   - tableName / indexName
         *   - noEncrypt all hashKey/rangeKeys in all IndexDescriptions.
         *
         * @param tableDescription is the description of the table.
         *
         * @param indexName is the name of the index to use (or null
         *         if main index is desired).
         */
        public Builder withTableDescription(TableDescription tableDescription, String indexName);
        public default Builder withTableDescription(TableDescription tableDescription) {
            return withTableDescription(tableDescription, null);
        }

        /**
         * @param name is the required hash key name
         *
         * @return this
         */
        public Builder withHashKeyName(String name);

        /**
         * @param name is the optional range key name
         *
         * @return this
         */
        public Builder withRangeKeyName(String name);

        /**
         * Only applicable to secondary indexes.
         *
         * @param names are the hash/range key of the main index.
         *
         * @return this
         */
        public Builder withOtherKeyNames(String... names);

        /**
         * @param convertValue is used for converting between T and
         *        Map<String, Object> and back.
         *
         * @return this
         */
        public Builder withConvertValue(ConvertValue convertValue);

        /**
         * Enable infinite retries, this is only useful if running in
         * some sort of batch mode.
         *
         * @return this
         */
        public Builder withInfiniteRetry();

        /**
         * @param tableName is the table name to use.
         *
         * @return this
         */
        public Builder withTableName(String tableName);

        /**
         * @param tableNameFormatStr is use to add a table name prefix or suffix.
         *        This string is passed as the first argument to String.format().
         *
         * @return this
         */
        public Builder withTableNameFormat(String tableNameFormatStr);

        /**
         * @param tableName is the name of the table to use.
         *
         * @param indexName is the name of the alternative index to use.
         *
         * @return this
         */
        public Builder withIndexName(String tableName, String indexName);

        /**
         * @param credProvider is used to obtain the DB username and
         *        password (or key id and secret key).
         *
         * @return this
         */
        public Builder withCredProvider(CredProvider credProvider);

        /**
         * @param proxyEndpoint is the DDB proxy to use, or null if no proxy is needed.
         *
         * @return this
         */
        public Builder withProxy(URI proxyEndpoint);

        /**
         * @param attrNames are the attribute names that should NOT be encrypted.
         *
         * @return this
         */
        public Builder withNoEncrypt(String... attrNames);

        /**
         * @param keyProvider is the KeyProvider used for obtaining encryption
         *        keys.
         *
         * @return this
         */
        public Builder withKeyProvider(KeyProvider keyProvider);

        /**
         * @return the index object based on the builder parameters.
         */
        public Index build();

        /**
         * @return the hash key name specified via withHashKeyName().
         */
        public String getHashKeyName();

        /**
         * @return the optional range key name specified via withRangeKeyName().
         */
        public String getRangeKeyName();

        public String[] getOtherKeyNames();

        /**
         * @return the fully formatted table name. Specifically, if
         *        tableNameFormat is set, this is the result of running
         *        String.format(tableNameFormat, tableName), otherwise
         *        this is simply the tableName.
         */
        public String getTableName();
    }

    /**
     * To provide suitable defaults for the endpoint/credProvider/proxy/keyProvider,
     * it is recommended to implement a custom Factory implementation.
     */
    public interface Factory {
        /**
         * @param clazz is the class of the items being stored by this index.
         *
         * @param  is the type of the items being stored by this index.
         *
         * @return a new builder instance.
         */
        public  Builder create(Class clazz);
    }

    /**
     * @return the hash key name.
     */
    public String getHashKeyName();

    /**
     * @return the range key name.
     */
    public String getRangeKeyName();

    /**
     * @return the fully qualified table name.
     */
    public String getTableName();

    /**
     * Obtain the underlying DynamoDB object for this table. This should only
     * be used by code paths that are specific to DynamoDB. Note that this only
     * works on MAIN indexes.
     *
     * @return an instance of com.amazonaws.services.dynamodbv2.document.DynamoDB
     *         or null if the underlying data store is NOT backed by dynamo.
     */
    public default Object getDynamoDBUnsafe() { return null; }

    /**
     * Obtain the underlaying DataSource object for this table. T
     *
     * @return an instance of javax.sql.DataSource or null if the underlying
     *         data store is NOT backed by a MySql DB.
     */
    public default Object getMySQLDataSourceUnsafe() { return null; }

    /**
     * Call the configured ConvertMarker.toMarker() implementation.
     *
     * @param item is an item for which we desire to obtain a marker for.
     *
     * @param hasHashKey should be set to true only if we are guaranteed
     *        to call fromMarker() with a non-null hash key parameter.
     *
     * @return a marker
     */
    public String toMarker(T item, boolean hasHashKey);

    /**
     * Clone this index, use the builder methods to customize the clone.
     * Useful if you want to obtain a different index of the same table
     * (for example).
     * 
     * @param  is the type of elements we plan to store/retrieve.
     *
     * @param clazz is the type of elements we plan to store/retrieve
     *        from the Index created by the returned builder.
     *
     * @return a new Index.Builder configured based on the parameters of
     *        this Index.
     */
    public  Builder clone(Class clazz);

    /**
     * @param hk is the hash key to query on.
     *
     * @param pageIterator is the page iterator to use for iterating over multiple
     *        result sets.
     *
     * @return a query item builder used to formulate the desired query.
     */
    public QueryItemsBuilder queryItems(Object hk, PageIterator pageIterator);

    /**
     * Iterate over all items in the table.
     *
     * @param pageIterator is the page iterator to use.
     *
     * @return the next list of results. This list is unmodifiable.
     */
    public List scanItems(PageIterator pageIterator);

    /**
     * Count all items in the table.
     *
     * @param pageIterator is the page iterator to use.
     *
     * @return the count of items in the first page of results.
     */
    public int countItems(PageIterator pageIterator);

    /**
     * Obtain an item stored with the specified hash key and range key.
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param hk is the hash key.
     *
     * @param rk is the range key, or null if this table does not have a range
     *        key name.
     *
     * @return the item with this primary key or null.
     */
    public T getItem(Object hk, Object rk);

    /**
     * Same as getItem(hk, null).
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param hk is the hash key.
     *
     * @return the item with this primary key or null.
     */
    public default T getItem(Object hk) {
        return getItem(hk, null);
    }

    /**
     * Obtain an item stored with the specified hash key and range key, but
     * convert to a different class type, and only select the specified
     * attributes.
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param hk is the hash key.
     *
     * @param rk is the range key (or null if this table has no range key).
     *
     * @param attributes is the set of attribute names to obtain.
     *
     * @param type is the class of the alternative item type to retrieve.
     *
     * @param  is the alternative item type to retrieve.
     *
     * @return the item with this primary key or null.
     */
    public  V getItem(Object hk, Object rk, Collection attributes, Class type);

    /**
     * Shortcut method to getItem() with all attributes.
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param hk is the hash key.
     *
     * @param rk is the range key.
     *
     * @param type is the class of the alternative item type to retrieve.
     *
     * @param  is the alternative item type to retrieve.
     *
     * @return the item with this primary key or null.
     */
    public default  V getItem(Object hk, Object rk, Class type) {
        return getItem(hk, rk, null, type);
    }

    /**
     * Obtain a specific item, but instead of returning null, throw EntityNotFoundException
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param hk is the hash key.
     *
     * @param rk is the range key.
     *
     * @return the item with this primary key, never returns null.
     *
     * @throws EntityNotFoundException if no such item exists.
     */
    public default T getItemOrThrow(Object hk, Object rk) throws EntityNotFoundException {
        T result = getItem(hk, rk);
        if ( null == result ) {
            StringBuilder sb = new StringBuilder()
                .append("Item in '")
                .append(getTableName())
                .append("' not found with ")
                .append(getHashKeyName())
                .append("='")
                .append(hk.toString())
                .append("'");
            if ( null != getRangeKeyName() ) {
                sb.append(" and ")
                    .append(getRangeKeyName())
                    .append("='")
                    .append(rk.toString())
                    .append("'");
            }
            throw new EntityNotFoundException(sb.toString());
        }
        return result;
    }

    /**
     * Do a batch get of items with the specified hash key and range keys. If an item does
     * not exist, there will not be an entry in the map for the IndexKey.
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param keys is an array of index keys to obtain in a single batch call.
     *
     * @return a map of IndexKey to the item, if an item does not exist the
     *        key will map to null. The returned map is unmodifiable.
     */
    public Map getItems(IndexKey... keys);

    /**
     * Test if a set of DB keys exist, if so those IndexKeys are returned in the set.
     * This is a little more efficient then calling getItems().
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param keys is an array of index keys to check for existance of.
     *
     * @return a set of index keys that do exist. Any key missing from this set
     *         does not exist. The returned set is unmodifiable.
     */
    public Set itemsExist(IndexKey... keys);

    /**
     * Overwrite or create a new item in the table.
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param item is the item to put.
     *
     * @return the previous item (or null)
     */
    public T putItem(T item);

    /**
     * Create a new item in the table, but if an item already exists, throw EntityExistsException.
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param item is the item to put.
     *
     * @throws EntityExistsException if the primary key of item already exists in this
     *         table.
     */
    public void putItemOrThrow(T item) throws EntityExistsException;

    /**
     * Shortcut method to catch EntityExistsException and return true/false instead.
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param item is the item to put.
     *
     * @return false if the primary key of this item already exists in which
     *         case the item was not actually saved to the table.
     */
    public default boolean putItemIfNotExists(T item) {
        try {
            putItemOrThrow(item);
            return true;
        } catch ( EntityExistsException ex ) {
            return false;
        }
    }

    /**
     * Batch put items, overwriting any items in the table that have the same hash key
     * and range key.
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param items are the items to put in the table.
     */
    public void putItems(T... items);

    /**
     * Update or create the item identified with the specified hash key and range key.
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param hk is the hash key.
     *
     * @param rk is the range key, or null if this table has no range key name.
     *
     * @return an update item builder used to describe what update should
     *         take place.
     *
     * @deprecated Use {@link #putItem(Object)} or {@link #putItems(Object[])} instead.
     */
    @Deprecated
    public UpdateItemBuilder updateItem(Object hk, Object rk);

    /**
     * Delete an item from the table with the specified hash key and range key, optionally
     * specify a filter condition that if evaluated to false causes a RollbackException
     * to be thrown (and no item deleted).
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param hk is the hash key.
     *
     * @param rk is the range key, or null if this table has no range key name.
     *
     * @param filterCondFn is used to describe under what condition this item may be
     *        deleted.
     *
     * @throws RollbackException if the filterCondFn condition was not met.
     */
    public void deleteItem(Object hk, Object rk, FilterCondFn filterCondFn) throws RollbackException;

    /**
     * Shortcut method to always delete an item (no condition specified).
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param hk is the hash key.
     *
     * @param rk is the range key, or null if this table has no range key name.
     */
    public default void deleteItem(Object hk, Object rk) {
        deleteItem(hk, rk, null);
    }

    /**
     * Batch delete all items with the specified hash key and range key in the IndexKey object.
     *
     * NOTE: This only works on "main" indexes.
     *
     * @param keys is an array of index keys that should be unconditionally deleted if they exist.
     */
    public void deleteItems(IndexKey... keys);
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy