Skip to content

Commit

Permalink
Serializers into JSON for MySQL API objects
Browse files Browse the repository at this point in the history
  • Loading branch information
iagaponenko committed Dec 15, 2024
1 parent cc2b51e commit e8a144b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 23 deletions.
25 changes: 25 additions & 0 deletions src/replica/mysql/DatabaseMySQL.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "lsst/log/Log.h"

using namespace std;
using json = nlohmann::json;

namespace {

Expand Down Expand Up @@ -495,6 +496,30 @@ void Connection::exportField(ProtocolResponseSqlField* ptr, size_t idx) const {
ptr->set_type(field.type);
}

json Connection::fieldsToJson() const {
_assertQueryContext();

json result;
for (size_t i = 0; i < _numFields; ++i) {
auto&& field = _fields[i];
json f;
f["name"] = field.name;
f["org_name"] = field.org_name;
f["table"] = field.table;
f["org_table"] = field.org_table;
f["db"] = field.db;
f["catalog"] = field.catalog;
f["def"] = field.def;
f["length"] = field.length;
f["max_length"] = field.max_length;
f["flags"] = field.flags;
f["decimals"] = field.decimals;
f["type"] = field.type;
result.push_back(move(f));
}
return result;
}

bool Connection::next(Row& row) {
string const context = "Connection[" + to_string(_id) + "]::" + string(__func__) +
"(_inTransaction=" + to_string(_inTransaction ? 1 : 0) + ") ";
Expand Down
15 changes: 15 additions & 0 deletions src/replica/mysql/DatabaseMySQL.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@

// Third party headers
#include <mysql/mysql.h>
#include "nlohmann/json.hpp"

// Qserv headers
#include "replica/mysql/DatabaseMySQLExceptions.h"
Expand Down Expand Up @@ -422,6 +423,20 @@ class Connection : public std::enable_shared_from_this<Connection> {
*/
void exportField(ProtocolResponseSqlField* ptr, size_t idx) const;

/**
* Convert the current result set into a JSON object.
*
* @note The method can be called only upon a successful completion of a query
* which has a result set. Otherwise it will throw an exception.
*
* @see Connection::hasResult
*
* @return a JSON object representing the current result set
* @throw std::logic_error if no SQL statement has ever been executed, or
* if the last query failed.
*/
nlohmann::json fieldsToJson() const;

/**
* Move the iterator to the next (first) row of the current result set
* and if the iterator is not beyond the last row then initialize an object
Expand Down
26 changes: 26 additions & 0 deletions src/replica/mysql/DatabaseMySQLRow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@

// Qserv headers
#include "replica/proto/protocol.pb.h"
#include "util/String.h"

// LSST headers
#include "lsst/log/Log.h"

using namespace std;
using json = nlohmann::json;

namespace {

Expand Down Expand Up @@ -204,4 +206,28 @@ void Row::exportRow(ProtocolResponseSqlRow* ptr) const {
}
}

json Row::toJson() const {
string const context = "Row::" + string(__func__) + " ";
if (not isValid()) {
throw logic_error(context + "the object is not valid");
}
json result = json::object();
result["cells"] = json::array();
result["nulls"] = json::array();
json& cellsJson = result["cells"];
json& nullsJson = result["nulls"];
for (Cell const& cell : _index2cell) {
char const* ptr = cell.first;
size_t const length = cell.second;
if (nullptr == ptr) {
cellsJson.push_back(string());
nullsJson.push_back(1);
} else {
cellsJson.push_back(util::String::toHex(ptr, length));
nullsJson.push_back(0);
}
}
return result;
}

} // namespace lsst::qserv::replica::database::mysql
39 changes: 16 additions & 23 deletions src/replica/mysql/DatabaseMySQLRow.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
#include <string>
#include <vector>

// Third party headers
#include "nlohmann/json.hpp"

// Qserv headers
#include "replica/mysql/DatabaseMySQLExceptions.h"

Expand Down Expand Up @@ -110,10 +113,7 @@ class Row {
*/
Row();

/// Copy constructor
Row(Row const& rhs) = default;

/// The Assignment operator
Row& operator=(Row const& rhs) = default;

~Row() = default;
Expand All @@ -133,8 +133,6 @@ class Row {
// There are two ways to access the values: either by a relative
// index of a column in a result set, or by the name of the column.
// The second method has some extra (though, minor) overhead.
//
// @see class Row

template <typename T>
T getAs(size_t columnIdx) const {
Expand Down Expand Up @@ -204,41 +202,36 @@ class Row {
// Other types

bool get(size_t columnIdx, bool& value) const;

bool get(std::string const& columnName, bool& value) const;

/**
* @return
* reference to the data cell for the column
*
* @param columnIdx
* the index of a column
* @param columnIdx the index of a column
* @return reference to the data cell for the column
*/
Cell const& getDataCell(size_t columnIdx) const;

/**
* @return
* reference to the data cell for the column
*
* @param columnName
* the name of a column
* @param columnName the name of a column
* @return reference to the data cell for the column
*/
Cell const& getDataCell(std::string const& columnName) const;

/**
* Fill a Protobuf object representing a row.
*
* @param ptr
* a valid pointer to the Protobuf object to be populated.
*
* @param std::invalid_argument
* if the input pointer is 0
* @param ptr a valid pointer to the Protobuf object to be populated.
* @param std::invalid_argument if the input pointer is 0
*/
void exportRow(ProtocolResponseSqlRow* ptr) const;

/**
* Convert the current row into a JSON object.
* @return a JSON object representing the current row
*/
nlohmann::json toJson() const;

private:
/**
* Mapping column names to the indexes
* Mapping column names to the indexes
*
* @note
* If the pointer is set to 'nullptr' then the object is not
Expand Down

0 comments on commit e8a144b

Please sign in to comment.