/************************* * * * * * * * * * * * * ***************************
    Copyright (c) 1999-2005 Ryan Bobko
                       ryan@ostrich-emulators.com

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     
************************** * * * * * * * * * * * * **************************/

#ifndef SQLDBPLUGINS_H
#define SQLDBPLUGINS_H

#include "plugins.h"
#include "plugininfo.h"

/****************************************************************/
/** QHACCSQLDBPLUGIN                                           **/
/**   An abstract class to interact with a sql database        **/
/**                                                            **/
/****************************************************************/
class QHaccSQLDBInfo : public PluginInfo{
 public:
	QHaccSQLDBInfo();
	virtual ~QHaccSQLDBInfo();
};

class QHaccSQLDBPlugin : public QHaccDBPlugin{
 public:
	static const QHaccSQLDBInfo pinfo;

	QHaccSQLDBPlugin();
	virtual ~QHaccSQLDBPlugin();

	bool load( Table, const QHaccResultSet * );

	virtual bool load( QString& err );
	virtual bool save( QString& err );
	virtual bool imprt( QHaccResultSet * );
	virtual bool exprt( QHaccResultSet * );
	virtual void setAtom( AtomicOp op, QString ="dbatom" );

	virtual const PluginInfo& info() const;
	/**
	 * Perform a select statement on the database
	 * @param stmt The query to run
	 * @param cols The number of columns returned by the query
	 * @param rr The number of rows returned in the ResultSet
	 **/
	virtual auto_ptr<QHaccResultSet> sel( const QString& stmt, vector<ColType>,
																				uint& rr ) =0;

	/**
	 * Perform an update, delete on the database
	 * @param stmt The SQL to run
	 * @return 0 for failure, or anything else for success
	 **/
	virtual int run( const QString& stmt ) =0;

	/**
	 * Gets a fieldname for a SQL statemtn in a QHacc-friendly format
	 * @param fieldname The name of the field to be selected
	 * @param ct The field's datatype
	 * @return Valid SQL for returning the given field in QHacc-accessable format
	 **/
	virtual QString selField( const QString& fieldname, ColType ct ) const;

	/**
	 * @returns A field identifier suitable for database insertion
	 **/
	virtual QString sqlField( const TableCol& tc, ColType ct ) const;

	/**
	 * @returns a field identifier suitable for where-clauses
	 **/
	virtual QString sqlField( const TableSelect&, ColType ct ) const;

	

	/**
	 * @returns a selection string suitable for select-clauses
	 **/
	//virtual QString sqlField( const TableGet& ) const =0;

	virtual bool dirty() const;
	virtual void startLoad( Table t, uint =0 );
	virtual void stopLoad( Table t );


	// these functions satisfy the QHaccDBPlugin interface, but the
	// above functions will do all the work
	int add( Table, const TableRow& );

	void updateWhere( Table, const TableSelect&, const TableUpdate& );
	void updateWhere( Table, const TableSelect&, const TableRow& );

	auto_ptr<QHaccResultSet> getWhere( Table, vector<TableSelect>,
																		 uint& retrows );
	auto_ptr<QHaccResultSet> getWhere( Table, const TableGet&,
																		 vector<TableSelect>, uint& retrows );
	auto_ptr<QHaccResultSet> getWhere( Table, const TableSelect&,
																		 uint& retrows );

	void deleteWhere( Table, const TableSelect& );

	TableCol max( Table, int col );
	TableCol min( Table, int col );

 protected:
	/**
	 * Convert a QHacc tablerow into a string suitable for 
	 * insertion to the given table. This function only provides the 
	 * part of the insert statement after 'values'
	 * @param t The table to get the insertion
	 * @param r The row to be inserted
	 * @return The valid
	 **/
	QString iconv( Table t, const TableRow& r ) const;

	/**
	 * String to in table lookup
	 * @return Table id
	 **/
	static int table( const QString& );

	/**
	 * Table to tablename lookup
	 * @return tablename
	 **/
	static QString table( Table t );

	/**
	 * Convert the given string and column type into a QHacc-friendly tablecol.
	 * @param str The string returned from the database
	 * @param ct The desired ColType
	 * @return A QHacc-friendly data structure
	 **/
	//TableCol maketc( const QString& str, ColType ct ) const;

	/**
	 * An itermediate function used for both the min() and max() functions
	 * @param col The column on which to operate
	 * @param max if true, find the maximum, else, the minimum
	 * @return a query suitable for figuring out the min, or max, of a table
	 */
	virtual QString minmax( Table, int col, bool max ) =0;
	TableCol minmax( const QString& query, ColType ct );


};

#endif
