package org.geotools.data.jdbc;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;

import org.geotools.data.Query;
import org.geotools.data.Transaction;
import org.geotools.feature.Feature;


/**
 * The interface encapsulates SQL queries executing routines and
 * SELECT/INSERT/UPDATE/DELETE database operations implementation
 * for <code>JDBCDataStore</code>s.
 * <p>
 * <ul>
 * <li>
 * Hides the differencies of SQL dialects
 * and specifics of proprietary databases from <code>DataStore</code> interface.
 * <li>
 * Hides actual implementation of query executing whether it is a <code>PreparedStatement</code>
 * or properietary JDBC extensions to execute SQL queries.
 * <li>
 * Has a design that lets to custimize and optimize SQL execution when inserting, updating
 * or deleting of features from database.
 * <li>
 *  
 * </ul>
 * <p>
 * The example design of interface for inserting operation:
 * <pre>
 *  FeatureReader reader;
 *  FeatureTypeInfo ftInfo;
 *  SQLExecutor sqlExecutor;
 *  ..
 *  while(reader.hasNext()){
 *  	if(!sqlExecutor.isPreparedInsert())
 *  		sqlExecutor.prepareInsert(ftInfo);
 *  
 *  	Feature next = reader.next();
 *  	sqlExecutor.execInsert(next);
 *  
 *  
 *  }
 *  
 *  sqlExecutor.closeInsert();
 *  
 * </pre>
 * <p>
 * Usually method <code>prepareInsert(..)</code> makes from <code>FeatureTypeInfo</code> 
 * prepared statement from JDBC stuff and cache it to insert features later.
 * 
 * 
 * @author Vitalus
 * @since Geotools 2.2.x
 *
 */
public interface SQLExecutor {
	
	
	/**
	 * Returns connection to database.
	 * 
	 * @return
	 * 		a connection to database.
	 */
	public Connection getConnection();
	
	
	/**
	 * Returns current transaction from <code>JDBCFeatureStore</code>
	 * for SQL executing.
	 * 
	 * @return
	 */
	public Transaction getTransaction();

	
	
	/**
	 * Performs SELECT query to particular database using <code>Query</code> object to
	 * load features with a feature type from <code>FeatureTypeInfo</code>.
	 * 
	 * <p>
	 * 
	 * <p>
	 * Used by <code>JDBCFeatureReader</code> of <code>JDBCDataStore</code>.
	 * 
	 * @see org.geotools.data.jdbc.JDBCFeatureReader
	 * 
	 * @param featureTypeInfo
	 * @param datastoreConfig
	 * @param query
	 * @return
	 * @throws SQLException
	 * @throws IOException
	 */
	public QueryData execSelect(FeatureTypeInfo featureTypeInfo, JDBCDataStoreConfig datastoreConfig, Query query) throws SQLException, IOException;

	
	
	/**
	 * Prepares inserting of new features to the database.
	 * <p>
	 * Possible scenarious:
	 * <ul>
	 * <li>
	 * May create SQL prepared statement from feature type and DB configuration and cache it
	 * for the following inserting through <code>execInsert(..)</code>.</li>
	 * <li>
	 * ...
	 * </ul>
	 * 
	 * @param 
	 * featureTypeInfo feature type information object having <code>FeatureType, 
	 * FIDMapper, etc. </code> of features to be inserted by <code>execInsert(..)</code>.
	 * 
	 * @param datastoreConfig
	 */
	public void prepareInsert(FeatureTypeInfo featureTypeInfo)  throws SQLException, IOException;
	
	
	/**
	 * Returns whether <code>prepareInsert(..)</code> has been called already before first usage of
	 * <code>execInsert(..)</code>.
	 * 
	 * @return
	 */
	public boolean isPreparedInsert();
	
	
	/**
	 * Performs INSERT query to the database.
	 * <ul>
	 * <li>Takes <code>PreparedStatement</code> created by last call of <code>prepareInsert(..)</code>
	 * and
	 * 
	 * @param feature
	 * @return
	 * @throws SQLException
	 * @throws IOException
	 */
	public int execInsert(Feature feature)   throws SQLException, IOException;
	
	/**
	 * Releases cached resources, statements have been prepared
	 * by <code>prepareInsert(..)</code> method.
	 */
	public void closeInsert();
	
	
	public void prepareUpdate(FeatureTypeInfo ftInfo)  throws SQLException, IOException;
	
	public boolean isPreparedUpdate();
	
	public int execUpdate(Feature feature)   throws SQLException, IOException;
	
	public void closeUpdate();
	
	public void close();
	
	
}
