audio_trans/orm_lib/inc/drogon/orm/RestfulController.h

175 lines
4.8 KiB
C++

/**
*
* @file RestfulController.h
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* Drogon
*
*/
#pragma once
#include <drogon/exports.h>
#include <drogon/drogon.h>
#include <drogon/orm/DbClient.h>
#include <drogon/orm/Mapper.h>
#include <trantor/utils/NonCopyable.h>
#include <string>
#include <functional>
#include <vector>
namespace drogon
{
/**
* @brief this class is a helper class for the implementation of restful api
* controllers generated by the drogon_ctl command.
*/
class DROGON_EXPORT RestfulController : trantor::NonCopyable
{
public:
void enableMasquerading(const std::vector<std::string> &pMasqueradingVector)
{
masquerading_ = true;
masqueradingVector_ = pMasqueradingVector;
for (size_t i = 0; i < masqueradingVector_.size(); ++i)
{
masqueradingMap_.insert(
std::pair<std::string, size_t>{masqueradingVector_[i], i});
}
}
void disableMasquerading()
{
masquerading_ = false;
masqueradingVector_ = columnsVector_;
for (size_t i = 0; i < masqueradingVector_.size(); ++i)
{
masqueradingMap_.insert(
std::pair<std::string, size_t>{masqueradingVector_[i], i});
}
}
void registerAJsonValidator(
const std::string &fieldName,
const std::function<bool(const Json::Value &, std::string &)>
&validator)
{
validators_.emplace_back(fieldName, validator);
}
void registerAJsonValidator(
const std::string &fieldName,
std::function<bool(const Json::Value &, std::string &)> &&validator)
{
validators_.emplace_back(fieldName, std::move(validator));
}
/**
* @brief make a criteria object for searching by ORM.
*
* @param pJson the json object presenting search criterias.
* The json object must be an array of depth 3.
* for example:
* [
* [
* ["color","=","red"], //AND
* ["price","<",1000]
* ], //OR
* [
* ["color","=","white"], //AND
* ["price","<",800], //AND
* ["brand","!=",null]
* ]
* ]
* @return orm::Criteria
*/
orm::Criteria makeCriteria(const Json::Value &pJson) noexcept(false);
protected:
RestfulController(const std::vector<std::string> &columnsVector)
: columnsVector_(columnsVector)
{
}
std::vector<std::string> fieldsSelector(const std::set<std::string> &fields)
{
std::vector<std::string> ret;
for (auto &field : masqueradingVector_)
{
if (!field.empty() && fields.find(field) != fields.end())
{
ret.emplace_back(field);
}
else
{
ret.emplace_back(std::string{});
}
}
return ret;
}
template <typename T>
Json::Value makeJson(const HttpRequestPtr &req, const T &obj)
{
auto &queryParams = req->parameters();
auto iter = queryParams.find("fields");
if (masquerading_)
{
if (iter != queryParams.end())
{
auto fields = utils::splitStringToSet(iter->second, ",");
return obj.toMasqueradedJson(fieldsSelector(fields));
}
else
{
return obj.toMasqueradedJson(masqueradingVector_);
}
}
else
{
if (iter != queryParams.end())
{
auto fields = utils::splitString(iter->second, ",");
return obj.toMasqueradedJson(fields);
}
else
{
return obj.toJson();
}
}
}
bool doCustomValidations(const Json::Value &pJson, std::string &err)
{
for (auto &validator : validators_)
{
if (pJson.isMember(validator.first))
{
if (!validator.second(pJson[validator.first], err))
{
return false;
}
}
}
return true;
}
bool isMasquerading() const
{
return masquerading_;
}
const std::vector<std::string> &masqueradingVector() const
{
return masqueradingVector_;
}
private:
bool masquerading_{true};
std::vector<std::string> masqueradingVector_;
std::vector<
std::pair<std::string,
std::function<bool(const Json::Value &, std::string &)>>>
validators_;
std::unordered_map<std::string, size_t> masqueradingMap_;
const std::vector<std::string> columnsVector_;
};
} // namespace drogon