| 1 | #pragma once | 
|---|
| 2 |  | 
|---|
| 3 | #include <mysqlxx/Types.h> | 
|---|
| 4 | #include <mysqlxx/Value.h> | 
|---|
| 5 | #include <mysqlxx/ResultBase.h> | 
|---|
| 6 | #include <mysqlxx/Exception.h> | 
|---|
| 7 |  | 
|---|
| 8 |  | 
|---|
| 9 | namespace mysqlxx | 
|---|
| 10 | { | 
|---|
| 11 |  | 
|---|
| 12 | class ResultBase; | 
|---|
| 13 |  | 
|---|
| 14 |  | 
|---|
| 15 | /** Строка результата. | 
|---|
| 16 | * В отличие от mysql++, | 
|---|
| 17 | *  представляет собой обёртку над MYSQL_ROW (char**), ссылается на ResultBase, не владеет сам никакими данными. | 
|---|
| 18 | * Это значит, что если будет уничтожен объект результата или соединение, | 
|---|
| 19 | *  или будет задан следующий запрос, то Row станет некорректным. | 
|---|
| 20 | * При использовании UseQueryResult, в памяти хранится только одна строка результата, | 
|---|
| 21 | *  это значит, что после чтения следующей строки, предыдущая становится некорректной. | 
|---|
| 22 | */ | 
|---|
| 23 | class Row | 
|---|
| 24 | { | 
|---|
| 25 | private: | 
|---|
| 26 | /** @brief Pointer to bool data member, for use by safe bool conversion operator. | 
|---|
| 27 | * @see http://www.artima.com/cppsource/safebool.html | 
|---|
| 28 | * Взято из mysql++. | 
|---|
| 29 | */ | 
|---|
| 30 | typedef MYSQL_ROW Row::*private_bool_type; | 
|---|
| 31 |  | 
|---|
| 32 | public: | 
|---|
| 33 | /** Для возможности отложенной инициализации. */ | 
|---|
| 34 | Row() | 
|---|
| 35 | { | 
|---|
| 36 | } | 
|---|
| 37 |  | 
|---|
| 38 | /** Для того, чтобы создать Row, используйте соответствующие методы UseQueryResult или StoreQueryResult. */ | 
|---|
| 39 | Row(MYSQL_ROW row_, ResultBase * res_, MYSQL_LENGTHS lengths_) | 
|---|
| 40 | : row(row_), res(res_), lengths(lengths_) | 
|---|
| 41 | { | 
|---|
| 42 | } | 
|---|
| 43 |  | 
|---|
| 44 | /** Получить значение по индексу. | 
|---|
| 45 | * Здесь используется int, а не unsigned, чтобы не было неоднозначности с тем же методом, принимающим const char *. | 
|---|
| 46 | */ | 
|---|
| 47 | Value operator[] (int n) const | 
|---|
| 48 | { | 
|---|
| 49 | if (unlikely(static_cast<size_t>(n) >= res->getNumFields())) | 
|---|
| 50 | throw Exception( "Index of column is out of range."); | 
|---|
| 51 | return Value(row[n], lengths[n], res); | 
|---|
| 52 | } | 
|---|
| 53 |  | 
|---|
| 54 | /** Get value by column name. Less efficient. */ | 
|---|
| 55 | Value operator[] (const char * name) const; | 
|---|
| 56 |  | 
|---|
| 57 | Value operator[] (const std::string & name) const | 
|---|
| 58 | { | 
|---|
| 59 | return operator[](name.c_str()); | 
|---|
| 60 | } | 
|---|
| 61 |  | 
|---|
| 62 | /** Получить значение по индексу. */ | 
|---|
| 63 | Value at(size_t n) const | 
|---|
| 64 | { | 
|---|
| 65 | return operator[](n); | 
|---|
| 66 | } | 
|---|
| 67 |  | 
|---|
| 68 | /** Количество столбцов. */ | 
|---|
| 69 | size_t size() const { return res->getNumFields(); } | 
|---|
| 70 |  | 
|---|
| 71 | /** Является ли пустым? Такой объект используется, чтобы обозначить конец результата | 
|---|
| 72 | * при использовании UseQueryResult. Или это значит, что объект не инициализирован. | 
|---|
| 73 | * Вы можете использовать вместо этого преобразование в bool. | 
|---|
| 74 | */ | 
|---|
| 75 | bool empty() const { return row == nullptr; } | 
|---|
| 76 |  | 
|---|
| 77 | /** Преобразование в bool. | 
|---|
| 78 | * (Точнее - в тип, который преобразуется в bool, и с которым больше почти ничего нельзя сделать.) | 
|---|
| 79 | */ | 
|---|
| 80 | operator private_bool_type() const { return row == nullptr ? nullptr : &Row::row; } | 
|---|
| 81 |  | 
|---|
| 82 | private: | 
|---|
| 83 | MYSQL_ROW row{}; | 
|---|
| 84 | ResultBase * res{}; | 
|---|
| 85 | MYSQL_LENGTHS lengths{}; | 
|---|
| 86 | }; | 
|---|
| 87 |  | 
|---|
| 88 | } | 
|---|
| 89 |  | 
|---|