From 7c907de7a6b2cf7e3ed81147b8195d52795ba499 Mon Sep 17 00:00:00 2001 From: antao Date: Wed, 28 Nov 2018 15:03:31 +0800 Subject: [PATCH] Add the MysqlResultImpl class --- orm_lib/src/mysql_impl/MysqlConnection.cc | 23 ++++---- orm_lib/src/mysql_impl/MysqlConnection.h | 3 +- orm_lib/src/mysql_impl/MysqlResultImpl.cc | 67 +++++++++++++++++++++++ orm_lib/src/mysql_impl/MysqlResultImpl.h | 41 ++++++++++++-- 4 files changed, 119 insertions(+), 15 deletions(-) diff --git a/orm_lib/src/mysql_impl/MysqlConnection.cc b/orm_lib/src/mysql_impl/MysqlConnection.cc index 2466dc3f..df645d58 100644 --- a/orm_lib/src/mysql_impl/MysqlConnection.cc +++ b/orm_lib/src/mysql_impl/MysqlConnection.cc @@ -12,6 +12,7 @@ */ #include "MysqlConnection.h" +#include "MysqlResultImpl.h" #include #include #include @@ -23,9 +24,11 @@ namespace drogon namespace orm { -Result makeResult(const std::shared_ptr &r = std::shared_ptr(nullptr), const std::string &query = "") +Result makeResult(const std::shared_ptr &r = std::shared_ptr(nullptr), + const std::string &query = "", + Result::size_type affectedRows = 0) { - return Result(std::shared_ptr(new MysqlResultImpl(r, query))); + return Result(std::shared_ptr(new MysqlResultImpl(r, query, affectedRows))); } } // namespace orm @@ -225,7 +228,7 @@ void MysqlConnection::handleEvent() case ExecStatus_SendQuery: { int err; - _waitStatus = mysql_send_query_cont(&err, _stmtPtr.get(), status); + _waitStatus = mysql_send_query_cont(&err, _mysqlPtr.get(), status); if (_waitStatus == 0) { if (err) @@ -237,7 +240,7 @@ void MysqlConnection::handleEvent() } _execStatus = ExecStatus_StoreResult; MYSQL_RES *ret; - _waitStatus = mysql_store_result_start(&ret, MYSQL * mysql); + _waitStatus = mysql_store_result_start(&ret, _mysqlPtr.get()); LOG_TRACE << "send_query completely!"; @@ -248,10 +251,10 @@ void MysqlConnection::handleEvent() case ExecStatus_StoreResult: { MYSQL_RES *ret; - _waitStatus = mysql_store_result_cont(&ret, MYSQL * mysql); + _waitStatus = mysql_store_result_cont(&ret, _mysqlPtr.get(), status); if (_waitStatus == 0) { - if(!ret) + if (!ret) { _execStatus = ExecStatus_None; outputError(); @@ -262,12 +265,12 @@ void MysqlConnection::handleEvent() auto resultPtr = std::shared_ptr(ret, [](MYSQL_RES *r) { mysql_free_result(r); }); - auto Result = makeResult(r, _sql); - if(_isWorking) + auto Result = makeResult(resultPtr, _sql, mysql_affected_rows(_mysqlPtr.get())); + if (_isWorking) { _cb(Result); _cb = decltype(_cb)(); - _exceptCb = decltype(_exceptCallback)(); + _exceptCb = decltype(_exceptCb)(); _isWorking = false; _idleCb(); _idleCb = decltype(_idleCb)(); @@ -310,7 +313,7 @@ void MysqlConnection::execSql(const std::string &sql, _loop->runInLoop([=]() { int err; //int mysql_send_query_start(int *ret, MYSQL *mysql, const char *q, unsigned long length) - _waitStatus = mysql_send_query_start(&err, _stmtPtr.get(), sql.c_str(), sql.length()); + _waitStatus = mysql_send_query_start(&err, _mysqlPtr.get(), sql.c_str(), sql.length()); if (_waitStatus == 0) { if (err) diff --git a/orm_lib/src/mysql_impl/MysqlConnection.h b/orm_lib/src/mysql_impl/MysqlConnection.h index c38f4dae..69a3632c 100644 --- a/orm_lib/src/mysql_impl/MysqlConnection.h +++ b/orm_lib/src/mysql_impl/MysqlConnection.h @@ -59,7 +59,8 @@ class MysqlConnection : public DbConnection, public std::enable_shared_from_this { ExecStatus_None = 0, ExecStatus_SendQuery, - ExecStatus_StmtPrepare + ExecStatus_StmtPrepare, + ExecStatus_StoreResult }; ExecStatus _execStatus = ExecStatus_None; std::shared_ptr _stmtPtr; diff --git a/orm_lib/src/mysql_impl/MysqlResultImpl.cc b/orm_lib/src/mysql_impl/MysqlResultImpl.cc index e69de29b..ab369a88 100644 --- a/orm_lib/src/mysql_impl/MysqlResultImpl.cc +++ b/orm_lib/src/mysql_impl/MysqlResultImpl.cc @@ -0,0 +1,67 @@ +/** + * + * MysqlResultImpl.cc + * An Tao + * + * Copyright 2018, An Tao. All rights reserved. + * Use of this source code is governed by a MIT license + * that can be found in the License file. + * + * + */ + +#include "MysqlResultImpl.h" +#include +#include + +using namespace drogon::orm; + +Result::size_type MysqlResultImpl::size() const noexcept +{ + return _rowsNum; +} +Result::row_size_type MysqlResultImpl::columns() const noexcept +{ + return _fieldNum; +} +const char *MysqlResultImpl::columnName(row_size_type number) const +{ + assert(number < _fieldNum); + if (_fieldArray) + return _fieldArray[number].name; + return ""; +} +Result::size_type MysqlResultImpl::affectedRows() const noexcept +{ + return _affectedRows; +} +Result::row_size_type MysqlResultImpl::columnNumber(const char colName[]) const +{ + if (!_fieldMapPtr) + return -1; + std::string col(colName); + std::transform(col.begin(), col.end(), col.begin(), tolower); + if (_fieldMapPtr->find(col) != _fieldMapPtr->end()) + return (*_fieldMapPtr)[col]; + return -1; +} +const char *MysqlResultImpl::getValue(size_type row, row_size_type column) const +{ + if (_rowsNum == 0 || _fieldNum == 0) + return NULL; + assert(row < _rowsNum); + assert(column < _fieldNum); + return (*_rowsPtr)[row].first[column]; +} +bool MysqlResultImpl::isNull(size_type row, row_size_type column) const +{ + return getValue(row, column) == NULL; +} +Result::field_size_type MysqlResultImpl::getLength(size_type row, row_size_type column) const +{ + if (_rowsNum == 0 || _fieldNum == 0) + return 0; + assert(row < _rowsNum); + assert(column < _fieldNum); + return (*_rowsPtr)[row].second[column]; +} diff --git a/orm_lib/src/mysql_impl/MysqlResultImpl.h b/orm_lib/src/mysql_impl/MysqlResultImpl.h index f53bcfaa..47c6c385 100644 --- a/orm_lib/src/mysql_impl/MysqlResultImpl.h +++ b/orm_lib/src/mysql_impl/MysqlResultImpl.h @@ -16,6 +16,9 @@ #include #include #include +#include +#include +#include namespace drogon { @@ -25,10 +28,34 @@ namespace orm class MysqlResultImpl : public ResultImpl { public: - MysqlResultImpl(const std::shared_ptr &r, const std::string &query) noexcept + MysqlResultImpl(const std::shared_ptr &r, const std::string &query, size_type affectedRows) noexcept : _result(r), - _query(query) + _query(query), + _rowsNum(_result ? mysql_num_rows(_result.get()) : 0), + _fieldArray(r ? mysql_fetch_fields(r.get()) : nullptr), + _fieldNum(r ? mysql_num_rows(r.get()) : 0), + _affectedRows(affectedRows) { + if (_fieldNum > 0) + { + _fieldMapPtr = std::make_shared>(); + for (row_size_type i = 0; i < _fieldNum; i++) + { + std::string fieldName = _fieldArray[i].name; + std::transform(fieldName.begin(), fieldName.end(), fieldName.begin(), tolower); + (*_fieldMapPtr)[fieldName] = i; + } + } + if (size() > 0) + { + _rowsPtr = std::make_shared>>(); + MYSQL_ROW row; + while ((row = mysql_fetch_row(r.get())) != NULL) + { + auto lengths = mysql_fetch_lengths(r.get()); + _rowsPtr->push_back(std::make_pair(row, lengths)); + } + } } virtual size_type size() const noexcept override; virtual row_size_type columns() const noexcept override; @@ -40,8 +67,14 @@ class MysqlResultImpl : public ResultImpl virtual field_size_type getLength(size_type row, row_size_type column) const override; private: - std::shared_ptr _result; - std::string _query; + const std::shared_ptr _result; + const std::string _query; + const Result::size_type _rowsNum; + const MYSQL_FIELD *_fieldArray; + const Result::row_size_type _fieldNum; + const size_type _affectedRows; + std::shared_ptr> _fieldMapPtr; + std::shared_ptr>> _rowsPtr; }; } // namespace orm