Add the MysqlResultImpl class
This commit is contained in:
parent
d92ce4cf9f
commit
7c907de7a6
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
|
||||
#include "MysqlConnection.h"
|
||||
#include "MysqlResultImpl.h"
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <regex>
|
||||
#include <algorithm>
|
||||
|
@ -23,9 +24,11 @@ namespace drogon
|
|||
namespace orm
|
||||
{
|
||||
|
||||
Result makeResult(const std::shared_ptr<MYSQL_RES> &r = std::shared_ptr<MYSQL_RES>(nullptr), const std::string &query = "")
|
||||
Result makeResult(const std::shared_ptr<MYSQL_RES> &r = std::shared_ptr<MYSQL_RES>(nullptr),
|
||||
const std::string &query = "",
|
||||
Result::size_type affectedRows = 0)
|
||||
{
|
||||
return Result(std::shared_ptr<MysqlResultImpl>(new MysqlResultImpl(r, query)));
|
||||
return Result(std::shared_ptr<MysqlResultImpl>(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<MYSQL_RES>(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)
|
||||
|
|
|
@ -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<MYSQL_STMT> _stmtPtr;
|
||||
|
|
|
@ -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 <assert.h>
|
||||
#include <algorithm>
|
||||
|
||||
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];
|
||||
}
|
|
@ -16,6 +16,9 @@
|
|||
#include <mysql.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
|
@ -25,10 +28,34 @@ namespace orm
|
|||
class MysqlResultImpl : public ResultImpl
|
||||
{
|
||||
public:
|
||||
MysqlResultImpl(const std::shared_ptr<MYSQL_RES> &r, const std::string &query) noexcept
|
||||
MysqlResultImpl(const std::shared_ptr<MYSQL_RES> &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<std::unordered_map<std::string, row_size_type>>();
|
||||
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<std::vector<std::pair<char **, field_size_type *>>>();
|
||||
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<MYSQL_RES> _result;
|
||||
std::string _query;
|
||||
const std::shared_ptr<MYSQL_RES> _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<std::unordered_map<std::string, row_size_type>> _fieldMapPtr;
|
||||
std::shared_ptr<std::vector<std::pair<char **, field_size_type *>>> _rowsPtr;
|
||||
};
|
||||
|
||||
} // namespace orm
|
||||
|
|
Loading…
Reference in New Issue