mirror of
https://github.com/drogonframework/drogon.git
synced 2025-07-20 00:00:28 -04:00
Compare commits
2 Commits
d9afdf279a
...
645c2d8aaf
Author | SHA1 | Date | |
---|---|---|---|
|
645c2d8aaf | ||
|
ab76e80089 |
@ -53,7 +53,7 @@ ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
|||||||
ConstructorInitializerIndentWidth: 4
|
ConstructorInitializerIndentWidth: 4
|
||||||
ContinuationIndentWidth: 4
|
ContinuationIndentWidth: 4
|
||||||
Cpp11BracedListStyle: true
|
Cpp11BracedListStyle: true
|
||||||
DerivePointerAlignment: true
|
DerivePointerAlignment: false
|
||||||
DisableFormat: false
|
DisableFormat: false
|
||||||
FixNamespaceComments: true
|
FixNamespaceComments: true
|
||||||
ForEachMacros:
|
ForEachMacros:
|
||||||
@ -94,7 +94,8 @@ PenaltyBreakString: 1000
|
|||||||
PenaltyBreakTemplateDeclaration: 10
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
PenaltyExcessCharacter: 1000000
|
PenaltyExcessCharacter: 1000000
|
||||||
PenaltyReturnTypeOnItsOwnLine: 2000
|
PenaltyReturnTypeOnItsOwnLine: 2000
|
||||||
PointerAlignment: Left
|
PointerAlignment: Right
|
||||||
|
ReferenceAlignment: Right
|
||||||
RawStringFormats:
|
RawStringFormats:
|
||||||
- Language: Cpp
|
- Language: Cpp
|
||||||
Delimiters:
|
Delimiters:
|
||||||
@ -125,7 +126,7 @@ RawStringFormats:
|
|||||||
BasedOnStyle: google
|
BasedOnStyle: google
|
||||||
ReflowComments: true
|
ReflowComments: true
|
||||||
SeparateDefinitionBlocks: Always
|
SeparateDefinitionBlocks: Always
|
||||||
SortIncludes: false
|
SortIncludes: Never
|
||||||
SortUsingDeclarations: true
|
SortUsingDeclarations: true
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
SpaceAfterTemplateKeyword: true
|
SpaceAfterTemplateKeyword: true
|
||||||
|
@ -50,8 +50,8 @@ class JsonStore : public HttpController<JsonStore>
|
|||||||
ADD_METHOD_VIA_REGEX(JsonStore::updateItem, "/([a-f0-9]{64})/(.*)", Put);
|
ADD_METHOD_VIA_REGEX(JsonStore::updateItem, "/([a-f0-9]{64})/(.*)", Put);
|
||||||
METHOD_LIST_END
|
METHOD_LIST_END
|
||||||
|
|
||||||
void getToken(const HttpRequestPtr&,
|
void getToken(const HttpRequestPtr &,
|
||||||
std::function<void(const HttpResponsePtr&)>&& callback)
|
std::function<void(const HttpResponsePtr &)> &&callback)
|
||||||
{
|
{
|
||||||
std::string randomString = getRandomString(64);
|
std::string randomString = getRandomString(64);
|
||||||
Json::Value res;
|
Json::Value res;
|
||||||
@ -60,10 +60,10 @@ class JsonStore : public HttpController<JsonStore>
|
|||||||
callback(HttpResponse::newHttpJsonResponse(std::move(res)));
|
callback(HttpResponse::newHttpJsonResponse(std::move(res)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void getItem(const HttpRequestPtr&,
|
void getItem(const HttpRequestPtr &,
|
||||||
std::function<void(const HttpResponsePtr&)>&& callback,
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
const std::string& token,
|
const std::string &token,
|
||||||
const std::string& path)
|
const std::string &path)
|
||||||
{
|
{
|
||||||
auto itemPtr = [this, &token]() -> std::shared_ptr<DataItem> {
|
auto itemPtr = [this, &token]() -> std::shared_ptr<DataItem> {
|
||||||
// It is possible that the item is being removed while another
|
// It is possible that the item is being removed while another
|
||||||
@ -81,12 +81,12 @@ class JsonStore : public HttpController<JsonStore>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& item = *itemPtr;
|
auto &item = *itemPtr;
|
||||||
// Prevents another thread from writing to the same item while this
|
// Prevents another thread from writing to the same item while this
|
||||||
// thread reads. Could cause blockage if multiple clients are asking to
|
// thread reads. Could cause blockage if multiple clients are asking to
|
||||||
// read the same object. But that should be rare.
|
// read the same object. But that should be rare.
|
||||||
std::lock_guard<std::mutex> lock(item.mtx);
|
std::lock_guard<std::mutex> lock(item.mtx);
|
||||||
Json::Value* valuePtr = walkJson(item.item, path);
|
Json::Value *valuePtr = walkJson(item.item, path);
|
||||||
|
|
||||||
if (valuePtr == nullptr)
|
if (valuePtr == nullptr)
|
||||||
{
|
{
|
||||||
@ -98,10 +98,10 @@ class JsonStore : public HttpController<JsonStore>
|
|||||||
callback(resp);
|
callback(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateItem(const HttpRequestPtr& req,
|
void updateItem(const HttpRequestPtr &req,
|
||||||
std::function<void(const HttpResponsePtr&)>&& callback,
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
const std::string& token,
|
const std::string &token,
|
||||||
const std::string& path)
|
const std::string &path)
|
||||||
{
|
{
|
||||||
auto jsonPtr = req->jsonObject();
|
auto jsonPtr = req->jsonObject();
|
||||||
auto itemPtr = [this, &token]() -> std::shared_ptr<DataItem> {
|
auto itemPtr = [this, &token]() -> std::shared_ptr<DataItem> {
|
||||||
@ -121,9 +121,9 @@ class JsonStore : public HttpController<JsonStore>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& item = *itemPtr;
|
auto &item = *itemPtr;
|
||||||
std::lock_guard<std::mutex> lock(item.mtx);
|
std::lock_guard<std::mutex> lock(item.mtx);
|
||||||
Json::Value* valuePtr = walkJson(item.item, path, 1);
|
Json::Value *valuePtr = walkJson(item.item, path, 1);
|
||||||
|
|
||||||
if (valuePtr == nullptr)
|
if (valuePtr == nullptr)
|
||||||
{
|
{
|
||||||
@ -137,9 +137,9 @@ class JsonStore : public HttpController<JsonStore>
|
|||||||
callback(makeSuccessResponse());
|
callback(makeSuccessResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
void createItem(const HttpRequestPtr& req,
|
void createItem(const HttpRequestPtr &req,
|
||||||
std::function<void(const HttpResponsePtr&)>&& callback,
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
const std::string& token)
|
const std::string &token)
|
||||||
{
|
{
|
||||||
auto jsonPtr = req->jsonObject();
|
auto jsonPtr = req->jsonObject();
|
||||||
if (jsonPtr == nullptr)
|
if (jsonPtr == nullptr)
|
||||||
@ -163,9 +163,9 @@ class JsonStore : public HttpController<JsonStore>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteItem(const HttpRequestPtr&,
|
void deleteItem(const HttpRequestPtr &,
|
||||||
std::function<void(const HttpResponsePtr&)>&& callback,
|
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||||
const std::string& token)
|
const std::string &token)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(storageMtx_);
|
std::lock_guard<std::mutex> lock(storageMtx_);
|
||||||
dataStore_.erase(token);
|
dataStore_.erase(token);
|
||||||
@ -174,19 +174,19 @@ class JsonStore : public HttpController<JsonStore>
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static Json::Value* walkJson(Json::Value& json,
|
static Json::Value *walkJson(Json::Value &json,
|
||||||
const std::string& path,
|
const std::string &path,
|
||||||
size_t ignore_back = 0)
|
size_t ignore_back = 0)
|
||||||
{
|
{
|
||||||
auto pathElem = utils::splitString(path, "/", false);
|
auto pathElem = utils::splitString(path, "/", false);
|
||||||
if (pathElem.size() >= ignore_back)
|
if (pathElem.size() >= ignore_back)
|
||||||
pathElem.resize(pathElem.size() - ignore_back);
|
pathElem.resize(pathElem.size() - ignore_back);
|
||||||
Json::Value* valuePtr = &json;
|
Json::Value *valuePtr = &json;
|
||||||
for (const auto& elem : pathElem)
|
for (const auto &elem : pathElem)
|
||||||
{
|
{
|
||||||
if (valuePtr->isArray())
|
if (valuePtr->isArray())
|
||||||
{
|
{
|
||||||
Json::Value& value = (*valuePtr)[std::stoi(elem)];
|
Json::Value &value = (*valuePtr)[std::stoi(elem)];
|
||||||
if (value.isNull())
|
if (value.isNull())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@ -194,7 +194,7 @@ class JsonStore : public HttpController<JsonStore>
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Json::Value& value = (*valuePtr)[elem];
|
Json::Value &value = (*valuePtr)[elem];
|
||||||
if (value.isNull())
|
if (value.isNull())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ struct ClientContext
|
|||||||
std::shared_ptr<nosql::RedisSubscriber> subscriber_;
|
std::shared_ptr<nosql::RedisSubscriber> subscriber_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void WsClient::handleNewMessage(const WebSocketConnectionPtr& wsConnPtr,
|
void WsClient::handleNewMessage(const WebSocketConnectionPtr &wsConnPtr,
|
||||||
std::string&& message,
|
std::string &&message,
|
||||||
const WebSocketMessageType& type)
|
const WebSocketMessageType &type)
|
||||||
{
|
{
|
||||||
if (type == WebSocketMessageType::Ping ||
|
if (type == WebSocketMessageType::Ping ||
|
||||||
type == WebSocketMessageType::Pong ||
|
type == WebSocketMessageType::Pong ||
|
||||||
@ -44,13 +44,13 @@ void WsClient::handleNewMessage(const WebSocketConnectionPtr& wsConnPtr,
|
|||||||
|
|
||||||
// Publisher
|
// Publisher
|
||||||
drogon::app().getRedisClient()->execCommandAsync(
|
drogon::app().getRedisClient()->execCommandAsync(
|
||||||
[wsConnPtr](const nosql::RedisResult& result) {
|
[wsConnPtr](const nosql::RedisResult &result) {
|
||||||
std::string nSubs = std::to_string(result.asInteger());
|
std::string nSubs = std::to_string(result.asInteger());
|
||||||
LOG_INFO << "PUBLISH success to " << nSubs << " subscribers.";
|
LOG_INFO << "PUBLISH success to " << nSubs << " subscribers.";
|
||||||
wsConnPtr->send("PUBLISH success to " + nSubs +
|
wsConnPtr->send("PUBLISH success to " + nSubs +
|
||||||
" subscribers.");
|
" subscribers.");
|
||||||
},
|
},
|
||||||
[wsConnPtr](const nosql::RedisException& ex) {
|
[wsConnPtr](const nosql::RedisException &ex) {
|
||||||
LOG_INFO << "PUBLISH failed, " << ex.what();
|
LOG_INFO << "PUBLISH failed, " << ex.what();
|
||||||
wsConnPtr->send(std::string("PUBLISH failed: ") + ex.what());
|
wsConnPtr->send(std::string("PUBLISH failed: ") + ex.what());
|
||||||
},
|
},
|
||||||
@ -84,8 +84,8 @@ void WsClient::handleNewMessage(const WebSocketConnectionPtr& wsConnPtr,
|
|||||||
|
|
||||||
context->subscriber_->subscribe(
|
context->subscriber_->subscribe(
|
||||||
channel,
|
channel,
|
||||||
[channel, wsConnPtr](const std::string& subChannel,
|
[channel, wsConnPtr](const std::string &subChannel,
|
||||||
const std::string& subMessage) {
|
const std::string &subMessage) {
|
||||||
assert(subChannel == channel);
|
assert(subChannel == channel);
|
||||||
LOG_INFO << "Receive channel message " << subMessage;
|
LOG_INFO << "Receive channel message " << subMessage;
|
||||||
std::string resp = "{\"channel\":\"" + subChannel +
|
std::string resp = "{\"channel\":\"" + subChannel +
|
||||||
@ -109,8 +109,8 @@ void WsClient::handleNewMessage(const WebSocketConnectionPtr& wsConnPtr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WsClient::handleNewConnection(const HttpRequestPtr& req,
|
void WsClient::handleNewConnection(const HttpRequestPtr &req,
|
||||||
const WebSocketConnectionPtr& wsConnPtr)
|
const WebSocketConnectionPtr &wsConnPtr)
|
||||||
{
|
{
|
||||||
if (req->getPath() == "/sub")
|
if (req->getPath() == "/sub")
|
||||||
{
|
{
|
||||||
@ -128,7 +128,7 @@ void WsClient::handleNewConnection(const HttpRequestPtr& req,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WsClient::handleConnectionClosed(const WebSocketConnectionPtr& wsConnPtr)
|
void WsClient::handleConnectionClosed(const WebSocketConnectionPtr &wsConnPtr)
|
||||||
{
|
{
|
||||||
LOG_DEBUG << "WsClient close connection from "
|
LOG_DEBUG << "WsClient close connection from "
|
||||||
<< wsConnPtr->peerAddr().toIpPort();
|
<< wsConnPtr->peerAddr().toIpPort();
|
||||||
|
@ -7,7 +7,7 @@ DROGON_TEST(BasicTest)
|
|||||||
// Add your tests here
|
// Add your tests here
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
using namespace drogon;
|
using namespace drogon;
|
||||||
|
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
static void redisLogin(std::function<void(int)>&& callback,
|
static void redisLogin(std::function<void(int)> &&callback,
|
||||||
const std::string& loginKey,
|
const std::string &loginKey,
|
||||||
unsigned int timeout);
|
unsigned int timeout);
|
||||||
static void redisLogout(std::function<void(int)>&& callback,
|
static void redisLogout(std::function<void(int)> &&callback,
|
||||||
const std::string& loginKey);
|
const std::string &loginKey);
|
||||||
|
|
||||||
struct ClientContext
|
struct ClientContext
|
||||||
{
|
{
|
||||||
@ -17,7 +17,7 @@ struct ClientContext
|
|||||||
std::shared_ptr<nosql::RedisSubscriber> subscriber_;
|
std::shared_ptr<nosql::RedisSubscriber> subscriber_;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool checkRoomNumber(const std::string& room)
|
static bool checkRoomNumber(const std::string &room)
|
||||||
{
|
{
|
||||||
if (room.empty() || room.size() > 2 || (room.size() == 2 && room[0] == '0'))
|
if (room.empty() || room.size() > 2 || (room.size() == 2 && room[0] == '0'))
|
||||||
{
|
{
|
||||||
@ -33,9 +33,9 @@ static bool checkRoomNumber(const std::string& room)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chat::handleNewMessage(const WebSocketConnectionPtr& wsConnPtr,
|
void Chat::handleNewMessage(const WebSocketConnectionPtr &wsConnPtr,
|
||||||
std::string&& message,
|
std::string &&message,
|
||||||
const WebSocketMessageType& type)
|
const WebSocketMessageType &type)
|
||||||
{
|
{
|
||||||
if (type == WebSocketMessageType::Close ||
|
if (type == WebSocketMessageType::Close ||
|
||||||
type == WebSocketMessageType::Ping)
|
type == WebSocketMessageType::Ping)
|
||||||
@ -63,10 +63,10 @@ void Chat::handleNewMessage(const WebSocketConnectionPtr& wsConnPtr,
|
|||||||
if (type == WebSocketMessageType::Pong)
|
if (type == WebSocketMessageType::Pong)
|
||||||
{
|
{
|
||||||
redisClient->execCommandAsync(
|
redisClient->execCommandAsync(
|
||||||
[wsConnPtr](const nosql::RedisResult&) {
|
[wsConnPtr](const nosql::RedisResult &) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
},
|
},
|
||||||
[wsConnPtr](const nosql::RedisException& ex) {
|
[wsConnPtr](const nosql::RedisException &ex) {
|
||||||
LOG_ERROR << "Update user status failed: " << ex.what();
|
LOG_ERROR << "Update user status failed: " << ex.what();
|
||||||
wsConnPtr->send("ERROR: Service unavailable.");
|
wsConnPtr->send("ERROR: Service unavailable.");
|
||||||
wsConnPtr->forceClose();
|
wsConnPtr->forceClose();
|
||||||
@ -111,8 +111,8 @@ void Chat::handleNewMessage(const WebSocketConnectionPtr& wsConnPtr,
|
|||||||
// NOTICE: Dangerous to concat username into redis command!!!
|
// NOTICE: Dangerous to concat username into redis command!!!
|
||||||
// Do not use in production.
|
// Do not use in production.
|
||||||
redisClient->execCommandAsync(
|
redisClient->execCommandAsync(
|
||||||
[](const nosql::RedisResult&) {},
|
[](const nosql::RedisResult &) {},
|
||||||
[wsConnPtr](const nosql::RedisException& ex) {
|
[wsConnPtr](const nosql::RedisException &ex) {
|
||||||
wsConnPtr->send(std::string("ERROR: ") + ex.what());
|
wsConnPtr->send(std::string("ERROR: ") + ex.what());
|
||||||
},
|
},
|
||||||
"publish %s %s",
|
"publish %s %s",
|
||||||
@ -133,7 +133,7 @@ void Chat::handleNewMessage(const WebSocketConnectionPtr& wsConnPtr,
|
|||||||
}
|
}
|
||||||
wsConnPtr->send("INFO: Enter room " + room);
|
wsConnPtr->send("INFO: Enter room " + room);
|
||||||
context->subscriber_->subscribe(
|
context->subscriber_->subscribe(
|
||||||
room, [wsConnPtr](const std::string&, const std::string& msg) {
|
room, [wsConnPtr](const std::string &, const std::string &msg) {
|
||||||
wsConnPtr->send(msg);
|
wsConnPtr->send(msg);
|
||||||
});
|
});
|
||||||
context->room_ = room;
|
context->room_ = room;
|
||||||
@ -160,8 +160,8 @@ void Chat::handleNewMessage(const WebSocketConnectionPtr& wsConnPtr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chat::handleNewConnection(const HttpRequestPtr& req,
|
void Chat::handleNewConnection(const HttpRequestPtr &req,
|
||||||
const WebSocketConnectionPtr& wsConnPtr)
|
const WebSocketConnectionPtr &wsConnPtr)
|
||||||
{
|
{
|
||||||
LOG_DEBUG << "WsClient new connection from "
|
LOG_DEBUG << "WsClient new connection from "
|
||||||
<< wsConnPtr->peerAddr().toIpPort();
|
<< wsConnPtr->peerAddr().toIpPort();
|
||||||
@ -201,7 +201,7 @@ void Chat::handleNewConnection(const HttpRequestPtr& req,
|
|||||||
120);
|
120);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chat::handleConnectionClosed(const WebSocketConnectionPtr& wsConnPtr)
|
void Chat::handleConnectionClosed(const WebSocketConnectionPtr &wsConnPtr)
|
||||||
{
|
{
|
||||||
LOG_DEBUG << "WsClient close connection from "
|
LOG_DEBUG << "WsClient close connection from "
|
||||||
<< wsConnPtr->peerAddr().toIpPort();
|
<< wsConnPtr->peerAddr().toIpPort();
|
||||||
@ -217,8 +217,8 @@ void Chat::handleConnectionClosed(const WebSocketConnectionPtr& wsConnPtr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void redisLogin(std::function<void(int)>&& callback,
|
static void redisLogin(std::function<void(int)> &&callback,
|
||||||
const std::string& loginKey,
|
const std::string &loginKey,
|
||||||
unsigned int timeout)
|
unsigned int timeout)
|
||||||
{
|
{
|
||||||
static const char script[] = R"(
|
static const char script[] = R"(
|
||||||
@ -229,10 +229,10 @@ return 1;
|
|||||||
)";
|
)";
|
||||||
|
|
||||||
drogon::app().getRedisClient()->execCommandAsync(
|
drogon::app().getRedisClient()->execCommandAsync(
|
||||||
[callback](const nosql::RedisResult& result) {
|
[callback](const nosql::RedisResult &result) {
|
||||||
callback((int)result.asInteger());
|
callback((int)result.asInteger());
|
||||||
},
|
},
|
||||||
[callback](const nosql::RedisException& ex) {
|
[callback](const nosql::RedisException &ex) {
|
||||||
LOG_ERROR << "Login error: " << ex.what();
|
LOG_ERROR << "Login error: " << ex.what();
|
||||||
callback(-1);
|
callback(-1);
|
||||||
},
|
},
|
||||||
@ -242,14 +242,14 @@ return 1;
|
|||||||
timeout);
|
timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void redisLogout(std::function<void(int)>&& callback,
|
static void redisLogout(std::function<void(int)> &&callback,
|
||||||
const std::string& loginKey)
|
const std::string &loginKey)
|
||||||
{
|
{
|
||||||
drogon::app().getRedisClient()->execCommandAsync(
|
drogon::app().getRedisClient()->execCommandAsync(
|
||||||
[callback](const nosql::RedisResult& result) {
|
[callback](const nosql::RedisResult &result) {
|
||||||
callback((int)result.asInteger());
|
callback((int)result.asInteger());
|
||||||
},
|
},
|
||||||
[callback](const nosql::RedisException& ex) {
|
[callback](const nosql::RedisException &ex) {
|
||||||
LOG_ERROR << "Logout error: " << ex.what();
|
LOG_ERROR << "Logout error: " << ex.what();
|
||||||
callback(-1);
|
callback(-1);
|
||||||
},
|
},
|
||||||
|
@ -14,7 +14,7 @@ int main(int argc, char *argv[])
|
|||||||
// Connect to a public echo server
|
// Connect to a public echo server
|
||||||
if (argc > 1 && std::string(argv[1]) == "-p")
|
if (argc > 1 && std::string(argv[1]) == "-p")
|
||||||
{
|
{
|
||||||
server = "wss://echo.websocket.org";
|
server = "wss://echo.websocket.events/.ws";
|
||||||
path = "/";
|
path = "/";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -60,8 +60,8 @@ DROGON_EXPORT extern std::atomic<size_t> numCorrectAssertions;
|
|||||||
DROGON_EXPORT extern std::atomic<size_t> numFailedTestCases;
|
DROGON_EXPORT extern std::atomic<size_t> numFailedTestCases;
|
||||||
DROGON_EXPORT extern bool printSuccessfulTests;
|
DROGON_EXPORT extern bool printSuccessfulTests;
|
||||||
|
|
||||||
DROGON_EXPORT void registerCase(Case* test);
|
DROGON_EXPORT void registerCase(Case *test);
|
||||||
DROGON_EXPORT void unregisterCase(Case* test);
|
DROGON_EXPORT void unregisterCase(Case *test);
|
||||||
|
|
||||||
template <typename _Tp, typename dummy = void>
|
template <typename _Tp, typename dummy = void>
|
||||||
struct is_printable : std::false_type
|
struct is_printable : std::false_type
|
||||||
@ -72,7 +72,7 @@ template <typename _Tp>
|
|||||||
struct is_printable<_Tp,
|
struct is_printable<_Tp,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
std::is_same<decltype(std::cout << std::declval<_Tp>()),
|
std::is_same<decltype(std::cout << std::declval<_Tp>()),
|
||||||
std::ostream&>::value>::type>
|
std::ostream &>::value>::type>
|
||||||
: std::true_type
|
: std::true_type
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
@ -110,19 +110,19 @@ DROGON_EXPORT std::string prettifyString(const std::string_view sv,
|
|||||||
|
|
||||||
#ifdef __cpp_fold_expressions
|
#ifdef __cpp_fold_expressions
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
inline void outputReason(Args&&... args)
|
inline void outputReason(Args &&...args)
|
||||||
{
|
{
|
||||||
(std::cout << ... << std::forward<Args>(args));
|
(std::cout << ... << std::forward<Args>(args));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
template <typename Head>
|
template <typename Head>
|
||||||
inline void outputReason(Head&& head)
|
inline void outputReason(Head &&head)
|
||||||
{
|
{
|
||||||
std::cout << std::forward<Head>(head);
|
std::cout << std::forward<Head>(head);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Head, typename... Tail>
|
template <typename Head, typename... Tail>
|
||||||
inline void outputReason(Head&& head, Tail&&... tail)
|
inline void outputReason(Head &&head, Tail &&...tail)
|
||||||
{
|
{
|
||||||
std::cout << std::forward<Head>(head);
|
std::cout << std::forward<Head>(head);
|
||||||
outputReason(std::forward<Tail>(tail)...);
|
outputReason(std::forward<Tail>(tail)...);
|
||||||
@ -133,7 +133,7 @@ template <bool P>
|
|||||||
struct AttemptPrintViaStream
|
struct AttemptPrintViaStream
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string operator()(const T& v)
|
std::string operator()(const T &v)
|
||||||
{
|
{
|
||||||
return "{un-printable}";
|
return "{un-printable}";
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ template <>
|
|||||||
struct AttemptPrintViaStream<true>
|
struct AttemptPrintViaStream<true>
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string operator()(const T& v)
|
std::string operator()(const T &v)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << v;
|
ss << v;
|
||||||
@ -153,14 +153,14 @@ struct AttemptPrintViaStream<true>
|
|||||||
|
|
||||||
struct StringPrinter
|
struct StringPrinter
|
||||||
{
|
{
|
||||||
std::string operator()(const std::string_view& v)
|
std::string operator()(const std::string_view &v)
|
||||||
{
|
{
|
||||||
return prettifyString(v);
|
return prettifyString(v);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline std::string attemptPrint(T&& v)
|
inline std::string attemptPrint(T &&v)
|
||||||
{
|
{
|
||||||
using DefaultPrinter =
|
using DefaultPrinter =
|
||||||
internal::AttemptPrintViaStream<is_printable<T>::value>;
|
internal::AttemptPrintViaStream<is_printable<T>::value>;
|
||||||
@ -175,31 +175,31 @@ inline std::string attemptPrint(T&& v)
|
|||||||
|
|
||||||
// Specializations to reduce template construction
|
// Specializations to reduce template construction
|
||||||
template <>
|
template <>
|
||||||
inline std::string attemptPrint(const std::nullptr_t& v)
|
inline std::string attemptPrint(const std::nullptr_t &v)
|
||||||
{
|
{
|
||||||
return "nullptr";
|
return "nullptr";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline std::string attemptPrint(const char& v)
|
inline std::string attemptPrint(const char &v)
|
||||||
{
|
{
|
||||||
return "'" + std::string(1, v) + "'";
|
return "'" + std::string(1, v) + "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string stringifyFuncCall(const std::string& funcName)
|
inline std::string stringifyFuncCall(const std::string &funcName)
|
||||||
{
|
{
|
||||||
return funcName + "()";
|
return funcName + "()";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string stringifyFuncCall(const std::string& funcName,
|
inline std::string stringifyFuncCall(const std::string &funcName,
|
||||||
const std::string& param1)
|
const std::string ¶m1)
|
||||||
{
|
{
|
||||||
return funcName + "(" + param1 + ")";
|
return funcName + "(" + param1 + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string stringifyFuncCall(const std::string& funcName,
|
inline std::string stringifyFuncCall(const std::string &funcName,
|
||||||
const std::string& param1,
|
const std::string ¶m1,
|
||||||
const std::string& param2)
|
const std::string ¶m2)
|
||||||
{
|
{
|
||||||
return funcName + "(" + param1 + ", " + param2 + ")";
|
return funcName + "(" + param1 + ", " + param2 + ")";
|
||||||
}
|
}
|
||||||
@ -225,14 +225,14 @@ struct Lhs
|
|||||||
return {(bool)ref_, attemptPrint(ref_)};
|
return {(bool)ref_, attemptPrint(ref_)};
|
||||||
}
|
}
|
||||||
|
|
||||||
Lhs(const T& lhs) : ref_(lhs)
|
Lhs(const T &lhs) : ref_(lhs)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& ref_;
|
const T &ref_;
|
||||||
|
|
||||||
template <typename RhsType>
|
template <typename RhsType>
|
||||||
ComparsionResult operator<(const RhsType& rhs)
|
ComparsionResult operator<(const RhsType &rhs)
|
||||||
{
|
{
|
||||||
return ComparsionResult{ref_ < rhs,
|
return ComparsionResult{ref_ < rhs,
|
||||||
attemptPrint(ref_) + " < " +
|
attemptPrint(ref_) + " < " +
|
||||||
@ -240,14 +240,14 @@ struct Lhs
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename RhsType>
|
template <typename RhsType>
|
||||||
ComparsionResult operator>(const RhsType& rhs)
|
ComparsionResult operator>(const RhsType &rhs)
|
||||||
{
|
{
|
||||||
return ComparsionResult{ref_ > rhs,
|
return ComparsionResult{ref_ > rhs,
|
||||||
attemptPrint(ref_) + " > " + attemptPrint(rhs)};
|
attemptPrint(ref_) + " > " + attemptPrint(rhs)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename RhsType>
|
template <typename RhsType>
|
||||||
ComparsionResult operator<=(const RhsType& rhs)
|
ComparsionResult operator<=(const RhsType &rhs)
|
||||||
{
|
{
|
||||||
return ComparsionResult{ref_ <= rhs,
|
return ComparsionResult{ref_ <= rhs,
|
||||||
attemptPrint(ref_) +
|
attemptPrint(ref_) +
|
||||||
@ -255,7 +255,7 @@ struct Lhs
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename RhsType>
|
template <typename RhsType>
|
||||||
ComparsionResult operator>=(const RhsType& rhs)
|
ComparsionResult operator>=(const RhsType &rhs)
|
||||||
{
|
{
|
||||||
return ComparsionResult{ref_ >= rhs,
|
return ComparsionResult{ref_ >= rhs,
|
||||||
attemptPrint(ref_) +
|
attemptPrint(ref_) +
|
||||||
@ -263,7 +263,7 @@ struct Lhs
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename RhsType>
|
template <typename RhsType>
|
||||||
ComparsionResult operator==(const RhsType& rhs)
|
ComparsionResult operator==(const RhsType &rhs)
|
||||||
{
|
{
|
||||||
return ComparsionResult{ref_ == rhs,
|
return ComparsionResult{ref_ == rhs,
|
||||||
attemptPrint(ref_) +
|
attemptPrint(ref_) +
|
||||||
@ -271,7 +271,7 @@ struct Lhs
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename RhsType>
|
template <typename RhsType>
|
||||||
ComparsionResult operator!=(const RhsType& rhs)
|
ComparsionResult operator!=(const RhsType &rhs)
|
||||||
{
|
{
|
||||||
return ComparsionResult{ref_ != rhs,
|
return ComparsionResult{ref_ != rhs,
|
||||||
attemptPrint(ref_) +
|
attemptPrint(ref_) +
|
||||||
@ -279,7 +279,7 @@ struct Lhs
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename RhsType>
|
template <typename RhsType>
|
||||||
ComparsionResult operator&&(const RhsType& rhs)
|
ComparsionResult operator&&(const RhsType &rhs)
|
||||||
{
|
{
|
||||||
static_assert(!std::is_same<RhsType, void>::value,
|
static_assert(!std::is_same<RhsType, void>::value,
|
||||||
" && is not supported in expression decomposition");
|
" && is not supported in expression decomposition");
|
||||||
@ -287,7 +287,7 @@ struct Lhs
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename RhsType>
|
template <typename RhsType>
|
||||||
ComparsionResult operator||(const RhsType& rhs)
|
ComparsionResult operator||(const RhsType &rhs)
|
||||||
{
|
{
|
||||||
static_assert(!std::is_same<RhsType, void>::value,
|
static_assert(!std::is_same<RhsType, void>::value,
|
||||||
" || is not supported in expression decomposition");
|
" || is not supported in expression decomposition");
|
||||||
@ -295,7 +295,7 @@ struct Lhs
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename RhsType>
|
template <typename RhsType>
|
||||||
ComparsionResult operator|(const RhsType& rhs)
|
ComparsionResult operator|(const RhsType &rhs)
|
||||||
{
|
{
|
||||||
static_assert(!std::is_same<RhsType, void>::value,
|
static_assert(!std::is_same<RhsType, void>::value,
|
||||||
" | is not supported in expression decomposition");
|
" | is not supported in expression decomposition");
|
||||||
@ -303,7 +303,7 @@ struct Lhs
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename RhsType>
|
template <typename RhsType>
|
||||||
ComparsionResult operator&(const RhsType& rhs)
|
ComparsionResult operator&(const RhsType &rhs)
|
||||||
{
|
{
|
||||||
static_assert(!std::is_same<RhsType, void>::value,
|
static_assert(!std::is_same<RhsType, void>::value,
|
||||||
" & is not supported in expression decomposition");
|
" & is not supported in expression decomposition");
|
||||||
@ -314,7 +314,7 @@ struct Lhs
|
|||||||
struct Decomposer
|
struct Decomposer
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Lhs<T> operator<=(const T& other)
|
Lhs<T> operator<=(const T &other)
|
||||||
{
|
{
|
||||||
return Lhs<T>(other);
|
return Lhs<T>(other);
|
||||||
}
|
}
|
||||||
@ -325,7 +325,7 @@ struct Decomposer
|
|||||||
class DROGON_EXPORT ThreadSafeStream final
|
class DROGON_EXPORT ThreadSafeStream final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ThreadSafeStream(std::ostream& os) : os_(os)
|
ThreadSafeStream(std::ostream &os) : os_(os)
|
||||||
{
|
{
|
||||||
mtx_.lock();
|
mtx_.lock();
|
||||||
}
|
}
|
||||||
@ -336,13 +336,13 @@ class DROGON_EXPORT ThreadSafeStream final
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::ostream& operator<<(const T& rhs)
|
std::ostream &operator<<(const T &rhs)
|
||||||
{
|
{
|
||||||
return os_ << rhs;
|
return os_ << rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::mutex mtx_;
|
static std::mutex mtx_;
|
||||||
std::ostream& os_;
|
std::ostream &os_;
|
||||||
};
|
};
|
||||||
|
|
||||||
DROGON_EXPORT ThreadSafeStream print();
|
DROGON_EXPORT ThreadSafeStream print();
|
||||||
@ -353,11 +353,11 @@ class CaseBase : public trantor::NonCopyable
|
|||||||
public:
|
public:
|
||||||
CaseBase() = default;
|
CaseBase() = default;
|
||||||
|
|
||||||
CaseBase(const std::string& name) : name_(name)
|
CaseBase(const std::string &name) : name_(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CaseBase(std::shared_ptr<CaseBase> parent, const std::string& name)
|
CaseBase(std::shared_ptr<CaseBase> parent, const std::string &name)
|
||||||
: parent_(parent), name_(name)
|
: parent_(parent), name_(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -378,7 +378,7 @@ class CaseBase : public trantor::NonCopyable
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& name() const
|
const std::string &name() const
|
||||||
{
|
{
|
||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
@ -406,12 +406,12 @@ class CaseBase : public trantor::NonCopyable
|
|||||||
class Case : public CaseBase
|
class Case : public CaseBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Case(const std::string& name) : CaseBase(name)
|
Case(const std::string &name) : CaseBase(name)
|
||||||
{
|
{
|
||||||
internal::registerCase(this);
|
internal::registerCase(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Case(std::shared_ptr<Case> parent, const std::string& name)
|
Case(std::shared_ptr<Case> parent, const std::string &name)
|
||||||
: CaseBase(parent, name)
|
: CaseBase(parent, name)
|
||||||
{
|
{
|
||||||
internal::registerCase(this);
|
internal::registerCase(this);
|
||||||
@ -425,7 +425,7 @@ class Case : public CaseBase
|
|||||||
|
|
||||||
struct TestCase : public CaseBase
|
struct TestCase : public CaseBase
|
||||||
{
|
{
|
||||||
TestCase(const std::string& name) : CaseBase(name)
|
TestCase(const std::string &name) : CaseBase(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,7 +434,7 @@ struct TestCase : public CaseBase
|
|||||||
};
|
};
|
||||||
|
|
||||||
DROGON_EXPORT void printTestStats();
|
DROGON_EXPORT void printTestStats();
|
||||||
DROGON_EXPORT int run(int argc, char** argv);
|
DROGON_EXPORT int run(int argc, char **argv);
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace drogon
|
} // namespace drogon
|
||||||
|
|
||||||
@ -478,7 +478,7 @@ DROGON_EXPORT int run(int argc, char** argv);
|
|||||||
{ \
|
{ \
|
||||||
eval; \
|
eval; \
|
||||||
} \
|
} \
|
||||||
catch (const std::exception& e) \
|
catch (const std::exception &e) \
|
||||||
{ \
|
{ \
|
||||||
(void)e; \
|
(void)e; \
|
||||||
on_exception; \
|
on_exception; \
|
||||||
@ -649,7 +649,7 @@ DROGON_EXPORT int run(int argc, char** argv);
|
|||||||
EVAL__(expr), \
|
EVAL__(expr), \
|
||||||
{ \
|
{ \
|
||||||
exceptionThrown = true; \
|
exceptionThrown = true; \
|
||||||
if (dynamic_cast<const except_type*>(&e) != nullptr) \
|
if (dynamic_cast<const except_type *>(&e) != nullptr) \
|
||||||
SET_TEST_SUCCESS__; \
|
SET_TEST_SUCCESS__; \
|
||||||
}, \
|
}, \
|
||||||
{ exceptionThrown = true; }, \
|
{ exceptionThrown = true; }, \
|
||||||
|
@ -53,8 +53,8 @@ class OStringStream
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::enable_if_t<!internal::CanConvertToString<T>::value, OStringStream&>
|
std::enable_if_t<!internal::CanConvertToString<T>::value, OStringStream &>
|
||||||
operator<<(T&& value)
|
operator<<(T &&value)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << std::forward<T>(value);
|
ss << std::forward<T>(value);
|
||||||
@ -63,45 +63,45 @@ class OStringStream
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::enable_if_t<internal::CanConvertToString<T>::value, OStringStream&>
|
std::enable_if_t<internal::CanConvertToString<T>::value, OStringStream &>
|
||||||
operator<<(T&& value)
|
operator<<(T &&value)
|
||||||
{
|
{
|
||||||
buffer_.append(std::to_string(std::forward<T>(value)));
|
buffer_.append(std::to_string(std::forward<T>(value)));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
OStringStream& operator<<(const char (&buf)[N])
|
OStringStream &operator<<(const char (&buf)[N])
|
||||||
{
|
{
|
||||||
buffer_.append(buf, N - 1);
|
buffer_.append(buf, N - 1);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
OStringStream& operator<<(const std::string_view& str)
|
OStringStream &operator<<(const std::string_view &str)
|
||||||
{
|
{
|
||||||
buffer_.append(str.data(), str.length());
|
buffer_.append(str.data(), str.length());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
OStringStream& operator<<(std::string_view&& str)
|
OStringStream &operator<<(std::string_view &&str)
|
||||||
{
|
{
|
||||||
buffer_.append(str.data(), str.length());
|
buffer_.append(str.data(), str.length());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
OStringStream& operator<<(const std::string& str)
|
OStringStream &operator<<(const std::string &str)
|
||||||
{
|
{
|
||||||
buffer_.append(str);
|
buffer_.append(str);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
OStringStream& operator<<(std::string&& str)
|
OStringStream &operator<<(std::string &&str)
|
||||||
{
|
{
|
||||||
buffer_.append(std::move(str));
|
buffer_.append(std::move(str));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
OStringStream& operator<<(const double& d)
|
OStringStream &operator<<(const double &d)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << d;
|
ss << d;
|
||||||
@ -109,7 +109,7 @@ class OStringStream
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
OStringStream& operator<<(const float& f)
|
OStringStream &operator<<(const float &f)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << f;
|
ss << f;
|
||||||
@ -117,7 +117,7 @@ class OStringStream
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
OStringStream& operator<<(double&& d)
|
OStringStream &operator<<(double &&d)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << d;
|
ss << d;
|
||||||
@ -125,7 +125,7 @@ class OStringStream
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
OStringStream& operator<<(float&& f)
|
OStringStream &operator<<(float &&f)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << f;
|
ss << f;
|
||||||
@ -133,12 +133,12 @@ class OStringStream
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string& str()
|
std::string &str()
|
||||||
{
|
{
|
||||||
return buffer_;
|
return buffer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& str() const
|
const std::string &str() const
|
||||||
{
|
{
|
||||||
return buffer_;
|
return buffer_;
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,9 @@ namespace drogon
|
|||||||
{
|
{
|
||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
void handleException(const std::exception& e,
|
void handleException(const std::exception &e,
|
||||||
const HttpRequestPtr& req,
|
const HttpRequestPtr &req,
|
||||||
std::function<void(const HttpResponsePtr&)>&& callback)
|
std::function<void(const HttpResponsePtr &)> &&callback)
|
||||||
{
|
{
|
||||||
app().getExceptionHandler()(e, req, std::move(callback));
|
app().getExceptionHandler()(e, req, std::move(callback));
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ struct XForwardedForParser : public trantor::NonCopyable
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
// Skip trailing separators
|
// Skip trailing separators
|
||||||
const char* cur;
|
const char *cur;
|
||||||
for (cur = start_ + len_ - 1; cur > start_; --cur, --len_)
|
for (cur = start_ + len_ - 1; cur > start_; --cur, --len_)
|
||||||
{
|
{
|
||||||
if (*cur != ' ' && *cur != ',')
|
if (*cur != ' ' && *cur != ',')
|
||||||
@ -56,11 +56,11 @@ struct XForwardedForParser : public trantor::NonCopyable
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string value_;
|
std::string value_;
|
||||||
const char* start_;
|
const char *start_;
|
||||||
size_t len_;
|
size_t len_;
|
||||||
};
|
};
|
||||||
|
|
||||||
static trantor::InetAddress parseAddress(const std::string& addr)
|
static trantor::InetAddress parseAddress(const std::string &addr)
|
||||||
{
|
{
|
||||||
auto pos = addr.find(':');
|
auto pos = addr.find(':');
|
||||||
uint16_t port = 0;
|
uint16_t port = 0;
|
||||||
@ -72,7 +72,7 @@ static trantor::InetAddress parseAddress(const std::string& addr)
|
|||||||
{
|
{
|
||||||
port = std::stoi(addr.substr(pos + 1));
|
port = std::stoi(addr.substr(pos + 1));
|
||||||
}
|
}
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception &ex)
|
||||||
{
|
{
|
||||||
(void)ex;
|
(void)ex;
|
||||||
LOG_ERROR << "Error in ipv4 address: " + addr;
|
LOG_ERROR << "Error in ipv4 address: " + addr;
|
||||||
@ -81,7 +81,7 @@ static trantor::InetAddress parseAddress(const std::string& addr)
|
|||||||
return trantor::InetAddress(addr.substr(0, pos), port);
|
return trantor::InetAddress(addr.substr(0, pos), port);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RealIpResolver::initAndStart(const Json::Value& config)
|
void RealIpResolver::initAndStart(const Json::Value &config)
|
||||||
{
|
{
|
||||||
fromHeader_ = config.get("from_header", "x-forwarded-for").asString();
|
fromHeader_ = config.get("from_header", "x-forwarded-for").asString();
|
||||||
attributeKey_ = config.get("attribute_key", "real-ip").asString();
|
attributeKey_ = config.get("attribute_key", "real-ip").asString();
|
||||||
@ -95,20 +95,20 @@ void RealIpResolver::initAndStart(const Json::Value& config)
|
|||||||
useXForwardedFor_ = true;
|
useXForwardedFor_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Json::Value& trustIps = config["trust_ips"];
|
const Json::Value &trustIps = config["trust_ips"];
|
||||||
if (!trustIps.isArray())
|
if (!trustIps.isArray())
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Invalid trusted_ips. Should be array.");
|
throw std::runtime_error("Invalid trusted_ips. Should be array.");
|
||||||
}
|
}
|
||||||
for (const auto& elem : trustIps)
|
for (const auto &elem : trustIps)
|
||||||
{
|
{
|
||||||
std::string ipOrCidr = elem.asString();
|
std::string ipOrCidr = elem.asString();
|
||||||
trustCIDRs_.emplace_back(ipOrCidr);
|
trustCIDRs_.emplace_back(ipOrCidr);
|
||||||
}
|
}
|
||||||
|
|
||||||
drogon::app().registerPreHandlingAdvice([this](const HttpRequestPtr& req) {
|
drogon::app().registerPreHandlingAdvice([this](const HttpRequestPtr &req) {
|
||||||
const std::string& ipHeader = req->getHeader(fromHeader_);
|
const std::string &ipHeader = req->getHeader(fromHeader_);
|
||||||
const trantor::InetAddress& peerAddr = req->getPeerAddr();
|
const trantor::InetAddress &peerAddr = req->getPeerAddr();
|
||||||
if (ipHeader.empty() || !matchCidr(peerAddr))
|
if (ipHeader.empty() || !matchCidr(peerAddr))
|
||||||
{
|
{
|
||||||
// Target header is empty, or
|
// Target header is empty, or
|
||||||
@ -153,10 +153,10 @@ void RealIpResolver::shutdown()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const trantor::InetAddress& RealIpResolver::GetRealAddr(
|
const trantor::InetAddress &RealIpResolver::GetRealAddr(
|
||||||
const HttpRequestPtr& req)
|
const HttpRequestPtr &req)
|
||||||
{
|
{
|
||||||
auto* plugin = app().getPlugin<drogon::plugin::RealIpResolver>();
|
auto *plugin = app().getPlugin<drogon::plugin::RealIpResolver>();
|
||||||
if (!plugin)
|
if (!plugin)
|
||||||
{
|
{
|
||||||
return req->getPeerAddr();
|
return req->getPeerAddr();
|
||||||
@ -164,10 +164,10 @@ const trantor::InetAddress& RealIpResolver::GetRealAddr(
|
|||||||
return plugin->getRealAddr(req);
|
return plugin->getRealAddr(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
const trantor::InetAddress& RealIpResolver::getRealAddr(
|
const trantor::InetAddress &RealIpResolver::getRealAddr(
|
||||||
const HttpRequestPtr& req) const
|
const HttpRequestPtr &req) const
|
||||||
{
|
{
|
||||||
const std::shared_ptr<Attributes>& attributesPtr = req->getAttributes();
|
const std::shared_ptr<Attributes> &attributesPtr = req->getAttributes();
|
||||||
if (!attributesPtr->find(attributeKey_))
|
if (!attributesPtr->find(attributeKey_))
|
||||||
{
|
{
|
||||||
return req->getPeerAddr();
|
return req->getPeerAddr();
|
||||||
@ -175,9 +175,9 @@ const trantor::InetAddress& RealIpResolver::getRealAddr(
|
|||||||
return attributesPtr->get<trantor::InetAddress>(attributeKey_);
|
return attributesPtr->get<trantor::InetAddress>(attributeKey_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealIpResolver::matchCidr(const trantor::InetAddress& addr) const
|
bool RealIpResolver::matchCidr(const trantor::InetAddress &addr) const
|
||||||
{
|
{
|
||||||
for (auto& cidr : trustCIDRs_)
|
for (auto &cidr : trustCIDRs_)
|
||||||
{
|
{
|
||||||
if ((addr.ipNetEndian() & cidr.mask_) == cidr.addr_)
|
if ((addr.ipNetEndian() & cidr.mask_) == cidr.addr_)
|
||||||
{
|
{
|
||||||
@ -187,7 +187,7 @@ bool RealIpResolver::matchCidr(const trantor::InetAddress& addr) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RealIpResolver::CIDR::CIDR(const std::string& ipOrCidr)
|
RealIpResolver::CIDR::CIDR(const std::string &ipOrCidr)
|
||||||
{
|
{
|
||||||
// Find CIDR slash
|
// Find CIDR slash
|
||||||
auto pos = ipOrCidr.find('/');
|
auto pos = ipOrCidr.find('/');
|
||||||
|
@ -19,11 +19,11 @@ namespace drogon
|
|||||||
namespace nosql
|
namespace nosql
|
||||||
{
|
{
|
||||||
std::shared_ptr<RedisClient> RedisClient::newRedisClient(
|
std::shared_ptr<RedisClient> RedisClient::newRedisClient(
|
||||||
const trantor::InetAddress& /*serverAddress*/,
|
const trantor::InetAddress & /*serverAddress*/,
|
||||||
size_t /*numberOfConnections*/,
|
size_t /*numberOfConnections*/,
|
||||||
const std::string& /*password*/,
|
const std::string & /*password*/,
|
||||||
const unsigned int /*db*/,
|
const unsigned int /*db*/,
|
||||||
const std::string& /*username*/)
|
const std::string & /*username*/)
|
||||||
{
|
{
|
||||||
LOG_FATAL << "Redis is not supported by drogon, please install the "
|
LOG_FATAL << "Redis is not supported by drogon, please install the "
|
||||||
"hiredis library first.";
|
"hiredis library first.";
|
||||||
|
@ -18,10 +18,10 @@
|
|||||||
using namespace drogon;
|
using namespace drogon;
|
||||||
|
|
||||||
SessionManager::SessionManager(
|
SessionManager::SessionManager(
|
||||||
trantor::EventLoop* loop,
|
trantor::EventLoop *loop,
|
||||||
size_t timeout,
|
size_t timeout,
|
||||||
const std::vector<AdviceStartSessionCallback>& startAdvices,
|
const std::vector<AdviceStartSessionCallback> &startAdvices,
|
||||||
const std::vector<AdviceDestroySessionCallback>& destroyAdvices)
|
const std::vector<AdviceDestroySessionCallback> &destroyAdvices)
|
||||||
: loop_(loop),
|
: loop_(loop),
|
||||||
timeout_(timeout),
|
timeout_(timeout),
|
||||||
sessionStartAdvices_(startAdvices),
|
sessionStartAdvices_(startAdvices),
|
||||||
@ -52,14 +52,14 @@ SessionManager::SessionManager(
|
|||||||
1.0,
|
1.0,
|
||||||
wheelNum,
|
wheelNum,
|
||||||
bucketNum,
|
bucketNum,
|
||||||
[this](const std::string& key) {
|
[this](const std::string &key) {
|
||||||
for (auto& advice : sessionStartAdvices_)
|
for (auto &advice : sessionStartAdvices_)
|
||||||
{
|
{
|
||||||
advice(key);
|
advice(key);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[this](const std::string& key) {
|
[this](const std::string &key) {
|
||||||
for (auto& advice : sessionDestroyAdvices_)
|
for (auto &advice : sessionDestroyAdvices_)
|
||||||
{
|
{
|
||||||
advice(key);
|
advice(key);
|
||||||
}
|
}
|
||||||
@ -73,14 +73,14 @@ SessionManager::SessionManager(
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
[this](const std::string& key) {
|
[this](const std::string &key) {
|
||||||
for (auto& advice : sessionStartAdvices_)
|
for (auto &advice : sessionStartAdvices_)
|
||||||
{
|
{
|
||||||
advice(key);
|
advice(key);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[this](const std::string& key) {
|
[this](const std::string &key) {
|
||||||
for (auto& advice : sessionDestroyAdvices_)
|
for (auto &advice : sessionDestroyAdvices_)
|
||||||
{
|
{
|
||||||
advice(key);
|
advice(key);
|
||||||
}
|
}
|
||||||
@ -88,14 +88,14 @@ SessionManager::SessionManager(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SessionPtr SessionManager::getSession(const std::string& sessionID,
|
SessionPtr SessionManager::getSession(const std::string &sessionID,
|
||||||
bool needToSet)
|
bool needToSet)
|
||||||
{
|
{
|
||||||
assert(!sessionID.empty());
|
assert(!sessionID.empty());
|
||||||
SessionPtr sessionPtr;
|
SessionPtr sessionPtr;
|
||||||
sessionMapPtr_->modify(
|
sessionMapPtr_->modify(
|
||||||
sessionID,
|
sessionID,
|
||||||
[&sessionPtr, &sessionID, needToSet](SessionPtr& sessionInCache) {
|
[&sessionPtr, &sessionID, needToSet](SessionPtr &sessionInCache) {
|
||||||
if (sessionInCache)
|
if (sessionInCache)
|
||||||
{
|
{
|
||||||
sessionPtr = sessionInCache;
|
sessionPtr = sessionInCache;
|
||||||
@ -112,7 +112,7 @@ SessionPtr SessionManager::getSession(const std::string& sessionID,
|
|||||||
return sessionPtr;
|
return sessionPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionManager::changeSessionId(const SessionPtr& sessionPtr)
|
void SessionManager::changeSessionId(const SessionPtr &sessionPtr)
|
||||||
{
|
{
|
||||||
auto oldId = sessionPtr->sessionId();
|
auto oldId = sessionPtr->sessionId();
|
||||||
auto newId = utils::getUuid();
|
auto newId = utils::getUuid();
|
||||||
|
@ -37,7 +37,7 @@ static inline size_t findTrailingSlashes(string_view url)
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void removeTrailingSlashes(string& url,
|
static inline void removeTrailingSlashes(string &url,
|
||||||
size_t start,
|
size_t start,
|
||||||
string_view originalUrl)
|
string_view originalUrl)
|
||||||
{
|
{
|
||||||
@ -67,7 +67,7 @@ static inline size_t findDuplicateSlashes(string_view url)
|
|||||||
return string::npos;
|
return string::npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void removeDuplicateSlashes(string& url, size_t start)
|
static inline void removeDuplicateSlashes(string &url, size_t start)
|
||||||
{
|
{
|
||||||
// +1 because we don't need to look at the same character again,
|
// +1 because we don't need to look at the same character again,
|
||||||
// which was found by `findDuplicateSlashes`, it saves one iteration
|
// which was found by `findDuplicateSlashes`, it saves one iteration
|
||||||
@ -137,7 +137,7 @@ static inline std::pair<size_t, size_t> findExcessiveSlashes(string_view url)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void removeExcessiveSlashes(string& url,
|
static inline void removeExcessiveSlashes(string &url,
|
||||||
std::pair<size_t, size_t> start,
|
std::pair<size_t, size_t> start,
|
||||||
string_view originalUrl)
|
string_view originalUrl)
|
||||||
{
|
{
|
||||||
@ -150,7 +150,7 @@ static inline void removeExcessiveSlashes(string& url,
|
|||||||
removeDuplicateSlashes(url, start.second);
|
removeDuplicateSlashes(url, start.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool handleReq(const drogon::HttpRequestPtr& req,
|
static inline bool handleReq(const drogon::HttpRequestPtr &req,
|
||||||
uint8_t removeMode)
|
uint8_t removeMode)
|
||||||
{
|
{
|
||||||
switch (removeMode)
|
switch (removeMode)
|
||||||
@ -193,7 +193,7 @@ static inline bool handleReq(const drogon::HttpRequestPtr& req,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlashRemover::initAndStart(const Json::Value& config)
|
void SlashRemover::initAndStart(const Json::Value &config)
|
||||||
{
|
{
|
||||||
trailingSlashes_ = config.get("remove_trailing_slashes", true).asBool();
|
trailingSlashes_ = config.get("remove_trailing_slashes", true).asBool();
|
||||||
duplicateSlashes_ = config.get("remove_duplicate_slashes", true).asBool();
|
duplicateSlashes_ = config.get("remove_duplicate_slashes", true).asBool();
|
||||||
@ -208,7 +208,7 @@ void SlashRemover::initAndStart(const Json::Value& config)
|
|||||||
LOG_ERROR << "Redirector plugin is not found!";
|
LOG_ERROR << "Redirector plugin is not found!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto func = [removeMode](const HttpRequestPtr& req) -> bool {
|
auto func = [removeMode](const HttpRequestPtr &req) -> bool {
|
||||||
return handleReq(req, removeMode);
|
return handleReq(req, removeMode);
|
||||||
};
|
};
|
||||||
if (redirect_)
|
if (redirect_)
|
||||||
|
@ -15,7 +15,7 @@ namespace internal
|
|||||||
std::mutex mtxRegister;
|
std::mutex mtxRegister;
|
||||||
std::mutex mtxTestStats;
|
std::mutex mtxTestStats;
|
||||||
bool testHasPrinted = false;
|
bool testHasPrinted = false;
|
||||||
std::set<Case*> registeredTests;
|
std::set<Case *> registeredTests;
|
||||||
std::promise<void> allTestRan;
|
std::promise<void> allTestRan;
|
||||||
std::atomic<size_t> numAssertions;
|
std::atomic<size_t> numAssertions;
|
||||||
std::atomic<size_t> numCorrectAssertions;
|
std::atomic<size_t> numCorrectAssertions;
|
||||||
@ -23,13 +23,13 @@ size_t numTestCases;
|
|||||||
std::atomic<size_t> numFailedTestCases;
|
std::atomic<size_t> numFailedTestCases;
|
||||||
bool printSuccessfulTests;
|
bool printSuccessfulTests;
|
||||||
|
|
||||||
void registerCase(Case* test)
|
void registerCase(Case *test)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(mtxRegister);
|
std::unique_lock<std::mutex> l(mtxRegister);
|
||||||
registeredTests.insert(test);
|
registeredTests.insert(test);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unregisterCase(Case* test)
|
void unregisterCase(Case *test)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(mtxRegister);
|
std::unique_lock<std::mutex> l(mtxRegister);
|
||||||
registeredTests.erase(test);
|
registeredTests.erase(test);
|
||||||
@ -38,7 +38,7 @@ void unregisterCase(Case* test)
|
|||||||
allTestRan.set_value();
|
allTestRan.set_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string leftpad(const std::string& str, size_t len)
|
static std::string leftpad(const std::string &str, size_t len)
|
||||||
{
|
{
|
||||||
if (len <= str.size())
|
if (len <= str.size())
|
||||||
return str;
|
return str;
|
||||||
@ -136,7 +136,7 @@ void printTestStats()
|
|||||||
internal::testHasPrinted = true;
|
internal::testHasPrinted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int run(int argc, char** argv)
|
int run(int argc, char **argv)
|
||||||
{
|
{
|
||||||
internal::numCorrectAssertions = 0;
|
internal::numCorrectAssertions = 0;
|
||||||
internal::numAssertions = 0;
|
internal::numAssertions = 0;
|
||||||
@ -190,13 +190,13 @@ int run(int argc, char** argv)
|
|||||||
if (listTests)
|
if (listTests)
|
||||||
{
|
{
|
||||||
print() << "Avaliable Tests:\n";
|
print() << "Avaliable Tests:\n";
|
||||||
for (const auto& name : classNames)
|
for (const auto &name : classNames)
|
||||||
{
|
{
|
||||||
if (name.find(DROGON_TESTCASE_PREIX_STR_) == 0)
|
if (name.find(DROGON_TESTCASE_PREIX_STR_) == 0)
|
||||||
{
|
{
|
||||||
auto test =
|
auto test =
|
||||||
std::unique_ptr<DrObjectBase>(DrClassMap::newObject(name));
|
std::unique_ptr<DrObjectBase>(DrClassMap::newObject(name));
|
||||||
auto ptr = dynamic_cast<TestCase*>(test.get());
|
auto ptr = dynamic_cast<TestCase *>(test.get());
|
||||||
if (ptr == nullptr)
|
if (ptr == nullptr)
|
||||||
continue;
|
continue;
|
||||||
print() << " " << ptr->name() << "\n";
|
print() << " " << ptr->name() << "\n";
|
||||||
@ -209,7 +209,7 @@ int run(int argc, char** argv)
|
|||||||
// NOTE: Registering a dummy case prevents the test-end signal to be
|
// NOTE: Registering a dummy case prevents the test-end signal to be
|
||||||
// emited too early as there's always an case that hasn't finish
|
// emited too early as there's always an case that hasn't finish
|
||||||
std::shared_ptr<Case> dummyCase = std::make_shared<Case>("__dummy_dummy_");
|
std::shared_ptr<Case> dummyCase = std::make_shared<Case>("__dummy_dummy_");
|
||||||
for (const auto& name : classNames)
|
for (const auto &name : classNames)
|
||||||
{
|
{
|
||||||
if (name.find(DROGON_TESTCASE_PREIX_STR_) == 0)
|
if (name.find(DROGON_TESTCASE_PREIX_STR_) == 0)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,7 @@ DROGON_TEST(CacheMapTest)
|
|||||||
cache.erase("30");
|
cache.erase("30");
|
||||||
CHECK(cache.find("30") == false);
|
CHECK(cache.find("30") == false);
|
||||||
|
|
||||||
cache.modify("bla", [](std::string& s) { s = "asd"; });
|
cache.modify("bla", [](std::string &s) { s = "asd"; });
|
||||||
CHECK(cache["bla"] == "asd");
|
CHECK(cache["bla"] == "asd");
|
||||||
|
|
||||||
std::string content;
|
std::string content;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
struct SameContent
|
struct SameContent
|
||||||
{
|
{
|
||||||
SameContent(const std::vector<std::string>& container)
|
SameContent(const std::vector<std::string> &container)
|
||||||
: container_(container.begin(), container.end())
|
: container_(container.begin(), container.end())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -13,9 +13,9 @@ struct SameContent
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename Container1>
|
template <typename Container1>
|
||||||
inline bool operator==(const Container1& a, const SameContent& wrapper)
|
inline bool operator==(const Container1 &a, const SameContent &wrapper)
|
||||||
{
|
{
|
||||||
const auto& b = wrapper.container_;
|
const auto &b = wrapper.container_;
|
||||||
if (a.size() != b.size())
|
if (a.size() != b.size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ DROGON_TEST(TestFrameworkSelfTest)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
std::promise<void> p1;
|
std::promise<void> p1;
|
||||||
std::future<void> f1 = p1.get_future();
|
std::future<void> f1 = p1.get_future();
|
||||||
|
@ -25,8 +25,8 @@ class SubscribeContext
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::shared_ptr<SubscribeContext> newContext(
|
static std::shared_ptr<SubscribeContext> newContext(
|
||||||
std::weak_ptr<RedisSubscriber>&& weakSub,
|
std::weak_ptr<RedisSubscriber> &&weakSub,
|
||||||
const std::string& channel,
|
const std::string &channel,
|
||||||
bool isPattern = false)
|
bool isPattern = false)
|
||||||
{
|
{
|
||||||
return std::shared_ptr<SubscribeContext>(
|
return std::shared_ptr<SubscribeContext>(
|
||||||
@ -38,22 +38,22 @@ class SubscribeContext
|
|||||||
return contextId_;
|
return contextId_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& channel() const
|
const std::string &channel() const
|
||||||
{
|
{
|
||||||
return channel_;
|
return channel_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& subscribeCommand() const
|
const std::string &subscribeCommand() const
|
||||||
{
|
{
|
||||||
return subscribeCommand_;
|
return subscribeCommand_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& unsubscribeCommand() const
|
const std::string &unsubscribeCommand() const
|
||||||
{
|
{
|
||||||
return unsubscribeCommand_;
|
return unsubscribeCommand_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMessageCallback(RedisMessageCallback&& messageCallback)
|
void addMessageCallback(RedisMessageCallback &&messageCallback)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
messageCallbacks_.emplace_back(std::move(messageCallback));
|
messageCallbacks_.emplace_back(std::move(messageCallback));
|
||||||
@ -78,17 +78,17 @@ class SubscribeContext
|
|||||||
* @param channel : target channel name
|
* @param channel : target channel name
|
||||||
* @param message : message from channel
|
* @param message : message from channel
|
||||||
*/
|
*/
|
||||||
void onMessage(const std::string& channel, const std::string& message);
|
void onMessage(const std::string &channel, const std::string &message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback called by RedisConnection, whenever a sub or re-sub is success
|
* Callback called by RedisConnection, whenever a sub or re-sub is success
|
||||||
*/
|
*/
|
||||||
void onSubscribe(const std::string& channel, long long numChannels);
|
void onSubscribe(const std::string &channel, long long numChannels);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback called by RedisConnection, when unsubscription success.
|
* Callback called by RedisConnection, when unsubscription success.
|
||||||
*/
|
*/
|
||||||
void onUnsubscribe(const std::string& channel, long long numChannels);
|
void onUnsubscribe(const std::string &channel, long long numChannels);
|
||||||
|
|
||||||
bool alive() const
|
bool alive() const
|
||||||
{
|
{
|
||||||
@ -96,8 +96,8 @@ class SubscribeContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SubscribeContext(std::weak_ptr<RedisSubscriber>&& weakSub,
|
SubscribeContext(std::weak_ptr<RedisSubscriber> &&weakSub,
|
||||||
const std::string& channel,
|
const std::string &channel,
|
||||||
bool isPattern);
|
bool isPattern);
|
||||||
static std::atomic<unsigned long long> maxContextId_;
|
static std::atomic<unsigned long long> maxContextId_;
|
||||||
|
|
||||||
|
@ -93,9 +93,9 @@ class BaseBuilder
|
|||||||
// map.
|
// map.
|
||||||
std::vector<std::pair<std::string, bool>> orders_;
|
std::vector<std::pair<std::string, bool>> orders_;
|
||||||
|
|
||||||
inline void assert_column(const std::string& colName) const
|
inline void assert_column(const std::string &colName) const
|
||||||
{
|
{
|
||||||
for (const typename T::MetaData& m : T::metaData_)
|
for (const typename T::MetaData &m : T::metaData_)
|
||||||
{
|
{
|
||||||
if (m.colName_ == colName)
|
if (m.colName_ == colName)
|
||||||
{
|
{
|
||||||
@ -158,7 +158,7 @@ class BaseBuilder
|
|||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
if (!filters_.empty())
|
if (!filters_.empty())
|
||||||
{
|
{
|
||||||
for (const Filter& f : filters_)
|
for (const Filter &f : filters_)
|
||||||
{
|
{
|
||||||
args.emplace_back(f.value);
|
args.emplace_back(f.value);
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@ class BaseBuilder
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
#ifdef __cpp_if_constexpr
|
#ifdef __cpp_if_constexpr
|
||||||
static ResultType convert_result(const Result& r)
|
static ResultType convert_result(const Result &r)
|
||||||
{
|
{
|
||||||
if constexpr (SelectAll)
|
if constexpr (SelectAll)
|
||||||
{
|
{
|
||||||
@ -179,7 +179,7 @@ class BaseBuilder
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::vector<T> ret;
|
std::vector<T> ret;
|
||||||
for (const Row& row : r)
|
for (const Row &row : r)
|
||||||
{
|
{
|
||||||
ret.emplace_back(T(row));
|
ret.emplace_back(T(row));
|
||||||
}
|
}
|
||||||
@ -203,7 +203,7 @@ class BaseBuilder
|
|||||||
bool SI = Single,
|
bool SI = Single,
|
||||||
std::enable_if_t<SA, std::nullptr_t> = nullptr,
|
std::enable_if_t<SA, std::nullptr_t> = nullptr,
|
||||||
std::enable_if_t<SI, std::nullptr_t> = nullptr>
|
std::enable_if_t<SI, std::nullptr_t> = nullptr>
|
||||||
static inline T convert_result(const Result& r)
|
static inline T convert_result(const Result &r)
|
||||||
{
|
{
|
||||||
return T(r[0]);
|
return T(r[0]);
|
||||||
}
|
}
|
||||||
@ -212,10 +212,10 @@ class BaseBuilder
|
|||||||
bool SI = Single,
|
bool SI = Single,
|
||||||
std::enable_if_t<SA, std::nullptr_t> = nullptr,
|
std::enable_if_t<SA, std::nullptr_t> = nullptr,
|
||||||
std::enable_if_t<!SI, std::nullptr_t> = nullptr>
|
std::enable_if_t<!SI, std::nullptr_t> = nullptr>
|
||||||
static inline std::vector<T> convert_result(const Result& r)
|
static inline std::vector<T> convert_result(const Result &r)
|
||||||
{
|
{
|
||||||
std::vector<T> ret;
|
std::vector<T> ret;
|
||||||
for (const Row& row : r)
|
for (const Row &row : r)
|
||||||
{
|
{
|
||||||
ret.template emplace_back(T(row));
|
ret.template emplace_back(T(row));
|
||||||
}
|
}
|
||||||
@ -226,7 +226,7 @@ class BaseBuilder
|
|||||||
bool SI = Single,
|
bool SI = Single,
|
||||||
std::enable_if_t<!SA, std::nullptr_t> = nullptr,
|
std::enable_if_t<!SA, std::nullptr_t> = nullptr,
|
||||||
std::enable_if_t<SI, std::nullptr_t> = nullptr>
|
std::enable_if_t<SI, std::nullptr_t> = nullptr>
|
||||||
static inline Row convert_result(const Result& r)
|
static inline Row convert_result(const Result &r)
|
||||||
{
|
{
|
||||||
return r[0];
|
return r[0];
|
||||||
}
|
}
|
||||||
@ -235,35 +235,35 @@ class BaseBuilder
|
|||||||
bool SI = Single,
|
bool SI = Single,
|
||||||
std::enable_if_t<!SA, std::nullptr_t> = nullptr,
|
std::enable_if_t<!SA, std::nullptr_t> = nullptr,
|
||||||
std::enable_if_t<!SI, std::nullptr_t> = nullptr>
|
std::enable_if_t<!SI, std::nullptr_t> = nullptr>
|
||||||
static inline Result convert_result(const Result& r)
|
static inline Result convert_result(const Result &r)
|
||||||
{
|
{
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline ResultType execSync(const DbClientPtr& client)
|
inline ResultType execSync(const DbClientPtr &client)
|
||||||
{
|
{
|
||||||
Result r(nullptr);
|
Result r(nullptr);
|
||||||
{
|
{
|
||||||
auto binder = *client << gen_sql(client->type());
|
auto binder = *client << gen_sql(client->type());
|
||||||
for (const std::string& a : gen_args())
|
for (const std::string &a : gen_args())
|
||||||
{
|
{
|
||||||
binder << a;
|
binder << a;
|
||||||
}
|
}
|
||||||
binder << Mode::Blocking;
|
binder << Mode::Blocking;
|
||||||
binder >> [&r](const Result& result) { r = result; };
|
binder >> [&r](const Result &result) { r = result; };
|
||||||
binder.exec(); // exec may throw exception
|
binder.exec(); // exec may throw exception
|
||||||
}
|
}
|
||||||
return convert_result(r);
|
return convert_result(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TFn, typename EFn>
|
template <typename TFn, typename EFn>
|
||||||
void execAsync(const DbClientPtr& client,
|
void execAsync(const DbClientPtr &client,
|
||||||
TFn&& rCallback,
|
TFn &&rCallback,
|
||||||
EFn&& exceptCallback) noexcept
|
EFn &&exceptCallback) noexcept
|
||||||
{
|
{
|
||||||
auto binder = *client << gen_sql(client->type());
|
auto binder = *client << gen_sql(client->type());
|
||||||
for (const std::string& a : gen_args())
|
for (const std::string &a : gen_args())
|
||||||
{
|
{
|
||||||
binder << a;
|
binder << a;
|
||||||
}
|
}
|
||||||
@ -272,19 +272,19 @@ class BaseBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline std::future<ResultType> execAsyncFuture(
|
inline std::future<ResultType> execAsyncFuture(
|
||||||
const DbClientPtr& client) noexcept
|
const DbClientPtr &client) noexcept
|
||||||
{
|
{
|
||||||
auto binder = *client << gen_sql(client->type());
|
auto binder = *client << gen_sql(client->type());
|
||||||
for (const std::string& a : gen_args())
|
for (const std::string &a : gen_args())
|
||||||
{
|
{
|
||||||
binder << a;
|
binder << a;
|
||||||
}
|
}
|
||||||
std::shared_ptr<std::promise<ResultType>> prom =
|
std::shared_ptr<std::promise<ResultType>> prom =
|
||||||
std::make_shared<std::promise<ResultType>>();
|
std::make_shared<std::promise<ResultType>>();
|
||||||
binder >>
|
binder >>
|
||||||
[prom](const Result& r) { prom->set_value(convert_result(r)); };
|
[prom](const Result &r) { prom->set_value(convert_result(r)); };
|
||||||
binder >>
|
binder >>
|
||||||
[prom](const std::exception_ptr& e) { prom->set_exception(e); };
|
[prom](const std::exception_ptr &e) { prom->set_exception(e); };
|
||||||
binder.exec();
|
binder.exec();
|
||||||
return prom->get_future();
|
return prom->get_future();
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ class FilterBuilder : public TransformBuilder<T, SelectAll, false>
|
|||||||
*
|
*
|
||||||
* @return FilterBuilder The FilterBuilder itself.
|
* @return FilterBuilder The FilterBuilder itself.
|
||||||
*/
|
*/
|
||||||
FilterBuilder(const std::string& from, const std::string& columns)
|
FilterBuilder(const std::string &from, const std::string &columns)
|
||||||
{
|
{
|
||||||
this->from_ = from;
|
this->from_ = from;
|
||||||
this->columns_ = columns;
|
this->columns_ = columns;
|
||||||
@ -54,8 +54,8 @@ class FilterBuilder : public TransformBuilder<T, SelectAll, false>
|
|||||||
*
|
*
|
||||||
* @return FilterBuilder& The FilterBuilder itself.
|
* @return FilterBuilder& The FilterBuilder itself.
|
||||||
*/
|
*/
|
||||||
inline FilterBuilder& eq(const std::string& column,
|
inline FilterBuilder &eq(const std::string &column,
|
||||||
const std::string& value)
|
const std::string &value)
|
||||||
{
|
{
|
||||||
this->assert_column(column);
|
this->assert_column(column);
|
||||||
this->filters_.push_back({column, CompareOperator::EQ, value});
|
this->filters_.push_back({column, CompareOperator::EQ, value});
|
||||||
@ -70,8 +70,8 @@ class FilterBuilder : public TransformBuilder<T, SelectAll, false>
|
|||||||
*
|
*
|
||||||
* @return FilterBuilder& The FilterBuilder itself.
|
* @return FilterBuilder& The FilterBuilder itself.
|
||||||
*/
|
*/
|
||||||
inline FilterBuilder& neq(const std::string& column,
|
inline FilterBuilder &neq(const std::string &column,
|
||||||
const std::string& value)
|
const std::string &value)
|
||||||
{
|
{
|
||||||
this->assert_column(column);
|
this->assert_column(column);
|
||||||
this->filters_.push_back({column, CompareOperator::NE, value});
|
this->filters_.push_back({column, CompareOperator::NE, value});
|
||||||
@ -86,8 +86,8 @@ class FilterBuilder : public TransformBuilder<T, SelectAll, false>
|
|||||||
*
|
*
|
||||||
* @return FilterBuilder& The FilterBuilder itself.
|
* @return FilterBuilder& The FilterBuilder itself.
|
||||||
*/
|
*/
|
||||||
inline FilterBuilder& gt(const std::string& column,
|
inline FilterBuilder >(const std::string &column,
|
||||||
const std::string& value)
|
const std::string &value)
|
||||||
{
|
{
|
||||||
this->assert_column(column);
|
this->assert_column(column);
|
||||||
this->filters_.push_back({column, CompareOperator::GT, value});
|
this->filters_.push_back({column, CompareOperator::GT, value});
|
||||||
@ -102,8 +102,8 @@ class FilterBuilder : public TransformBuilder<T, SelectAll, false>
|
|||||||
*
|
*
|
||||||
* @return FilterBuilder& The FilterBuilder itself.
|
* @return FilterBuilder& The FilterBuilder itself.
|
||||||
*/
|
*/
|
||||||
inline FilterBuilder& gte(const std::string& column,
|
inline FilterBuilder >e(const std::string &column,
|
||||||
const std::string& value)
|
const std::string &value)
|
||||||
{
|
{
|
||||||
this->assert_column(column);
|
this->assert_column(column);
|
||||||
this->filters_.push_back({column, CompareOperator::GE, value});
|
this->filters_.push_back({column, CompareOperator::GE, value});
|
||||||
@ -118,8 +118,8 @@ class FilterBuilder : public TransformBuilder<T, SelectAll, false>
|
|||||||
*
|
*
|
||||||
* @return FilterBuilder& The FilterBuilder itself.
|
* @return FilterBuilder& The FilterBuilder itself.
|
||||||
*/
|
*/
|
||||||
inline FilterBuilder& lt(const std::string& column,
|
inline FilterBuilder <(const std::string &column,
|
||||||
const std::string& value)
|
const std::string &value)
|
||||||
{
|
{
|
||||||
this->assert_column(column);
|
this->assert_column(column);
|
||||||
this->filters_.push_back({column, CompareOperator::LT, value});
|
this->filters_.push_back({column, CompareOperator::LT, value});
|
||||||
@ -134,8 +134,8 @@ class FilterBuilder : public TransformBuilder<T, SelectAll, false>
|
|||||||
*
|
*
|
||||||
* @return FilterBuilder& The FilterBuilder itself.
|
* @return FilterBuilder& The FilterBuilder itself.
|
||||||
*/
|
*/
|
||||||
inline FilterBuilder& lte(const std::string& column,
|
inline FilterBuilder <e(const std::string &column,
|
||||||
const std::string& value)
|
const std::string &value)
|
||||||
{
|
{
|
||||||
this->assert_column(column);
|
this->assert_column(column);
|
||||||
this->filters_.push_back({column, CompareOperator::LE, value});
|
this->filters_.push_back({column, CompareOperator::LE, value});
|
||||||
@ -150,8 +150,8 @@ class FilterBuilder : public TransformBuilder<T, SelectAll, false>
|
|||||||
*
|
*
|
||||||
* @return FilterBuilder& The FilterBuilder itself.
|
* @return FilterBuilder& The FilterBuilder itself.
|
||||||
*/
|
*/
|
||||||
inline FilterBuilder& like(const std::string& column,
|
inline FilterBuilder &like(const std::string &column,
|
||||||
const std::string& pattern)
|
const std::string &pattern)
|
||||||
{
|
{
|
||||||
this->assert_column(column);
|
this->assert_column(column);
|
||||||
this->filters_.push_back({column, CompareOperator::Like, pattern});
|
this->filters_.push_back({column, CompareOperator::Like, pattern});
|
||||||
|
@ -30,7 +30,7 @@ class QueryBuilder : public FilterBuilder<T, true>
|
|||||||
*
|
*
|
||||||
* @return std::string The table name
|
* @return std::string The table name
|
||||||
*/
|
*/
|
||||||
inline const std::string& getTableName() const
|
inline const std::string &getTableName() const
|
||||||
{
|
{
|
||||||
return this->from_.empty() ? T::tableName : this->from_;
|
return this->from_.empty() ? T::tableName : this->from_;
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ class QueryBuilder : public FilterBuilder<T, true>
|
|||||||
*
|
*
|
||||||
* @return QueryBuilder& The QueryBuilder itself.
|
* @return QueryBuilder& The QueryBuilder itself.
|
||||||
*/
|
*/
|
||||||
inline QueryBuilder& from(const std::string& table)
|
inline QueryBuilder &from(const std::string &table)
|
||||||
{
|
{
|
||||||
this->from_ = table;
|
this->from_ = table;
|
||||||
return *this;
|
return *this;
|
||||||
@ -59,7 +59,7 @@ class QueryBuilder : public FilterBuilder<T, true>
|
|||||||
* @note If you would return all rows, please use the `selectAll` method.
|
* @note If you would return all rows, please use the `selectAll` method.
|
||||||
* The method can return rows as model type `T`.
|
* The method can return rows as model type `T`.
|
||||||
*/
|
*/
|
||||||
inline FilterBuilder<T, false> select(const std::string& columns) const
|
inline FilterBuilder<T, false> select(const std::string &columns) const
|
||||||
{
|
{
|
||||||
return {getTableName(), columns};
|
return {getTableName(), columns};
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ class TransformBuilder : public BaseBuilder<T, SelectAll, Single>
|
|||||||
* @note This function is enabled only when `Single` is true.
|
* @note This function is enabled only when `Single` is true.
|
||||||
*/
|
*/
|
||||||
template <bool SI = Single, std::enable_if_t<SI, std::nullptr_t> = nullptr>
|
template <bool SI = Single, std::enable_if_t<SI, std::nullptr_t> = nullptr>
|
||||||
TransformBuilder(const TransformBuilder<T, SelectAll, false>& tb)
|
TransformBuilder(const TransformBuilder<T, SelectAll, false> &tb)
|
||||||
{
|
{
|
||||||
this->from_ = tb.from_;
|
this->from_ = tb.from_;
|
||||||
this->columns_ = tb.columns_;
|
this->columns_ = tb.columns_;
|
||||||
@ -59,7 +59,7 @@ class TransformBuilder : public BaseBuilder<T, SelectAll, Single>
|
|||||||
*
|
*
|
||||||
* @return TransformBuilder& The TransformBuilder itself.
|
* @return TransformBuilder& The TransformBuilder itself.
|
||||||
*/
|
*/
|
||||||
inline TransformBuilder& limit(std::uint64_t count)
|
inline TransformBuilder &limit(std::uint64_t count)
|
||||||
{
|
{
|
||||||
this->limit_ = count;
|
this->limit_ = count;
|
||||||
return *this;
|
return *this;
|
||||||
@ -72,7 +72,7 @@ class TransformBuilder : public BaseBuilder<T, SelectAll, Single>
|
|||||||
*
|
*
|
||||||
* @return TransformBuilder& The TransformBuilder itself.
|
* @return TransformBuilder& The TransformBuilder itself.
|
||||||
*/
|
*/
|
||||||
inline TransformBuilder& offset(std::uint64_t count)
|
inline TransformBuilder &offset(std::uint64_t count)
|
||||||
{
|
{
|
||||||
this->offset_ = count;
|
this->offset_ = count;
|
||||||
return *this;
|
return *this;
|
||||||
@ -86,7 +86,7 @@ class TransformBuilder : public BaseBuilder<T, SelectAll, Single>
|
|||||||
*
|
*
|
||||||
* @return TransformBuilder& The TransformBuilder itself.
|
* @return TransformBuilder& The TransformBuilder itself.
|
||||||
*/
|
*/
|
||||||
inline TransformBuilder& range(std::uint64_t from, std::uint64_t to)
|
inline TransformBuilder &range(std::uint64_t from, std::uint64_t to)
|
||||||
{
|
{
|
||||||
this->offset_ = from;
|
this->offset_ = from;
|
||||||
this->limit_ = to - from + 1; // inclusive
|
this->limit_ = to - from + 1; // inclusive
|
||||||
@ -101,7 +101,7 @@ class TransformBuilder : public BaseBuilder<T, SelectAll, Single>
|
|||||||
*
|
*
|
||||||
* @return TransformBuilder& The TransformBuilder itself.
|
* @return TransformBuilder& The TransformBuilder itself.
|
||||||
*/
|
*/
|
||||||
inline TransformBuilder& order(const std::string& column, bool asc = true)
|
inline TransformBuilder &order(const std::string &column, bool asc = true)
|
||||||
{
|
{
|
||||||
this->assert_column(column);
|
this->assert_column(column);
|
||||||
this->orders_.emplace_back(column, asc);
|
this->orders_.emplace_back(column, asc);
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
using namespace drogon::orm;
|
using namespace drogon::orm;
|
||||||
|
|
||||||
std::map<std::string, std::string> DbConnection::parseConnString(
|
std::map<std::string, std::string> DbConnection::parseConnString(
|
||||||
const std::string& connInfo)
|
const std::string &connInfo)
|
||||||
{
|
{
|
||||||
const static std::regex re(
|
const static std::regex re(
|
||||||
R"((\w+) *= *('(?:[^\n]|\\[^\n])+'|(?:\S|\\\S)+))");
|
R"((\w+) *= *('(?:[^\n]|\\[^\n])+'|(?:\S|\\\S)+))");
|
||||||
|
@ -27,8 +27,8 @@ using namespace drogon::orm;
|
|||||||
DbListener::~DbListener() = default;
|
DbListener::~DbListener() = default;
|
||||||
|
|
||||||
std::shared_ptr<DbListener> DbListener::newPgListener(
|
std::shared_ptr<DbListener> DbListener::newPgListener(
|
||||||
const std::string& connInfo,
|
const std::string &connInfo,
|
||||||
trantor::EventLoop* loop)
|
trantor::EventLoop *loop)
|
||||||
{
|
{
|
||||||
#if USE_POSTGRESQL
|
#if USE_POSTGRESQL
|
||||||
std::shared_ptr<PgListener> pgListener =
|
std::shared_ptr<PgListener> pgListener =
|
||||||
|
@ -21,7 +21,7 @@ using namespace drogon::orm;
|
|||||||
#define MAX_UNLISTEN_RETRY 3
|
#define MAX_UNLISTEN_RETRY 3
|
||||||
#define MAX_LISTEN_RETRY 10
|
#define MAX_LISTEN_RETRY 10
|
||||||
|
|
||||||
PgListener::PgListener(std::string connInfo, trantor::EventLoop* loop)
|
PgListener::PgListener(std::string connInfo, trantor::EventLoop *loop)
|
||||||
: connectionInfo_(std::move(connInfo)), loop_(loop)
|
: connectionInfo_(std::move(connInfo)), loop_(loop)
|
||||||
{
|
{
|
||||||
if (!loop)
|
if (!loop)
|
||||||
@ -56,7 +56,7 @@ void PgListener::init() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PgListener::listen(
|
void PgListener::listen(
|
||||||
const std::string& channel,
|
const std::string &channel,
|
||||||
std::function<void(std::string, std::string)> messageCallback) noexcept
|
std::function<void(std::string, std::string)> messageCallback) noexcept
|
||||||
{
|
{
|
||||||
if (loop_->isInLoopThread())
|
if (loop_->isInLoopThread())
|
||||||
@ -80,7 +80,7 @@ void PgListener::listen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgListener::unlisten(const std::string& channel) noexcept
|
void PgListener::unlisten(const std::string &channel) noexcept
|
||||||
{
|
{
|
||||||
if (loop_->isInLoopThread())
|
if (loop_->isInLoopThread())
|
||||||
{
|
{
|
||||||
@ -102,8 +102,8 @@ void PgListener::unlisten(const std::string& channel) noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgListener::onMessage(const std::string& channel,
|
void PgListener::onMessage(const std::string &channel,
|
||||||
const std::string& message) const noexcept
|
const std::string &message) const noexcept
|
||||||
{
|
{
|
||||||
loop_->assertInLoopThread();
|
loop_->assertInLoopThread();
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ void PgListener::onMessage(const std::string& channel,
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (auto& cb : iter->second)
|
for (auto &cb : iter->second)
|
||||||
{
|
{
|
||||||
cb(channel, message);
|
cb(channel, message);
|
||||||
}
|
}
|
||||||
@ -123,7 +123,7 @@ void PgListener::listenAll() noexcept
|
|||||||
loop_->assertInLoopThread();
|
loop_->assertInLoopThread();
|
||||||
|
|
||||||
listenTasks_.clear();
|
listenTasks_.clear();
|
||||||
for (auto& item : listenChannels_)
|
for (auto &item : listenChannels_)
|
||||||
{
|
{
|
||||||
listenTasks_.emplace_back(true, item.first);
|
listenTasks_.emplace_back(true, item.first);
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ void PgListener::listenNext() noexcept
|
|||||||
listenInLoop(channel, listen);
|
listenInLoop(channel, listen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgListener::listenInLoop(const std::string& channel,
|
void PgListener::listenInLoop(const std::string &channel,
|
||||||
bool listen,
|
bool listen,
|
||||||
std::shared_ptr<unsigned int> retryCnt)
|
std::shared_ptr<unsigned int> retryCnt)
|
||||||
{
|
{
|
||||||
@ -173,7 +173,7 @@ void PgListener::listenInLoop(const std::string& channel,
|
|||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
[listen, channel, sql](const Result& r) {
|
[listen, channel, sql](const Result &r) {
|
||||||
if (listen)
|
if (listen)
|
||||||
{
|
{
|
||||||
LOG_TRACE << "Listen channel " << channel;
|
LOG_TRACE << "Listen channel " << channel;
|
||||||
@ -184,12 +184,12 @@ void PgListener::listenInLoop(const std::string& channel,
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
[listen, channel, weakThis, sql, retryCnt, loop = loop_](
|
[listen, channel, weakThis, sql, retryCnt, loop = loop_](
|
||||||
const std::exception_ptr& exception) {
|
const std::exception_ptr &exception) {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::rethrow_exception(exception);
|
std::rethrow_exception(exception);
|
||||||
}
|
}
|
||||||
catch (const DrogonDbException& ex)
|
catch (const DrogonDbException &ex)
|
||||||
{
|
{
|
||||||
++(*retryCnt);
|
++(*retryCnt);
|
||||||
if (listen)
|
if (listen)
|
||||||
@ -251,7 +251,7 @@ PgConnectionPtr PgListener::newConnection(
|
|||||||
if (!retryCnt)
|
if (!retryCnt)
|
||||||
retryCnt = std::make_shared<unsigned int>(0);
|
retryCnt = std::make_shared<unsigned int>(0);
|
||||||
connPtr->setCloseCallback(
|
connPtr->setCloseCallback(
|
||||||
[weakPtr, retryCnt](const DbConnectionPtr& closeConnPtr) {
|
[weakPtr, retryCnt](const DbConnectionPtr &closeConnPtr) {
|
||||||
auto thisPtr = weakPtr.lock();
|
auto thisPtr = weakPtr.lock();
|
||||||
if (!thisPtr)
|
if (!thisPtr)
|
||||||
return;
|
return;
|
||||||
@ -276,7 +276,7 @@ PgConnectionPtr PgListener::newConnection(
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
connPtr->setOkCallback(
|
connPtr->setOkCallback(
|
||||||
[weakPtr, retryCnt](const DbConnectionPtr& okConnPtr) {
|
[weakPtr, retryCnt](const DbConnectionPtr &okConnPtr) {
|
||||||
LOG_TRACE << "connected after " << *retryCnt << " tries";
|
LOG_TRACE << "connected after " << *retryCnt << " tries";
|
||||||
(*retryCnt) = 0;
|
(*retryCnt) = 0;
|
||||||
auto thisPtr = weakPtr.lock();
|
auto thisPtr = weakPtr.lock();
|
||||||
@ -295,7 +295,7 @@ PgConnectionPtr PgListener::newConnection(
|
|||||||
});
|
});
|
||||||
|
|
||||||
connPtr->setMessageCallback(
|
connPtr->setMessageCallback(
|
||||||
[weakPtr](const std::string& channel, const std::string& message) {
|
[weakPtr](const std::string &channel, const std::string &message) {
|
||||||
auto thisPtr = weakPtr.lock();
|
auto thisPtr = weakPtr.lock();
|
||||||
if (thisPtr)
|
if (thisPtr)
|
||||||
{
|
{
|
||||||
@ -305,12 +305,12 @@ PgConnectionPtr PgListener::newConnection(
|
|||||||
return connPtr;
|
return connPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string PgListener::escapeIdentifier(const PgConnectionPtr& conn,
|
std::string PgListener::escapeIdentifier(const PgConnectionPtr &conn,
|
||||||
const char* str,
|
const char *str,
|
||||||
size_t length)
|
size_t length)
|
||||||
{
|
{
|
||||||
auto res = std::unique_ptr<char, std::function<void(char*)>>(
|
auto res = std::unique_ptr<char, std::function<void(char *)>>(
|
||||||
PQescapeIdentifier(conn->pgConn().get(), str, length), [](char* res) {
|
PQescapeIdentifier(conn->pgConn().get(), str, length), [](char *res) {
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
PQfreemem(res);
|
PQfreemem(res);
|
||||||
|
@ -30,23 +30,23 @@ class PgListener : public DbListener,
|
|||||||
public std::enable_shared_from_this<PgListener>
|
public std::enable_shared_from_this<PgListener>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PgListener(std::string connInfo, trantor::EventLoop* loop);
|
PgListener(std::string connInfo, trantor::EventLoop *loop);
|
||||||
~PgListener() override;
|
~PgListener() override;
|
||||||
void init() noexcept;
|
void init() noexcept;
|
||||||
|
|
||||||
trantor::EventLoop* loop() const
|
trantor::EventLoop *loop() const
|
||||||
{
|
{
|
||||||
return loop_;
|
return loop_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void listen(const std::string& channel,
|
void listen(const std::string &channel,
|
||||||
MessageCallback messageCallback) noexcept override;
|
MessageCallback messageCallback) noexcept override;
|
||||||
void unlisten(const std::string& channel) noexcept override;
|
void unlisten(const std::string &channel) noexcept override;
|
||||||
|
|
||||||
// methods below should be called in loop
|
// methods below should be called in loop
|
||||||
|
|
||||||
void onMessage(const std::string& channel,
|
void onMessage(const std::string &channel,
|
||||||
const std::string& message) const noexcept;
|
const std::string &message) const noexcept;
|
||||||
void listenAll() noexcept;
|
void listenAll() noexcept;
|
||||||
void listenNext() noexcept;
|
void listenNext() noexcept;
|
||||||
|
|
||||||
@ -67,11 +67,11 @@ class PgListener : public DbListener,
|
|||||||
* byte is also added. The return string will also be surrounded by double
|
* byte is also added. The return string will also be surrounded by double
|
||||||
* quotes.
|
* quotes.
|
||||||
*/
|
*/
|
||||||
static std::string escapeIdentifier(const PgConnectionPtr& conn,
|
static std::string escapeIdentifier(const PgConnectionPtr &conn,
|
||||||
const char* str,
|
const char *str,
|
||||||
size_t length);
|
size_t length);
|
||||||
|
|
||||||
void listenInLoop(const std::string& channel,
|
void listenInLoop(const std::string &channel,
|
||||||
bool listen,
|
bool listen,
|
||||||
std::shared_ptr<unsigned int> = nullptr);
|
std::shared_ptr<unsigned int> = nullptr);
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ class PgListener : public DbListener,
|
|||||||
|
|
||||||
std::string connectionInfo_;
|
std::string connectionInfo_;
|
||||||
std::unique_ptr<trantor::EventLoopThread> threadPtr_;
|
std::unique_ptr<trantor::EventLoopThread> threadPtr_;
|
||||||
trantor::EventLoop* loop_;
|
trantor::EventLoop *loop_;
|
||||||
DbConnectionPtr connHolder_;
|
DbConnectionPtr connHolder_;
|
||||||
DbConnectionPtr conn_;
|
DbConnectionPtr conn_;
|
||||||
std::deque<std::pair<bool, std::string>> listenTasks_;
|
std::deque<std::pair<bool, std::string>> listenTasks_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user