view SQLGenerator.hpp @ 59:74be5a2f49db

Separate SQLGenerator into a separate header.
author Tom Fredrik Blenning Klaussen <bfg@blenning.no>
date Fri, 14 Sep 2012 00:20:06 +0200
parents
children e5fa379d4030
line wrap: on
line source

#ifndef SQLGENERATOR_HPP
#define SQLGENERATOR_HPP

#include "OrderedPair.hpp"
#include "ThreadSafeLookup.hpp"
#include "UniqueString.hpp"

#include "Exception/IOException.hpp"
#include "Exception/SQLException.hpp"

#include <QtCore/QStringList>
#include <QtCore/QVariant>

#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlError>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlRecord>

#include <boost/optional.hpp>

#include <QtCore/QString>

template<typename T>
struct SQLGenerator
{
};

template<>
struct SQLGenerator<int>
{
  static QString fieldName(const QString &prefix = QString())
  {
    return QString("%1_Int").arg(prefix);
  }

  static QString createFields(const QString &prefix = QString())
  {
    return QString("%1 INTEGER").arg(fieldName(prefix));
  }

  static QString valueString(const QString &prefix = QString())
  {
    return QString(":") + fieldName(prefix);
  }

  static void bindValue(QSqlQuery& query,
			int value,
			const QString& prefix = QString())
  {
    query.bindValue(valueString(prefix), value);
  }

  static void bindValues(QSqlQuery& query,
			 const QVariantList& values,
			 const QString& prefix = QString())
  {
    query.bindValue(valueString(prefix), values);
  }

  static void bindValues(QSqlQuery& query,
			 const QList<int>& values,
			 const QString& prefix = QString())
  {
    QVariantList list;
    foreach(int value, values) {
      list << value;
    }
    bindValues(query, list, prefix);
  }

  static boost::optional<int> extract(QSqlQuery& query,
				      const QString& prefix = QString())
  {
    int fieldNo = query.record().indexOf(fieldName(prefix));
    if (query.at() >= 0)
      return query.value(fieldNo).toInt();
    else
      return boost::optional<int>();
  }

};

template<>
struct SQLGenerator<QString>
{
  static QString fieldName(const QString &prefix = QString())
  {
    return QString("%1_QString").arg(prefix);
  }

  static QString createFields(const QString &prefix = QString())
  {
    return QString("%1 TEXT").arg(fieldName(prefix));
  }

  static QString valueString(const QString &prefix = QString())
  {
    return QString(":") + fieldName(prefix);
  }

  static QString restrict(const QString &prefix = QString())
  {
    return QString("%1 = %2").arg(fieldName(prefix)).arg(valueString(prefix));
  }

  static void bindValue(QSqlQuery& query,
			const QString& value,
			const QString& prefix = QString())
  {
    query.bindValue(valueString(prefix), value);
  }

  static void bindValues(QSqlQuery& query,
			 const QVariantList& value,
			 const QString& prefix = QString())
  {
    query.bindValue(valueString(prefix), value);
  }

  static void bindValues(QSqlQuery& query,
			 const QList<QString>& values,
			 const QString& prefix = QString())
  {
    QVariantList list;
    foreach(const QString& value, values) {
      list << value;
    }
    bindValues(query, list, prefix);
  }

  static boost::optional<QString> extract(QSqlQuery& query,
					  const QString& prefix = QString())
  {
    int fieldNo = query.record().indexOf(fieldName(prefix));
    if (query.at() >= 0)
      return query.value(fieldNo).toString();
    else
      return boost::optional<QString>();
  }


};

template<>
struct SQLGenerator<UniqueString>
{
  static QString fieldName(const QString &prefix = QString())
  {
    return QString("%1_QString").arg(prefix);
  }

  static QString createFields(const QString &prefix = QString())
  {
    return QString("%1 TEXT").arg(fieldName(prefix));
  }

  static QString valueString(const QString &prefix = QString())
  {
    return QString(":") + fieldName(prefix);
  }

  static QString restrict(const QString &prefix = QString())
  {
    return QString("%1 = %2").arg(fieldName(prefix)).arg(valueString(prefix));
  }

  static void bindValue(QSqlQuery& query,
			const QString& value,
			const QString& prefix = QString())
  {
    query.bindValue(valueString(prefix), value);
  }

  static void bindValues(QSqlQuery& query,
			 const QVariantList& values,
			 const QString& prefix = QString())
  {
    query.bindValue(valueString(prefix), values);
  }

  static void bindValues(QSqlQuery& query,
			 const QList<UniqueString>& values,
			 const QString& prefix = QString())
  {
    QVariantList list;
    foreach(const UniqueString& value, values) {
      list << static_cast<const QString>(value);
    }
    bindValues(query, list, prefix);
  }

  static boost::optional<QString> extract(QSqlQuery& query,
					  const QString& prefix = QString())
  {
    int fieldNo = query.record().indexOf(fieldName(prefix));
    if (query.at() >= 0)
      return query.value(fieldNo).toString();
    else
      return boost::optional<QString>();
  }


};

template<typename T>
struct SQLGenerator<OrderedPair<T> >
{
  static QString fieldName(const QString &prefix = QString())
  {
    return SQLGenerator<T>::fieldName(prefix + "_1") + ", " +
      SQLGenerator<T>::fieldName(prefix + "_2");
  }

  static QString createFields(const QString &prefix = QString())
  {
    return SQLGenerator<T>::createFields(prefix + "_1") + ", " +
      SQLGenerator<T>::createFields(prefix + "_2");
  }

  static QString restriction(const QString& prefix = QString())
  {
    return SQLGenerator<T>::restrict(prefix + "_1") + " AND " +
      SQLGenerator<T>::restrict(prefix + "_2");
  }

  static QString valueString(const QString &prefix = QString())
  {
    return SQLGenerator<T>::valueString(prefix + "_1") + ", " +
      SQLGenerator<T>::valueString(prefix + "_2");
  }

  static void bindValue(QSqlQuery& query,
			const OrderedPair<T>& value,
			const QString& prefix = QString())
  {
    SQLGenerator<T>::bindValue(query, value.first, prefix + "_1");
    SQLGenerator<T>::bindValue(query, value.second, prefix + "_2");
  }

  static void bindValues(QSqlQuery& query,
			 const QList<OrderedPair<T> >& values,
			 const QString& prefix = QString())
  {
    QList<T> first;
    QList<T> second;
    foreach(OrderedPair<T> value, values) {
      first << value.first;
      second << value.second;
    }
    SQLGenerator<T>::bindValues(query, first, prefix + "_1");
    SQLGenerator<T>::bindValues(query, second, prefix + "_2");
  }

  static boost::optional<OrderedPair<T> >
  extract(QSqlQuery& query,
	  const QString& prefix = QString())
  {
    if (query.at() >= 0)
      return OrderedPair<T> (*SQLGenerator<T>::extract(query, prefix + "_1"),
			     *SQLGenerator<T>::extract(query, prefix + "_2"));
    else
      return boost::optional<OrderedPair<T> >();
  }
};


#endif //SQLGENERATOR_HPP