mysqlxx: fixed error when reusing *Result objects for different results.

This commit is contained in:
Alexey Milovidov 2011-04-28 17:12:28 +00:00
parent 1a5b3c0473
commit 9829b84ef5
5 changed files with 69 additions and 5 deletions

View File

@ -21,6 +21,8 @@ class ResultBase
{ {
public: public:
ResultBase(MYSQL_RES * res_, Connection * conn_, const Query * query_); ResultBase(MYSQL_RES * res_, Connection * conn_, const Query * query_);
ResultBase(const ResultBase & x);
ResultBase & operator= (const ResultBase & x);
Connection * getConnection() { return conn; } Connection * getConnection() { return conn; }
MYSQL_FIELDS getFields() { return fields; } MYSQL_FIELDS getFields() { return fields; }
@ -39,6 +41,9 @@ protected:
const Query * query; const Query * query;
MYSQL_FIELDS fields; MYSQL_FIELDS fields;
unsigned num_fields; unsigned num_fields;
private:
void init();
}; };
} }

View File

@ -26,6 +26,9 @@ class StoreQueryResult : public std::vector<Row>, public ResultBase
public: public:
StoreQueryResult(MYSQL_RES * res_, Connection * conn_, const Query * query_); StoreQueryResult(MYSQL_RES * res_, Connection * conn_, const Query * query_);
StoreQueryResult(const StoreQueryResult & x);
StoreQueryResult & operator= (const StoreQueryResult & x);
size_t num_rows() const { return size(); } size_t num_rows() const { return size(); }
private: private:
@ -39,6 +42,8 @@ private:
*/ */
typedef std::vector<MYSQL_LENGTH> Lengths; typedef std::vector<MYSQL_LENGTH> Lengths;
Lengths lengths; Lengths lengths;
void init();
}; };
} }

View File

@ -27,6 +27,13 @@ class UseQueryResult : public ResultBase
public: public:
UseQueryResult(MYSQL_RES * res_, Connection * conn_, const Query * query_); UseQueryResult(MYSQL_RES * res_, Connection * conn_, const Query * query_);
UseQueryResult(const UseQueryResult & x) : ResultBase(x) {}
UseQueryResult & operator= (const UseQueryResult & x)
{
ResultBase::operator=(x);
return *this;
}
Row fetch(); Row fetch();
/// Для совместимости /// Для совместимости

View File

@ -5,10 +5,36 @@
namespace mysqlxx namespace mysqlxx
{ {
ResultBase::ResultBase(MYSQL_RES * res_, Connection * conn_, const Query * query_) : res(res_), conn(conn_), query(query_) void ResultBase::init()
{ {
fields = mysql_fetch_fields(res); fields = mysql_fetch_fields(res);
num_fields = mysql_num_fields(res); num_fields = mysql_num_fields(res);
} }
ResultBase::ResultBase(MYSQL_RES * res_, Connection * conn_, const Query * query_) : res(res_), conn(conn_), query(query_)
{
init();
}
ResultBase::ResultBase(const ResultBase & x)
{
res = x.res;
conn = x.conn;
query = x.query;
init();
}
ResultBase & ResultBase::operator= (const ResultBase & x)
{
mysql_free_result(res);
res = x.res;
conn = x.conn;
query = x.query;
init();
return *this;
}
} }

View File

@ -5,21 +5,42 @@
namespace mysqlxx namespace mysqlxx
{ {
StoreQueryResult::StoreQueryResult(MYSQL_RES * res_, Connection * conn_, const Query * query_) : ResultBase(res_, conn_, query_) void StoreQueryResult::init()
{ {
UInt64 rows = mysql_num_rows(res); UInt64 rows = mysql_num_rows(res);
UInt32 fields = getNumFields(); UInt32 fields = getNumFields();
reserve(rows); reserve(rows);
lengths.resize(rows * fields); lengths.resize(rows * fields);
for (UInt64 i = 0; MYSQL_ROW row = mysql_fetch_row(res); ++i) for (UInt64 i = 0; MYSQL_ROW row = mysql_fetch_row(res); ++i)
{ {
MYSQL_LENGTHS lengths_for_row = mysql_fetch_lengths(res); MYSQL_LENGTHS lengths_for_row = mysql_fetch_lengths(res);
memcpy(&lengths[i * fields], lengths_for_row, sizeof(lengths[0]) * fields); memcpy(&lengths[i * fields], lengths_for_row, sizeof(lengths[0]) * fields);
push_back(Row(row, this, &lengths[i * fields])); push_back(Row(row, this, &lengths[i * fields]));
} }
checkError(conn->getDriver()); checkError(conn->getDriver());
} }
StoreQueryResult::StoreQueryResult(MYSQL_RES * res_, Connection * conn_, const Query * query_) : ResultBase(res_, conn_, query_)
{
init();
}
StoreQueryResult::StoreQueryResult(const StoreQueryResult & x) : ResultBase(x)
{
init();
}
StoreQueryResult & StoreQueryResult::operator= (const StoreQueryResult & x)
{
ResultBase::operator=(x);
clear();
lengths.clear();
init();
return *this;
}
} }