/***************************************************************************
                          sqloutputiface.h  -  description
                             -------------------
    begin                : Fre Mär 8 2002
    copyright            : (C) 2002 by Harald Fernengel
    email                : harry@kdevelop.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef SQLOUTPUTIFACE_H
#define SQLOUTPUTIFACE_H

#include <qobject.h>
#include <qstring.h>
#include <qsqlerror.h>
#include <qsqlquery.h>
#include <qsqldriver.h>
#include <qstylesheet.h>
#include <qsqlindex.h>

#include <klocale.h>
#include <kurl.h>

class QSqlDatabase;

/** Interface for outputting SQL stuff */
class SqlOutputIface
{
public:
  /** the requested URL and the (already opened!) database connection */
  SqlOutputIface( const KURL&, QSqlDatabase* = 0 );
  virtual ~SqlOutputIface();

  virtual void setDatabase( QSqlDatabase* ) = 0;

  /** returns a list of available tables */
  virtual QString showTables() = 0;
  /** shows the contents of a query */
  virtual QString showQuery( const QString& ) = 0;
  /** shows the contents of a table, displays only a number of rows (limit)
      starting from offset (limitOffset) */
  virtual QString showTable( const QString&, int limit = -1, int limitOffset = -1 ) = 0;
  /** an error has occured, you can get the message via lastError() */
  virtual void error( const QString&, const QSqlError& = QSqlError() ) = 0;
  /** An action was successful */
  virtual QString success( const QString& ) = 0;
  /** shows the start page if no host/plugin/database is given */
  virtual QString showStartPage() = 0;
  /** the mimetype of the returned data */
  virtual QString mimeType() const = 0;
  /** the text of the last error that occured */
  virtual QString lastError() const = 0;
  /** shows table structure and meta-data */
  virtual QString showMetaData( const QString& ) = 0;

  /** Shows special pages. Note that this is highly output format dependent, so
   *  not every outputformat might implement each special output. The second
   *  parameter stands for the desired table, QString::null means "no table".
   *  Additional parameters (function specific) can be passed on in the QStringList.
   */
  virtual QString showSpecial( const QString&, const QString& = QString::null, const QStringList& = QStringList(),
			       int limit = -1, int limitOffset = -1 );
  
  static QString noPluginsAvailableStr()
  {
    return i18n( "Cannot find Qt SQL plugins. "
	"Please make sure you have at least one installed" );
  }

  static QString pluginNotFoundStr( const QString& name )
  {
    return i18n( "Cannot find Qt SQL plugin \"%1\"." ).arg( name );
  }

  static QString emptyResultSet()
  {
    return i18n( "The query returned no results." );
  }
  
  static QString cannotOpenDatabase()
  {
    return i18n( "Could not establish connection to database." );
  }

  static QString errorExecuteQuery()
  {
    return i18n( "Could not execute query." );
  }

  static QString errorNotCapable()
  {
    return i18n( "This outputformat is not capable of displaying the desired action" );
  }
  
  static QString errorNoPrimaryKey()
  {
    return i18n( "This action requires a table with a primary key" );
  }
    
  // stupid little helper function that returns a SQL command that selects all/limit from a table
  static QString generateSQLCommand( const QString& tableName, int limit = -1, int limitOffset = -1 )
  {
    QString query = "SELECT * FROM " + tableName;
    if ( limitOffset < 0 )
      limitOffset = 0;
    if ( limit > 0 ) {
      query += " LIMIT " + QString::number( limitOffset );
      query += " OFFSET " + QString::number( limit );
    }
    return query;
  }
  
  // generates a url encoded string with the primary key/value pairs
  // for example &_fieldID=1&_fieldName=harry
  static QString generatePrimaryKey( const QSqlQuery& query, const QSqlIndex& pk )
  {
    QString out;
    QSqlRecord rec = query.driver()->record( query );
      
    for ( uint i = 0; i < pk.count(); ++i ) {
      out += "&_field" + QStyleSheet::escape( pk.fieldName( i ) ) +
             "=" + QStyleSheet::escape( query.value( rec.position( pk.fieldName( i ) ) ).toString() );
    }
    
    return out;
  }

};

inline SqlOutputIface::SqlOutputIface( const KURL&, QSqlDatabase* ) {}
inline SqlOutputIface::~SqlOutputIface() {}
inline QString SqlOutputIface::showSpecial( const QString&, const QString&, const QStringList&, int, int ) 
{
  return errorNotCapable();
}

#endif
