/*
* ome.api.IQuery
*
* Copyright 2006 University of Dundee. All rights reserved.
* Use is subject to license terms supplied in LICENSE.txt
*/
package ome.api;
import java.util.List;
import ome.annotations.NotNull;
import ome.conditions.ApiUsageException;
import ome.conditions.ValidationException;
import ome.model.IObject;
import ome.parameters.Filter;
import ome.parameters.Parameters;
import ome.parameters.QueryParameter;
/**
* Provides methods for directly querying object graphs. As far as is possible,
* IQuery should be considered the lowest level DB-access (SELECT) interface.
* Unlike the {@link ome.api.IUpdate} interface, using other methods will most
* likely not leave the database in an inconsitent state, but may provide stale
* data in some situations.
*
* By convention, all methods that begin with <code>get</code> will never
* return a null or empty {@link java.util.Collection}, but instead will throw
* a {@link ome.conditions.ValidationException}.
*
* @author Josh Moore <a
* href="mailto:josh.moore@gmx.de">josh.moore@gmx.de</a>
* @version 3.0
* @since 3.0
* @see Filter
* @see Parameters
* @see QueryParameter
*/
public interface IQuery extends ServiceInterface {
// ~ Simple Lookups
// =========================================================================
/**
* lookup an entity by class and id. If no such object exists, an exception
* will be thrown.
*
* @param klass
* the type of the entity. Not null.
* @param id
* the entity's id
* @return an initialized entity
* @throws ValidationException
* if the id doesn't exist.
*/
<T extends IObject> T get(@NotNull
Class<T> klass, long id) throws ValidationException;
/**
* lookup an entity by class and id. If no such objects exists, return a
* null.
*
* @param klass
* klass the type of the entity. Not null.
* @param id
* the entity's id
* @return an initialized entity or null if id doesn't exist.
*/
<T extends IObject> T find(@NotNull
Class<T> klass, long id);
/**
* lookup all entities that belong to this class and match filter.
*
* @param klass
* entity type to be searched. Not null.
* @param filter
* filters the result set. Can be null.
* @return a collection if initialized entities or an empty List if none
* exist.
*/
<T extends IObject> List<T> findAll(@NotNull
Class<T> klass, Filter filter);
// ~ Example-based Queries
// =========================================================================
/**
* search based on provided example entity. The example entity should
* <em>uniquely</em> specify the entity or an exception will be thrown.
*
* Note: findByExample does not operate on the <code>id</code> field. For
* that, use {@link #find(Class, long)}, {@link #get(Class, long)},
* {@link #findByQuery(String, Parameters)}, or
* {@link #findAllByQuery(String, Parameters)}
*
* @param example
* Non-null example object.
* @return Possibly null IObject result.
* @throws ApiUsageException
* if more than one result is return.
*/
<T extends IObject> T findByExample(@NotNull
T example) throws ApiUsageException;
/**
* search based on provided example entity. The returned entities will be
* limited by the {@link Filter} object.
*
* Note: findAllbyExample does not operate on the <code>id</code> field.
* For that, use {@link #find(Class, long)}, {@link #get(Class, long)},
* {@link #findByQuery(String, Parameters)}, or
* {@link #findAllByQuery(String, Parameters)}
*
*
* @param example
* Non-null example object.
* @param filter
* filters the result set. Can be null.
* @return Possibly empty List of IObject results.
*/
<T extends IObject> List<T> findAllByExample(@NotNull
T example, Filter filter);
// ~ String-field-Queries
// =========================================================================
/**
* search a given field matching against a String. Method does <em>not</em>
* allow for case sensitive or insensitive searching since this is
* essentially a lookup. The existence of more than one result will result
* in an exception.
*
* @param klass
* type of entity to be searched
* @param field
* the name of the field, either as simple string or as public
* final static from the entity class, e.g.
* {@link ome.model.containers.Project#NAME}
* @param value
* String used for search.
* @return found entity or possibly null.
* @throws ome.conditions.ApiUsageException
* if more than one result.
*/
<T extends IObject> T findByString(@NotNull
Class<T> klass, @NotNull
String field, String value) throws ApiUsageException;
/**
* search a given field matching against a String. Method allows for case
* sensitive or insensitive searching using the (I)LIKE comparators. Result
* set will be reduced by the {@link Filter} instance.
*
* @param klass
* type of entity to be searched. Not null.
* @param field
* the name of the field, either as simple string or as public
* final static from the entity class, e.g.
* {@link ome.model.containers.Project#NAME}. Not null.
* @param stringValue
* String used for search. Not null.
* @param caseSensitive
* whether to use LIKE or ILIKE
* @param filter
* filters the result set. Can be null.
* @return A list (possibly empty) with the results.
*/
<T extends IObject> List<T> findAllByString(@NotNull
Class<T> klass, @NotNull
String field, String stringValue, boolean caseSensitive, Filter filter);
// ~ Parameter-based Queries
// =========================================================================
// These methods use the ome.parameters package for representing
// arbitrary (Integer, Long, String, IObject, etc.) parameters. We have
// removed java.lang.Object based parameters from the API for cross-language
// support.
// We don't provide methods with Page argument. Include in QueryParameters.
// Available queries:
// is class in hibernate? use parameters as field name.
// see ClassnameQuery for documentation
// is class of querysource?
// lookup in hibernate named query
// lookup in database
// else: see StringQuerySource documentation.
/**
* executes the stored query with the given name. If a query with the name
* cannot be found, an exception will be thrown.
*
* The queryName parameter can be an actual query String if the
* StringQuerySource is configured on the server and the user running the
* query has proper permissions.
*
* @param queryName
* String identifier of the query to execute
* @param parameters
* array of {@link QueryParameter}. Not null. The
* {@link QueryParameter#name} field maps to a field-name which
* is then matched against the {@link QueryParameter#value}
* @return Possibly null IObject result.
* @throws ValidationException
*/
<T extends IObject> T findByQuery(@NotNull
String queryName, Parameters parameters) throws ValidationException;
/**
* executes the stored query with the given name. If a query with the name
* cannot be found, an exception will be thrown.
*
* The queryName parameter can be an actual query String if the
* StringQuerySource is configured on the server and the user running the
* query has proper permissions.
*
* Queries can only return lists of {@link IObject} instances. This means
* all must be of the form:
*
* <pre>
* select this from SomeModelClass this ...
* </pre>
*
* though the alias "this" is unimportant. Do not try to return multiple
* classes in one call like:
*
* <pre>
* select this, that from SomeClass this, SomeOtherClass that ...
* </pre>
*
* nor to project values out of an object:
*
* <pre>
* select this.name from SomeClass this ...
* </pre>
*
* If a page is desired, add it to the query parameters.
*
* @param queryName
* String identifier of the query to execute. Not null.
* @param parameters
* array of {@link QueryParameter}. The
* {@link QueryParameter#name} field maps to a field-name which
* is then matched against the {@link QueryParameter#value}
* @return Possibly empty List of IObject results.
*/
<T extends IObject> List<T> findAllByQuery(@NotNull
String queryName, Parameters parameters);
/**
* executes a full text search based on Lucene. Each term in the query can
* also be prefixed by the name of the field to which is should be
* restricted.
*
* Examples:
* <ul>
* <li>owner:root AND annotation:someTag</li>
* <li>file:xml AND name:*hoechst*</li>
* </ul>
*
* For more information, see
* <a href="http://lucene.apache.org/java/docs/queryparsersyntax.html">Query Parser Synax</a>
*
* The return values are first filtered by the security system.
*
* @param <T>
* @param type
* A non-null class specification of which type should be
* searched.
* @param query
* A non-null query string. An empty string will return no
* results.
* @param parameters
* Currently the parameters themselves are unusued. But the
* {@link Parameters#filter} can be used to limit the number
* of results returned ({@link Filter#limit}) or the
* user for who the results will be found ({@link Filter#owner()}).
* @return A list of loaded {@link IObject} instances. Never null.
*/
<T extends IObject> List<T> findAllByFullText(@NotNull
Class<T> type, @NotNull
String query, Parameters parameters);
// ~ Projections
// =========================================================================
/**
* Return a list of Java {@link Object} instances (not {@link IObject}
* instances). These are the column names as specified in the HQL
* select statement (more than one is required).
*
* If an aggregation statement is used, a group by clause must be added.
*
* Examples:
* <ul>
* <li>select i.name, i.description from Image i where i.name like '%.dv'</li>
* <li>select tag.textValue, tagset.textValue from TagAnnotation tag join tag.annotationLinks l join l.child tagset</li>
* <li>select p.pixelsType.value, count(p.id) from Pixel p group by p.pixelsType.value</li>
* </ul>
*/
List<Object[]> projection(@NotNull String query, Parameters parameters);
// ~ Other
// =========================================================================
/**
* refreshes an entire {@link IObject} graph, recursive loading all data for
* the managed instances in the graph from the database. If any non-managed
* entities are detected (e.g. without ids), an {@link ApiUsageException}
* will be thrown.
*
* @param iObject
* Non-null managed {@link IObject} graph which should have all
* values re-assigned from the database
* @return a similar {@link IObject} graph (with possible additions and
* deletions) which is in-sync with the database.
* @throws ApiUsageException
* if any non-managed entities are found.
*/
<T extends IObject> T refresh(@NotNull
T iObject) throws ApiUsageException;
}