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

com.speedment.runtime.core.manager.Manager Maven / Gradle / Ivy

Go to download

A Speedment bundle that shades all dependencies into one jar. This is useful when deploying an application on a server.

The newest version!
/*
 *
 * Copyright (c) 2006-2019, Speedment, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); You may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.speedment.runtime.core.manager;

import com.speedment.runtime.core.component.PersistenceTableInfo;
import com.speedment.runtime.core.exception.SpeedmentException;
import com.speedment.runtime.field.method.BackwardFinder;
import com.speedment.runtime.field.method.FindFrom;
import com.speedment.runtime.field.trait.HasFinder;
import com.speedment.runtime.field.trait.HasNullableFinder;

import java.util.function.Function;
import java.util.stream.Stream;

/**
 * A Manager is responsible for abstracting away an Entity's data source CRUD
 * operations. Entity sources can be RDBMSes, files or other data sources.
 *
 * A Manager must be thread safe and be able to handle several reading and
 * writing threads at the same time.
 *
 * @param  entity type for this Manager
 *
 * @author Per Minborg
 * @author Emil Forslund
 * @since 2.0.0
 */
public interface Manager extends PersistenceProvider, PersistenceTableInfo {

    /**
     * Creates and returns a new {@link Stream} over all entities in the
     * underlying data source (e.g database). This is the main query API for
     * Speedment.
     * 

* The order in which elements are returned when the stream is eventually * consumed is unspecified. The order may even change from one * invocation to another. Thus, it is an error to assume any particular * element order even though is might appear, for some stream sources, that * there is a de-facto order. *

* If a deterministic order is required, then make sure to invoke the * {@link Stream#sorted(java.util.Comparator)} method on the {@link Stream} * returned. *

* Mutable elements are not reused within the stream. More formally, there * are no pair of mutable stream elements e1 and * e2 such that e1 == e2. *

* The Stream will never contain null elements. *

* This is an inexpensive O(1) operation that will complete in * constant time regardless of the number of entities in the underlying * database. *

* The returned stream is aware of its own pipeline and will optionally * optimize its own pipeline whenever it encounters a Terminal * Operation so that it will only iterate over a minimum set of * matching entities. *

* When a Terminal Operation is eventually called on the {@link Stream}, * that execution time of the Terminal Operation will depend on the * optimized pipeline and the entities in the underlying database. *

* The Stream will be automatically * {@link Stream#onClose(java.lang.Runnable) closed} after the Terminal * Operation is completed or if an Exception is thrown during the Terminal * Operation. *

* Some of the Terminal Operations are: *

    *
  • {@link Stream#forEach(java.util.function.Consumer) forEach(Consumer)} *
  • {@link Stream#forEachOrdered(java.util.function.Consumer) forEachOrdered(Consumer)} *
  • {@link Stream#toArray() toArray()} *
  • {@link Stream#toArray(java.util.function.IntFunction) toArray(IntFunction)} *
  • {@link Stream#reduce(java.util.function.BinaryOperator) reduce(BinaryOperation} *
  • {@link Stream#reduce(java.lang.Object, java.util.function.BinaryOperator) reduce(Object, BinaryOperator)} *
  • {@link Stream#reduce(java.lang.Object, java.util.function.BiFunction, java.util.function.BinaryOperator) reduce(Object, BiFunction, BinaryOperator)} *
  • {@link Stream#collect(java.util.stream.Collector) collect(Collector)} *
  • {@link Stream#collect(java.util.function.Supplier, java.util.function.BiConsumer, java.util.function.BiConsumer) collect(Supplier, BiConsumer, BiConsumer)} *
  • {@link Stream#min(java.util.Comparator) min(Comparator)} *
  • {@link Stream#max(java.util.Comparator) min(Comparator)} *
  • {@link Stream#count() count()} *
  • {@link Stream#anyMatch(java.util.function.Predicate) anyMatch(Predicate)} *
  • {@link Stream#noneMatch(java.util.function.Predicate) noneMatch(Predicate)} *
  • {@link Stream#findFirst() findFirst()} *
  • {@link Stream#findAny() findAny()} *
  • {@link Stream#iterator() iterator()} *
*

* Any Terminating Operation may throw a {@link SpeedmentException} if the * underlying database throws an Exception (e.g. an SqlException) *

* Because the Stream may short-circuit operations in the Stream pipeline, * methods having side-effects (like * {@link Stream#peek(java.util.function.Consumer) peek(Consumer)} will * potentially be affected by the optimization. *

* Here are some examples of how the stream optimization might work: *

    *
  • *
    {@code stream
         *   .filter(Hare.NAME.equal("Henry")
         *   .collect(toList());}
    *
    {@code -> select * from hares where name='Henry'}
    *
  • *
  • *
    {@code stream.count();}
    *
    {@code -> select count(*) from hares}
    *
  • *
  • *
    {@code stream
         *   .filter(Hare.NAME.equal("Henry")
         *   .count();}
    *
    {@code -> select count(*) from hares where
         *   name='Henry'}
    *

    *

  • *
  • *
    {@code stream
         *   .filter(Hare.NAME.equal("Henry")
         *   .filter(Hare.AGE.greaterThan(5)
         *   .count();}
    *
    {@code -> select count(*) from hares where
         *          name ='Henry'
         *        and
         *          age > 5}
    *
  • *
* * * @return a new stream over all entities in this table in unspecified order * * @throws SpeedmentException if an error occurs during a Terminal Operation * (e.g. an SqlException is thrown by the underlying database) * * @see java.util.stream * @see Stream */ Stream stream(); /** * Persists the provided entity to the underlying database and returns a * potentially updated entity. If the persistence fails for any reason, an * unchecked {@link SpeedmentException} is thrown. *

* It is unspecified if the returned updated entity is the same provided * entity instance or another entity instance. It is erroneous to assume * either, so you should use only the returned entity after the method has * been called. However, it is guaranteed that the provided entity is * untouched if an exception is thrown. *

* The fields of returned entity instance may differ from the provided * entity fields due to auto generated column(s) or because of any other * modification that the underlying database imposed on the persisted * entity. * * @param entity to persist * @return an entity reflecting the result of the persisted entity * * @throws SpeedmentException if the underlying database throws an exception * (e.g. SQLException) */ default ENTITY persist(ENTITY entity) throws SpeedmentException { return persister().apply(entity); } /** * Updates the provided entity in the underlying database and returns a * potentially updated entity. If the update fails for any reason, an * unchecked {@link SpeedmentException} is thrown. *

* It is unspecified if the returned updated entity is the same provided * entity instance or another entity instance. It is erroneous to assume * either, so you should use only the returned entity after the method has * been called. However, it is guaranteed that the provided entity is * untouched if an exception is thrown. *

* The fields of returned entity instance may differ from the provided * entity fields due to auto generated column(s) or because of any other * modification that the underlying database imposed on the persisted * entity. *

* Entities are uniquely identified by their primary key(s). * * @param entity to update * @return an entity reflecting the result of the updated entity * * @throws SpeedmentException if the underlying database throws an exception * (e.g. SQLException) */ default ENTITY update(ENTITY entity) throws SpeedmentException { return updater().apply(entity); } /** * Removes the provided entity from the underlying database and returns the * provided entity instance. If the deletion fails for any reason, an * unchecked {@link SpeedmentException} is thrown. *

* Entities are uniquely identified by their primary key(s). * * @param entity to remove * @return the provided entity instance * * @throws SpeedmentException if the underlying database throws an exception * (e.g. SQLException) */ default ENTITY remove(ENTITY entity) throws SpeedmentException { return remover().apply(entity); } /** * Returns a Function that, when it is applied, will produce an equivalent * result as if {@link #finderByNullable(HasNullableFinder)} was called. * * @param the type of the foreign entity * * @param fkField the foreign key field * @return a function that returns an Entity (if any) that matches the given * a foreign key relation (foreign field and entity) * * @see #finderByNullable(HasNullableFinder) */ default FindFrom finderBy( HasFinder fkField) { return fkField.finder(getTableIdentifier(), this::stream); } /** * Retrieves and returns an Entity that matches the given a foreign key * relation (foreign field and entity). For example, if there is an entity * Carrot with a FK to Hare using the column "hare", then * hares.find(Carrot.HARE, carrot) will return the Hare that the Carrot.HARE * field is pointing to. * * @param the type of the foreign entity * * @param fkField the foreign key field * @param fkEntity the foreign key entity * @return an Entity (if any) that matches the given a foreign key relation * (foreign field and entity) */ default ENTITY findBy( HasFinder fkField, FK_ENTITY fkEntity) { return finderBy(fkField).apply(fkEntity); } /** * Returns a Function that, when it is applied, will produce an equivalent * result as if {@link #findByNullable(HasNullableFinder, Object)} was * called. * * @param the type of the foreign entity * * @param fkField the foreign key field * @return a function that returns an Entity (if any) that matches the given * a foreign key relation (foreign field and entity) * * @see #findByNullable(HasNullableFinder, Object) */ default Function> finderByNullable( HasNullableFinder fkField) { return fkField.nullableFinder(getTableIdentifier(), this::stream); } /** * Retrieves and returns a stream of Entities (with one or zero elements) * that matches the given a foreign key relation (foreign field and entity). * For example, if there is an entity Carrot with a FK to Hare using the * column "hare", then hares.find(Carrot.HARE, carrot) will return a stream * with the Hare that the Carrot.HARE field is pointing to or Stream.empty() * if the hare column in carrot was null. I.e. The returned Stream will * contain either zero or one element. * * @param the type of the foreign entity * * @param fkField the foreign key field * @param fkEntity the foreign key entity * @return an Entity (if any) that matches the given a foreign key relation * (foreign field and entity) */ default Stream findByNullable( HasNullableFinder fkField, FK_ENTITY fkEntity) { return finderByNullable(fkField).apply(fkEntity); } /** * Returns a Function that, when it is applied, will produce an equivalent * result as if {@link #findBackwardsBy(HasFinder, Object)} was called. * * @param the type of the foreign entity * * @param fkField the foreign key field * @return an Entity (if any) that matches the given a foreign key relation * (foreign field and entity) * * @see #findBackwardsBy(HasFinder, Object) */ default BackwardFinder finderBackwardsBy( HasFinder fkField) { return fkField.backwardFinder(getTableIdentifier(), this::stream); } /** * Retrieves and returns a stream of matching entities that matches the * given a foreign key relation (foreign field and entity). For example, if * there is an entity Carrot with a FK to Hare using the column "hare", then * carrots.findBackwardsBy(Carrot.HARE, hare) will produce a Stream of all * the Carrots that points to the given hare using the Carrot.HARE column. * * @param the type of the foreign entity * * @param fkField the foreign key field * @param fkEntity the foreign key entity * @return an Entity (if any) that matches the given a foreign key relation * (foreign field and entity) */ default Stream findBackwardsBy( HasFinder fkField, FK_ENTITY fkEntity) { return finderBackwardsBy(fkField).apply(fkEntity); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy