diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-05-31 13:18:17 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-05-31 13:18:17 +0100 |
commit | 63b2ca0dbdae190941d60a55c9cff99d4a75a0e1 (patch) | |
tree | d3766bcbc98fb5fb0fb2d8dddf2f194bedcb0325 /lib/input/mysqlRecordSet.cpp | |
parent | Map std::size_t to a sensible header (diff) | |
download | mygrate-63b2ca0dbdae190941d60a55c9cff99d4a75a0e1.tar.bz2 mygrate-63b2ca0dbdae190941d60a55c9cff99d4a75a0e1.tar.xz mygrate-63b2ca0dbdae190941d60a55c9cff99d4a75a0e1.zip |
Initial commit of prepstmt, selects, record sets
This is full of holes, but all the basics are covered.
Diffstat (limited to 'lib/input/mysqlRecordSet.cpp')
-rw-r--r-- | lib/input/mysqlRecordSet.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/lib/input/mysqlRecordSet.cpp b/lib/input/mysqlRecordSet.cpp new file mode 100644 index 0000000..51be15f --- /dev/null +++ b/lib/input/mysqlRecordSet.cpp @@ -0,0 +1,99 @@ +#include "mysqlRecordSet.h" +#include "mysqlBindings.h" +#include "mysqlStmt.h" +#include <cstdint> +#include <dbTypes.h> +#include <helpers.h> +#include <stdexcept> +#include <string_view> +#include <utility> +// IWYU pragma: no_include <ext/alloc_traits.h> + +namespace MyGrate::Input { + MySQLRecordSet::MySQLRecordSet(StmtPtr s) : + stmt {std::move(s)}, stmtres {nullptr, nullptr}, fields(mysql_stmt_field_count(stmt.get())), + extras(fields.size()) + { + auto getBind = [](const MYSQL_FIELD & f, MYSQL_BIND & b) -> std::unique_ptr<ResultData> { + switch (f.type) { + case MYSQL_TYPE_DECIMAL: + case MYSQL_TYPE_NEWDECIMAL: + case MYSQL_TYPE_DOUBLE: + return std::make_unique<ResultDataT<double>>(b, f); + case MYSQL_TYPE_FLOAT: + return std::make_unique<ResultDataT<float>>(b, f); + case MYSQL_TYPE_TINY: + return std::make_unique<ResultDataT<int8_t>>(b, f); + case MYSQL_TYPE_SHORT: + case MYSQL_TYPE_YEAR: + return std::make_unique<ResultDataT<int16_t>>(b, f); + case MYSQL_TYPE_LONG: + case MYSQL_TYPE_INT24: + return std::make_unique<ResultDataT<int32_t>>(b, f); + case MYSQL_TYPE_LONGLONG: + return std::make_unique<ResultDataT<int64_t>>(b, f); + case MYSQL_TYPE_NULL: + return std::make_unique<ResultDataT<std::nullptr_t>>(b, f); + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_TIMESTAMP2: + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_DATETIME2: + return std::make_unique<ResultDataTime<DateTime>>(b, f); + case MYSQL_TYPE_TIME: + case MYSQL_TYPE_TIME2: + return std::make_unique<ResultDataTime<Time>>(b, f); + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_NEWDATE: + return std::make_unique<ResultDataTime<Date>>(b, f); + case MYSQL_TYPE_VARCHAR: + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_JSON: + case MYSQL_TYPE_ENUM: + return std::make_unique<ResultDataT<std::string_view>>(b, f); + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_BLOB: + return std::make_unique<ResultDataT<Blob>>(b, f); + case MAX_NO_FIELD_TYPES: + case MYSQL_TYPE_BIT: + case MYSQL_TYPE_SET: + case MYSQL_TYPE_GEOMETRY:; + } + throw std::runtime_error("Unsupported column type"); + }; + ResPtr meta {mysql_stmt_result_metadata(stmt.get()), mysql_free_result}; + const auto fieldDefs = mysql_fetch_fields(meta.get()); + verify<std::runtime_error>(fieldDefs, "Fetch fields"); + for (std::size_t i = 0; i < fields.size(); i += 1) { + extras[i] = getBind(fieldDefs[i], fields[i]); + } + verify<std::runtime_error>(!mysql_stmt_bind_result(stmt.get(), fields.data()), "Store result error"); + verify<std::runtime_error>(!mysql_stmt_store_result(stmt.get()), "Store result error"); + stmtres = {stmt.get(), mysql_stmt_free_result}; + verify<std::runtime_error>(!mysql_stmt_fetch(stmt.get()), "Fetch"); + } + + std::size_t + MySQLRecordSet::rows() const + { + return mysql_stmt_num_rows(stmt.get()); + } + + std::size_t + MySQLRecordSet::columns() const + { + return fields.size(); + } + + DbValue + MySQLRecordSet::at(std::size_t row, std::size_t col) const + { + mysql_stmt_data_seek(stmt.get(), row); + if (extras[col]->null) { + return nullptr; + } + return extras[col]->getValue(); + } +} |