The Battle for Wesnoth  1.15.3+dev
result_set.hpp
Go to the documentation of this file.
1 //
2 // M A R I A D B + +
3 //
4 // Copyright Sylvain Rochette Langlois 2013,
5 // Frantisek Boranek 2015,
6 // The ViaDuck Project 2016 - 2018.
7 // Distributed under the Boost Software License, Version 1.0.
8 // (See accompanying file LICENSE or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 
11 #ifndef _MARIADB_RESULT_SET_HPP_
12 #define _MARIADB_RESULT_SET_HPP_
13 
14 #include <map>
15 #include <vector>
16 #include <mariadb++/bind.hpp>
17 #include <mariadb++/data.hpp>
18 #include <mariadb++/date_time.hpp>
19 #include <mariadb++/decimal.hpp>
20 #include <mariadb++/last_error.hpp>
21 
22 #define MAKE_GETTER_SIG_STR(nm, rtype, fq) rtype fq get_##nm(const std::string& name) const
23 #define MAKE_GETTER_SIG_INT(nm, rtype, fq) rtype fq get_##nm(u32 index) const
24 
25 #define MAKE_GETTER_DECL(nm, rtype) \
26  MAKE_GETTER_SIG_STR(nm, rtype, ); \
27  MAKE_GETTER_SIG_INT(nm, rtype, )
28 
29 #define MAKE_GETTER(nm, rtype, vtype) \
30  MAKE_GETTER_SIG_STR(nm, rtype, result_set::) { return get_##nm(column_index(name)); } \
31  MAKE_GETTER_SIG_INT(nm, rtype, result_set::) { \
32  check_row_fetched(); \
33  check_type(index, vtype); \
34  \
35  if (index >= m_field_count) throw std::out_of_range("Column index out of range");
36 
37 namespace mariadb {
38 class connection;
39 class statement;
40 
41 /*
42  * This data is shared between a statement and its result_set,
43  * therefore it needs to be destroyed only when
44  * - the statement is freed
45  * - all of the result_sets are freed
46  *
47  * A shared_ptr is used to keep the data alive in the statement and the result_set.
48  */
50  explicit statement_data(MYSQL_STMT* stmt) : m_statement(stmt) {}
51 
53 
54  // number of binds in this query
55  unsigned long m_bind_count = 0;
56  // pointer to underlying statement
57  MYSQL_STMT* m_statement;
58  // pointer to raw binds
59  MYSQL_BIND* m_raw_binds = nullptr;
60  // pointer to managed binds
61  std::vector<bind_ref> m_binds;
62 };
63 
64 typedef std::shared_ptr<statement_data> statement_data_ref;
65 
66 /**
67  * Class used to store query and statement results
68  */
69 class result_set : public last_error {
70  friend class connection;
71  friend class statement;
72 
73  typedef std::map<std::string, u32> map_indexes_t;
74 
75  public:
76  /**
77  * Destructs the result_set and frees all result data
78  */
79  virtual ~result_set();
80 
81  /**
82  * Get the count of columns contained in this result_set
83  *
84  * @return Count of columns
85  */
86  u32 column_count() const;
87 
88  /**
89  * Get the index of a column by column-name (case sensitive)
90  *
91  * @param name Name of column to look up
92  * @return Index of column if found, maximum uint32 if not found
93  */
94  u32 column_index(const std::string& name) const;
95 
96  /**
97  * Gets the type of a column by index
98  *
99  * @param index Index of the column to examine
100  * @return Type enum indicating column type
101  */
102  value::type column_type(u32 index) const;
103 
104  /**
105  * Gets the name of a column by index
106  *
107  * @param index Index of the column to get the name for
108  * @return String representing column name
109  */
110  const std::string column_name(u32 index);
111 
112  /**
113  * Gets the size of the data contained in the column at index
114  *
115  * @param index Index of the column to get the size for
116  * @return Size of the column contents for the currently active row
117  */
118  unsigned long column_size(u32 index) const;
119 
120  /**
121  * Gets the row index of the currently selected row
122  *
123  * @return Index of current row
124  */
125  u64 row_index() const;
126 
127  /**
128  * Gets the number of rows in this result
129  *
130  * @return Number of rows in result_set
131  */
132  u64 row_count() const;
133 
134  /**
135  * Fetch next row from result_set
136  *
137  * @return True if next row exists
138  */
139  bool next();
140 
141  /**
142  * Set the current row index in result_set (seek to result).
143  * Also immediately fetches the selected row.
144  *
145  * @param index Index of row to select
146  * @return True if row could be seeked to and fetched.
147  */
148  bool set_row_index(u64 index);
149 
150  // declare all getters
157  MAKE_GETTER_DECL(string, std::string);
158  MAKE_GETTER_DECL(boolean, bool);
167  MAKE_GETTER_DECL(float, f32);
168  MAKE_GETTER_DECL(double, f64);
169  MAKE_GETTER_DECL(is_null, bool);
170 
171  private:
172  /**
173  * Create result_set from connection
174  */
175  explicit result_set(connection* conn);
176 
177  /**
178  * Create result_set from statement
179  */
180  explicit result_set(connection* conn, const statement_data_ref& stmt);
181 
182  /**
183  * Throws if the result set was created, but no row was ever fetched (using next())
184  */
185  void check_row_fetched() const;
186 
187  /**
188  * Throws if the actual type of column at index cannot be converted to the requested type
189  *
190  * @param index Index of column to check
191  * @param requested Requested type
192  */
193  void check_type(u32 index, value::type requested) const;
194 
195  // pointer to result set
196  MYSQL_RES* m_result_set;
197  // pointer to array of fields
198  MYSQL_FIELD* m_fields;
199  // pointer to current row
200  MYSQL_ROW m_row;
201  // pointer to raw binds
202  MYSQL_BIND* m_raw_binds;
203 
204  // vector of managed binds
205  std::vector<bind_ref> m_binds;
206  // optional pointer to statement
207  statement_data_ref m_stmt_data;
208  // map caching column name by index
209  map_indexes_t m_indexes;
210  // array of content lengths for the columns of current row
211  long unsigned int* m_lengths;
212 
213  // count of fields per row
215  // indicates if a row was fetched using next()
217 };
218 
219 typedef std::shared_ptr<result_set> result_set_ref;
220 }
221 
222 #endif
signed int s32
Definition: types.hpp:25
std::shared_ptr< result_set > result_set_ref
Definition: result_set.hpp:219
MYSQL_BIND * m_raw_binds
Definition: result_set.hpp:59
MYSQL_FIELD * m_fields
Definition: result_set.hpp:198
Class representing SQL time.
Definition: time.hpp:23
unsigned long m_bind_count
Definition: result_set.hpp:55
double f64
Definition: types.hpp:27
float f32
Definition: types.hpp:26
std::shared_ptr< std::istream > stream_ref
Definition: types.hpp:78
std::vector< bind_ref > m_binds
Definition: result_set.hpp:205
std::map< std::string, u32 > map_indexes_t
Definition: result_set.hpp:73
#define MAKE_GETTER_DECL(nm, rtype)
Definition: result_set.hpp:25
map_indexes_t m_indexes
Definition: result_set.hpp:209
std::shared_ptr< ::mariadb::data< char > > data_ref
Definition: data.hpp:170
MYSQL_STMT * m_statement
Definition: result_set.hpp:57
unsigned char u8
Definition: types.hpp:20
unsigned short u16
Definition: types.hpp:21
Class representing a prepared statement with binding functionality.
Definition: statement.hpp:39
signed long long s64
Definition: types.hpp:35
std::vector< bind_ref > m_binds
Definition: result_set.hpp:61
Class used to represent SQL date_time.
Definition: date_time.hpp:20
Wraps a Database connection.
Definition: connection.hpp:27
statement_data(MYSQL_STMT *stmt)
Definition: result_set.hpp:50
static void statement(LexState *ls)
Definition: lparser.cpp:1537
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
MYSQL_RES * m_result_set
Definition: result_set.hpp:196
#define next(ls)
Definition: llex.cpp:32
long unsigned int * m_lengths
Definition: result_set.hpp:211
std::shared_ptr< statement_data > statement_data_ref
Definition: result_set.hpp:64
signed short s16
Definition: types.hpp:24
unsigned long long u64
Definition: types.hpp:34
MYSQL_BIND * m_raw_binds
Definition: result_set.hpp:202
statement_data_ref m_stmt_data
Definition: result_set.hpp:207
Class used to store query and statement results.
Definition: result_set.hpp:69
unsigned int u32
Definition: types.hpp:22
signed char s8
Definition: types.hpp:23