mirror of
https://gitee.com/an-tao/drogon.git
synced 2024-12-02 11:47:56 +08:00
1508 lines
58 KiB
Plaintext
1508 lines
58 KiB
Plaintext
<%inc#include "create_model.h"
|
|
using namespace drogon_ctl;
|
|
%>
|
|
/**
|
|
*
|
|
* [[className]].cc
|
|
* DO NOT EDIT. This file is generated by drogon_ctl
|
|
*
|
|
*/
|
|
|
|
#include "[[className]].h"
|
|
<%c++
|
|
auto &relationships=@@.get<std::vector<Relationship>>("relationships");
|
|
auto rdbms=@@.get<std::string>("rdbms");
|
|
for(auto &relationship : relationships)
|
|
{
|
|
if(relationship.type() == Relationship::Type::HasOne ||
|
|
relationship.type() == Relationship::Type::HasMany ||
|
|
relationship.type() == Relationship::Type::ManyToMany)
|
|
{
|
|
auto &name=relationship.targetTableName();
|
|
auto relationshipClassName=nameTransform(name, true);
|
|
auto originalClassName=nameTransform(relationship.originalTableName(),true);
|
|
if(relationshipClassName!=originalClassName)
|
|
{
|
|
%>
|
|
#include "{%relationshipClassName%}.h"
|
|
<%c++
|
|
}
|
|
}
|
|
if(relationship.type() == Relationship::Type::ManyToMany)
|
|
{
|
|
auto &pivotTableName=relationship.pivotTable().tableName();
|
|
auto pivotTableClassName=nameTransform(pivotTableName, true);
|
|
%>
|
|
#include "{%pivotTableClassName%}.h"
|
|
<%c++
|
|
}
|
|
}
|
|
%>
|
|
#include <drogon/utils/Utilities.h>
|
|
#include <string>
|
|
<%c++
|
|
const auto &cols=@@.get<std::vector<ColumnInfo>>("columns");
|
|
auto className=@@.get<std::string>("className");
|
|
std::string indentStr(@@.get<std::string>("className").length(), ' ');
|
|
%>
|
|
|
|
using namespace drogon;
|
|
using namespace drogon_model::[[dbName]]<%c++
|
|
auto &schema=@@.get<std::string>("schema");
|
|
if(!schema.empty())
|
|
{
|
|
$$<<"::"<<schema<<";\n";
|
|
}
|
|
else
|
|
{
|
|
$$<<";\n";
|
|
}
|
|
%>
|
|
|
|
<%c++for(auto col:cols){
|
|
%>
|
|
const std::string [[className]]::Cols::_{%col.colName_%} = "{%col.colName_%}";
|
|
<%c++
|
|
}%>
|
|
<%c++if(@@.get<int>("hasPrimaryKey")<=1){%>
|
|
const std::string [[className]]::primaryKeyName = "[[primaryKeyName]]";
|
|
<%c++}else{%>
|
|
const std::vector<std::string> [[className]]::primaryKeyName = {<%c++
|
|
auto pkName=@@.get<std::vector<std::string>>("primaryKeyName");
|
|
for(size_t i=0;i<pkName.size();i++)
|
|
{
|
|
$$<<"\""<<pkName[i]<<"\"";
|
|
if(i<(pkName.size()-1))
|
|
$$<<",";
|
|
}
|
|
%>};
|
|
<%c++}%>
|
|
<%c++ if(@@.get<int>("hasPrimaryKey")>0){%>
|
|
const bool [[className]]::hasPrimaryKey = true;
|
|
<%c++ }else{%>
|
|
const bool [[className]]::hasPrimaryKey = false;
|
|
<%c++}%>
|
|
const std::string [[className]]::tableName = "<%c++
|
|
if(!schema.empty())
|
|
{
|
|
$$<<schema<<".";
|
|
}
|
|
%>[[tableName]]";
|
|
|
|
const std::vector<typename [[className]]::MetaData> [[className]]::metaData_={
|
|
<%c++for(size_t i=0;i<cols.size();i++){
|
|
auto &col=cols[i];
|
|
$$<<"{\""<<col.colName_<<"\",\""<<col.colType_<<"\",\""<<col.colDatabaseType_<<"\","<<col.colLength_<<","<<col.isAutoVal_<<","<<col.isPrimaryKey_<<","<<col.notNull_<<"}";
|
|
if(i<(cols.size()-1))
|
|
$$<<",\n";
|
|
else
|
|
$$<<"\n";
|
|
}%>
|
|
};
|
|
const std::string &[[className]]::getColumnName(size_t index) noexcept(false)
|
|
{
|
|
assert(index < metaData_.size());
|
|
return metaData_[index].colName_;
|
|
}
|
|
[[className]]::[[className]](const Row &r, const ssize_t indexOffset) noexcept
|
|
{
|
|
if(indexOffset < 0)
|
|
{
|
|
<%c++
|
|
for(size_t i = 0; i <cols.size(); ++i)
|
|
{
|
|
auto &col = cols[i];
|
|
if(col.colType_.empty())
|
|
continue;
|
|
%>
|
|
if(!r["{%col.colName_%}"].isNull())
|
|
{
|
|
<%c++
|
|
if(col.colDatabaseType_=="date")
|
|
{
|
|
$$<<" auto daysStr = r[\""<<col.colName_<<"\"].as<std::string>();\n";
|
|
$$<<" struct tm stm;\n";
|
|
$$<<" memset(&stm,0,sizeof(stm));\n";
|
|
$$<<" strptime(daysStr.c_str(),\"%Y-%m-%d\",&stm);\n";
|
|
$$<<" time_t t = mktime(&stm);\n";
|
|
// $$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(::trantor::Date(946656000000000).after(daysNum*86400));\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(t*1000000);\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_.find("timestamp")!=std::string::npos||col.colDatabaseType_.find("datetime")!=std::string::npos)
|
|
{
|
|
$$<<" auto timeStr = r[\""<<col.colName_<<"\"].as<std::string>();\n";
|
|
$$<<" struct tm stm;\n";
|
|
$$<<" memset(&stm,0,sizeof(stm));\n";
|
|
$$<<" auto p = strptime(timeStr.c_str(),\"%Y-%m-%d %H:%M:%S\",&stm);\n";
|
|
$$<<" time_t t = mktime(&stm);\n";
|
|
$$<<" size_t decimalNum = 0;\n";
|
|
$$<<" if(*p=='.')\n";
|
|
$$<<" {\n";
|
|
$$<<" std::string decimals(p+1,&timeStr[timeStr.length()]);\n";
|
|
$$<<" while(decimals.length()<6)\n";
|
|
$$<<" {\n";
|
|
$$<<" decimals += \"0\";\n";
|
|
$$<<" }\n";
|
|
$$<<" decimalNum = (size_t)atol(decimals.c_str());\n";
|
|
$$<<" }\n";
|
|
// $$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(::trantor::Date(946656000000000).after(daysNum*86400));\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(t*1000000+decimalNum);\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_=="bytea")
|
|
{
|
|
$$<<" auto str = r[\""<<col.colName_<<"\"].as<string_view>();\n";
|
|
$$<<" if(str.length()>=2&&\n";
|
|
$$<<" str[0]=='\\\\'&&str[1]=='x')\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<std::vector<char>>(drogon::utils::hexToBinaryVector(str.data()+2,str.length()-2));\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
%>
|
|
{%col.colValName_%}_=std::make_shared<{%col.colType_%}>(r["{%col.colName_%}"].as<{%col.colType_%}>());
|
|
}
|
|
<%c++}
|
|
%>
|
|
}
|
|
else
|
|
{
|
|
size_t offset = (size_t)indexOffset;
|
|
if(offset + {%cols.size()%} > r.size())
|
|
{
|
|
LOG_FATAL << "Invalid SQL result for this model";
|
|
return;
|
|
}
|
|
size_t index;
|
|
<%c++
|
|
for(size_t i = 0; i <cols.size(); ++i)
|
|
{
|
|
auto &col = cols[i];
|
|
if(col.colType_.empty())
|
|
continue;
|
|
%>
|
|
index = offset + {%i%};
|
|
if(!r[index].isNull())
|
|
{
|
|
<%c++
|
|
if(col.colDatabaseType_=="date")
|
|
{
|
|
$$<<" auto daysStr = r[index].as<std::string>();\n";
|
|
$$<<" struct tm stm;\n";
|
|
$$<<" memset(&stm,0,sizeof(stm));\n";
|
|
$$<<" strptime(daysStr.c_str(),\"%Y-%m-%d\",&stm);\n";
|
|
$$<<" time_t t = mktime(&stm);\n";
|
|
// $$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(::trantor::Date(946656000000000).after(daysNum*86400));\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(t*1000000);\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_.find("timestamp")!=std::string::npos||col.colDatabaseType_.find("datetime")!=std::string::npos)
|
|
{
|
|
$$<<" auto timeStr = r[index].as<std::string>();\n";
|
|
$$<<" struct tm stm;\n";
|
|
$$<<" memset(&stm,0,sizeof(stm));\n";
|
|
$$<<" auto p = strptime(timeStr.c_str(),\"%Y-%m-%d %H:%M:%S\",&stm);\n";
|
|
$$<<" time_t t = mktime(&stm);\n";
|
|
$$<<" size_t decimalNum = 0;\n";
|
|
$$<<" if(*p=='.')\n";
|
|
$$<<" {\n";
|
|
$$<<" std::string decimals(p+1,&timeStr[timeStr.length()]);\n";
|
|
$$<<" while(decimals.length()<6)\n";
|
|
$$<<" {\n";
|
|
$$<<" decimals += \"0\";\n";
|
|
$$<<" }\n";
|
|
$$<<" decimalNum = (size_t)atol(decimals.c_str());\n";
|
|
$$<<" }\n";
|
|
// $$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(::trantor::Date(946656000000000).after(daysNum*86400));\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(t*1000000+decimalNum);\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_=="bytea")
|
|
{
|
|
$$<<" auto str = r[index].as<string_view>();\n";
|
|
$$<<" if(str.length()>=2&&\n";
|
|
$$<<" str[0]=='\\\\'&&str[1]=='x')\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<std::vector<char>>(drogon::utils::hexToBinaryVector(str.data()+2,str.length()-2));\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
%>
|
|
{%col.colValName_%}_=std::make_shared<{%col.colType_%}>(r[index].as<{%col.colType_%}>());
|
|
}
|
|
<%c++}%>
|
|
}
|
|
|
|
}
|
|
|
|
[[className]]::[[className]](const Json::Value &pJson, const std::vector<std::string> &pMasqueradingVector) noexcept(false)
|
|
{
|
|
if(pMasqueradingVector.size() != {%cols.size()%})
|
|
{
|
|
LOG_ERROR << "Bad masquerading vector";
|
|
return;
|
|
}
|
|
<%c++
|
|
for(size_t i=0; i<cols.size(); ++i)
|
|
{
|
|
auto &col = cols[i];
|
|
if(col.colType_.empty())
|
|
continue;
|
|
%>
|
|
if(!pMasqueradingVector[{%i%}].empty() && pJson.isMember(pMasqueradingVector[{%i%}]))
|
|
{
|
|
dirtyFlag_[{%i%}] = true;
|
|
<%c++
|
|
if(col.colType_ == "std::string")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<std::string>(pJson[pMasqueradingVector["<<i<<"]].asString());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_=="date")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" auto daysStr = pJson[pMasqueradingVector["<<i<<"]].asString();\n";
|
|
$$<<" struct tm stm;\n";
|
|
$$<<" memset(&stm,0,sizeof(stm));\n";
|
|
$$<<" strptime(daysStr.c_str(),\"%Y-%m-%d\",&stm);\n";
|
|
$$<<" time_t t = mktime(&stm);\n";
|
|
// $$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(::trantor::Date(946656000000000).after(daysNum*86400));\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(t*1000000);\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_.find("timestamp")!=std::string::npos||col.colDatabaseType_.find("datetime")!=std::string::npos)
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" auto timeStr = pJson[pMasqueradingVector["<<i<<"]].asString();\n";
|
|
$$<<" struct tm stm;\n";
|
|
$$<<" memset(&stm,0,sizeof(stm));\n";
|
|
$$<<" auto p = strptime(timeStr.c_str(),\"%Y-%m-%d %H:%M:%S\",&stm);\n";
|
|
$$<<" time_t t = mktime(&stm);\n";
|
|
$$<<" size_t decimalNum = 0;\n";
|
|
$$<<" if(*p=='.')\n";
|
|
$$<<" {\n";
|
|
$$<<" std::string decimals(p+1,&timeStr[timeStr.length()]);\n";
|
|
$$<<" while(decimals.length()<6)\n";
|
|
$$<<" {\n";
|
|
$$<<" decimals += \"0\";\n";
|
|
$$<<" }\n";
|
|
$$<<" decimalNum = (size_t)atol(decimals.c_str());\n";
|
|
$$<<" }\n";
|
|
// $$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(::trantor::Date(946656000000000).after(daysNum*86400));\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(t*1000000+decimalNum);\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_=="bytea" || col.colDatabaseType_.find("blob") != std::string::npos)
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" auto str = pJson[pMasqueradingVector["<<i<<"]].asString();\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<std::vector<char>>(drogon::utils::base64DecodeToVector(str));\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_.find("uint") == 0 || col.colType_ == "unsigned short")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<"<<col.colType_<<">(("<<col.colType_<<")pJson[pMasqueradingVector["<<i<<"]].asUInt64());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_.find("int") == 0 || col.colType_ == "short")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<"<<col.colType_<<">(("<<col.colType_<<")pJson[pMasqueradingVector["<<i<<"]].asInt64());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_ == "float")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<float>(pJson[pMasqueradingVector["<<i<<"]].asFloat());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_ == "double")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<double>(pJson[pMasqueradingVector["<<i<<"]].asDouble());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_ == "bool")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<bool>(pJson[pMasqueradingVector["<<i<<"]].asBool());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
%>
|
|
}
|
|
<%c++
|
|
}
|
|
%>
|
|
}
|
|
|
|
[[className]]::[[className]](const Json::Value &pJson) noexcept(false)
|
|
{
|
|
<%c++
|
|
for(size_t i=0;i<cols.size();i++)
|
|
{
|
|
auto &col = cols[i];
|
|
if(col.colType_.empty())
|
|
continue;
|
|
%>
|
|
if(pJson.isMember("{%col.colName_%}"))
|
|
{
|
|
dirtyFlag_[{%i%}]=true;
|
|
<%c++
|
|
if(col.colType_ == "std::string")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<std::string>(pJson[\""<<col.colName_<<"\"].asString());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_=="date")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" auto daysStr = pJson[\""<<col.colName_<<"\"].asString();\n";
|
|
$$<<" struct tm stm;\n";
|
|
$$<<" memset(&stm,0,sizeof(stm));\n";
|
|
$$<<" strptime(daysStr.c_str(),\"%Y-%m-%d\",&stm);\n";
|
|
$$<<" time_t t = mktime(&stm);\n";
|
|
// $$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(::trantor::Date(946656000000000).after(daysNum*86400));\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(t*1000000);\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_.find("timestamp")!=std::string::npos||col.colDatabaseType_.find("datetime")!=std::string::npos)
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" auto timeStr = pJson[\""<<col.colName_<<"\"].asString();\n";
|
|
$$<<" struct tm stm;\n";
|
|
$$<<" memset(&stm,0,sizeof(stm));\n";
|
|
$$<<" auto p = strptime(timeStr.c_str(),\"%Y-%m-%d %H:%M:%S\",&stm);\n";
|
|
$$<<" time_t t = mktime(&stm);\n";
|
|
$$<<" size_t decimalNum = 0;\n";
|
|
$$<<" if(*p=='.')\n";
|
|
$$<<" {\n";
|
|
$$<<" std::string decimals(p+1,&timeStr[timeStr.length()]);\n";
|
|
$$<<" while(decimals.length()<6)\n";
|
|
$$<<" {\n";
|
|
$$<<" decimals += \"0\";\n";
|
|
$$<<" }\n";
|
|
$$<<" decimalNum = (size_t)atol(decimals.c_str());\n";
|
|
$$<<" }\n";
|
|
// $$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(::trantor::Date(946656000000000).after(daysNum*86400));\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(t*1000000+decimalNum);\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_=="bytea" || col.colDatabaseType_.find("blob") != std::string::npos)
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" auto str = pJson[\""<<col.colName_<<"\"].asString();\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<std::vector<char>>(drogon::utils::base64DecodeToVector(str));\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_.find("uint") == 0 || col.colType_ == "unsigned short")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<"<<col.colType_<<">(("<<col.colType_<<")pJson[\""<<col.colName_<<"\"].asUInt64());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_.find("int") == 0 || col.colType_ == "short")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<"<<col.colType_<<">(("<<col.colType_<<")pJson[\""<<col.colName_<<"\"].asInt64());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_ == "float")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<float>(pJson[\""<<col.colName_<<"\"].asFloat());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_ == "double")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<double>(pJson[\""<<col.colName_<<"\"].asDouble());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_ == "bool")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<bool>(pJson[\""<<col.colName_<<"\"].asBool());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
%>
|
|
}
|
|
<%c++
|
|
}
|
|
%>
|
|
}
|
|
|
|
void [[className]]::updateByMasqueradedJson(const Json::Value &pJson,
|
|
const std::vector<std::string> &pMasqueradingVector) noexcept(false)
|
|
{
|
|
if(pMasqueradingVector.size() != {%cols.size()%})
|
|
{
|
|
LOG_ERROR << "Bad masquerading vector";
|
|
return;
|
|
}
|
|
<%c++
|
|
for(size_t i=0;i<cols.size();i++)
|
|
{
|
|
auto &col = cols[i];
|
|
if(col.colType_.empty())
|
|
continue;
|
|
%>
|
|
if(!pMasqueradingVector[{%i%}].empty() && pJson.isMember(pMasqueradingVector[{%i%}]))
|
|
{
|
|
<%c++
|
|
if(!col.isAutoVal_ && !col.isPrimaryKey_)
|
|
{
|
|
$$<<" dirtyFlag_["<<i<<"] = true;\n";
|
|
}
|
|
if(col.colType_ == "std::string")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<std::string>(pJson[pMasqueradingVector["<<i<<"]].asString());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_=="date")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" auto daysStr = pJson[pMasqueradingVector["<<i<<"]].asString();\n";
|
|
$$<<" struct tm stm;\n";
|
|
$$<<" memset(&stm,0,sizeof(stm));\n";
|
|
$$<<" strptime(daysStr.c_str(),\"%Y-%m-%d\",&stm);\n";
|
|
$$<<" time_t t = mktime(&stm);\n";
|
|
// $$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(::trantor::Date(946656000000000).after(daysNum*86400));\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(t*1000000);\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_.find("timestamp")!=std::string::npos||col.colDatabaseType_.find("datetime")!=std::string::npos)
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" auto timeStr = pJson[pMasqueradingVector["<<i<<"]].asString();\n";
|
|
$$<<" struct tm stm;\n";
|
|
$$<<" memset(&stm,0,sizeof(stm));\n";
|
|
$$<<" auto p = strptime(timeStr.c_str(),\"%Y-%m-%d %H:%M:%S\",&stm);\n";
|
|
$$<<" time_t t = mktime(&stm);\n";
|
|
$$<<" size_t decimalNum = 0;\n";
|
|
$$<<" if(*p=='.')\n";
|
|
$$<<" {\n";
|
|
$$<<" std::string decimals(p+1,&timeStr[timeStr.length()]);\n";
|
|
$$<<" while(decimals.length()<6)\n";
|
|
$$<<" {\n";
|
|
$$<<" decimals += \"0\";\n";
|
|
$$<<" }\n";
|
|
$$<<" decimalNum = (size_t)atol(decimals.c_str());\n";
|
|
$$<<" }\n";
|
|
// $$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(::trantor::Date(946656000000000).after(daysNum*86400));\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(t*1000000+decimalNum);\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_=="bytea" || col.colDatabaseType_.find("blob") != std::string::npos)
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" auto str = pJson[pMasqueradingVector["<<i<<"]].asString();\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<std::vector<char>>(drogon::utils::base64DecodeToVector(str));\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_.find("uint") == 0 || col.colType_ == "unsigned short")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<"<<col.colType_<<">(("<<col.colType_<<")pJson[pMasqueradingVector["<<i<<"]].asUInt64());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_.find("int") == 0 || col.colType_ == "short")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<"<<col.colType_<<">(("<<col.colType_<<")pJson[pMasqueradingVector["<<i<<"]].asInt64());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_ == "float")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<float>(pJson[pMasqueradingVector["<<i<<"]].asFloat());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_ == "double")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<double>(pJson[pMasqueradingVector["<<i<<"]].asDouble());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_ == "bool")
|
|
{
|
|
$$<<" if(!pJson[pMasqueradingVector["<<i<<"]].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<bool>(pJson[pMasqueradingVector["<<i<<"]].asBool());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
%>
|
|
}
|
|
<%c++
|
|
}
|
|
%>
|
|
}
|
|
|
|
void [[className]]::updateByJson(const Json::Value &pJson) noexcept(false)
|
|
{
|
|
<%c++
|
|
for(size_t i=0;i<cols.size();i++)
|
|
{
|
|
auto &col = cols[i];
|
|
if(col.colType_.empty())
|
|
continue;
|
|
%>
|
|
if(pJson.isMember("{%col.colName_%}"))
|
|
{
|
|
<%c++
|
|
if(!col.isAutoVal_ && !col.isPrimaryKey_)
|
|
{
|
|
$$<<" dirtyFlag_["<<i<<"] = true;\n";
|
|
}
|
|
if(col.colType_ == "std::string")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<std::string>(pJson[\""<<col.colName_<<"\"].asString());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_=="date")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" auto daysStr = pJson[\""<<col.colName_<<"\"].asString();\n";
|
|
$$<<" struct tm stm;\n";
|
|
$$<<" memset(&stm,0,sizeof(stm));\n";
|
|
$$<<" strptime(daysStr.c_str(),\"%Y-%m-%d\",&stm);\n";
|
|
$$<<" time_t t = mktime(&stm);\n";
|
|
// $$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(::trantor::Date(946656000000000).after(daysNum*86400));\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(t*1000000);\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_.find("timestamp")!=std::string::npos||col.colDatabaseType_.find("datetime")!=std::string::npos)
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" auto timeStr = pJson[\""<<col.colName_<<"\"].asString();\n";
|
|
$$<<" struct tm stm;\n";
|
|
$$<<" memset(&stm,0,sizeof(stm));\n";
|
|
$$<<" auto p = strptime(timeStr.c_str(),\"%Y-%m-%d %H:%M:%S\",&stm);\n";
|
|
$$<<" time_t t = mktime(&stm);\n";
|
|
$$<<" size_t decimalNum = 0;\n";
|
|
$$<<" if(*p=='.')\n";
|
|
$$<<" {\n";
|
|
$$<<" std::string decimals(p+1,&timeStr[timeStr.length()]);\n";
|
|
$$<<" while(decimals.length()<6)\n";
|
|
$$<<" {\n";
|
|
$$<<" decimals += \"0\";\n";
|
|
$$<<" }\n";
|
|
$$<<" decimalNum = (size_t)atol(decimals.c_str());\n";
|
|
$$<<" }\n";
|
|
// $$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(::trantor::Date(946656000000000).after(daysNum*86400));\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<::trantor::Date>(t*1000000+decimalNum);\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colDatabaseType_=="bytea" || col.colDatabaseType_.find("blob") != std::string::npos)
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" auto str = pJson[\""<<col.colName_<<"\"].asString();\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<std::vector<char>>(drogon::utils::base64DecodeToVector(str));\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_.find("uint") == 0 || col.colType_ == "unsigned short")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<"<<col.colType_<<">(("<<col.colType_<<")pJson[\""<<col.colName_<<"\"].asUInt64());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_.find("int") == 0 || col.colType_ == "short")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<"<<col.colType_<<">(("<<col.colType_<<")pJson[\""<<col.colName_<<"\"].asInt64());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_ == "float")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<float>(pJson[\""<<col.colName_<<"\"].asFloat());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_ == "double")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<double>(pJson[\""<<col.colName_<<"\"].asDouble());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
else if(col.colType_ == "bool")
|
|
{
|
|
$$<<" if(!pJson[\""<<col.colName_<<"\"].isNull())\n";
|
|
$$<<" {\n";
|
|
$$<<" "<<col.colValName_<<"_=std::make_shared<bool>(pJson[\""<<col.colName_<<"\"].asBool());\n";
|
|
$$<<" }\n";
|
|
$$<<" }\n";
|
|
continue;
|
|
}
|
|
%>
|
|
}
|
|
<%c++
|
|
}
|
|
%>
|
|
}
|
|
|
|
<%c++
|
|
for(size_t i=0;i<cols.size();i++)
|
|
{
|
|
auto &col = cols[i];
|
|
if(!col.colType_.empty())
|
|
{
|
|
$$<<"const "<<col.colType_<<" &"<<className<<"::getValueOf"<<col.colTypeName_<<"() const noexcept\n";
|
|
$$<<"{\n";
|
|
$$<<" const static "<<col.colType_<<" defaultValue = "<<col.colType_<<"();\n";
|
|
$$<<" if("<<col.colValName_<<"_)\n";
|
|
$$<<" return *"<<col.colValName_<<"_;\n";
|
|
$$<<" return defaultValue;\n";
|
|
$$<<"}\n";
|
|
if(col.colType_=="std::vector<char>")
|
|
{
|
|
$$<<"std::string "<<className<<"::getValueOf"<<col.colTypeName_<<"AsString() const noexcept\n";
|
|
$$<<"{\n";
|
|
$$<<" const static std::string defaultValue = std::string();\n";
|
|
$$<<" if("<<col.colValName_<<"_)\n";
|
|
$$<<" return std::string("<<col.colValName_<<"_->data(),"<<col.colValName_<<"_->size());\n";
|
|
$$<<" return defaultValue;\n";
|
|
$$<<"}\n";
|
|
}
|
|
$$<<"const std::shared_ptr<"<<col.colType_<<"> &"<<className<<"::get"<<col.colTypeName_<<"() const noexcept\n";
|
|
$$<<"{\n";
|
|
$$<<" return "<<col.colValName_<<"_;\n";
|
|
$$<<"}\n";
|
|
|
|
$$<<"void "<<className<<"::set"<<col.colTypeName_<<"(const "<<col.colType_<<" &p"<<col.colTypeName_<<") noexcept\n";
|
|
$$<<"{\n";
|
|
if(col.colDatabaseType_=="date")
|
|
{
|
|
$$<<" "<<col.colValName_<<"_ = std::make_shared<"<<col.colType_<<">(p"<<col.colTypeName_<<".roundDay());\n";
|
|
}
|
|
else
|
|
{
|
|
$$<<" "<<col.colValName_<<"_ = std::make_shared<"<<col.colType_<<">(p"<<col.colTypeName_<<");\n";
|
|
}
|
|
$$<<" dirtyFlag_["<<i<<"] = true;\n";
|
|
$$<<"}\n";
|
|
|
|
if(col.colType_=="std::string")
|
|
{
|
|
$$<<"void "<<className<<"::set"<<col.colTypeName_<<"("<<col.colType_<<" &&p"<<col.colTypeName_<<") noexcept\n";
|
|
$$<<"{\n";
|
|
$$<<" "<<col.colValName_<<"_ = std::make_shared<"<<col.colType_<<">(std::move(p"<<col.colTypeName_<<"));\n";
|
|
$$<<" dirtyFlag_["<<i<<"] = true;\n";
|
|
$$<<"}\n";
|
|
}
|
|
|
|
if(col.colType_=="std::vector<char>")
|
|
{
|
|
$$<<"void "<<className<<"::set"<<col.colTypeName_<<"(const std::string &p"<<col.colTypeName_<<") noexcept\n";
|
|
$$<<"{\n";
|
|
$$<<" "<<col.colValName_<<"_ = std::make_shared<std::vector<char>>(p"<<col.colTypeName_<<".c_str(),p"<<col.colTypeName_<<".c_str()+p"<<col.colTypeName_<<".length());\n";
|
|
$$<<" dirtyFlag_["<<i<<"] = true;\n";
|
|
$$<<"}\n";
|
|
}
|
|
|
|
if(!col.notNull_)
|
|
{
|
|
$$<<"void "<<className<<"::set"<<col.colTypeName_<<"ToNull() noexcept\n";
|
|
$$<<"{\n";
|
|
$$<<" "<<col.colValName_<<"_.reset();\n";
|
|
$$<<" dirtyFlag_["<<i<<"] = true;\n";
|
|
$$<<"}\n";
|
|
}
|
|
|
|
if(col.isPrimaryKey_&&@@.get<int>("hasPrimaryKey")==1)
|
|
{
|
|
$$<<"const typename "<<className<<"::PrimaryKeyType & "<<className<<"::getPrimaryKey() const\n";
|
|
$$<<"{\n";
|
|
$$<<" assert("<<col.colValName_<<"_);\n";
|
|
$$<<" return *"<<col.colValName_<<"_;\n";
|
|
$$<<"}\n";
|
|
}
|
|
}
|
|
$$<<"\n";
|
|
}
|
|
if(@@.get<std::string>("rdbms")=="postgresql"||@@.get<int>("hasPrimaryKey")!=1)
|
|
{
|
|
$$<<"void "<<className<<"::updateId(const uint64_t id)\n";
|
|
$$<<"{\n";
|
|
$$<<"}\n";
|
|
}
|
|
else if(@@.get<std::string>("rdbms")=="mysql"||@@.get<std::string>("rdbms")=="sqlite3")
|
|
{
|
|
auto primaryKeyTypeString=@@.get<std::string>("primaryKeyType");
|
|
$$<<"void "<<className<<"::updateId(const uint64_t id)\n";
|
|
$$<<"{\n";
|
|
for(auto col:cols)
|
|
{
|
|
if(col.isAutoVal_)
|
|
{
|
|
if(primaryKeyTypeString!="uint64_t")
|
|
{
|
|
$$<<" "<<col.colValName_<<"_ = std::make_shared<"<<primaryKeyTypeString<<">(static_cast<"<<primaryKeyTypeString<<">(id));\n";
|
|
}
|
|
else
|
|
{
|
|
$$<<" "<<col.colValName_<<"_ = std::make_shared<uint64_t>(id);\n";
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
$$<<"}\n";
|
|
}
|
|
if(@@.get<int>("hasPrimaryKey")>1)
|
|
{
|
|
$$<<"typename "<<className<<"::PrimaryKeyType "<<className<<"::getPrimaryKey() const\n";
|
|
$$<<"{\n";
|
|
$$<<" return std::make_tuple(";
|
|
int count=0;
|
|
auto pkNames=@@.get<std::vector<std::string>>("primaryKeyValNames");
|
|
for(auto pkName:pkNames)
|
|
{
|
|
++count;
|
|
$$<<"*"<<pkName<<"_";
|
|
if(count<@@.get<int>("hasPrimaryKey"))
|
|
$$<<",";
|
|
}
|
|
$$<<");\n";
|
|
$$<<"}\n";
|
|
}
|
|
%>
|
|
|
|
const std::vector<std::string> &[[className]]::insertColumns() noexcept
|
|
{
|
|
static const std::vector<std::string> inCols={
|
|
<%c++for(size_t i=0;i<cols.size();i++){
|
|
auto col=cols[i];
|
|
if(!col.isAutoVal_&&!col.colType_.empty())
|
|
{
|
|
$$<<" \""<<col.colName_<<"\"";
|
|
if(i<(cols.size()-1))
|
|
$$<<",\n";
|
|
else
|
|
$$<<"\n";
|
|
}
|
|
}%>
|
|
};
|
|
return inCols;
|
|
}
|
|
|
|
void [[className]]::outputArgs(drogon::orm::internal::SqlBinder &binder) const
|
|
{
|
|
<%c++for(size_t i = 0; i < cols.size(); ++i){
|
|
auto &col = cols[i];
|
|
if(!col.isAutoVal_&&!col.colType_.empty())
|
|
{
|
|
%>
|
|
if(dirtyFlag_[{%i%}])
|
|
{
|
|
if(get{%col.colTypeName_%}())
|
|
{
|
|
binder << getValueOf{%col.colTypeName_%}();
|
|
}
|
|
else
|
|
{
|
|
binder << nullptr;
|
|
}
|
|
}
|
|
<%c++
|
|
}
|
|
}
|
|
%>
|
|
}
|
|
|
|
const std::vector<std::string> [[className]]::updateColumns() const
|
|
{
|
|
std::vector<std::string> ret;
|
|
<%c++
|
|
for(size_t i=0;i<cols.size();i++)
|
|
{
|
|
auto & col=cols[i];
|
|
if(col.colType_.empty()||col.isAutoVal_)
|
|
continue;
|
|
%>
|
|
if(dirtyFlag_[{%i%}])
|
|
{
|
|
ret.push_back(getColumnName({%i%}));
|
|
}
|
|
<%c++
|
|
}
|
|
%>
|
|
return ret;
|
|
}
|
|
|
|
void [[className]]::updateArgs(drogon::orm::internal::SqlBinder &binder) const
|
|
{
|
|
<%c++
|
|
for(size_t i=0;i<cols.size();i++)
|
|
{
|
|
auto & col=cols[i];
|
|
if(col.colType_.empty()||col.isAutoVal_)
|
|
continue;
|
|
%>
|
|
if(dirtyFlag_[{%i%}])
|
|
{
|
|
if(get{%col.colTypeName_%}())
|
|
{
|
|
binder << getValueOf{%col.colTypeName_%}();
|
|
}
|
|
else
|
|
{
|
|
binder << nullptr;
|
|
}
|
|
}
|
|
<%c++
|
|
}
|
|
%>
|
|
}
|
|
Json::Value [[className]]::toJson() const
|
|
{
|
|
Json::Value ret;
|
|
<%c++for(auto col:cols){%>
|
|
if(get{%col.colTypeName_%}())
|
|
{
|
|
<%c++if(col.colDatabaseType_=="date"){%>
|
|
ret["{%col.colName_%}"]=get{%col.colTypeName_%}()->toDbStringLocal();
|
|
<%c++}else if(col.colDatabaseType_.find("timestamp")!=std::string::npos||col.colDatabaseType_.find("datetime")!=std::string::npos){%>
|
|
ret["{%col.colName_%}"]=get{%col.colTypeName_%}()->toDbStringLocal();
|
|
<%c++}else if(col.colDatabaseType_=="bytea"||col.colDatabaseType_.find("blob")!=std::string::npos){%>
|
|
ret["{%col.colName_%}"]=drogon::utils::base64Encode((const unsigned char *)get{%col.colTypeName_%}()->data(),get{%col.colTypeName_%}()->size());
|
|
<%c++}else if(col.colType_=="int64_t"){%>
|
|
ret["{%col.colName_%}"]=(Json::Int64)getValueOf{%col.colTypeName_%}();
|
|
<%c++}else if(col.colType_=="uint64_t"){%>
|
|
ret["{%col.colName_%}"]=(Json::UInt64)getValueOf{%col.colTypeName_%}();
|
|
<%c++}else{%>
|
|
ret["{%col.colName_%}"]=getValueOf{%col.colTypeName_%}();
|
|
<%c++}%>
|
|
}
|
|
else
|
|
{
|
|
ret["{%col.colName_%}"]=Json::Value();
|
|
}
|
|
<%c++
|
|
}%>
|
|
return ret;
|
|
}
|
|
|
|
Json::Value [[className]]::toMasqueradedJson(
|
|
const std::vector<std::string> &pMasqueradingVector) const
|
|
{
|
|
Json::Value ret;
|
|
if(pMasqueradingVector.size() == {%cols.size()%})
|
|
{
|
|
<%c++for(size_t i = 0; i < cols.size(); ++i){
|
|
auto &col = cols[i];
|
|
%>
|
|
if(!pMasqueradingVector[{%i%}].empty())
|
|
{
|
|
if(get{%col.colTypeName_%}())
|
|
{
|
|
<%c++if(col.colDatabaseType_=="date"){%>
|
|
ret[pMasqueradingVector[{%i%}]]=get{%col.colTypeName_%}()->toDbStringLocal();
|
|
<%c++}else if(col.colDatabaseType_.find("timestamp")!=std::string::npos||col.colDatabaseType_.find("datetime")!=std::string::npos){%>
|
|
ret[pMasqueradingVector[{%i%}]]=get{%col.colTypeName_%}()->toDbStringLocal();
|
|
<%c++}else if(col.colDatabaseType_=="bytea"||col.colDatabaseType_.find("blob")!=std::string::npos){%>
|
|
ret[pMasqueradingVector[{%i%}]]=drogon::utils::base64Encode((const unsigned char *)get{%col.colTypeName_%}()->data(),get{%col.colTypeName_%}()->size());
|
|
<%c++}else if(col.colType_=="int64_t"){%>
|
|
ret[pMasqueradingVector[{%i%}]]=(Json::Int64)getValueOf{%col.colTypeName_%}();
|
|
<%c++}else if(col.colType_=="uint64_t"){%>
|
|
ret[pMasqueradingVector[{%i%}]]=(Json::UInt64)getValueOf{%col.colTypeName_%}();
|
|
<%c++}else{%>
|
|
ret[pMasqueradingVector[{%i%}]]=getValueOf{%col.colTypeName_%}();
|
|
<%c++}%>
|
|
}
|
|
else
|
|
{
|
|
ret[pMasqueradingVector[{%i%}]]=Json::Value();
|
|
}
|
|
}
|
|
<%c++
|
|
}%>
|
|
return ret;
|
|
}
|
|
LOG_ERROR << "Masquerade failed";
|
|
<%c++for(auto col:cols){%>
|
|
if(get{%col.colTypeName_%}())
|
|
{
|
|
<%c++if(col.colDatabaseType_=="date"){%>
|
|
ret["{%col.colName_%}"]=get{%col.colTypeName_%}()->toDbStringLocal();
|
|
<%c++}else if(col.colDatabaseType_.find("timestamp")!=std::string::npos||col.colDatabaseType_.find("datetime")!=std::string::npos){%>
|
|
ret["{%col.colName_%}"]=get{%col.colTypeName_%}()->toDbStringLocal();
|
|
<%c++}else if(col.colDatabaseType_=="bytea"||col.colDatabaseType_.find("blob")!=std::string::npos){%>
|
|
ret["{%col.colName_%}"]=drogon::utils::base64Encode((const unsigned char *)get{%col.colTypeName_%}()->data(),get{%col.colTypeName_%}()->size());
|
|
<%c++}else if(col.colType_=="int64_t"){%>
|
|
ret["{%col.colName_%}"]=(Json::Int64)getValueOf{%col.colTypeName_%}();
|
|
<%c++}else if(col.colType_=="uint64_t"){%>
|
|
ret["{%col.colName_%}"]=(Json::UInt64)getValueOf{%col.colTypeName_%}();
|
|
<%c++}else{%>
|
|
ret["{%col.colName_%}"]=getValueOf{%col.colTypeName_%}();
|
|
<%c++}%>
|
|
}
|
|
else
|
|
{
|
|
ret["{%col.colName_%}"]=Json::Value();
|
|
}
|
|
<%c++
|
|
}%>
|
|
return ret;
|
|
}
|
|
|
|
bool [[className]]::validateJsonForCreation(const Json::Value &pJson, std::string &err)
|
|
{
|
|
<%c++
|
|
for(size_t i=0;i<cols.size();i++)
|
|
{
|
|
auto &col = cols[i];
|
|
if(col.colType_.empty())
|
|
continue;
|
|
%>
|
|
if(pJson.isMember("{%col.colName_%}"))
|
|
{
|
|
if(!validJsonOfField({%i%}, "{%col.colName_%}", pJson["{%col.colName_%}"], err, true))
|
|
return false;
|
|
}
|
|
<%c++if(col.notNull_ && !col.isAutoVal_ && !col.hasDefaultVal_){%>
|
|
else
|
|
{
|
|
err="The {%col.colName_%} column cannot be null";
|
|
return false;
|
|
}
|
|
<%c++}
|
|
}%>
|
|
return true;
|
|
}
|
|
bool [[className]]::validateMasqueradedJsonForCreation(const Json::Value &pJson,
|
|
{%indentStr%} const std::vector<std::string> &pMasqueradingVector,
|
|
{%indentStr%} std::string &err)
|
|
{
|
|
if(pMasqueradingVector.size() != {%cols.size()%})
|
|
{
|
|
err = "Bad masquerading vector";
|
|
return false;
|
|
}
|
|
<%c++
|
|
for(size_t i=0;i<cols.size();i++)
|
|
{
|
|
auto &col = cols[i];
|
|
if(col.colType_.empty())
|
|
continue;
|
|
%>
|
|
if(!pMasqueradingVector[{%i%}].empty())
|
|
{
|
|
if(pJson.isMember(pMasqueradingVector[{%i%}]))
|
|
{
|
|
if(!validJsonOfField({%i%}, pMasqueradingVector[{%i%}], pJson[pMasqueradingVector[{%i%}]], err, true))
|
|
return false;
|
|
}
|
|
<%c++if(col.notNull_ && !col.isAutoVal_ && !col.hasDefaultVal_){%>
|
|
else
|
|
{
|
|
err="The " + pMasqueradingVector[{%i%}] + " column cannot be null";
|
|
return false;
|
|
}
|
|
<%c++}%>
|
|
}
|
|
<%c++}%>
|
|
return true;
|
|
}
|
|
bool [[className]]::validateJsonForUpdate(const Json::Value &pJson, std::string &err)
|
|
{
|
|
<%c++
|
|
for(size_t i=0;i<cols.size();i++)
|
|
{
|
|
auto &col = cols[i];
|
|
if(col.colType_.empty())
|
|
continue;
|
|
%>
|
|
if(pJson.isMember("{%col.colName_%}"))
|
|
{
|
|
if(!validJsonOfField({%i%}, "{%col.colName_%}", pJson["{%col.colName_%}"], err, false))
|
|
return false;
|
|
}
|
|
<%c++
|
|
if(col.isPrimaryKey_)
|
|
{
|
|
%>
|
|
else
|
|
{
|
|
err = "The value of primary key must be set in the json object for update";
|
|
return false;
|
|
}
|
|
<%c++
|
|
}
|
|
}%>
|
|
return true;
|
|
}
|
|
bool [[className]]::validateMasqueradedJsonForUpdate(const Json::Value &pJson,
|
|
{%indentStr%} const std::vector<std::string> &pMasqueradingVector,
|
|
{%indentStr%} std::string &err)
|
|
{
|
|
if(pMasqueradingVector.size() != {%cols.size()%})
|
|
{
|
|
err = "Bad masquerading vector";
|
|
return false;
|
|
}
|
|
<%c++
|
|
for(size_t i=0;i<cols.size();i++)
|
|
{
|
|
auto &col = cols[i];
|
|
if(col.colType_.empty())
|
|
continue;
|
|
%>
|
|
if(!pMasqueradingVector[{%i%}].empty() && pJson.isMember(pMasqueradingVector[{%i%}]))
|
|
{
|
|
if(!validJsonOfField({%i%}, pMasqueradingVector[{%i%}], pJson[pMasqueradingVector[{%i%}]], err, false))
|
|
return false;
|
|
}
|
|
<%c++
|
|
if(col.isPrimaryKey_)
|
|
{
|
|
%>
|
|
else
|
|
{
|
|
err = "The value of primary key must be set in the json object for update";
|
|
return false;
|
|
}
|
|
<%c++
|
|
}
|
|
}%>
|
|
return true;
|
|
}
|
|
bool [[className]]::validJsonOfField(size_t index,
|
|
{%indentStr%} const std::string &fieldName,
|
|
{%indentStr%} const Json::Value &pJson,
|
|
{%indentStr%} std::string &err,
|
|
{%indentStr%} bool isForCreation)
|
|
{
|
|
switch(index)
|
|
{
|
|
<%c++
|
|
for(size_t i=0;i<cols.size();i++)
|
|
{
|
|
auto &col = cols[i];
|
|
if(col.colType_.empty())
|
|
continue;
|
|
%>
|
|
case {%i%}:
|
|
<%c++if(col.notNull_){%>
|
|
if(pJson.isNull())
|
|
{
|
|
err="The " + fieldName + " column cannot be null";
|
|
return false;
|
|
}
|
|
<%c++}
|
|
if(col.isAutoVal_)
|
|
{
|
|
if(col.isPrimaryKey_)
|
|
{
|
|
%>
|
|
if(isForCreation)
|
|
{
|
|
err="The automatic primary key cannot be set";
|
|
return false;
|
|
}
|
|
<%c++
|
|
}else
|
|
{
|
|
%>
|
|
if(isForCreation)
|
|
{
|
|
err="The automatic primary key cannot be set";
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
err="The automatic primary key cannot be update";
|
|
return false;
|
|
}
|
|
<%c++
|
|
}
|
|
}
|
|
if(!col.notNull_){%>
|
|
if(pJson.isNull())
|
|
{
|
|
return true;
|
|
}
|
|
<%c++}
|
|
if(col.colType_ == "uint64_t")
|
|
{
|
|
%>
|
|
if(!pJson.isUInt64())
|
|
{
|
|
err="Type error in the "+fieldName+" field";
|
|
return false;
|
|
}
|
|
<%c++
|
|
}
|
|
else if(col.colType_ == "int64_t")
|
|
{
|
|
%>
|
|
if(!pJson.isInt64())
|
|
{
|
|
err="Type error in the "+fieldName+" field";
|
|
return false;
|
|
}
|
|
<%c++
|
|
}
|
|
else if(col.colType_.find("uint") == 0)
|
|
{
|
|
%>
|
|
if(!pJson.isUInt())
|
|
{
|
|
err="Type error in the "+fieldName+" field";
|
|
return false;
|
|
}
|
|
<%c++
|
|
}
|
|
else if(col.colType_.find("int") == 0)
|
|
{
|
|
%>
|
|
if(!pJson.isInt())
|
|
{
|
|
err="Type error in the "+fieldName+" field";
|
|
return false;
|
|
}
|
|
<%c++
|
|
}
|
|
else if(col.colType_ == "float" || col.colType_ == "double")
|
|
{
|
|
%>
|
|
if(!pJson.isNumeric())
|
|
{
|
|
err="Type error in the "+fieldName+" field";
|
|
return false;
|
|
}
|
|
<%c++
|
|
}
|
|
else if(col.colType_ == "bool")
|
|
{
|
|
%>
|
|
if(!pJson.isBool())
|
|
{
|
|
err="Type error in the "+fieldName+" field";
|
|
return false;
|
|
}
|
|
<%c++
|
|
}
|
|
else
|
|
{
|
|
%>
|
|
if(!pJson.isString())
|
|
{
|
|
err="Type error in the "+fieldName+" field";
|
|
return false;
|
|
}
|
|
<%c++
|
|
if(col.colType_ == "std::string" && col.colLength_>0)
|
|
{
|
|
%>
|
|
// asString().length() creates a string object, is there any better way to validate the length?
|
|
if(pJson.isString() && pJson.asString().length() > {%col.colLength_%})
|
|
{
|
|
err="String length exceeds limit for the " +
|
|
fieldName +
|
|
" field (the maximum value is {%col.colLength_%})";
|
|
return false;
|
|
}
|
|
|
|
<%c++
|
|
}
|
|
}
|
|
%>
|
|
break;
|
|
<%c++
|
|
}%>
|
|
default:
|
|
err="Internal error in the server";
|
|
return false;
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
<%c++
|
|
for(auto &relationship : relationships)
|
|
{
|
|
if(relationship.targetKey().empty() || relationship.originalKey().empty())
|
|
{
|
|
continue;
|
|
}
|
|
auto &name=relationship.targetTableName();
|
|
auto relationshipClassName=nameTransform(name, true);
|
|
auto relationshipValName=nameTransform(name, false);
|
|
auto alias=relationship.targetTableAlias();
|
|
auto aliasValName=nameTransform(alias, false);
|
|
if(relationship.type() == Relationship::Type::HasOne)
|
|
{
|
|
if(!alias.empty())
|
|
{
|
|
if(alias[0] <= 'z' && alias[0] >= 'a')
|
|
{
|
|
alias[0] += ('A' - 'a');
|
|
}
|
|
std::string alind(alias.length(), ' ');
|
|
%>
|
|
void [[className]]::get{%alias%}(const DbClientPtr &clientPtr,
|
|
{%indentStr%} {%alind%} const std::function<void({%relationshipClassName%})> &rcb,
|
|
{%indentStr%} {%alind%} const ExceptionCallback &ecb) const
|
|
<%c++
|
|
}
|
|
else
|
|
{
|
|
std::string relationshipClassInde(relationshipClassName.length(), ' ');
|
|
%>
|
|
void [[className]]::get{%relationshipClassName%}(const DbClientPtr &clientPtr,
|
|
{%indentStr%} {%relationshipClassInde%} const std::function<void({%relationshipClassName%})> &rcb,
|
|
{%indentStr%} {%relationshipClassInde%} const ExceptionCallback &ecb) const
|
|
<%c++
|
|
}
|
|
%>
|
|
{
|
|
const static std::string sql = "select * from {%name%} where {%relationship.targetKey()%} = <%c++
|
|
if(rdbms=="postgresql")
|
|
{
|
|
$$<<"$1";
|
|
}
|
|
else
|
|
{
|
|
$$<<"?";
|
|
}%>";
|
|
*clientPtr << sql
|
|
<< *{%nameTransform(relationship.originalKey(), false)%}_
|
|
>> [rcb = std::move(rcb), ecb](const Result &r){
|
|
if (r.size() == 0)
|
|
{
|
|
ecb(UnexpectedRows("0 rows found"));
|
|
}
|
|
else if (r.size() > 1)
|
|
{
|
|
ecb(UnexpectedRows("Found more than one row"));
|
|
}
|
|
else
|
|
{
|
|
rcb({%relationshipClassName%}(r[0]));
|
|
}
|
|
}
|
|
>> ecb;
|
|
}
|
|
<%c++
|
|
}
|
|
else if(relationship.type() == Relationship::Type::HasMany)
|
|
{
|
|
if(!alias.empty())
|
|
{
|
|
if(alias[0] <= 'z' && alias[0] >= 'a')
|
|
{
|
|
alias[0] += ('A' - 'a');
|
|
}
|
|
std::string alind(alias.length(), ' ');
|
|
%>
|
|
void [[className]]::get{%alias%}(const DbClientPtr &clientPtr,
|
|
{%indentStr%} {%alind%} const std::function<void(std::vector<{%relationshipClassName%}>)> &rcb,
|
|
{%indentStr%} {%alind%} const ExceptionCallback &ecb) const
|
|
<%c++
|
|
}
|
|
else
|
|
{
|
|
std::string relationshipClassInde(relationshipClassName.length(), ' ');
|
|
%>
|
|
void [[className]]::get{%relationshipClassName%}(const DbClientPtr &clientPtr,
|
|
{%indentStr%} {%relationshipClassInde%} const std::function<void(std::vector<{%relationshipClassName%}>)> &rcb,
|
|
{%indentStr%} {%relationshipClassInde%} const ExceptionCallback &ecb) const
|
|
<%c++
|
|
}
|
|
%>
|
|
{
|
|
const static std::string sql = "select * from {%name%} where {%relationship.targetKey()%} = <%c++
|
|
if(rdbms=="postgresql")
|
|
{
|
|
$$<<"$1";
|
|
}
|
|
else
|
|
{
|
|
$$<<"?";
|
|
}%>";
|
|
*clientPtr << sql
|
|
<< *{%nameTransform(relationship.originalKey(), false)%}_
|
|
>> [rcb = std::move(rcb)](const Result &r){
|
|
std::vector<{%relationshipClassName%}> ret;
|
|
ret.reserve(ret.size());
|
|
for (auto const &row : r)
|
|
{
|
|
ret.emplace_back({%relationshipClassName%}(row));
|
|
}
|
|
rcb(ret);
|
|
}
|
|
>> ecb;
|
|
}
|
|
<%c++
|
|
}
|
|
else if(relationship.type() == Relationship::Type::ManyToMany)
|
|
{
|
|
auto &pivotTableName=relationship.pivotTable().tableName();
|
|
auto pivotTableClassName=nameTransform(pivotTableName, true);
|
|
auto &pivotOriginalKey=relationship.pivotTable().originalKey();
|
|
auto &pivotTargetKey=relationship.pivotTable().targetKey();
|
|
if(!alias.empty())
|
|
{
|
|
if(alias[0] <= 'z' && alias[0] >= 'a')
|
|
{
|
|
alias[0] += ('A' - 'a');
|
|
}
|
|
std::string alind(alias.length(), ' ');
|
|
%>
|
|
void [[className]]::get{%alias%}(const DbClientPtr &clientPtr,
|
|
{%indentStr%} {%alind%} const std::function<void(std::vector<std::pair<{%relationshipClassName%},{%pivotTableClassName%}>>)> &rcb,
|
|
{%indentStr%} {%alind%} const ExceptionCallback &ecb) const
|
|
<%c++
|
|
}
|
|
else
|
|
{
|
|
std::string relationshipClassInde(relationshipClassName.length(), ' ');
|
|
%>
|
|
void [[className]]::get{%relationshipClassName%}(const DbClientPtr &clientPtr,
|
|
{%indentStr%} {%relationshipClassInde%} const std::function<void(std::vector<std::pair<{%relationshipClassName%},{%pivotTableClassName%}>>)> &rcb,
|
|
{%indentStr%} {%relationshipClassInde%} const ExceptionCallback &ecb) const
|
|
<%c++
|
|
}
|
|
%>
|
|
{
|
|
const static std::string sql = "select * from {%name%},{%pivotTableName%} where {%pivotTableName%}.{%pivotOriginalKey%} = <%c++
|
|
if(rdbms=="postgresql")
|
|
{
|
|
$$<<"$1";
|
|
}
|
|
else
|
|
{
|
|
$$<<"?";
|
|
}%> and {%pivotTableName%}.{%pivotTargetKey%} = {%name%}.{%relationship.targetKey()%}";
|
|
*clientPtr << sql
|
|
<< *{%nameTransform(relationship.originalKey(), false)%}_
|
|
>> [rcb = std::move(rcb)](const Result &r){
|
|
std::vector<std::pair<{%relationshipClassName%},{%pivotTableClassName%}>> ret;
|
|
ret.reserve(ret.size());
|
|
for (auto const &row : r)
|
|
{
|
|
ret.emplace_back(std::pair<{%relationshipClassName%},{%pivotTableClassName%}>(
|
|
{%relationshipClassName%}(row),{%pivotTableClassName%}(row,{%relationshipClassName%}::getColumnNumber())));
|
|
}
|
|
rcb(ret);
|
|
}
|
|
>> ecb;
|
|
}
|
|
<%c++
|
|
}
|
|
}
|
|
%>
|