modules/devapi/mod_mysqlx_resultset.cc (612 lines of code) (raw):
/*
* Copyright (c) 2014, 2024, 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
*/
#include "modules/devapi/mod_mysqlx_resultset.h"
#include <memory>
#include <utility>
#include "modules/devapi/base_constants.h"
#include "modules/mysqlxtest_utils.h"
#include "mysqlshdk/include/scripting/common.h"
#include "mysqlshdk/include/scripting/obj_date.h"
#include "mysqlshdk/include/scripting/type_info/custom.h"
#include "mysqlshdk/include/scripting/type_info/generic.h"
#include "mysqlshdk/include/shellcore/base_shell.h"
#include "mysqlshdk/include/shellcore/utils_help.h"
#include "mysqlshdk/libs/db/charset.h"
#include "mysqlshdk/libs/db/row_copy.h"
#include "mysqlshdk/libs/db/session.h"
#include "mysqlshdk/libs/utils/strformat.h"
#include "mysqlshdk/libs/utils/utils_json.h"
using shcore::Value;
using std::placeholders::_1;
namespace mysqlsh {
namespace mysqlx {
// -----------------------------------------------------------------------
// Documentation of BaseResult class
REGISTER_HELP_CLASS(BaseResult, mysqlx);
REGISTER_HELP(
BASERESULT_BRIEF,
"Base class for the different types of results returned by the server.");
BaseResult::BaseResult(std::shared_ptr<mysqlshdk::db::mysqlx::Result> result)
: _result(result) {
add_property("affectedItemsCount", "getAffectedItemsCount");
add_property("executionTime", "getExecutionTime");
add_property("warningCount", "getWarningCount");
add_property("warningsCount", "getWarningsCount");
add_property("warnings", "getWarnings");
}
BaseResult::~BaseResult() {}
// Documentation of getWarnings function
REGISTER_HELP_PROPERTY(warnings, BaseResult);
REGISTER_HELP(BASERESULT_WARNINGS_BRIEF, "Same as <<<getWarnings>>>");
REGISTER_HELP_FUNCTION(getWarnings, BaseResult);
REGISTER_HELP_FUNCTION_TEXT(BASERESULT_GETWARNINGS, R"*(
Retrieves the warnings generated by the executed operation.
@returns A list containing a warning object for each generated warning.
This is the same value than C API mysql_warning_count, see
https://dev.mysql.com/doc/refman/en/mysql-warning-count.html
Each warning object contains a key/value pair describing the information
related to a specific warning.
This information includes: Level, Code and Message.
)*");
/**
* $(BASERESULT_GETWARNINGS_BRIEF)
*
* $(BASERESULT_GETWARNINGS)
*/
#if DOXYGEN_JS
List BaseResult::getWarnings() {}
#elif DOXYGEN_PY
list BaseResult::get_warnings() {}
#endif
shcore::Value BaseResult::get_member(const std::string &prop) const {
shcore::Value ret_val;
if (prop == "affectedItemsCount") {
ret_val = Value(get_affected_items_count());
} else if (prop == "executionTime") {
return shcore::Value(get_execution_time());
} else if (prop == "warningCount") {
log_warning("'%s' is deprecated, use '%s' instead.",
get_function_name("warningCount").c_str(),
get_function_name("warningsCount").c_str());
ret_val = Value(get_warnings_count());
} else if (prop == "warningsCount") {
ret_val = Value(get_warnings_count());
} else if (prop == "warnings") {
std::shared_ptr<shcore::Value::Array_type> array(
new shcore::Value::Array_type);
if (_result) {
while (std::unique_ptr<mysqlshdk::db::Warning> warning =
_result->fetch_one_warning()) {
auto warning_row = std::make_shared<mysqlsh::Row>();
switch (warning->level) {
case mysqlshdk::db::Warning::Level::Note:
warning_row->add_item("level", shcore::Value("Note"));
break;
case mysqlshdk::db::Warning::Level::Warn:
warning_row->add_item("level", shcore::Value("Warning"));
break;
case mysqlshdk::db::Warning::Level::Error:
warning_row->add_item("level", shcore::Value("Error"));
break;
}
warning_row->add_item("code", shcore::Value(warning->code));
warning_row->add_item("message", shcore::Value(warning->msg));
array->push_back(shcore::Value::wrap(std::move(warning_row)));
}
}
ret_val = shcore::Value(array);
} else {
ret_val = ShellBaseResult::get_member(prop);
}
return ret_val;
}
bool BaseResult::has_data() const {
return _result && _result->has_resultset();
}
// Documentation of getAffectedItemCount function
REGISTER_HELP_PROPERTY(affectedItemsCount, BaseResult);
REGISTER_HELP(BASERESULT_AFFECTEDITEMSCOUNT_BRIEF,
"Same as <<<getAffectedItemsCount>>>");
REGISTER_HELP_FUNCTION(getAffectedItemsCount, BaseResult);
REGISTER_HELP_FUNCTION_TEXT(BASERESULT_GETAFFECTEDITEMSCOUNT, R"*(
The the number of affected items for the last operation.
@returns the number of affected items.
Returns the number of records affected by the executed operation.
)*");
/**
* $(BASERESULT_GETAFFECTEDITEMSCOUNT_BRIEF)
*
* $(BASERESULT_GETAFFECTEDITEMSCOUNT)
*/
#if DOXYGEN_JS
Integer BaseResult::getAffectedItemsCount() {}
#elif DOXYGEN_PY
int BaseResult::get_affected_items_count() {}
#endif
int64_t BaseResult::get_affected_items_count() const {
if (!_result) return -1;
return _result->get_affected_row_count();
}
// Documentation of getExecutionTime function
REGISTER_HELP_PROPERTY(executionTime, BaseResult);
REGISTER_HELP(BASERESULT_EXECUTIONTIME_BRIEF, "Same as <<<getExecutionTime>>>");
REGISTER_HELP_FUNCTION(getExecutionTime, BaseResult);
REGISTER_HELP(BASERESULT_GETEXECUTIONTIME_BRIEF,
"Retrieves a string value indicating the execution time of the "
"executed operation.");
/**
* $(BASERESULT_GETEXECUTIONTIME_BRIEF)
*/
#if DOXYGEN_JS
String BaseResult::getExecutionTime() {}
#elif DOXYGEN_PY
str BaseResult::get_execution_time() {}
#endif
std::string BaseResult::get_execution_time() const {
return mysqlshdk::utils::format_seconds(_result->get_execution_time());
}
// Documentation of getWarningCount function
REGISTER_HELP_PROPERTY(warningCount, BaseResult);
REGISTER_HELP(BASERESULT_WARNINGCOUNT_BRIEF, "Same as <<<getWarningCount>>>");
REGISTER_HELP(BASERESULT_WARNINGCOUNT_DETAIL,
"${BASERESULT_WARNINGCOUNT_DEPRECATED}");
REGISTER_HELP(BASERESULT_WARNINGCOUNT_DEPRECATED,
"@attention This property will be removed in a future release, "
"use the <b><<<warningsCount>>></b> property instead.");
REGISTER_HELP_FUNCTION(getWarningCount, BaseResult);
REGISTER_HELP_FUNCTION_TEXT(BASERESULT_GETWARNINGCOUNT, R"*(
The number of warnings produced by the last statement execution.
@returns the number of warnings.
@attention This function will be removed in a future release, use the
<b><<<getWarningsCount>>></b> function instead.
This is the same value than C API mysql_warning_count, see
https://dev.mysql.com/doc/refman/en/mysql-warning-count.html
See <<<getWarnings>>>() for more details.
)*");
/**
* $(BASERESULT_GETWARNINGCOUNT_BRIEF)
*
* $(BASERESULT_GETWARNINGCOUNT)
*
* \sa warnings
*/
#if DOXYGEN_JS
Integer BaseResult::getWarningCount() {}
#elif DOXYGEN_PY
int BaseResult::get_warning_count() {}
#endif
// Documentation of getWarningCount function
REGISTER_HELP_PROPERTY(warningsCount, BaseResult);
REGISTER_HELP(BASERESULT_WARNINGSCOUNT_BRIEF, "Same as <<<getWarningsCount>>>");
REGISTER_HELP_FUNCTION(getWarningsCount, BaseResult);
REGISTER_HELP_FUNCTION_TEXT(BASERESULT_GETWARNINGSCOUNT, R"*(
The number of warnings produced by the last statement execution.
@returns the number of warnings.
This is the same value than C API mysql_warning_count, see
https://dev.mysql.com/doc/refman/en/mysql-warning-count.html
See <<<getWarnings>>>() for more details.
)*");
/**
* $(BASERESULT_GETWARNINGSCOUNT_BRIEF)
*
* $(BASERESULT_GETWARNINGSCOUNT)
*
* \sa warnings
*/
#if DOXYGEN_JS
Integer BaseResult::getWarningsCount() {}
#elif DOXYGEN_PY
int BaseResult::get_warnings_count() {}
#endif
uint64_t BaseResult::get_warnings_count() const {
if (_result) return _result->get_warning_count();
return 0;
}
void BaseResult::append_json(shcore::JSON_dumper &dumper) const {
bool create_object = (dumper.deep_level() == 0);
if (create_object) dumper.start_object();
dumper.append_value("executionTime", get_member("executionTime"));
dumper.append_value("affectedItemsCount", get_member("affectedItemsCount"));
if (mysqlsh::current_shell_options()->get().show_warnings) {
dumper.append_value("warningCount", get_member("warningsCount"));
dumper.append_value("warningsCount", get_member("warningsCount"));
dumper.append_value("warnings", get_member("warnings"));
}
if (create_object) dumper.end_object();
}
// -----------------------------------------------------------------------
// Documentation of Result class
REGISTER_HELP_SUB_CLASS(Result, mysqlx, BaseResult);
REGISTER_HELP_CLASS_TEXT(RESULT, R"*(
Allows retrieving information about non query operations performed on the
database.
An instance of this class will be returned on the CRUD operations that change
the content of the database:
@li On Table: insert, update and delete
@li On Collection: add, modify and remove
Other functions on the Session class also return an instance of this class:
@li Transaction handling functions
)*");
Result::Result(std::shared_ptr<mysqlshdk::db::mysqlx::Result> result)
: BaseResult(result) {
add_property("affectedItemCount", "getAffectedItemCount");
add_property("autoIncrementValue", "getAutoIncrementValue");
add_property("generatedIds", "getGeneratedIds");
}
shcore::Value Result::get_member(const std::string &prop) const {
Value ret_val;
if (prop == "affectedItemCount") {
ret_val = Value(get_affected_items_count());
log_warning("'%s' is deprecated, use '%s' instead.",
get_function_name("affectedItemCount").c_str(),
get_function_name("affectedItemsCount").c_str());
} else if (prop == "autoIncrementValue") {
ret_val = Value(get_auto_increment_value());
} else if (prop == "generatedIds") {
auto array = shcore::make_array();
for (auto &doc_id : get_generated_ids()) {
array->emplace_back(std::move(doc_id));
}
ret_val = Value(std::move(array));
} else {
ret_val = BaseResult::get_member(prop);
}
return ret_val;
}
// Documentation of getAffectedItemCount function
REGISTER_HELP_PROPERTY(affectedItemCount, Result);
REGISTER_HELP(RESULT_AFFECTEDITEMCOUNT_BRIEF,
"Same as <<<getAffectedItemCount>>>");
REGISTER_HELP(RESULT_AFFECTEDITEMCOUNT_DETAIL,
"${RESULT_AFFECTEDITEMCOUNT_DEPRECATED}");
REGISTER_HELP(RESULT_AFFECTEDITEMCOUNT_DEPRECATED,
"@attention This property will be removed in a future release, "
"use the <b><<<affectedItemsCount>>></b> property instead.");
REGISTER_HELP_FUNCTION(getAffectedItemCount, Result);
REGISTER_HELP_FUNCTION_TEXT(RESULT_GETAFFECTEDITEMCOUNT, R"*(
The the number of affected items for the last operation.
@returns the number of affected items.
@attention This function will be removed in a future release, use the
<b><<<getAffectedItemsCount>>></b> function instead.
This is the value of the C API mysql_affected_rows(), see
https://dev.mysql.com/doc/refman/en/mysql-affected-rows.html
)*");
/**
* $(RESULT_GETAFFECTEDITEMCOUNT_BRIEF)
*
* $(RESULT_GETAFFECTEDITEMCOUNT)
*/
#if DOXYGEN_JS
Integer Result::getAffectedItemCount() {}
#elif DOXYGEN_PY
int Result::get_affected_item_count() {}
#endif
// Documentation of getAutoIncrementValue function
REGISTER_HELP_PROPERTY(autoIncrementValue, Result);
REGISTER_HELP(RESULT_AUTOINCREMENTVALUE_BRIEF,
"Same as <<<getAutoIncrementValue>>>");
REGISTER_HELP_FUNCTION(getAutoIncrementValue, Result);
REGISTER_HELP_FUNCTION_TEXT(RESULT_GETAUTOINCREMENTVALUE, R"*(
The last insert id auto generated (from an insert operation)
@returns the integer representing the last insert id
For more details, see
https://dev.mysql.com/doc/refman/en/information-functions.html#function_last-insert-id
Note that this value will be available only when the result is for a
Table.insert operation.
)*");
/**
* $(RESULT_GETAUTOINCREMENTVALUE_BRIEF)
*
* $(RESULT_GETAUTOINCREMENTVALUE)
*/
#if DOXYGEN_JS
Integer Result::getAutoIncrementValue() {}
#elif DOXYGEN_PY
int Result::get_auto_increment_value() {}
#endif
int64_t Result::get_auto_increment_value() const {
if (_result) return _result->get_auto_increment_value();
return 0;
}
// Documentation of getLastDocumentId function
REGISTER_HELP_PROPERTY(generatedIds, Result);
REGISTER_HELP(RESULT_GENERATEDIDS_BRIEF, "Same as <<<getGeneratedIds>>>.");
REGISTER_HELP_FUNCTION(getGeneratedIds, Result);
REGISTER_HELP_FUNCTION_TEXT(RESULT_GETGENERATEDIDS, R"*(
Returns the list of document ids generated on the server.
@returns a list of strings containing the generated ids.
When adding documents into a collection, it is required that an ID is
associated to the document, if a document is added without an '_id' field, an
error will be generated.
At MySQL 8.0.11 if the documents being added do not have an '_id' field, the
server will automatically generate an ID and assign it to the document.
This function returns a list of the IDs that were generated for the server to
satisfy this requirement.
)*");
/**
* $(RESULT_GETGENERATEDIDS_BRIEF)
*
* $(RESULT_GETGENERATEDIDS)
*/
#if DOXYGEN_JS
List Result::getGeneratedIds() {}
#elif DOXYGEN_PY
list Result::get_generated_ids() {}
#endif
const std::vector<std::string> Result::get_generated_ids() const {
if (_result)
return _result->get_generated_ids();
else
return {};
}
void Result::append_json(shcore::JSON_dumper &dumper) const {
dumper.start_object();
BaseResult::append_json(dumper);
dumper.append_value("affectedItemCount", get_member("affectedItemsCount"));
dumper.append_value("autoIncrementValue", get_member("autoIncrementValue"));
dumper.append_value("generatedIds", get_member("generatedIds"));
dumper.end_object();
}
// -----------------------------------------------------------------------
// Documentation of DocResult class
REGISTER_HELP_SUB_CLASS(DocResult, mysqlx, BaseResult);
REGISTER_HELP(DOCRESULT_BRIEF,
"Allows traversing the DbDoc objects returned by a "
"Collection.find operation.");
DocResult::DocResult(std::shared_ptr<mysqlshdk::db::mysqlx::Result> result)
: BaseResult(result) {
expose("fetchOne", &DocResult::fetch_one);
expose("fetchAll", &DocResult::fetch_all);
}
// Documentation of fetchOne function
REGISTER_HELP_FUNCTION(fetchOne, DocResult);
REGISTER_HELP_FUNCTION_TEXT(DOCRESULT_FETCHONE, R"*(
Retrieves the next DbDoc on the DocResult.
@returns A DbDoc object representing the next Document in the result.
)*");
/**
* $(DOCRESULT_FETCHONE_BRIEF)
*
* $(DOCRESULT_FETCHONE)
*/
#if DOXYGEN_JS
Document DocResult::fetchOne() {}
#elif DOXYGEN_PY
Document DocResult::fetch_one() {}
#endif
shcore::Dictionary_t DocResult::fetch_one() const {
shcore::Dictionary_t ret_val;
if (_result) {
if (const mysqlshdk::db::IRow *r = _result->fetch_one()) {
ret_val = Value::parse(r->get_string(0)).as_map();
}
}
return ret_val;
}
// Documentation of fetchAll function
REGISTER_HELP_FUNCTION(fetchAll, DocResult);
REGISTER_HELP_FUNCTION_TEXT(DOCRESULT_FETCHALL, R"*(
Returns a list of DbDoc objects which contains an element for every unread
document.
@returns A List of DbDoc objects.
If this function is called right after executing a query, it will return a
DbDoc for every document on the resultset.
If fetchOne is called before this function, when this function is called it
will return a DbDoc for each of the remaining documents on the resultset.
)*");
/**
* $(DOCRESULT_FETCHALL_BRIEF)
*
* $(DOCRESULT_FETCHALL)
*/
#if DOXYGEN_JS
List DocResult::fetchAll() {}
#elif DOXYGEN_PY
list DocResult::fetch_all() {}
#endif
shcore::Array_t DocResult::fetch_all() const {
auto array = shcore::make_array();
// Gets the next document
auto record = fetch_one();
while (record) {
array->push_back(shcore::Value(record));
record = fetch_one();
}
return array;
}
void DocResult::append_json(shcore::JSON_dumper &dumper) const {
dumper.start_object();
dumper.append_value("documents", shcore::Value(fetch_all()));
BaseResult::append_json(dumper);
dumper.end_object();
}
// -----------------------------------------------------------------------
// Documentation of RowResult class
REGISTER_HELP_SUB_CLASS(RowResult, mysqlx, BaseResult);
REGISTER_HELP(
ROWRESULT_BRIEF,
"Allows traversing the Row objects returned by a Table.select operation.");
RowResult::RowResult(std::shared_ptr<mysqlshdk::db::mysqlx::Result> result)
: BaseResult(result) {
add_property("columnCount", "getColumnCount");
add_property("columns", "getColumns");
add_property("columnNames", "getColumnNames");
expose("fetchOne", &RowResult::fetch_one);
expose("fetchAll", &RowResult::fetch_all);
expose("fetchOneObject", &RowResult::_fetch_one_object);
}
shcore::Value RowResult::get_member(const std::string &prop) const {
Value ret_val;
if (prop == "columnCount") {
ret_val = shcore::Value(get_column_count());
} else if (prop == "columnNames") {
update_column_cache();
auto array = shcore::make_array();
if (m_column_names) {
for (auto &column : *m_column_names) {
array->push_back(shcore::Value(column));
}
}
ret_val = shcore::Value(array);
} else if (prop == "columns") {
update_column_cache();
if (m_columns) {
ret_val = shcore::Value(m_columns);
} else {
ret_val = shcore::Value(shcore::make_array());
}
} else {
ret_val = BaseResult::get_member(prop);
}
return ret_val;
}
// Documentation of getColumnCount function
REGISTER_HELP_PROPERTY(columnCount, RowResult);
REGISTER_HELP(ROWRESULT_COLUMNCOUNT_BRIEF, "Same as <<<getColumnCount>>>");
REGISTER_HELP_FUNCTION(getColumnCount, RowResult);
REGISTER_HELP_FUNCTION_TEXT(ROWRESULT_GETCOLUMNCOUNT, R"*(
Retrieves the number of columns on the current result.
@returns the number of columns on the current result.
)*");
/**
* $(ROWRESULT_GETCOLUMNCOUNT_BRIEF)
*
* $(ROWRESULT_GETCOLUMNCOUNT)
*/
#if DOXYGEN_JS
Integer RowResult::getColumnCount() {}
#elif DOXYGEN_PY
int RowResult::get_column_count() {}
#endif
int64_t RowResult::get_column_count() const {
return _result->get_metadata().size();
}
// Documentation of getColumnNames function
REGISTER_HELP_PROPERTY(columnNames, RowResult);
REGISTER_HELP(ROWRESULT_COLUMNNAMES_BRIEF, "Same as <<<getColumnNames>>>");
REGISTER_HELP_FUNCTION(getColumnNames, RowResult);
REGISTER_HELP_FUNCTION_TEXT(ROWRESULT_GETCOLUMNNAMES, R"*(
Gets the columns on the current result.
@returns A list with the names of the columns returned on the active result.
)*");
/**
* $(ROWRESULT_GETCOLUMNNAMES_BRIEF)
*
* $(ROWRESULT_GETCOLUMNNAMES)
*/
#if DOXYGEN_JS
List RowResult::getColumnNames() {}
#elif DOXYGEN_PY
list RowResult::get_column_names() {}
#endif
// Documentation of getColumns function
REGISTER_HELP_PROPERTY(columns, RowResult);
REGISTER_HELP(ROWRESULT_COLUMNS_BRIEF, "Same as <<<getColumns>>>");
REGISTER_HELP_FUNCTION(getColumns, RowResult);
REGISTER_HELP_FUNCTION_TEXT(ROWRESULT_GETCOLUMNS, R"*(
Gets the column metadata for the columns on the active result.
@returns a list of Column objects containing information about the columns
included on the active result.
)*");
/**
* $(ROWRESULT_GETCOLUMNS_BRIEF)
*
* $(ROWRESULT_GETCOLUMNS)
*/
#if DOXYGEN_JS
List RowResult::getColumns() {}
#elif DOXYGEN_PY
list RowResult::get_columns() {}
#endif
// Documentation of fetchOne function
REGISTER_HELP_FUNCTION(fetchOne, RowResult);
REGISTER_HELP_FUNCTION_TEXT(ROWRESULT_FETCHONE, R"*(
Retrieves the next Row on the RowResult.
@returns A Row object representing the next record on the result.
)*");
/**
* $(ROWRESULT_FETCHONE_BRIEF)
*
* $(ROWRESULT_FETCHONE)
*/
#if DOXYGEN_JS
Row RowResult::fetchOne() {}
#elif DOXYGEN_PY
Row RowResult::fetch_one() {}
#endif
std::shared_ptr<mysqlsh::Row> RowResult::fetch_one() const {
std::shared_ptr<mysqlsh::Row> ret_val;
auto row = fetch_one_row();
if (row) {
ret_val = std::shared_ptr<mysqlsh::Row>(row.release());
}
return ret_val;
}
REGISTER_HELP_FUNCTION(fetchOneObject, RowResult);
REGISTER_HELP_FUNCTION_TEXT(ROWRESULT_FETCHONEOBJECT, R"*(
Retrieves the next Row on the result and returns it as an object.
@returns A dictionary containing the row information.
The column names will be used as keys in the returned dictionary and the column
data will be used as the key values.
If a column is a valid identifier it will be accessible as an object attribute
as @<dict@>.@<column@>.
If a column is not a valid identifier, it will be accessible as a dictionary
key as @<dict@>[@<column@>].
)*");
/**
* $(ROWRESULT_FETCHONEOBJECT_BRIEF)
*
* $(ROWRESULT_FETCHONEOBJECT)
*/
#if DOXYGEN_JS
Dictionary RowResult::fetchOneObject() {}
#elif DOXYGEN_PY
dict RowResult::fetch_one_object() {}
#endif
shcore::Dictionary_t RowResult::_fetch_one_object() {
return ShellBaseResult::fetch_one_object();
}
// Documentation of fetchAll function
REGISTER_HELP_FUNCTION(fetchAll, RowResult);
REGISTER_HELP_FUNCTION_TEXT(ROWRESULT_FETCHALL, R"*(
Returns a list of DbDoc objects which contains an element for every unread
document.
@returns A List of DbDoc objects.
)*");
/**
* $(ROWRESULT_FETCHALL_BRIEF)
*
* $(ROWRESULT_FETCHALL)
*/
#if DOXYGEN_JS
List RowResult::fetchAll() {}
#elif DOXYGEN_PY
list RowResult::fetch_all() {}
#endif
shcore::Array_t RowResult::fetch_all() const {
auto array = shcore::make_array();
// Gets the next row
auto record = fetch_one();
while (record) {
array->push_back(shcore::Value(record));
record = fetch_one();
}
return array;
}
void RowResult::append_json(shcore::JSON_dumper &dumper) const {
bool create_object = (dumper.deep_level() == 0);
if (create_object) dumper.start_object();
BaseResult::append_json(dumper);
dumper.append_value("rows", shcore::Value(fetch_all()));
if (create_object) dumper.end_object();
}
// Documentation of SqlResult class
REGISTER_HELP_SUB_CLASS(SqlResult, mysqlx, RowResult);
REGISTER_HELP(SQLRESULT_BRIEF,
"Allows browsing through the result information after performing "
"an operation on the database done through Session.sql");
SqlResult::SqlResult(std::shared_ptr<mysqlshdk::db::mysqlx::Result> result)
: RowResult(result) {
expose("hasData", &SqlResult::has_data);
expose("nextDataSet", &SqlResult::next_data_set);
expose("nextResult", &SqlResult::next_result);
add_property("autoIncrementValue", "getAutoIncrementValue");
add_property("affectedRowCount", "getAffectedRowCount");
}
// Documentation of getAutoIncrementValue function
REGISTER_HELP_PROPERTY(autoIncrementValue, SqlResult);
REGISTER_HELP(SQLRESULT_AUTOINCREMENTVALUE_BRIEF,
"Same as <<<getAutoIncrementValue>>>");
REGISTER_HELP_FUNCTION(getAutoIncrementValue, SqlResult);
REGISTER_HELP_FUNCTION_TEXT(SQLRESULT_GETAUTOINCREMENTVALUE, R"*(
Returns the identifier for the last record inserted.
Note that this value will only be set if the executed statement inserted a
record in the database and an ID was automatically generated.
)*");
/**
* $(SQLRESULT_GETAUTOINCREMENTVALUE_BRIEF)
*
* $(SQLRESULT_GETAUTOINCREMENTVALUE)
*/
#if DOXYGEN_JS
Integer SqlResult::getAutoIncrementValue() {}
#elif DOXYGEN_PY
int SqlResult::get_auto_increment_value() {}
#endif
int64_t SqlResult::get_auto_increment_value() const {
if (_result) return _result->get_auto_increment_value();
return 0;
}
// Documentation of getAffectedRowCount function
REGISTER_HELP_PROPERTY(affectedRowCount, SqlResult);
REGISTER_HELP(SQLRESULT_AFFECTEDROWCOUNT_BRIEF,
"Same as <<<getAffectedRowCount>>>");
REGISTER_HELP(SQLRESULT_AFFECTEDROWCOUNT_DETAIL,
"${SQLRESULT_AFFECTEDROWCOUNT_DEPRECATED}");
REGISTER_HELP(SQLRESULT_AFFECTEDROWCOUNT_DEPRECATED,
"@attention This property will be removed in a future release, "
"use the <b><<<affectedItemsCount>>></b> property instead.");
REGISTER_HELP_FUNCTION(getAffectedRowCount, SqlResult);
REGISTER_HELP_FUNCTION_TEXT(SQLRESULT_GETAFFECTEDROWCOUNT, R"*(
Returns the number of rows affected by the executed query.
@attention This function will be removed in a future release, use the
<b><<<getAffectedItemsCount>>></b> function instead.
)*");
/**
* $(SQLRESULT_GETAFFECTEDROWCOUNT_BRIEF)
*
* $(SQLRESULT_GETAFFECTEDROWCOUNT)
*/
#if DOXYGEN_JS
Integer SqlResult::getAffectedRowCount() {}
#elif DOXYGEN_PY
int SqlResult::get_affected_row_count() {}
#endif
int64_t SqlResult::get_affected_row_count() const {
if (_result) return _result->get_affected_row_count();
return 0;
}
shcore::Value SqlResult::get_member(const std::string &prop) const {
Value ret_val;
if (prop == "autoIncrementValue") {
ret_val = Value(get_auto_increment_value());
} else if (prop == "affectedRowCount") {
ret_val = Value(get_affected_row_count());
log_warning("'%s' is deprecated, use '%s' instead.",
get_function_name("affectedRowCount").c_str(),
get_function_name("affectedItemsCount").c_str());
} else {
ret_val = RowResult::get_member(prop);
}
return ret_val;
}
// Documentation of hasData function
REGISTER_HELP_FUNCTION(hasData, SqlResult);
REGISTER_HELP(SQLRESULT_HASDATA_BRIEF,
"Returns true if the last statement execution has a result set.");
/**
* $(SQLRESULT_HASDATA_BRIEF)
*/
#if DOXYGEN_JS
Bool SqlResult::hasData() {}
#elif DOXYGEN_PY
bool SqlResult::has_data() {}
#endif
// Documentation of nextDataSet function
REGISTER_HELP_FUNCTION(nextDataSet, SqlResult);
REGISTER_HELP_FUNCTION_TEXT(SQLRESULT_NEXTDATASET, R"*(
Prepares the SqlResult to start reading data from the next Result (if many
results were returned).
@returns A boolean value indicating whether there is another result or not.
@attention This function will be removed in a future release, use the
<b><<<nextResult>>></b> function instead.
)*");
/**
* $(SQLRESULT_NEXTDATASET_BRIEF)
*
* $(SQLRESULT_NEXTDATASET)
*/
#if DOXYGEN_JS
Bool SqlResult::nextDataSet() {}
#elif DOXYGEN_PY
bool SqlResult::next_data_set() {}
#endif
bool SqlResult::next_data_set() {
log_warning("'%s' is deprecated, use '%s' instead.",
get_function_name("nextDataSet").c_str(),
get_function_name("nextResult").c_str());
return next_result();
}
// Documentation of nextDataSet function
REGISTER_HELP_FUNCTION(nextResult, SqlResult);
REGISTER_HELP_FUNCTION_TEXT(SQLRESULT_NEXTRESULT, R"*(
Prepares the SqlResult to start reading data from the next Result (if many
results were returned).
@returns A boolean value indicating whether there is another result or not.
)*");
/**
* $(SQLRESULT_NEXTRESULT_BRIEF)
*
* $(SQLRESULT_NEXTRESULT)
*/
#if DOXYGEN_JS
Bool SqlResult::nextResult() {}
#elif DOXYGEN_PY
bool SqlResult::next_result() {}
#endif
bool SqlResult::next_result() {
reset_column_cache();
return _result->next_resultset();
}
void SqlResult::append_json(shcore::JSON_dumper &dumper) const {
dumper.start_object();
RowResult::append_json(dumper);
dumper.append_value("hasData", shcore::Value(has_data()));
dumper.append_value("affectedRowCount", get_member("affectedItemsCount"));
dumper.append_value("autoIncrementValue", get_member("autoIncrementValue"));
dumper.end_object();
}
} // namespace mysqlx
} // namespace mysqlsh