<%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 <%c++ auto tableInfo = @@.get("tableInfo"); auto modelName = tableInfo.get("className"); bool hasPrimaryKey = (tableInfo.get("hasPrimaryKey")==1); auto namespaceVector=@@.get>("namespaceVector"); std::string namespaceStr; for(auto &name:namespaceVector) { namespaceStr.append(name); namespaceStr.append("::"); } if(!namespaceStr.empty()) { namespaceStr.resize(namespaceStr.length()-2); $$<<"using namespace "<("className").length(), ' '); %> <%c++ if(hasPrimaryKey) {%> void [[className]]Base::getOne(const HttpRequestPtr &req, {%indentStr%} std::function &&callback, {%indentStr%} {%modelName%}::PrimaryKeyType &&id) { auto dbClientPtr = getDbClient(); auto callbackPtr = std::make_shared>( 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(&e.base()); if(s) { auto resp = HttpResponse::newHttpResponse(); resp->setStatusCode(k404NotFound); (*callbackPtr)(resp); return; } LOG_ERROR<setStatusCode(k500InternalServerError); (*callbackPtr)(resp); }); } void [[className]]Base::updateOne(const HttpRequestPtr &req, {%indentStr%} std::function &&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::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 &&callback, {%indentStr%} {%modelName%}::PrimaryKeyType &&id) { auto dbClientPtr = getDbClient(); auto callbackPtr = std::make_shared>( 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 &&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::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 &&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::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 &&callback) { }*/ [[className]]Base::[[className]]Base() : RestfulController({ <%c++ tableInfo = @@.get("tableInfo"); const auto &cols=tableInfo.get>("columns"); for(size_t i=0; i "{%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 "{%col.colName_%}", // the alias for the {%col.colName_%} column. <%c++ }else{ %> "{%col.colName_%}" // the alias for the {%col.colName_%} column. <%c++ } } %> }); }