drogon/drogon_ctl/templates/model_h.csp

548 lines
16 KiB
Plaintext
Raw Normal View History

2018-11-27 17:37:41 +08:00
<%inc#include "create_model.h"
using namespace drogon_ctl;
%>
/**
*
* [[className]].h
2018-11-27 17:37:41 +08:00
* DO NOT EDIT. This file is generated by drogon_ctl
*
*/
2018-11-27 17:37:41 +08:00
#pragma once
#include <drogon/orm/Result.h>
#include <drogon/orm/Row.h>
#include <drogon/orm/Field.h>
2018-11-01 15:40:24 +08:00
#include <drogon/orm/SqlBinder.h>
2018-11-23 10:31:45 +08:00
#include <drogon/orm/Mapper.h>
2018-11-05 16:00:49 +08:00
#include <trantor/utils/Date.h>
#include <trantor/utils/Logger.h>
#include <json/json.h>
#include <string>
#include <memory>
2018-11-01 15:40:24 +08:00
#include <vector>
2018-11-07 18:46:16 +08:00
#include <tuple>
2018-10-31 19:07:37 +08:00
#include <stdint.h>
2018-11-07 18:46:16 +08:00
#include <iostream>
using namespace drogon::orm;
2019-10-26 23:44:31 +08:00
namespace drogon
{
namespace orm
{
class DbClient;
2019-11-21 11:27:47 +08:00
using DbClientPtr = std::shared_ptr<DbClient>;
2019-10-26 23:44:31 +08:00
}
}
namespace drogon_model
{
namespace [[dbName]]
{
<%c++
auto &schema=@@.get<std::string>("schema");
if(!schema.empty())
{
$$<<"namespace "<<schema<<"\n";
$$<<"{\n";
}
2019-10-26 23:44:31 +08:00
auto &relationships=@@.get<std::vector<Relationship>>("relationships");
for(auto &relationship : relationships)
{
auto &name=relationship.targetTableName();
auto relationshipClassName=nameTransform(name, true);
%>
2019-10-26 23:44:31 +08:00
class {%relationshipClassName%};
<%c++
if(relationship.type() == Relationship::Type::ManyToMany)
{
auto &pivotTableName=relationship.pivotTable().tableName();
auto pivotTableClassName=nameTransform(pivotTableName, true);
%>
class {%pivotTableClassName%};
<%c++
}
}
%>
class [[className]]
{
2018-10-31 17:32:46 +08:00
public:
2018-11-01 17:58:32 +08:00
struct Cols
2018-11-01 15:40:24 +08:00
{
<%c++
auto cols=@@.get<std::vector<ColumnInfo>>("columns");
2018-11-01 22:14:53 +08:00
for(size_t i=0;i<cols.size();i++)
2018-11-01 15:40:24 +08:00
{
2019-11-21 11:27:47 +08:00
$$<<" static const std::string _"<<cols[i].colName_<<";\n";
2018-11-01 15:40:24 +08:00
}
%>
};
2018-11-01 17:58:32 +08:00
2018-11-07 18:46:16 +08:00
const static int primaryKeyNumber;
const static std::string tableName;
2018-11-07 18:46:16 +08:00
const static bool hasPrimaryKey;
<%c++if(@@.get<int>("hasPrimaryKey")<=1){%>
const static std::string primaryKeyName;
2018-10-31 19:07:37 +08:00
<%c++if(!@@.get<std::string>("primaryKeyType").empty()){%>
2019-11-21 11:27:47 +08:00
using PrimaryKeyType = [[primaryKeyType]];
2019-08-17 20:05:32 +08:00
const PrimaryKeyType &getPrimaryKey() const;
2018-10-31 19:07:37 +08:00
<%c++}else{%>
2019-11-21 11:27:47 +08:00
using PrimaryKeyType = void;
int getPrimaryKey() const { assert(false); return 0; }
2018-11-07 18:46:16 +08:00
<%c++}%>
<%c++}else{
auto pkTypes=@@.get<std::vector<std::string>>("primaryKeyType");
std::string typelist;
for(size_t i=0;i<pkTypes.size();i++)
{
typelist += pkTypes[i];
if(i<(pkTypes.size()-1))
typelist += ",";
}
%>
const static std::vector<std::string> primaryKeyName;
2019-11-21 11:27:47 +08:00
using PrimaryKeyType = std::tuple<{%typelist%}>;//<%c++
2018-11-08 11:20:07 +08:00
auto pkName=@@.get<std::vector<std::string>>("primaryKeyName");
2018-11-09 15:55:20 +08:00
for(size_t i=0;i<pkName.size();i++)
2018-11-08 11:20:07 +08:00
{
$$<<pkName[i];
if(i<(pkName.size()-1))
$$<<",";
}
%>
2018-11-07 18:46:16 +08:00
PrimaryKeyType getPrimaryKey() const;
2018-10-31 19:07:37 +08:00
<%c++}%>
/**
* @brief constructor
* @param r One row of records in the SQL query result.
* @param indexOffset Set the offset to -1 to access all columns by column names,
* otherwise access all columns by offsets.
* @note If the SQL is not a style of 'select * from table_name ...' (select all
* columns by an asterisk), please set the offset to -1.
*/
explicit [[className]](const Row &r, const ssize_t indexOffset = 0) noexcept;
/**
* @brief constructor
* @param pJson The json object to construct a new instance.
*/
explicit [[className]](const Json::Value &pJson) noexcept(false);
/**
* @brief constructor
* @param pJson The json object to construct a new instance.
* @param pMasqueradingVector The aliases of table columns.
*/
[[className]](const Json::Value &pJson, const std::vector<std::string> &pMasqueradingVector) noexcept(false);
[[className]]() = default;
2018-10-31 17:32:46 +08:00
void updateByJson(const Json::Value &pJson) noexcept(false);
void updateByMasqueradedJson(const Json::Value &pJson,
const std::vector<std::string> &pMasqueradingVector) noexcept(false);
static bool validateJsonForCreation(const Json::Value &pJson, std::string &err);
static bool validateMasqueradedJsonForCreation(const Json::Value &,
const std::vector<std::string> &pMasqueradingVector,
std::string &err);
static bool validateJsonForUpdate(const Json::Value &pJson, std::string &err);
static bool validateMasqueradedJsonForUpdate(const Json::Value &,
const std::vector<std::string> &pMasqueradingVector,
std::string &err);
static bool validJsonOfField(size_t index,
const std::string &fieldName,
const Json::Value &pJson,
std::string &err,
bool isForCreation);
2018-10-31 17:32:46 +08:00
<%c++
for(const auto &col:cols)
{
2019-11-21 11:27:47 +08:00
$$<<" /** For column "<<col.colName_<<" */\n";
if(!col.colType_.empty())
{
2019-11-21 11:27:47 +08:00
$$<<" ///Get the value of the column "<<col.colName_<<", returns the default value if the column is null\n";
$$<<" const "<<col.colType_<<" &getValueOf"<<col.colTypeName_<<"() const noexcept;\n";
if(col.colType_=="std::vector<char>")
2018-11-20 10:54:46 +08:00
{
2019-04-29 14:47:23 +08:00
$$<<" ///Return the column value by std::string with binary data\n";
2019-11-21 11:27:47 +08:00
$$<<" std::string getValueOf"<<col.colTypeName_<<"AsString() const noexcept;\n";
2018-11-20 10:54:46 +08:00
}
2019-04-29 14:47:23 +08:00
$$<<" ///Return a shared_ptr object pointing to the column const value, or an empty shared_ptr object if the column is null\n";
2019-11-21 11:27:47 +08:00
$$<<" const std::shared_ptr<"<<col.colType_<<"> &get"<<col.colTypeName_<<"() const noexcept;\n";
2019-11-21 11:27:47 +08:00
$$<<" ///Set the value of the column "<<col.colName_<<"\n";
$$<<" void set"<<col.colTypeName_<<"(const "<<col.colType_<<" &p"<<col.colTypeName_<<") noexcept;\n";
if(col.colType_=="std::string")
$$<<" void set"<<col.colTypeName_<<"("<<col.colType_<<" &&p"<<col.colTypeName_<<") noexcept;\n";
if(col.colType_=="std::vector<char>")
2018-11-20 10:54:46 +08:00
{
2019-11-21 11:27:47 +08:00
$$<<" void set"<<col.colTypeName_<<"(const std::string &p"<<col.colTypeName_<<") noexcept;\n";
2018-11-20 10:54:46 +08:00
}
2019-11-21 11:27:47 +08:00
if(!col.notNull_)
{
2019-11-21 11:27:47 +08:00
$$<<" void set"<<col.colTypeName_<<"ToNull() noexcept;\n";
}
}
else
2019-11-21 11:27:47 +08:00
$$<<" //FIXME!!"<<" getValueOf"<<col.colTypeName_<<"() const noexcept;\n";
$$<<"\n";
}
2018-10-31 17:32:46 +08:00
%>
2018-11-01 15:40:24 +08:00
2018-12-07 19:08:17 +08:00
static size_t getColumnNumber() noexcept { return {% cols.size() %}; }
2018-11-23 10:31:45 +08:00
static const std::string &getColumnName(size_t index) noexcept(false);
2018-11-01 15:40:24 +08:00
Json::Value toJson() const;
Json::Value toMasqueradedJson(const std::vector<std::string> &pMasqueradingVector) const;
2019-10-26 23:44:31 +08:00
/// Relationship interfaces
<%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 get{%alias%}(const DbClientPtr &clientPtr,
{%alind%} const std::function<void({%relationshipClassName%})> &rcb,
{%alind%} const ExceptionCallback &ecb) const;
<%c++
}
else
{
std::string relationshipClassInde(relationshipClassName.length(), ' ');
%>
void get{%relationshipClassName%}(const DbClientPtr &clientPtr,
{%relationshipClassInde%} const std::function<void({%relationshipClassName%})> &rcb,
{%relationshipClassInde%} const ExceptionCallback &ecb) const;
<%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 get{%alias%}(const DbClientPtr &clientPtr,
{%alind%} const std::function<void(std::vector<{%relationshipClassName%}>)> &rcb,
{%alind%} const ExceptionCallback &ecb) const;
<%c++
}
else
{
std::string relationshipClassInde(relationshipClassName.length(), ' ');
%>
void get{%relationshipClassName%}(const DbClientPtr &clientPtr,
{%relationshipClassInde%} const std::function<void(std::vector<{%relationshipClassName%}>)> &rcb,
{%relationshipClassInde%} const ExceptionCallback &ecb) const;
<%c++
}
}
else if(relationship.type() == Relationship::Type::ManyToMany)
{
auto &pivotTableName=relationship.pivotTable().tableName();
auto pivotTableClassName=nameTransform(pivotTableName, true);
if(!alias.empty())
{
if(alias[0] <= 'z' && alias[0] >= 'a')
{
alias[0] += ('A' - 'a');
}
std::string alind(alias.length(), ' ');
%>
void get{%alias%}(const DbClientPtr &clientPtr,
{%alind%} const std::function<void(std::vector<std::pair<{%relationshipClassName%},{%pivotTableClassName%}>>)> &rcb,
{%alind%} const ExceptionCallback &ecb) const;
<%c++
}
else
{
std::string relationshipClassInde(relationshipClassName.length(), ' ');
%>
void get{%relationshipClassName%}(const DbClientPtr &clientPtr,
{%relationshipClassInde%} const std::function<void(std::vector<std::pair<{%relationshipClassName%},{%pivotTableClassName%}>>)> &rcb,
{%relationshipClassInde%} const ExceptionCallback &ecb) const;
<%c++
}
}
}
%>
private:
friend Mapper<[[className]]>;
2018-11-23 10:31:45 +08:00
static const std::vector<std::string> &insertColumns() noexcept;
void outputArgs(drogon::orm::internal::SqlBinder &binder) const;
const std::vector<std::string> updateColumns() const;
void updateArgs(drogon::orm::internal::SqlBinder &binder) const;
2019-03-07 11:56:20 +08:00
///For mysql or sqlite3
2018-12-29 18:02:39 +08:00
void updateId(const uint64_t id);
2018-10-31 17:32:46 +08:00
<%c++
for(auto col:cols)
{
2019-11-21 11:27:47 +08:00
if(!col.colType_.empty())
$$<<" std::shared_ptr<"<<col.colType_<<"> "<<col.colValName_<<"_;\n";
}
%>
2018-11-01 15:40:24 +08:00
struct MetaData
{
2019-11-21 11:27:47 +08:00
const std::string colName_;
const std::string colType_;
const std::string colDatabaseType_;
const ssize_t colLength_;
const bool isAutoVal_;
const bool isPrimaryKey_;
const bool notNull_;
2018-11-01 15:40:24 +08:00
};
2019-11-21 11:27:47 +08:00
static const std::vector<MetaData> metaData_;
bool dirtyFlag_[{%cols.size()%}]={ false };
public:
static const std::string &sqlForFindingByPrimaryKey()
{
<%c++
auto rdbms=@@.get<std::string>("rdbms");
if(@@.get<int>("hasPrimaryKey")<=1){
if(!@@.get<std::string>("primaryKeyType").empty()){%>
static const std::string sql="select * from " + tableName + " where [[primaryKeyName]] = {%(rdbms=="postgresql"?"$1":"?")%}";
<%c++}else{%>
static const std::string sql="";
<%c++}%>
<%c++}else{
auto pkName=@@.get<std::vector<std::string>>("primaryKeyName");
%>
static const std::string sql="select * from " + tableName + " where <%c++
for(size_t i=0;i<pkName.size();i++)
{
if(rdbms=="postgresql")
{
$$<<pkName[i]<<" = $"<<i+1;
}
else
{
$$<<pkName[i]<<" = ?";
}
if(i<(pkName.size()-1))
$$<<" and ";
}
$$<<"\";\n";
}
%>
return sql;
}
static const std::string &sqlForDeletingByPrimaryKey()
{
<%c++
if(@@.get<int>("hasPrimaryKey")<=1){
if(!@@.get<std::string>("primaryKeyType").empty()){%>
static const std::string sql="delete from " + tableName + " where [[primaryKeyName]] = {%(rdbms=="postgresql"?"$1":"?")%}";
<%c++}else{%>
static const std::string sql="";
<%c++}%>
<%c++}else{
auto pkName=@@.get<std::vector<std::string>>("primaryKeyName");
%>
static const std::string sql="delete from " + tableName + " where <%c++
for(size_t i=0;i<pkName.size();i++)
{
if(rdbms=="postgresql")
{
$$<<pkName[i]<<" = $"<<i+1;
}
else
{
$$<<pkName[i]<<" = ?";
}
if(i<(pkName.size()-1))
$$<<" and ";
}
$$<<"\";\n";
}
%>
return sql;
}
std::string sqlForInserting(bool &needSelection) const
{
std::string sql="insert into " + tableName + " (";
size_t parametersCount = 0;
needSelection = false;
<%c++
bool selFlag=false;
for(size_t i=0;i<cols.size();i++)
{
2019-11-21 11:27:47 +08:00
if(cols[i].isAutoVal_)
{
if(@@.get<std::string>("rdbms")=="sqlite3")
{
continue;
}
if(@@.get<int>("hasPrimaryKey")>0)
{
selFlag = true;
}
2019-11-21 11:27:47 +08:00
$$<<" sql += \""<<cols[i].colName_<<",\";\n";
$$<<" ++parametersCount;\n";
continue;
}
2019-11-21 11:27:47 +08:00
if(cols[i].colType_.empty())
continue;
2019-11-21 11:27:47 +08:00
if(cols[i].hasDefaultVal_)
{
if(@@.get<std::string>("rdbms")!="sqlite3")
{
$$<<" sql += \""<<cols[i].colName_<<",\";\n";
$$<<" ++parametersCount;\n";
}
else
{
%>
if(dirtyFlag_[{%i%}])
{
sql += "{%cols[i].colName_%},";
++parametersCount;
}
<%c++
}
if(@@.get<int>("hasPrimaryKey")>0||@@.get<std::string>("rdbms")=="postgresql")
{
%>
2019-11-21 11:27:47 +08:00
if(!dirtyFlag_[{%i%}])
{
needSelection=true;
}
<%c++
}
}
else
{
%>
2019-11-21 11:27:47 +08:00
if(dirtyFlag_[{%i%}])
{
2019-11-21 11:27:47 +08:00
sql += "{%cols[i].colName_%},";
++parametersCount;
}
<%c++
}
}
if(selFlag)
{
$$<<" needSelection=true;\n";
}
%>
if(parametersCount > 0)
{
sql[sql.length()-1]=')';
sql += " values (";
}
else
sql += ") values (";
<%c++
if(@@.get<std::string>("rdbms")=="postgresql")
{
%>
int placeholder=1;
char placeholderStr[64];
size_t n=0;
<%c++
}
for(size_t i=0;i<cols.size();i++)
{
2019-11-21 11:27:47 +08:00
if(cols[i].isAutoVal_)
{
if(@@.get<std::string>("rdbms")!="sqlite3")
{
%>
sql +="default,";
<%c++
}
continue;
}
2019-11-21 11:27:47 +08:00
if(cols[i].colType_.empty())
continue;
%>
2019-11-21 11:27:47 +08:00
if(dirtyFlag_[{%i%}])
{
<%c++
if(@@.get<std::string>("rdbms")=="postgresql")
{
%>
n = sprintf(placeholderStr,"$%d,",placeholder++);
sql.append(placeholderStr, n);
<%c++
}else
{
%>
sql.append("?,");
<%c++
}
%>
}
<%c++
if(cols[i].hasDefaultVal_&&@@.get<std::string>("rdbms")!="sqlite3")
{
%>
else
{
sql +="default,";
}
<%c++
}
}
%>
if(parametersCount > 0)
{
sql.resize(sql.length() - 1);
}
<%c++
if(rdbms=="postgresql")
{
%>
if(needSelection)
{
sql.append(") returning *");
}
else
{
sql.append(1, ')');
}
<%c++
}
else
{
$$<<" sql.append(1, ')');\n";
}
%>
LOG_TRACE << sql;
return sql;
}
};
<%c++
if(!schema.empty())
{
$$<<"} // namespace "<<schema<<"\n";
}
%>
} // namespace [[dbName]]
} // namespace drogon_model