#ifndef BASEADAPTOR_H
#define BASEADAPTOR_H

#include "dal.h"
#include "query.h"
#include "field.h"
#include "database.h"

#include <QString>
#include <QVariant>
#include <QList>

class QSqlDatabase;
class QUrl;

class BaseAdaptor
{
public:
    enum ConstraintAction { None = 0, SetNull, SetDefault, Cascade, Restrict };
    BaseAdaptor( const Database *db );
    virtual ~BaseAdaptor();

    QStringList tables( const QVariant &clause ) const;
    QString expand( const QVariant& other ) const;
    QString represent( const QVariant &value ) const;

    virtual QString ADD( const QVariantList &args ) const;
    virtual QString DIV( const QVariantList &args ) const;
    virtual QString SUB( const QVariantList &args ) const;
    virtual QString DESC( const QVariantList &args ) const;
    virtual QString COMMA( const QVariantList &args ) const;
    virtual QString MUL( const QVariantList &args ) const;
    virtual QString GT( const QVariantList& args ) const;
    virtual QString GE( const QVariantList& args ) const;
    virtual QString EQ( const QVariantList& args ) const;
    virtual QString NE( const QVariantList& args ) const;
    virtual QString LT( const QVariantList& args ) const;
    virtual QString LE( const QVariantList& args ) const;
    virtual QString LIKE( const QVariantList& args ) const;
    virtual QString BELONGS( const QVariantList& args ) const;
    virtual QString AND( const QVariantList& args ) const;
    virtual QString OR( const QVariantList& args ) const;
    virtual QString NOT( const QVariantList& args ) const;

    virtual QString LOWER( const QVariantList &args ) const;
    virtual QString UPPER( const QVariantList &args ) const;
    virtual QString EXTRACT( const QVariantList &args ) const;
    virtual QString AGGREGATE( const QVariantList &args ) const;
    virtual QString ON( const QVariantList &args ) const;
    virtual QString RANDOM() const;
    virtual QString LEFT_JOIN() const;

    virtual QString DELETE(const QString &table, const Query &where = Query() ) const;
    virtual QString DROP( const QString &table ) const;
    virtual QString INSERT( const QString &table, const QMap<QString,QVariant> &values ) const;
    virtual QString UPDATE( const QString &table, const QMap<Field,QVariant> &values, const Query &where = Query() ) const;
    virtual QString SELECT( const QList<Field> &fields, const Query &where, const QMap<QString,QVariant> &options) const;
    virtual QString SELECT_LIMITBY( const QString &selectClause, const QString &fieldsClause,
                                    const QString &tablesClause, const QString &whereClause,
                                    const QString &orderBy, const QVariant &limitby ) const;
    virtual QStringList TRUNCATE( const QString &table ) const;
    virtual QString COUNT( const QString &table, const Query &where = Query()) const;
    virtual QString DEFAULT( const QVariant &defaultValue ) const;
    virtual QString NOT_NULL( bool notNull ) const;
    virtual QString PRIMARY_KEY( ) const;

    virtual QString TABLE_CONSTRAINT_FOREIGN_KEY( const Field &source, const Field &target, ConstraintAction onDelete = None, ConstraintAction onUpdate = None ) const;
    virtual QString TABLE_CONSTRAINT_CHECK( const Table &source, const Query &clause ) const;
    virtual QString TABLE_CONSTRAINT_UNIQUE( const QList<Field> &fields  ) const;

    virtual QString constraintName( const QString &tableName, const QString &fieldName ) const;

    virtual QString representCustom( const QVariant &value ) const;
    virtual QString mapFieldType( const QVariant::Type &type ) const = 0;
    virtual QString lastrowid( const QString &table ) const = 0;
    virtual QSqlDatabase connection( ) const = 0;
    virtual QString quoteFieldName( const Field &field ) const;
    virtual QString quoteFieldName( const QString &name ) const;

    virtual bool open();
    virtual void close();

    QString formatDatabaseString( const QString &source, const QMap<QString,QString> &values ) const;
    QString formatDatabaseString( const QString &source, const QString &key, const QString &value ) const;
protected:
    QString connectionName() const;

private:
    QString mathOperation( const QVariantList &args, const QString &op) const;

    const Database *m_db;
    QString m_connectionName;

};

#endif // BASEADAPTOR_H

