Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 

233 rindas
6.5 KiB

  1. #pragma once
  2. #include "row.h"
  3. #include "field.inl"
  4. #include "result.inl"
  5. namespace cppmariadb
  6. {
  7. namespace __impl
  8. {
  9. template<typename T>
  10. struct row_iterator
  11. {
  12. public:
  13. using this_type = row_iterator<T>;
  14. using iterator_category = std::random_access_iterator_tag;
  15. using value_type = T;
  16. using difference_type = ssize_t;
  17. using pointer = T*;
  18. using reference = T&;
  19. private:
  20. enum class compare_result : int
  21. {
  22. lower = -1,
  23. equals = 0,
  24. greater = 1,
  25. mismatch = 2
  26. };
  27. using value_ptru_type = std::unique_ptr<value_type>;
  28. private:
  29. const row* _owner;
  30. ssize_t _index;
  31. ssize_t _direction;
  32. mutable value_ptru_type _cache;
  33. public:
  34. inline row_iterator(const row& p_row, ssize_t index, ssize_t direction)
  35. : _owner (&p_row)
  36. , _index (index)
  37. , _direction(direction)
  38. { }
  39. inline row_iterator(const this_type& other)
  40. { assign(other); }
  41. public:
  42. inline bool operator == (const this_type& other) const
  43. { return compare(other) == compare_result::equals; }
  44. inline bool operator != (const this_type& other) const
  45. { return compare(other) != compare_result::equals; }
  46. inline bool operator < (const this_type& other) const
  47. { return compare(other) == compare_result::less; }
  48. inline bool operator <= (const this_type& other) const
  49. {
  50. auto c = compare(other);
  51. return (c == compare_result::less || c == compare_result::equals);
  52. }
  53. inline bool operator > (const this_type& other) const
  54. { return compare(other) == compare_result::greater; }
  55. inline bool operator >= (const this_type& other) const
  56. {
  57. auto c = compare(other);
  58. return (c == compare_result::greater || c == compare_result::equals);
  59. }
  60. inline reference operator * () const
  61. { return field(); }
  62. inline pointer operator -> () const
  63. { return &field(); }
  64. inline this_type& operator ++ ()
  65. {
  66. next();
  67. return *this;
  68. }
  69. inline this_type& operator -- ()
  70. {
  71. prev();
  72. return *this;
  73. }
  74. inline this_type operator ++ (int)
  75. {
  76. auto tmp(*this);
  77. next();
  78. return tmp;
  79. }
  80. inline this_type operator -- (int)
  81. {
  82. auto tmp(*this);
  83. prev();
  84. return tmp;
  85. }
  86. inline this_type& operator += (difference_type diff)
  87. {
  88. next(diff);
  89. return *this;
  90. }
  91. inline this_type& operator -= (difference_type diff)
  92. {
  93. prev(diff);
  94. return *this;
  95. }
  96. inline this_type operator + (difference_type diff) const
  97. {
  98. auto tmp(*this);
  99. tmp += diff;
  100. return tmp;
  101. }
  102. inline this_type operator - (difference_type diff) const
  103. {
  104. auto tmp(*this);
  105. tmp -= diff;
  106. return tmp;
  107. }
  108. inline difference_type operator - (const this_type& other) const
  109. { return (_index - other._index) * _direction; }
  110. inline this_type operator [] (difference_type diff)
  111. {
  112. auto tmp(*this);
  113. tmp += diff;
  114. return tmp;
  115. }
  116. private:
  117. inline compare_result compare(const this_type& other) const
  118. {
  119. if (_owner != other._owner)
  120. return compare_result::mismatch;
  121. else if (_index < other._index)
  122. return compare_result::lower;
  123. else if (_index > other._index)
  124. return compare_result::greater;
  125. else
  126. return compare_result::equals;
  127. }
  128. inline reference field() const
  129. {
  130. if (!_cache)
  131. _cache.reset(new value_type(_owner->at(_index)));
  132. return *_cache;
  133. }
  134. inline void assign(const this_type& other)
  135. {
  136. _owner = other._owner;
  137. _index = other._index;
  138. _direction = other._direction;
  139. _cache.reset();
  140. }
  141. inline void next(difference_type i = 1)
  142. {
  143. _cache.reset();
  144. _index = _index + _direction * i;
  145. }
  146. inline void prev(difference_type i = 1)
  147. {
  148. _cache.reset();
  149. _index = _index - _direction * i;
  150. }
  151. };
  152. }
  153. /* row */
  154. row::row(const result& p_result, MYSQL_ROW p_row)
  155. : handle(p_row)
  156. , _result (p_result)
  157. , _lengths (nullptr)
  158. { }
  159. field row::operator[](size_t i) const
  160. { return at(i); }
  161. field row::operator[](const std::string& name) const
  162. { return at(name); }
  163. const column_vector& row::columns() const
  164. { return _result.columns(); }
  165. unsigned int row::size() const
  166. { return _result.columncount(); }
  167. row::iterator_type row::begin() const
  168. { return iterator_type(*this, 0, 1); }
  169. row::iterator_type row::end() const
  170. { return iterator_type(*this, size(), 1); }
  171. row::const_iterator_type row::cbegin() const
  172. { return const_iterator_type(*this, 0, 1); }
  173. row::const_iterator_type row::cend() const
  174. { return const_iterator_type(*this, size(), 1); }
  175. row::iterator_type row::rbegin() const
  176. { return iterator_type(*this, size()-1, -1); }
  177. row::iterator_type row::rend() const
  178. { return iterator_type(*this, -1, -1); }
  179. row::const_iterator_type row::crbegin() const
  180. { return const_iterator_type(*this, size()-1, -1); }
  181. row::const_iterator_type row::crend() const
  182. { return const_iterator_type(*this, -1, -1); }
  183. }