xapi/result.cc (101 lines of code) (raw):
/*
* Copyright (c) 2016, 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.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* https://oss.oracle.com/licenses/universal-foss-exception.
*
* 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 <mysqlx/xapi.h>
#include "mysqlx_cc_internal.h"
using namespace mysqlx::common;
/*
Convert CDK type and encoding information into XAPI type constant.
*/
uint32_t get_type(const Format_info &fi)
{
switch (fi.m_type)
{
case cdk::TYPE_INTEGER:
{
auto &format = fi.get<cdk::TYPE_INTEGER>().m_format;
if(format.is_bit())
return MYSQLX_TYPE_BIT;
if (format.length() == 1)
return MYSQLX_TYPE_BOOL;
if (format.is_unsigned())
return MYSQLX_TYPE_UINT;
return MYSQLX_TYPE_SINT;
}
case cdk::TYPE_FLOAT:
{
auto &format = fi.get<cdk::TYPE_FLOAT>().m_format;
if (format.type() == format.FLOAT)
return MYSQLX_TYPE_FLOAT;
else if (format.type() == format.DOUBLE)
return MYSQLX_TYPE_DOUBLE;
else
return MYSQLX_TYPE_DECIMAL;
}
case cdk::TYPE_DATETIME:
{
auto &format = fi.get<cdk::TYPE_DATETIME>().m_format;
switch(format.type())
{
case cdk::Format<cdk::TYPE_DATETIME>::TIME:
return MYSQLX_TYPE_TIME;
case cdk::Format<cdk::TYPE_DATETIME>::TIMESTAMP:
return MYSQLX_TYPE_TIMESTAMP;
default:
return MYSQLX_TYPE_DATETIME;
}
break;
}
// TODO: differ the blob types by their length
case cdk::TYPE_BYTES:
{
// TODO: use it when GEOMETRY type is supported by CDK
// cdk::Format<cdk::TYPE_BYTES> format(m_cursor->format(pos));
return MYSQLX_TYPE_BYTES;
}
case cdk::TYPE_STRING:
{
auto &format = fi.get<cdk::TYPE_STRING>().m_format;
if (format.is_enum())
return MYSQLX_TYPE_ENUM;
else if (format.is_set())
return MYSQLX_TYPE_SET;
return MYSQLX_TYPE_STRING;
}
case cdk::TYPE_DOCUMENT:
return MYSQLX_TYPE_JSON;
case cdk::TYPE_GEOMETRY:
return MYSQLX_TYPE_GEOMETRY;
default:
return fi.m_type;
}
}
/*
Read the next JSON string from the result and advance the cursor position
*/
const char * mysqlx_result_struct::read_json(size_t *json_byte_size)
{
assert(!m_result_mdata.empty());
assert(1 == m_result_mdata.front()->col_count());
assert(cdk::TYPE_DOCUMENT == m_result_mdata.front()->get_type(0));
mysqlx_row_struct *row = read_row();
if (!row)
return NULL;
cdk::bytes data = row->get_bytes(0);
/*
Note: we return size in bytes, including the '\0' terminator.
*/
if (json_byte_size)
*json_byte_size = data.size();
if (0 == data.size())
{
// remove unnecessary row structure for null document.
m_row_set.pop_back();
return NULL;
}
return (const char*) data.begin();
}
const char * mysqlx_result_struct::get_next_generated_id()
{
if (m_doc_id_list.empty() && m_current_id_index == 0)
{
if (!m_reply)
return NULL;
for (auto id : m_reply->generated_ids())
m_doc_id_list.push_back(id);
}
if (m_current_id_index >= m_doc_id_list.size())
return NULL;
return m_doc_id_list[m_current_id_index++].c_str();
}
mysqlx_error_struct* mysqlx_result_struct::get_next_warning()
{
if (!m_warn_it.next())
return NULL;
m_current_warning.reset(new mysqlx_error_struct(m_warn_it.entry().get_error(), true));
return m_current_warning.get();
}