495 lines
15 KiB
Plaintext
495 lines
15 KiB
Plaintext
<%inc#include "create_model.h"
|
|
using namespace drogon_ctl;
|
|
%>
|
|
|
|
/**
|
|
*
|
|
* [[fileName]]Base.cc
|
|
* DO NOT EDIT. This file is generated by drogon_ctl automatically.
|
|
* Users should implement business logic in the derived class.
|
|
*/
|
|
|
|
#include "[[fileName]]Base.h"
|
|
#include <string>
|
|
|
|
<%c++
|
|
auto tableInfo = @@.get<DrTemplateData>("tableInfo");
|
|
auto modelName = tableInfo.get<std::string>("className");
|
|
bool hasPrimaryKey = (tableInfo.get<int>("hasPrimaryKey")==1);
|
|
auto namespaceVector=@@.get<std::vector<std::string>>("namespaceVector");
|
|
std::string namespaceStr;
|
|
for(auto &name:namespaceVector)
|
|
{
|
|
namespaceStr.append(name);
|
|
namespaceStr.append("::");
|
|
}
|
|
if(!namespaceStr.empty())
|
|
{
|
|
namespaceStr.resize(namespaceStr.length()-2);
|
|
$$<<"using namespace "<<namespaceStr<<";\n";
|
|
}
|
|
std::string indentStr(@@.get<std::string>("className").length(), ' ');
|
|
%>
|
|
<%c++
|
|
if(hasPrimaryKey)
|
|
{%>
|
|
void [[className]]Base::getOne(const HttpRequestPtr &req,
|
|
{%indentStr%} std::function<void(const HttpResponsePtr &)> &&callback,
|
|
{%indentStr%} {%modelName%}::PrimaryKeyType &&id)
|
|
{
|
|
|
|
auto dbClientPtr = getDbClient();
|
|
auto callbackPtr =
|
|
std::make_shared<std::function<void(const HttpResponsePtr &)>>(
|
|
std::move(callback));
|
|
drogon::orm::Mapper<{%modelName%}> mapper(dbClientPtr);
|
|
mapper.findByPrimaryKey(
|
|
id,
|
|
[req, callbackPtr, this]({%modelName%} r) {
|
|
(*callbackPtr)(HttpResponse::newHttpJsonResponse(makeJson(req, r)));
|
|
},
|
|
[callbackPtr](const DrogonDbException &e) {
|
|
const drogon::orm::UnexpectedRows *s=dynamic_cast<const drogon::orm::UnexpectedRows *>(&e.base());
|
|
if(s)
|
|
{
|
|
auto resp = HttpResponse::newHttpResponse();
|
|
resp->setStatusCode(k404NotFound);
|
|
(*callbackPtr)(resp);
|
|
return;
|
|
}
|
|
LOG_ERROR<<e.base().what();
|
|
Json::Value ret;
|
|
ret["error"] = "database error";
|
|
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k500InternalServerError);
|
|
(*callbackPtr)(resp);
|
|
});
|
|
}
|
|
|
|
|
|
void [[className]]Base::updateOne(const HttpRequestPtr &req,
|
|
{%indentStr%} std::function<void(const HttpResponsePtr &)> &&callback,
|
|
{%indentStr%} {%modelName%}::PrimaryKeyType &&id)
|
|
{
|
|
auto jsonPtr=req->jsonObject();
|
|
if(!jsonPtr)
|
|
{
|
|
Json::Value ret;
|
|
ret["error"]="No json object is found in the request";
|
|
auto resp= HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k400BadRequest);
|
|
callback(resp);
|
|
return;
|
|
}
|
|
{%modelName%} object;
|
|
std::string err;
|
|
if(!doCustomValidations(*jsonPtr, err))
|
|
{
|
|
Json::Value ret;
|
|
ret["error"] = err;
|
|
auto resp= HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k400BadRequest);
|
|
callback(resp);
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
if(isMasquerading())
|
|
{
|
|
if(!{%modelName%}::validateMasqueradedJsonForUpdate(*jsonPtr, masqueradingVector(), err))
|
|
{
|
|
Json::Value ret;
|
|
ret["error"] = err;
|
|
auto resp= HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k400BadRequest);
|
|
callback(resp);
|
|
return;
|
|
}
|
|
object.updateByMasqueradedJson(*jsonPtr, masqueradingVector());
|
|
}
|
|
else
|
|
{
|
|
if(!{%modelName%}::validateJsonForUpdate(*jsonPtr, err))
|
|
{
|
|
Json::Value ret;
|
|
ret["error"] = err;
|
|
auto resp= HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k400BadRequest);
|
|
callback(resp);
|
|
return;
|
|
}
|
|
object.updateByJson(*jsonPtr);
|
|
}
|
|
}
|
|
catch(const Json::Exception &e)
|
|
{
|
|
LOG_ERROR << e.what();
|
|
Json::Value ret;
|
|
ret["error"]="Field type error";
|
|
auto resp= HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k400BadRequest);
|
|
callback(resp);
|
|
return;
|
|
}
|
|
if(object.getPrimaryKey() != id)
|
|
{
|
|
Json::Value ret;
|
|
ret["error"]="Bad primary key";
|
|
auto resp= HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k400BadRequest);
|
|
callback(resp);
|
|
return;
|
|
}
|
|
|
|
auto dbClientPtr = getDbClient();
|
|
auto callbackPtr =
|
|
std::make_shared<std::function<void(const HttpResponsePtr &)>>(
|
|
std::move(callback));
|
|
drogon::orm::Mapper<{%modelName%}> mapper(dbClientPtr);
|
|
|
|
mapper.update(
|
|
object,
|
|
[callbackPtr](const size_t count)
|
|
{
|
|
if(count == 1)
|
|
{
|
|
auto resp = HttpResponse::newHttpResponse();
|
|
resp->setStatusCode(k202Accepted);
|
|
(*callbackPtr)(resp);
|
|
}
|
|
else if(count == 0)
|
|
{
|
|
Json::Value ret;
|
|
ret["error"]="No resources are updated";
|
|
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k404NotFound);
|
|
(*callbackPtr)(resp);
|
|
}
|
|
else
|
|
{
|
|
LOG_FATAL << "More than one resource is updated: " << count;
|
|
Json::Value ret;
|
|
ret["error"] = "database error";
|
|
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k500InternalServerError);
|
|
(*callbackPtr)(resp);
|
|
}
|
|
},
|
|
[callbackPtr](const DrogonDbException &e) {
|
|
LOG_ERROR << e.base().what();
|
|
Json::Value ret;
|
|
ret["error"] = "database error";
|
|
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k500InternalServerError);
|
|
(*callbackPtr)(resp);
|
|
});
|
|
}
|
|
|
|
|
|
void [[className]]Base::deleteOne(const HttpRequestPtr &req,
|
|
{%indentStr%} std::function<void(const HttpResponsePtr &)> &&callback,
|
|
{%indentStr%} {%modelName%}::PrimaryKeyType &&id)
|
|
{
|
|
|
|
auto dbClientPtr = getDbClient();
|
|
auto callbackPtr =
|
|
std::make_shared<std::function<void(const HttpResponsePtr &)>>(
|
|
std::move(callback));
|
|
drogon::orm::Mapper<{%modelName%}> mapper(dbClientPtr);
|
|
mapper.deleteByPrimaryKey(
|
|
id,
|
|
[callbackPtr](const size_t count) {
|
|
if(count == 1)
|
|
{
|
|
auto resp = HttpResponse::newHttpResponse();
|
|
resp->setStatusCode(k204NoContent);
|
|
(*callbackPtr)(resp);
|
|
}
|
|
else if(count == 0)
|
|
{
|
|
Json::Value ret;
|
|
ret["error"] = "No resources deleted";
|
|
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k404NotFound);
|
|
(*callbackPtr)(resp);
|
|
}
|
|
else
|
|
{
|
|
LOG_FATAL << "Delete more than one records: " << count;
|
|
Json::Value ret;
|
|
ret["error"] = "Database error";
|
|
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k500InternalServerError);
|
|
(*callbackPtr)(resp);
|
|
}
|
|
},
|
|
[callbackPtr](const DrogonDbException &e) {
|
|
LOG_ERROR << e.base().what();
|
|
Json::Value ret;
|
|
ret["error"] = "database error";
|
|
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k500InternalServerError);
|
|
(*callbackPtr)(resp);
|
|
});
|
|
}
|
|
<%c++}%>
|
|
|
|
void [[className]]Base::get(const HttpRequestPtr &req,
|
|
{%indentStr%} std::function<void(const HttpResponsePtr &)> &&callback)
|
|
{
|
|
auto dbClientPtr = getDbClient();
|
|
drogon::orm::Mapper<{%modelName%}> mapper(dbClientPtr);
|
|
auto ¶meters = req->parameters();
|
|
auto iter = parameters.find("sort");
|
|
if(iter != parameters.end())
|
|
{
|
|
auto sortFields = drogon::utils::splitString(iter->second, ",");
|
|
for(auto &field : sortFields)
|
|
{
|
|
if(field.empty())
|
|
continue;
|
|
if(field[0] == '+')
|
|
{
|
|
field = field.substr(1);
|
|
mapper.orderBy(field, SortOrder::ASC);
|
|
}
|
|
else if(field[0] == '-')
|
|
{
|
|
field = field.substr(1);
|
|
mapper.orderBy(field, SortOrder::DESC);
|
|
}
|
|
else
|
|
{
|
|
mapper.orderBy(field, SortOrder::ASC);
|
|
}
|
|
}
|
|
}
|
|
iter = parameters.find("offset");
|
|
if(iter != parameters.end())
|
|
{
|
|
try{
|
|
auto offset = std::stoll(iter->second);
|
|
mapper.offset(offset);
|
|
}
|
|
catch(...)
|
|
{
|
|
auto resp = HttpResponse::newHttpResponse();
|
|
resp->setStatusCode(k400BadRequest);
|
|
callback(resp);
|
|
return;
|
|
}
|
|
}
|
|
iter = parameters.find("limit");
|
|
if(iter != parameters.end())
|
|
{
|
|
try{
|
|
auto limit = std::stoll(iter->second);
|
|
mapper.limit(limit);
|
|
}
|
|
catch(...)
|
|
{
|
|
auto resp = HttpResponse::newHttpResponse();
|
|
resp->setStatusCode(k400BadRequest);
|
|
callback(resp);
|
|
return;
|
|
}
|
|
}
|
|
auto callbackPtr =
|
|
std::make_shared<std::function<void(const HttpResponsePtr &)>>(
|
|
std::move(callback));
|
|
auto jsonPtr = req->jsonObject();
|
|
if(jsonPtr && jsonPtr->isMember("filter"))
|
|
{
|
|
try{
|
|
auto criteria = makeCriteria((*jsonPtr)["filter"]);
|
|
mapper.findBy(criteria,
|
|
[req, callbackPtr, this](const std::vector<{%modelName%}> &v) {
|
|
Json::Value ret;
|
|
ret.resize(0);
|
|
for (auto &obj : v)
|
|
{
|
|
ret.append(makeJson(req, obj));
|
|
}
|
|
(*callbackPtr)(HttpResponse::newHttpJsonResponse(ret));
|
|
},
|
|
[callbackPtr](const DrogonDbException &e) {
|
|
LOG_ERROR << e.base().what();
|
|
Json::Value ret;
|
|
ret["error"] = "database error";
|
|
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k500InternalServerError);
|
|
(*callbackPtr)(resp);
|
|
});
|
|
}
|
|
catch(const std::exception &e)
|
|
{
|
|
LOG_ERROR << e.what();
|
|
Json::Value ret;
|
|
ret["error"] = e.what();
|
|
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k400BadRequest);
|
|
(*callbackPtr)(resp);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mapper.findAll([req, callbackPtr, this](const std::vector<{%modelName%}> &v) {
|
|
Json::Value ret;
|
|
ret.resize(0);
|
|
for (auto &obj : v)
|
|
{
|
|
ret.append(makeJson(req, obj));
|
|
}
|
|
(*callbackPtr)(HttpResponse::newHttpJsonResponse(ret));
|
|
},
|
|
[callbackPtr](const DrogonDbException &e) {
|
|
LOG_ERROR << e.base().what();
|
|
Json::Value ret;
|
|
ret["error"] = "database error";
|
|
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k500InternalServerError);
|
|
(*callbackPtr)(resp);
|
|
});
|
|
}
|
|
}
|
|
|
|
void [[className]]Base::create(const HttpRequestPtr &req,
|
|
{%indentStr%} std::function<void(const HttpResponsePtr &)> &&callback)
|
|
{
|
|
auto jsonPtr=req->jsonObject();
|
|
if(!jsonPtr)
|
|
{
|
|
Json::Value ret;
|
|
ret["error"]="No json object is found in the request";
|
|
auto resp= HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k400BadRequest);
|
|
callback(resp);
|
|
return;
|
|
}
|
|
std::string err;
|
|
if(!doCustomValidations(*jsonPtr, err))
|
|
{
|
|
Json::Value ret;
|
|
ret["error"] = err;
|
|
auto resp= HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k400BadRequest);
|
|
callback(resp);
|
|
return;
|
|
}
|
|
if(isMasquerading())
|
|
{
|
|
if(!{%modelName%}::validateMasqueradedJsonForCreation(*jsonPtr, masqueradingVector(), err))
|
|
{
|
|
Json::Value ret;
|
|
ret["error"] = err;
|
|
auto resp= HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k400BadRequest);
|
|
callback(resp);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(!{%modelName%}::validateJsonForCreation(*jsonPtr, err))
|
|
{
|
|
Json::Value ret;
|
|
ret["error"] = err;
|
|
auto resp= HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k400BadRequest);
|
|
callback(resp);
|
|
return;
|
|
}
|
|
}
|
|
try
|
|
{
|
|
{%modelName%} object =
|
|
(isMasquerading()?
|
|
{%modelName%}(*jsonPtr, masqueradingVector()) :
|
|
{%modelName%}(*jsonPtr));
|
|
auto dbClientPtr = getDbClient();
|
|
auto callbackPtr =
|
|
std::make_shared<std::function<void(const HttpResponsePtr &)>>(
|
|
std::move(callback));
|
|
drogon::orm::Mapper<{%modelName%}> mapper(dbClientPtr);
|
|
mapper.insert(
|
|
object,
|
|
[req, callbackPtr, this]({%modelName%} newObject){
|
|
(*callbackPtr)(HttpResponse::newHttpJsonResponse(
|
|
makeJson(req, newObject)));
|
|
},
|
|
[callbackPtr](const DrogonDbException &e){
|
|
LOG_ERROR << e.base().what();
|
|
Json::Value ret;
|
|
ret["error"] = "database error";
|
|
auto resp = HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k500InternalServerError);
|
|
(*callbackPtr)(resp);
|
|
});
|
|
}
|
|
catch(const Json::Exception &e)
|
|
{
|
|
LOG_ERROR << e.what();
|
|
Json::Value ret;
|
|
ret["error"]="Field type error";
|
|
auto resp= HttpResponse::newHttpJsonResponse(ret);
|
|
resp->setStatusCode(k400BadRequest);
|
|
callback(resp);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*
|
|
void [[className]]Base::update(const HttpRequestPtr &req,
|
|
{%indentStr%} std::function<void(const HttpResponsePtr &)> &&callback)
|
|
{
|
|
|
|
}*/
|
|
|
|
[[className]]Base::[[className]]Base()
|
|
: RestfulController({
|
|
<%c++
|
|
tableInfo = @@.get<DrTemplateData>("tableInfo");
|
|
const auto &cols=tableInfo.get<std::vector<ColumnInfo>>("columns");
|
|
for(size_t i=0; i<cols.size(); ++i)
|
|
{
|
|
auto &col = cols[i];
|
|
if(i < (cols.size()-1))
|
|
{
|
|
%>
|
|
"{%col.colName_%}",
|
|
<%c++
|
|
}else{
|
|
%>
|
|
"{%col.colName_%}"
|
|
<%c++
|
|
}
|
|
}
|
|
%>
|
|
})
|
|
{
|
|
/**
|
|
* The items in the vector are aliases of column names in the table.
|
|
* if one item is set to an empty string, the related column is not sent
|
|
* to clients.
|
|
*/
|
|
enableMasquerading({
|
|
<%c++
|
|
for(size_t i=0; i<cols.size(); ++i)
|
|
{
|
|
auto &col = cols[i];
|
|
if(i < (cols.size()-1))
|
|
{
|
|
%>
|
|
"{%col.colName_%}", // the alias for the {%col.colName_%} column.
|
|
<%c++
|
|
}else{
|
|
%>
|
|
"{%col.colName_%}" // the alias for the {%col.colName_%} column.
|
|
<%c++
|
|
}
|
|
}
|
|
%>
|
|
});
|
|
}
|