void table_delete(const std::string &table_name, mysql::Row_of_fields &fields) {

    std::cout << "DELETE FROM "
    << table_name
    << " WHERE ";

    mysql::Row_of_fields::iterator field_it = fields.begin();
    int field_id = 0;
    mysql::Converter converter;
    do {

        std::string str;
        converter.to(str, *field_it);
        if (is_text_field(*field_it))
            std::cout << field_id << "= " << '\'' << str << '\'';
        else
            std::cout << field_id << "= " << str;

        ++field_it;
        ++field_id;
        if (field_it != fields.end())
            std::cout << " AND ";
    } while (field_it != fields.end());
    std::cout << " LIMIT 1" << std::endl;
}
void table_insert(const std::string &table_name, mysql::Row_of_fields &fields) {

    std::cout << "INSERT INTO "
    << table_name
    << " VALUES (";

    mysql::Row_of_fields::iterator field_it = fields.begin();
    mysql::Converter converter;
    do {
        /*
         Each row contains a vector of Value objects. The converter
         allows us to transform the value into another
         representation.
        */
        std::string str;
        converter.to(str, *field_it);
        if (is_text_field(*field_it))
            std::cout << '\'' << str << '\'';
        else
            std::cout << str;

        ++field_it;
        if (field_it != fields.end())
            std::cout << ", ";
    } while (field_it != fields.end());
    std::cout << ")" << std::endl;
}
void table_update(const std::string& table_name,
                  mysql::Row_of_fields &old_fields, mysql::Row_of_fields &new_fields)
{
  std::cout << "UPDATE "
           << table_name
           << " SET ";

  int field_id= 0;
  mysql::Row_of_fields::iterator field_it= new_fields.begin();
  mysql::Converter converter;
  do {
    std::string str;
    converter.to(str, *field_it);
    std::cout << field_id << "= ";
    if (is_text_field(*field_it))
      std::cout << '\'';
    std::cout << str;
    if (is_text_field(*field_it))
      std::cout << '\'';
    ++field_it;
    ++field_id;
    if (field_it != new_fields.end())
      std::cout << ", ";
  } while(field_it != new_fields.end());
  std::cout << " WHERE ";
  field_it= old_fields.begin();
  field_id= 0;
  do {
    std::string str;
    converter.to(str, *field_it);
    std::cout << field_id << "= ";
    if (is_text_field(*field_it))
      std::cout << '\'';
    std::cout << str;
    if (is_text_field(*field_it))
      std::cout << '\'';
    ++field_it;
    ++field_id;
    if (field_it != old_fields.end())
      std::cout << " AND ";
  } while(field_it != old_fields.end());
  std::cout << " LIMIT 1" << std::endl;

}
void RowEvent::proc0(mysql::Row_of_fields &fields, VALUE rb_fields) {
  mysql::Row_of_fields::iterator itor = fields.begin();

  do {
    VALUE rval = Qnil;

    if (itor->is_null()) {
      rb_ary_push(rb_fields, rval);
      continue;
    }

    switch(itor->type()) {
      case mysql::system::MYSQL_TYPE_FLOAT:
        rval = rb_float_new(itor->as_float());
        break;

      case mysql::system::MYSQL_TYPE_DOUBLE:
        rval = rb_float_new(itor->as_double());
        break;

      case mysql::system::MYSQL_TYPE_TINY:
        rval = UINT2NUM(itor->as_int8());
        break;

      case mysql::system::MYSQL_TYPE_SHORT:
        rval = UINT2NUM((boost::uint16_t)(itor->as_int16()));
        break;

      case mysql::system::MYSQL_TYPE_INT24: {
        const unsigned char* buf = (const unsigned char*) itor->storage();
//      if (buf[2] & 0x80) {
//        rval = INT2NUM((0xff << 24) | (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0));
//      } else {
          rval = UINT2NUM((buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0));
//      }
      } break;

      case mysql::system::MYSQL_TYPE_LONG:
        rval = INT2NUM(itor->as_int32());
        break;

      case mysql::system::MYSQL_TYPE_LONGLONG:
        rval = LL2NUM(itor->as_int64());
        break;

      case mysql::system::MYSQL_TYPE_BIT: {
        const unsigned char* buf = (const unsigned char*) itor->storage();
	int len = (itor->metadata() >> 8U) & 0xff;
        if (itor->metadata() & 0xff) len++;

        boost::uint64_t result = 0;
        for(int i = 0; i < len; i++) {
          result |= buf[len - i - 1] << (i * 8);
        }

        rval = INT2NUM(result);
      } break;

      case mysql::system::MYSQL_TYPE_VAR_STRING:
        rval = rb_str_new(itor->storage(), itor->length());
        break;

      case mysql::system::MYSQL_TYPE_TIMESTAMP:
        rval = INT2NUM((boost::uint32_t)itor->as_int32());
        break;

      case mysql::system::MYSQL_TYPE_NEWDECIMAL: {
        std::string s = decimal2str(*itor);
        VALUE BigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
        rval = rb_funcall(BigDecimal, rb_intern("new"), 1, rb_str_new(s.c_str(), s.length()));
      } break;

      case mysql::system::MYSQL_TYPE_DATE: {
        const char* storage = itor->storage();
        unsigned int date = (storage[0] & 0xff) + ((storage[1] & 0xff) << 8) + ((storage[2] & 0xff) << 16);
        unsigned int year = date >> 9;
        date-= (year << 9);
        unsigned int month = date >> 5;
        unsigned int day = date - (month << 5);

        VALUE Date = rb_const_get(rb_cObject, rb_intern("Date"));
        rval = rb_funcall(Date, rb_intern("new"), 3, UINT2NUM(year), UINT2NUM(month), UINT2NUM(day));
      } break;

      case mysql::system::MYSQL_TYPE_TIME: {
        const char* storage = itor->storage();
        unsigned int time = (storage[0] & 0xff) + ((storage[1] & 0xff) << 8) + ((storage[2] & 0xff) << 16);
        unsigned int sec = time % 100;
        time -= sec;
        unsigned int min = (time % 10000) / 100;
        unsigned int hour = (time - min) / 10000;

        VALUE Time = rb_const_get(rb_cObject, rb_intern("Time"));
        rval = rb_funcall(Time, rb_intern("utc"), 6, 2000, 1, 1, UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec));
      } break;

      case mysql::system::MYSQL_TYPE_YEAR: {
        const char* storage = itor->storage();
        unsigned int year = (storage[0] & 0xff);
        rval = INT2NUM(year > 0 ? (year + 1900) : 0);
      } break;

      case mysql::system::MYSQL_TYPE_DATETIME: {
        boost::uint64_t timestamp = itor->as_int64();
        unsigned long d = timestamp / 1000000;
        unsigned long t = timestamp % 1000000;

        VALUE DateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
        rval = rb_funcall(DateTime, rb_intern("new"), 6,
            INT2FIX(d / 10000), INT2FIX((d % 10000) / 100), INT2FIX(d % 100),
            INT2FIX(t / 10000), INT2FIX((t % 10000) / 100), INT2FIX(t % 100));
      } break;

      case mysql::system::MYSQL_TYPE_STRING:
      case mysql::system::MYSQL_TYPE_VARCHAR: {
        unsigned long size;
        char *ptr = itor->as_c_str(size);
        rval = rb_str_new(ptr, size);
      } break;

      case mysql::system::MYSQL_TYPE_TINY_BLOB:
      case mysql::system::MYSQL_TYPE_MEDIUM_BLOB:
      case mysql::system::MYSQL_TYPE_LONG_BLOB:
      case mysql::system::MYSQL_TYPE_BLOB: {
        unsigned long size;
        unsigned char *ptr = itor->as_blob(size);
        rval = rb_str_new((const char *)ptr, size);
      } break;

      default: break;
    }

    rb_ary_push(rb_fields, rval);
  } while(++itor != fields.end());
}