2013-01-06 16:07:01 +00:00
|
|
|
|
#pragma once
|
2011-03-03 19:57:34 +00:00
|
|
|
|
|
|
|
|
|
#include <mysqlxx/Types.h>
|
2014-05-19 22:05:33 +00:00
|
|
|
|
#include <mysqlxx/Value.h>
|
2011-03-03 19:57:34 +00:00
|
|
|
|
#include <mysqlxx/ResultBase.h>
|
2016-02-03 01:17:58 +00:00
|
|
|
|
#include <mysqlxx/Exception.h>
|
2011-03-03 19:57:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace mysqlxx
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
class ResultBase;
|
|
|
|
|
|
2011-03-18 20:26:54 +00:00
|
|
|
|
|
|
|
|
|
/** Строка результата.
|
|
|
|
|
* В отличие от mysql++,
|
|
|
|
|
* представляет собой обёртку над MYSQL_ROW (char**), ссылается на ResultBase, не владеет сам никакими данными.
|
|
|
|
|
* Это значит, что если будет уничтожен объект результата или соединение,
|
|
|
|
|
* или будет задан следующий запрос, то Row станет некорректным.
|
|
|
|
|
* При использовании UseQueryResult, в памяти хранится только одна строка результата,
|
|
|
|
|
* это значит, что после чтения следующей строки, предыдущая становится некорректной.
|
|
|
|
|
*/
|
2011-03-03 19:57:34 +00:00
|
|
|
|
class Row
|
|
|
|
|
{
|
2013-01-06 19:06:21 +00:00
|
|
|
|
private:
|
2017-04-01 07:20:54 +00:00
|
|
|
|
/** @brief Pointer to bool data member, for use by safe bool conversion operator.
|
|
|
|
|
* @see http://www.artima.com/cppsource/safebool.html
|
|
|
|
|
* Взято из mysql++.
|
|
|
|
|
*/
|
|
|
|
|
typedef MYSQL_ROW Row::*private_bool_type;
|
2013-01-06 19:06:21 +00:00
|
|
|
|
|
2011-03-03 19:57:34 +00:00
|
|
|
|
public:
|
2017-04-01 07:20:54 +00:00
|
|
|
|
/** Для возможности отложенной инициализации. */
|
|
|
|
|
Row()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-02 19:07:23 +00:00
|
|
|
|
/** Для того, чтобы создать Row, используйте соответствующие методы UseQueryResult. */
|
2017-04-01 07:20:54 +00:00
|
|
|
|
Row(MYSQL_ROW row_, ResultBase * res_, MYSQL_LENGTHS lengths_)
|
|
|
|
|
: row(row_), res(res_), lengths(lengths_)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Получить значение по индексу.
|
|
|
|
|
* Здесь используется int, а не unsigned, чтобы не было неоднозначности с тем же методом, принимающим const char *.
|
|
|
|
|
*/
|
|
|
|
|
Value operator[] (int n) const
|
|
|
|
|
{
|
|
|
|
|
if (unlikely(static_cast<size_t>(n) >= res->getNumFields()))
|
|
|
|
|
throw Exception("Index of column is out of range.");
|
|
|
|
|
return Value(row[n], lengths[n], res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Get value by column name. Less efficient. */
|
|
|
|
|
Value operator[] (const char * name) const;
|
|
|
|
|
|
|
|
|
|
Value operator[] (const std::string & name) const
|
|
|
|
|
{
|
|
|
|
|
return operator[](name.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Получить значение по индексу. */
|
|
|
|
|
Value at(size_t n) const
|
|
|
|
|
{
|
|
|
|
|
return operator[](n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Количество столбцов. */
|
|
|
|
|
size_t size() const { return res->getNumFields(); }
|
|
|
|
|
|
|
|
|
|
/** Является ли пустым? Такой объект используется, чтобы обозначить конец результата
|
|
|
|
|
* при использовании UseQueryResult. Или это значит, что объект не инициализирован.
|
|
|
|
|
* Вы можете использовать вместо этого преобразование в bool.
|
|
|
|
|
*/
|
|
|
|
|
bool empty() const { return row == nullptr; }
|
|
|
|
|
|
|
|
|
|
/** Преобразование в bool.
|
|
|
|
|
* (Точнее - в тип, который преобразуется в bool, и с которым больше почти ничего нельзя сделать.)
|
|
|
|
|
*/
|
2018-08-10 04:02:56 +00:00
|
|
|
|
operator private_bool_type() const { return row == nullptr ? nullptr : &Row::row; }
|
2013-01-06 19:06:21 +00:00
|
|
|
|
|
2011-03-03 19:57:34 +00:00
|
|
|
|
private:
|
2019-04-22 16:07:09 +00:00
|
|
|
|
MYSQL_ROW row{};
|
|
|
|
|
ResultBase * res{};
|
|
|
|
|
MYSQL_LENGTHS lengths{};
|
2011-03-03 19:57:34 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|