1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
|
/*
* Copyright (c) 2015, 2025, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0,
* as published by the Free Software Foundation.
*
* This program is designed to work with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an additional
* permission to link the program and your derivative works with the
* separately licensed software that they have either included with
* the program or referenced in the documentation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// MySQL DB access module, for use by plugins and others
// For the module that implements interactive DB functionality see mod_db
#ifndef PLUGIN_X_CLIENT_MYSQLXCLIENT_XQUERY_RESULT_H_
#define PLUGIN_X_CLIENT_MYSQLXCLIENT_XQUERY_RESULT_H_
#include <memory>
#include <string>
#include <vector>
#include "mysqlxclient/xerror.h"
#include "mysqlxclient/xrow.h"
namespace xcl {
/**
Interface responsible for fetching 'resultsets'.
The interface defines methods that correspond to X Protocol message flow
which transmits multiple 'resultsets':
loop has more resultsets
group resultset
loop has more columns
server --> client: ColumnMetaData
end
loop has more rows
server --> client: Row
end
end
alt has more resultsets
server --> client: FetchDoneMoreResultsets
end
end
loop has more OUT-paramsets
server --> client: FetchDoneMoreOutParams
group resultset
loop has more columns
server --> client: ColumnMetaData
end
loop has more rows
server --> client: Row
end
end
end
server --> client: FetchDone
While designing it there was an assumption that the implementation may not
fetch/buffers row data. Because of it some return containers may "grow" with
the realization of the X Protocol flow.
*/
class XQuery_result {
public:
using Warning = ::Mysqlx::Notice::Warning;
using Row = ::Mysqlx::Resultset::Row;
using Metadata = std::vector<Column_metadata>;
using Warnings = std::vector<Warning>;
public:
virtual ~XQuery_result() = default;
/**
Get last insert identifier.
If last insert identifier was generated by the query then
it is going to be send in few last messages of the statement
execution flow thus the value can be checked after last 'resultset'
was received (@ref next_resultset returned false). Before this point
the method is going to return 'false'.
@param[out] out_last_id returns last insert identifier
@return Information if the last insert identifier is defined for
last 'resultset'
@retval == true last insert id is defined
@retval == false last insert id is not defined
*/
virtual bool try_get_last_insert_id(uint64_t *out_last_id) const = 0;
/**
Get number of affected rows.
If affected row count was generated by the query then
it is going to be send in few last messages of the statement
execution flow thus the value can be checked after last 'resultset'
was received (@ref next_resultset returned false). Before this point
the method is going to return 'false'.
@param[out] out_affected_number returns last insert identifier
@return Information if the affected number of rows is defined for
last 'resultset'
@retval == true number of affected rows is defined
@retval == false number of affected rows is not defined
*/
virtual bool try_get_affected_rows(uint64_t *out_affected_number) const = 0;
/**
Get message returned for the server.
If the message was generated by the query then it is going to be send
in few last messages of the statement execution flow thus the value
can be checked after last 'resultset' was received (@ref next_resultset
returned false). Before this point the method is going to return 'false'.
@param[out] out_message returns message
@return Information if the message is defined for last 'resultset'
@retval == true number of affected rows is defined
@retval == false number of affected rows is not defined
*/
virtual bool try_get_info_message(std::string *out_message) const = 0;
/**
Get auto-generated identifiers for inserted documents.
If an identifiers were auto-generated by the Crud::Insert message
then the list of them be send to client thus the value can be checked after
last 'resultset' was received (@ref next_resultset returned false).
Before this point the method is going to return 'false'.
@param[out] out_ids returns list of inserted identifiers
@return Information if the auto-generated identifiers are defined for
last 'resultset'
@retval == true auto-generated identifiers list is not empty
@retval == false auto-generated identifiers list is empty
*/
virtual bool try_get_generated_document_ids(
std::vector<std::string> *out_ids) const = 0;
/**
Get column information for current 'resultset'.
Returns column information in case when there was no error
earlier and fetch of metadata was successful.
The method doesn't need to be called before call to "get_next_row*",
it is done implicitly in that case and the metadata-s are cached.
@param[out] out_error return error in case the fetch operation fails
or last error. To omit the value the method
accepts "nullptr" value.
@return Container holding Column_metadata for all columns
*/
virtual const Metadata &get_metadata(XError *out_error = nullptr) = 0;
/**
Set column information for the current 'resultset'.
It should be used when metadata is decoupled from the resultset.
@param metadata column information for the current 'resultset'
*/
virtual void set_metadata(const Metadata &metadata) = 0;
/**
Get warning generated for current 'resultset'.
Warnings are generated by X Plugin or SQL executed on the server
and are forwarded to the client through X Protocol notices.
Number of warnings is going to increase with flow realization and
may be generated while serializing 'row', 'field'.
@return Container holding warnings generated until now
*/
virtual const Warnings &get_warnings() = 0;
/**
Get next row of the current 'resultset'.
@param[out] out_row returns a row pointer from the internal storage,
if the value is 'nullptr' then row is skipped
@param[out] out_error returns an error when fetching of row failed
or last error
@return Result of row fetching
@retval == true out_row contains a valid row
@retval == false there are no rows to fetch in current 'resultset' or
an error occurred
*/
virtual bool get_next_row(const XRow **out_row, XError *out_error) = 0;
/**
Get next row of the current 'resultset'.
@param[out] out_error returns an error when fetching of row failed
or last error
@return Result of row fetching
@retval != nullptr pointer to fetched row owned by this interface
@retval == nullptr there are no rows to fetch in current 'resultset' or
an error occurred
*/
virtual const XRow *get_next_row(XError *out_error = nullptr) = 0;
/**
Get next row of the current 'resultset' as X Protocol message.
@param[out] out_error returns an error when fetching of row failed
or last error
@return Result of row fetching
@retval != nullptr pointer to fetched X Protocol message
@retval == nullptr there are no rows to fetch in current 'resultset' or
an error occurred
*/
virtual std::unique_ptr<Row> get_next_row_raw(
XError *out_error = nullptr) = 0;
/**
Move to next 'resultset'.
Method checks if the executed query generated multiple/next "resultset/s".
It returns "true" if the next "resultset" is present and can be read
by calling once again by methods like @ref get_metadata,
@ref get_warnings, @ref get_next_row, @ref get_next_row_raw.
In case of "false", user should check out_error to see if the cause of
stopping was an error or an end of resultsets.
Using this method user can skip in middle of current resultset and
go to next one or even skip whole resultset.
@param[out] out_error returns an error if it occurred while
skipping/moving message flow to the next
'resultset' or last error
@return Information if user is able to read next 'resultset'
@retval == true next 'resultset' is available
@retval == false all 'resultset' received or an error occur
*/
virtual bool next_resultset(XError *out_error) = 0;
/**
Check if there is a 'resultset'.
Method tries to fetch 'resultset' metadata to check if there
is a resultset.
@param[out] out_error returns an error if it occurred while
checking the resultset
*/
virtual bool has_resultset(XError *out_error = nullptr) = 0;
/**
Check if 'resultset' that is fetched contains 'out-params'.
@return Is 'out-param'
@retval == true resultset contains out-params
@retval == false resultset contains query result
*/
virtual bool is_out_parameter_resultset() const = 0;
};
} // namespace xcl
#endif // PLUGIN_X_CLIENT_MYSQLXCLIENT_XQUERY_RESULT_H_
|