/*
* Copyright 2001-2008 Geert Bevin <gbevin[remove] at uwyn dot com> and
* JR Boyens <gnu-jrb[remove] at gmx dot net>
* Licensed under the Apache License, Version 2.0 (the "License")
* $Id: GenericQueryManager.java 3918 2008-04-14 17:35:35Z gbevin $
*/
package com.uwyn.rife.database.querymanagers.generic;
import com.uwyn.rife.database.DbRowProcessor;
import com.uwyn.rife.database.exceptions.DatabaseException;
import com.uwyn.rife.database.queries.CreateTable;
import com.uwyn.rife.site.ValidationContext;
import java.util.List;
/**
* A <code>GenericQueryManager</code> provides features that make it easy to
* persist and retrieve beans in a database with single method calls. An
* instance of the manager can by obtained by using the {@link
* GenericQueryManagerFactory} class.
* <p>Callbacks are also supported to make it possible to interact with the
* persistence actions in a bean-centric way. More information can be found in
* the {@link Callbacks} interface.
*
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
* @version $Revision: 3918 $
* @see
* com.uwyn.rife.database.querymanagers.generic.GenericQueryManagerFactory
* @see com.uwyn.rife.database.querymanagers.generic.Callbacks
* @since 1.0
*/
public interface GenericQueryManager<BeanType> extends ValidationContext
{
/**
* Get the handled class
*
* @return the handled class
* @since 1.0
*/
Class getBaseClass();
/**
* Get the managed database table name
*
* @return the table name
* @since 1.0
*/
String getTable();
/**
* Get the name of the property defined as the identifier.
* <p>Defaults to "id".
*
* @return the name of the property defined as the identifier
* @since 1.0
*/
String getIdentifierName();
/**
* Get the value of the property defined as the identifier.
* <p>The property defaults to "id".
*
* @param bean the bean to retrieve the identifier value for
* @return the value of the property defined as the identifier
* @since 1.0
*/
int getIdentifierValue(BeanType bean) throws DatabaseException;
/**
* Install the database structure into the database.
* <p>This method will cause the structure needed to persist the bean to
* be installed into the database. This includes any validatity checks
* that the database supports and that have already been defined.
* Including (but not limited to): length, notNull, notEmpty, etc. etc.
* This method will fail semi-gracefully if the installation fails.
* Generally it's best to catch the {@link DatabaseException} and assume
* that the database is already installed.
*
* @see #remove()
* @since 1.0
*/
void install() throws DatabaseException;
/**
* Install the database structure into the database using a custom query.
* <p>This method will cause the structure needed to persist the bean to
* be installed into the database using the provided custom query. The
* custom query is usually obtained by using {@link
* #getInstallTableQuery()}. This includes any validatity checks that the
* database supports and that have already been defined. Including (but
* not limited to): length, notNull, notEmpty, etc. etc. This method will
* fail semi-gracefully if the installation fails. Generally it's best to
* catch the {@link DatabaseException} and assume that the database is
* already installed.
*
* @param query the {@link CreateTable} query to use to create the table
* @see #install()
* @see #remove()
* @since 1.0
*/
void install(CreateTable query) throws DatabaseException;
/**
* Remove the database structure
* <p>This method will cause the database structure to be removed from the
* database deleting all saved beans in the process. No new beans of this
* type can be persisted until the database structure is reinstalled.
*
* @see #install()
* @since 1.0
*/
void remove() throws DatabaseException;
/**
* Persist a bean.
* <p>This method allows a person to persist a bean to a DB to be later
* restored. A bean to be persisted must have at least one integer
* identifier and one bean property both with accessors. If the identifier
* value is greater than or equal to 0, the bean is attempted to be
* updated first, if this fails (or the identifier is -1) the bean is
* assumed to be a new bean and a new sequential identifier is generated
* by the database.
*
* @param bean the bean to be saved
* @return the identifier assigned to the new/updated bean
* @since 1.0
*/
int save(BeanType bean) throws DatabaseException;
/**
* Insert a bean in the database.
* <p>This method specifically forces insertion of the bean into the
* database. This method is only recommended for use when you know what
* you are doing. The {@link #save(Object bean)} method is safer because
* it can detect whether to insert or update the bean in that database,
* leading to safer, simpler code. Bean restrictions mirror {@link
* #save(Object bean)}.
*
* @param bean the bean to be inserted
* @return the indentier assigned to the new bean
* @see #save(Object bean)
* @since 1.0
*/
int insert(BeanType bean) throws DatabaseException;
/**
* Update an existing bean in the database.
* <p>This method specifically forces the updating of the bean into the
* database. This method is only recommended for use when you know what
* you are doing. The {@link #save(Object bean)} method is safer because
* it can detect whether to insert or update the bean in that database,
* leading to safer, simpler code. Bean restrictions mirror {@link
* #save(Object bean)}.
*
* @param bean the bean to be updated
* @return the indentier assigned to the new bean
* @see #save(Object bean)
* @since 1.0
*/
int update(BeanType bean) throws DatabaseException;
/**
* Restore all the beans persisted under this manager.
* <p>This method will return a {@link List} of all the beans persisted
* under this manager.
*
* @return a {@link List} of all the persisted beans
* @since 1.0
*/
List<BeanType> restore() throws DatabaseException;
/**
* Restore a single bean using the identifier.
* <p>This method will return a single bean having the provided
* identifier. Since the identifier is unique, you can be assured of a
* single bean with a persistent id. This id is never changed under normal
* circumstances.
*
* @param objectId the identifier to identify the bean to restore
* @return the bean that matches the identifier provided
* @since 1.0
*/
BeanType restore(int objectId) throws DatabaseException;
/**
* Restore all beans using the row processor provided.
* <p>This method will return all beans using a {@link DbRowProcessor} for
* reduced memory requirements as opposed to the full {@link List} version
* of {@link #restore()}.
*
* @param rowProcessor the DbRowProcessor each row should be passed to
* @return true if beans were restored, false if not
* @see #restore()
* @since 1.0
*/
boolean restore(DbRowProcessor rowProcessor) throws DatabaseException;
/**
* Restore the first bean that matches the {@link RestoreQuery}.
* <p>This method will return the first bean that matches the {@link
* RestoreQuery}. Especially useful for selecting the first returned bean
* from a complex query.
*
* @param query the query the bean should be restored from
* @return the first bean that matches the {@link RestoreQuery}
* @see #restore(RestoreQuery)
* @since 1.0
*/
BeanType restoreFirst(RestoreQuery query) throws DatabaseException;
/**
* Restore a list of beans that match the provided {@link RestoreQuery}.
* <p>This method will return a list of beans that match the provided
* {@link RestoreQuery}. This can be used for more complex queries, or for
* exclusion of certain beans from the results.
*
* @param query the query the beans should be restored from
* @return a list containing all the restored beans
* @see #restore()
* @since 1.0
*/
List<BeanType> restore(RestoreQuery query) throws DatabaseException;
/**
* Restore a list of beans that match the provided {@link RestoreQuery}
* and process with the {@link DbRowProcessor}.
* <p>This method will return a list of beans that match the provided
* RestoreQuery and process these matches with the provided {@link
* DbRowProcessor}. This can be used for more memory-intensive (or larger
* result sets) complex queries or for the exclusion of certain beans from
* the results.
*
* @param query the query the beans should be restored from
* @param rowProcessor the row processor that should be used to process
* each matched bean row
* @return true if beans were processed, false if not
* @since 1.0
*/
boolean restore(RestoreQuery query, DbRowProcessor rowProcessor) throws DatabaseException;
/**
* Get the query that would be used to install the table.
* <p>This method will return the query that would be used to install the
* database structure. Can be used to modify the structure if i custom
* structure is needed. Mostly likely to be passed into {@link
* #install(CreateTable)}
*
* @return the query that would be used to install the database structure
* @since 1.0
*/
CreateTable getInstallTableQuery() throws DatabaseException;
/**
* Get the base query used to restore beans.
* <p>This method will return the base query that would be used to restore
* beans with {@link #restore()}. This can be used to restrict the query
* so that less beans are returned or certain beans are returned.
*
* @return the query that would be used to restore a number of beans
* @since 1.0
*/
RestoreQuery getRestoreQuery();
/**
* Get the base query used to restore a single identifed bean.
* <p>This method will return the base query that would be used to restore
* a single bean with {@link #restore(int)}. This can be used to restrict
* the query so that a bean not matching the query will not be returned.
*
* @return the query that would be used to restore a single identified
* bean
* @since 1.0
*/
RestoreQuery getRestoreQuery(int objectId);
/**
* Count the number of beans persisted.
* <p>This method will count the total number of beans persisted under
* this manager.
*
* @since 1.0
* @return the number of beans persisted under this manager
* @since 1.0
*/
int count() throws DatabaseException;
/**
* Count the number of beans persisted with a custom {@link CountQuery}.
* <p>This method will count the total number of beans persisted under
* this manager that match the provided {@link CountQuery}.
*
* @param query the query that will be used to determine which beans to
* count
* @return the number of beans persisted under this manager that match the
* provided query
* @since 1.0
*/
int count(CountQuery query) throws DatabaseException;
/**
* Get the base {@link CountQuery} used to count the number of beans
* persisted under this manager
*
* @return the query that would be used to count the total number of beans
* persisted under this managerù
* @since 1.0
*/
CountQuery getCountQuery();
/**
* Delete a single identified bean
* <p>This method will delete the bean identifed by the passed in
* identifier.
*
* @param objectId the identifier of the bean
* @return true if the deletion suceeded, false if it did not
* @since 1.0
*/
boolean delete(int objectId) throws DatabaseException;
/**
* Delete beans selected by the passed in {@link DeleteQuery}
* <p>This method will delete all beans identified by the passed in {@link
* DeleteQuery}.
*
* @param query the query to select the beans
* @return true if the deletion suceeded, false if it did not
* @since 1.0
*/
boolean delete(DeleteQuery query) throws DatabaseException;
/**
* Return the base {@link DeleteQuery} that would be used to delete beans
*
* @return the base {@link DeleteQuery}
* @since 1.0
*/
DeleteQuery getDeleteQuery();
/**
* Return the base {@link DeleteQuery} that would be used to delete a
* single bean
*
* @param objectId the identifier to fill into the base {@link DeleteQuery}
* @return the base {@link DeleteQuery}
* @since 1.0
*/
DeleteQuery getDeleteQuery(int objectId);
/**
* Add the listener to the manager to get notifications when actions
* were successful.
*
* @param listener the listener that has to be added
* @since 1.5
*/
void addListener(GenericQueryManagerListener listener);
/**
* Remove all the listeners that are registered to the manager.
*
* @since 1.5
*/
void removeListeners();
/**
* Create a new generic query manager of the same kind but for another
* bean class.
*
* @param beanClass the class of the bean for which the new generic query
* manager has to be created
* @return a new generic query manager instance
* @since 1.6
*/
<OtherBeanType> GenericQueryManager<OtherBeanType> createNewManager(Class<OtherBeanType> beanClass);
}