// DO NOT EDIT MANUALLY
// 
// generated by sqlgg 0.2.3-43-g8cd5b20 on 2009-11-07T13:43Z

#pragma once

template <class Traits>
struct sqlgg
{
  struct create_person
  {
    typename Traits::statement stmt;

    create_person(typename Traits::connection db) : stmt(db,SQLGG_STR("CREATE TABLE IF NOT EXISTS person (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT,surname TEXT)"))
    {
    }
  public:
    bool operator()()
    {
      return stmt.execute(typename Traits::no_params());
    }
  }; // struct create_person

  struct add_person
  {
    typename Traits::statement stmt;

    add_person(typename Traits::connection db) : stmt(db,SQLGG_STR("INSERT INTO person (name,surname) VALUES (@name,@surname)"))
    {
    }
  private:
    struct params
    {
      typename Traits::Text const& name;
      typename Traits::Text const& surname;

      params(typename Traits::Text const& name, typename Traits::Text const& surname) : name(name),surname(surname)
      {
      }

      // binding slots in a query (one param may be bound several times)
      enum { count = 2 };

      template <class T>
      void set_params(T& target)
      {
        Traits::set_param(target, name, 0);
        Traits::set_param(target, surname, 1);
      }

    }; // struct params

  public:
    bool operator()(typename Traits::Text const& name, typename Traits::Text const& surname)
    {
      return stmt.execute(params(name, surname));
    }
  }; // struct add_person

  struct create_money
  {
    typename Traits::statement stmt;

    create_money(typename Traits::connection db) : stmt(db,SQLGG_STR("CREATE TABLE IF NOT EXISTS money (src INTEGER, dst INTEGER, amount INTEGER)"))
    {
    }
  public:
    bool operator()()
    {
      return stmt.execute(typename Traits::no_params());
    }
  }; // struct create_money

  struct add_money
  {
    typename Traits::statement stmt;

    add_money(typename Traits::connection db) : stmt(db,SQLGG_STR("INSERT INTO money VALUES (@src,@dst,@amount)"))
    {
    }
  private:
    struct params
    {
      typename Traits::Int const& src;
      typename Traits::Int const& dst;
      typename Traits::Int const& amount;

      params(typename Traits::Int const& src, typename Traits::Int const& dst, typename Traits::Int const& amount) : src(src),dst(dst),amount(amount)
      {
      }

      // binding slots in a query (one param may be bound several times)
      enum { count = 3 };

      template <class T>
      void set_params(T& target)
      {
        Traits::set_param(target, src, 0);
        Traits::set_param(target, dst, 1);
        Traits::set_param(target, amount, 2);
      }

    }; // struct params

  public:
    bool operator()(typename Traits::Int const& src, typename Traits::Int const& dst, typename Traits::Int const& amount)
    {
      return stmt.execute(params(src, dst, amount));
    }
  }; // struct add_money

  struct calc_total
  {
    typename Traits::statement stmt;

    calc_total(typename Traits::connection db) : stmt(db,SQLGG_STR("SELECT name || ' ' || surname AS fullname, SUM(amount) as total FROM person JOIN money ON src = id GROUP BY id"))
    {
    }
  private:
    template <class T>
    struct output
    {
      typename Traits::Text fullname;
      typename Traits::Int total;

      enum { count = 2 };

      void get(typename Traits::row row, T result)
      {
        Traits::get_column_Text(row, 0, fullname);
        Traits::get_column_Int(row, 1, total);
        result(fullname, total);
      }
      void bind(typename Traits::row row)
      {
        Traits::bind_column_Text(row, 0, fullname);
        Traits::bind_column_Int(row, 1, total);
      }
    }; // struct output

  public:
    template<class T>
    bool operator()(T result)
    {
      return stmt.select(result,output<T>(),typename Traits::no_params());
    }
  }; // struct calc_total

  struct list_donors
  {
    typename Traits::statement stmt;

    list_donors(typename Traits::connection db) : stmt(db,SQLGG_STR("SELECT DISTINCT surname FROM person JOIN money ON src = id AND dst = (SELECT id FROM person WHERE surname LIKE ?) LIMIT ?"))
    {
    }
  private:
    template <class T>
    struct output
    {
      typename Traits::Text surname;

      enum { count = 1 };

      void get(typename Traits::row row, T result)
      {
        Traits::get_column_Text(row, 0, surname);
        result(surname);
      }
      void bind(typename Traits::row row)
      {
        Traits::bind_column_Text(row, 0, surname);
      }
    }; // struct output

  private:
    struct params
    {
      typename Traits::Text const& _0;
      typename Traits::Int const& limit;

      params(typename Traits::Text const& _0, typename Traits::Int const& limit) : _0(_0),limit(limit)
      {
      }

      // binding slots in a query (one param may be bound several times)
      enum { count = 2 };

      template <class T>
      void set_params(T& target)
      {
        Traits::set_param(target, _0, 0);
        Traits::set_param(target, limit, 1);
      }

    }; // struct params

  public:
    template<class T>
    bool operator()(typename Traits::Text const& _0, typename Traits::Int const& limit, T result)
    {
      return stmt.select(result,output<T>(),params(_0, limit));
    }
  }; // struct list_donors

  struct drop_person
  {
    typename Traits::statement stmt;

    drop_person(typename Traits::connection db) : stmt(db,SQLGG_STR("DROP TABLE IF EXISTS person"))
    {
    }
  public:
    bool operator()()
    {
      return stmt.execute(typename Traits::no_params());
    }
  }; // struct drop_person

  struct drop_money
  {
    typename Traits::statement stmt;

    drop_money(typename Traits::connection db) : stmt(db,SQLGG_STR("DROP TABLE IF EXISTS money"))
    {
    }
  public:
    bool operator()()
    {
      return stmt.execute(typename Traits::no_params());
    }
  }; // struct drop_money

  create_person create_person;
  add_person add_person;
  create_money create_money;
  add_money add_money;
  calc_total calc_total;
  list_donors list_donors;
  drop_person drop_person;
  drop_money drop_money;

  sqlgg(typename Traits::connection db) : create_person(db), add_person(db), create_money(db), add_money(db), calc_total(db), list_donors(db), drop_person(db), drop_money(db)
  {
  }
}; // struct sqlgg

