Pages

Wrapping up MYSQL_ROW

Our task is to improve the Connection class, to let it a way to return its current row, possibly a dummy one, to the client programmer.

Here we think about the Row class that would wrap the MYSQL_ROW type make it easier to use.

We know that a MYSQL_ROW is nothing more than an array of c-strings (or better, array of bytes, since they could contains null bytes when representing binary data), and we are developing for the C++ language, so a natural way of representing a row would be by a vector of strings.

Besides a couple of constructors, and the boolean operator to let the class user to understand if an object is a real row or a dummy one, we are about to provide just a function to dump the row on an output stream (and a global operator "put to"):

class Row
{
private:
std::vector<std::string> row_;
public:
Row() : row_(0) {} // 1.
Row(MYSQL_ROW row, unsigned int nr);

_OPERATOR_BOOL() const { return (row_.size() > 0 ? _CONVERTIBLE_TO_TRUE : 0); }

std::ostream& dump(std::ostream& os) const;
};

std::ostream& operator<<(std::ostream& os, const Row& row);

1. dummy ctor, the size of the member vector is set to zero.

Here's the functions' implementation:

Row::Row(MYSQL_ROW row, unsigned int nr) : row_(nr)
{
for(unsigned int i = 0; i < nr; ++i)
row_[i] = row[i]; // 1.
}

std::ostream& Row::dump(std::ostream& os) const
{
if(row_.empty())
{
os << "Dummy" << std::endl;
return os;
}

std::vector<std::string>::const_iterator it;
for(it = row_.begin(); it != row_.end(); ++it)
os << *it << ' ';
os << std::endl;

return os;
}

1. Actually, this implementation is buggy. As you can see, the string at position i in the vector is initialized with the i c-string in the original MYSQL_ROW. This works fine for all the "normal" fields, it doesn't for the binary ones, that will be truncated at the first null byte. This is not an issue here, but we should keep in mind this limitation.

No comments:

Post a Comment