clang-format

This commit is contained in:
antao 2019-05-18 20:39:57 +08:00
parent d350dc7232
commit 11b6d20a69
78 changed files with 2439 additions and 2045 deletions

View File

@ -86,13 +86,13 @@ ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 10000
PenaltyBreakBeforeFirstCallParameter: 100
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 10000
PenaltyReturnTypeOnItsOwnLine: 200
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 2000
PointerAlignment: Left
RawStringFormats:
- Language: Cpp

19
drogon_ctl/CommandHandler.h Executable file → Normal file
View File

@ -22,8 +22,19 @@ class CommandHandler : public virtual drogon::DrObjectBase
{
public:
virtual void handleCommand(std::vector<std::string> &parameters) = 0;
virtual bool isTopCommand() { return false; }
virtual std::string script() { return ""; }
virtual std::string detail() { return ""; }
virtual ~CommandHandler() {}
virtual bool isTopCommand()
{
return false;
}
virtual std::string script()
{
return "";
}
virtual std::string detail()
{
return "";
}
virtual ~CommandHandler()
{
}
};

14
drogon_ctl/cmd.cc Executable file → Normal file
View File

@ -22,7 +22,8 @@ void exeCommand(std::vector<std::string> &parameters)
{
if (parameters.empty())
{
std::cout << "incomplete command!use help command to get usage!" << std::endl;
std::cout << "incomplete command!use help command to get usage!"
<< std::endl;
return;
}
std::string command = parameters[0];
@ -31,8 +32,9 @@ void exeCommand(std::vector<std::string> &parameters)
parameters.erase(parameters.begin());
//new command handler to do cmd
auto obj = std::shared_ptr<DrObjectBase>(drogon::DrClassMap::newObject(handlerName));
// new command handler to do cmd
auto obj = std::shared_ptr<DrObjectBase>(
drogon::DrClassMap::newObject(handlerName));
if (obj)
{
auto ctl = std::dynamic_pointer_cast<CommandHandler>(obj);
@ -42,11 +44,13 @@ void exeCommand(std::vector<std::string> &parameters)
}
else
{
std::cout << "command not found!use help command to get usage!" << std::endl;
std::cout << "command not found!use help command to get usage!"
<< std::endl;
}
}
else
{
std::cout << "command error!use help command to get usage!" << std::endl;
std::cout << "command error!use help command to get usage!"
<< std::endl;
}
}

8
drogon_ctl/create.cc Executable file → Normal file
View File

@ -21,8 +21,10 @@ using namespace drogon_ctl;
std::string create::detail()
{
return "Use create command to create some source files of drogon webapp\n\n"
"Usage:drogon_ctl create <view|controller|filter|project|model> [-options] <object name>\n\n"
"drogon_ctl create view <csp file name> //create HttpView source files from csp file\n\n"
"Usage:drogon_ctl create <view|controller|filter|project|model> "
"[-options] <object name>\n\n"
"drogon_ctl create view <csp file name> //create HttpView source "
"files from csp file\n\n"
"drogon_ctl create controller [-s] <[namespace::]class_name> //"
"create HttpSimpleController source files\n\n"
"drogon_ctl create controller -h <[namespace::]class_name> //"
@ -41,7 +43,7 @@ std::string create::detail()
void create::handleCommand(std::vector<std::string> &parameters)
{
//std::cout<<"create!"<<std::endl;
// std::cout<<"create!"<<std::endl;
auto createObjName = parameters[0];
createObjName = std::string("create_") + createObjName;
parameters[0] = createObjName;

13
drogon_ctl/create.h Executable file → Normal file
View File

@ -23,8 +23,15 @@ class create : public DrObject<create>, public CommandHandler
{
public:
virtual void handleCommand(std::vector<std::string> &parameters) override;
virtual std::string script() override { return "create some source files(Use 'drogon_ctl help create' for more information)"; }
virtual bool isTopCommand() override { return true; }
virtual std::string script() override
{
return "create some source files(Use 'drogon_ctl help create' for more "
"information)";
}
virtual bool isTopCommand() override
{
return true;
}
virtual std::string detail() override;
};
} // namespace drogon_ctl
} // namespace drogon_ctl

137
drogon_ctl/create_controller.cc Executable file → Normal file
View File

@ -22,7 +22,7 @@ using namespace drogon_ctl;
void create_controller::handleCommand(std::vector<std::string> &parameters)
{
//std::cout<<"create!"<<std::endl;
// std::cout<<"create!"<<std::endl;
ControllerType type = Simple;
for (auto iter = parameters.begin(); iter != parameters.end(); iter++)
{
@ -55,7 +55,9 @@ void create_controller::handleCommand(std::vector<std::string> &parameters)
createController(parameters, type);
}
void create_controller::newSimpleControllerHeaderFile(std::ofstream &file, const std::string &className)
void create_controller::newSimpleControllerHeaderFile(
std::ofstream &file,
const std::string &className)
{
file << "#pragma once\n";
file << "#include <drogon/HttpSimpleController.h>\n";
@ -74,14 +76,21 @@ void create_controller::newSimpleControllerHeaderFile(std::ofstream &file, const
indent.append(" ");
pos = class_name.find("::");
}
file << indent << "class " << class_name << ":public drogon::HttpSimpleController<" << class_name << ">\n";
file << indent << "class " << class_name
<< ":public drogon::HttpSimpleController<" << class_name << ">\n";
file << indent << "{\n";
file << indent << "public:\n";
file << indent << " virtual void asyncHandleHttpRequest(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback) override;\n";
file << indent
<< " virtual void asyncHandleHttpRequest(const HttpRequestPtr& "
"req, std::function<void (const HttpResponsePtr &)> &&callback) "
"override;\n";
file << indent << " PATH_LIST_BEGIN\n";
file << indent << " //list path definitions here;\n";
file << indent << " //PATH_ADD(\"/path\",\"filter1\",\"filter2\",HttpMethod1,HttpMethod2...);\n";
file << indent
<< " "
"//PATH_ADD(\"/"
"path\",\"filter1\",\"filter2\",HttpMethod1,HttpMethod2...);\n";
file << indent << " PATH_LIST_END\n";
file << indent << "};\n";
if (indent == "")
@ -92,7 +101,10 @@ void create_controller::newSimpleControllerHeaderFile(std::ofstream &file, const
file << indent << "}\n";
} while (indent != "");
}
void create_controller::newSimpleControllerSourceFile(std::ofstream &file, const std::string &className, const std::string &filename)
void create_controller::newSimpleControllerSourceFile(
std::ofstream &file,
const std::string &className,
const std::string &filename)
{
file << "#include \"" << filename << ".h\"\n";
auto pos = className.rfind("::");
@ -103,13 +115,17 @@ void create_controller::newSimpleControllerSourceFile(std::ofstream &file, const
file << "using namespace " << namespacename << ";\n";
class_name = className.substr(pos + 2);
}
file << "void " << class_name << "::asyncHandleHttpRequest(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback)\n";
file << "void " << class_name
<< "::asyncHandleHttpRequest(const HttpRequestPtr& req, "
"std::function<void (const HttpResponsePtr &)> &&callback)\n";
file << "{\n";
file << " //write your application logic here\n";
file << "}";
}
void create_controller::newWebsockControllerHeaderFile(std::ofstream &file, const std::string &className)
void create_controller::newWebsockControllerHeaderFile(
std::ofstream &file,
const std::string &className)
{
file << "#pragma once\n";
file << "#include <drogon/WebSocketController.h>\n";
@ -128,18 +144,29 @@ void create_controller::newWebsockControllerHeaderFile(std::ofstream &file, cons
indent.append(" ");
pos = class_name.find("::");
}
file << indent << "class " << class_name << ":public drogon::WebSocketController<" << class_name << ">\n";
file << indent << "class " << class_name
<< ":public drogon::WebSocketController<" << class_name << ">\n";
file << indent << "{\n";
file << indent << "public:\n";
file << indent << " virtual void handleNewMessage(const WebSocketConnectionPtr&,\n";
file
<< indent
<< " virtual void handleNewMessage(const WebSocketConnectionPtr&,\n";
file << indent << " std::string &&,\n";
file << indent << " const WebSocketMessageType &) override;\n";
file << indent << " virtual void handleNewConnection(const HttpRequestPtr &,\n";
file << indent << " const WebSocketConnectionPtr&)override;\n";
file << indent << " virtual void handleConnectionClosed(const WebSocketConnectionPtr&)override;\n";
file << indent
<< " const WebSocketMessageType &) "
"override;\n";
file << indent
<< " virtual void handleNewConnection(const HttpRequestPtr &,\n";
file << indent
<< " const "
"WebSocketConnectionPtr&)override;\n";
file << indent
<< " virtual void handleConnectionClosed(const "
"WebSocketConnectionPtr&)override;\n";
file << indent << " WS_PATH_LIST_BEGIN\n";
file << indent << " //list path definitions here;\n";
file << indent << " //WS_PATH_ADD(\"/path\",\"filter1\",\"filter2\",...);\n";
file << indent
<< " //WS_PATH_ADD(\"/path\",\"filter1\",\"filter2\",...);\n";
file << indent << " WS_PATH_LIST_END\n";
file << indent << "};\n";
if (indent == "")
@ -150,7 +177,10 @@ void create_controller::newWebsockControllerHeaderFile(std::ofstream &file, cons
file << indent << "}\n";
} while (indent != "");
}
void create_controller::newWebsockControllerSourceFile(std::ofstream &file, const std::string &className, const std::string &filename)
void create_controller::newWebsockControllerSourceFile(
std::ofstream &file,
const std::string &className,
const std::string &filename)
{
file << "#include \"" << filename << ".h\"\n";
auto pos = className.rfind("::");
@ -161,21 +191,29 @@ void create_controller::newWebsockControllerSourceFile(std::ofstream &file, cons
file << "using namespace " << namespacename << ";\n";
class_name = className.substr(pos + 2);
}
file << "void " << class_name << "::handleNewMessage(const WebSocketConnectionPtr& wsConnPtr, std::string &&message, const WebSocketMessageType &type)\n";
file << "void " << class_name
<< "::handleNewMessage(const WebSocketConnectionPtr& wsConnPtr, "
"std::string &&message, const WebSocketMessageType &type)\n";
file << "{\n";
file << " //write your application logic here\n";
file << "}\n";
file << "void " << class_name << "::handleNewConnection(const HttpRequestPtr &req,const WebSocketConnectionPtr& wsConnPtr)\n";
file << "void " << class_name
<< "::handleNewConnection(const HttpRequestPtr &req,const "
"WebSocketConnectionPtr& wsConnPtr)\n";
file << "{\n";
file << " //write your application logic here\n";
file << "}\n";
file << "void " << class_name << "::handleConnectionClosed(const WebSocketConnectionPtr& wsConnPtr)\n";
file << "void " << class_name
<< "::handleConnectionClosed(const WebSocketConnectionPtr& "
"wsConnPtr)\n";
file << "{\n";
file << " //write your application logic here\n";
file << "}\n";
}
void create_controller::newHttpControllerHeaderFile(std::ofstream &file, const std::string &className)
void create_controller::newHttpControllerHeaderFile(
std::ofstream &file,
const std::string &className)
{
file << "#pragma once\n";
file << "#include <drogon/HttpController.h>\n";
@ -194,28 +232,38 @@ void create_controller::newHttpControllerHeaderFile(std::ofstream &file, const s
indent.append(" ");
pos = class_name.find("::");
}
file << indent << "class " << class_name << ":public drogon::HttpController<" << class_name << ">\n";
file << indent << "class " << class_name
<< ":public drogon::HttpController<" << class_name << ">\n";
file << indent << "{\n";
file << indent << "public:\n";
indent.append(" ");
file << indent << "METHOD_LIST_BEGIN\n";
file << indent << "//use METHOD_ADD to add your custom processing function here;\n";
file << indent << "//METHOD_ADD(" << class_name << "::get,\"/get/{2}/{1}\",Get);"
"//path is "
file << indent
<< "//use METHOD_ADD to add your custom processing function here;\n";
file << indent << "//METHOD_ADD(" << class_name
<< "::get,\"/get/{2}/{1}\",Get);"
"//path is "
<< namepace_path << class_name << "/get/{arg2}/{arg1}\n";
file << indent << "//METHOD_ADD(" << class_name << "::your_method_name,\"/{1}/{2}/list\",Get);"
"//path is "
file << indent << "//METHOD_ADD(" << class_name
<< "::your_method_name,\"/{1}/{2}/list\",Get);"
"//path is "
<< namepace_path << class_name << "/{arg1}/{arg2}/list\n";
file << indent << "//ADD_METHOD_TO(" << class_name << "::your_method_name,\"/absolute/path/{1}/{2}/list\",Get);"
"//path is "
file << indent << "//ADD_METHOD_TO(" << class_name
<< "::your_method_name,\"/absolute/path/{1}/{2}/list\",Get);"
"//path is "
<< namepace_path << "/absolute/path/{arg1}/{arg2}/list\n";
file << indent << "\n";
file << indent << "METHOD_LIST_END\n";
file << indent << "//your declaration of processing function maybe like this:\n";
file << indent << "//void get(const HttpRequestPtr& req,"
"std::function<void (const HttpResponsePtr &)> &&callback,int p1,std::string p2);\n";
file << indent << "//void your_method_name(const HttpRequestPtr& req,"
"std::function<void (const HttpResponsePtr &)> &&callback,double p1,int p2) const;\n";
file << indent
<< "//your declaration of processing function maybe like this:\n";
file << indent
<< "//void get(const HttpRequestPtr& req,"
"std::function<void (const HttpResponsePtr &)> &&callback,int "
"p1,std::string p2);\n";
file << indent
<< "//void your_method_name(const HttpRequestPtr& req,"
"std::function<void (const HttpResponsePtr &)> &&callback,double "
"p1,int p2) const;\n";
indent.resize(indent.length() - 4);
file << indent << "};\n";
if (indent == "")
@ -226,7 +274,10 @@ void create_controller::newHttpControllerHeaderFile(std::ofstream &file, const s
file << indent << "}\n";
} while (indent != "");
}
void create_controller::newHttpControllerSourceFile(std::ofstream &file, const std::string &className, const std::string &filename)
void create_controller::newHttpControllerSourceFile(
std::ofstream &file,
const std::string &className,
const std::string &filename)
{
file << "#include \"" << filename << ".h\"\n";
auto pos = className.rfind("::");
@ -241,7 +292,8 @@ void create_controller::newHttpControllerSourceFile(std::ofstream &file, const s
file << "//add definition of your processing function here\n";
}
void create_controller::createController(std::vector<std::string> &httpClasses, ControllerType type)
void create_controller::createController(std::vector<std::string> &httpClasses,
ControllerType type)
{
for (auto iter = httpClasses.begin(); iter != httpClasses.end(); iter++)
{
@ -257,10 +309,12 @@ void create_controller::createController(std::vector<std::string> &httpClasses,
}
}
void create_controller::createController(const std::string &className, ControllerType type)
void create_controller::createController(const std::string &className,
ControllerType type)
{
std::regex regex("::");
std::string ctlName = std::regex_replace(className, regex, std::string("_"));
std::string ctlName =
std::regex_replace(className, regex, std::string("_"));
std::string headFileName = ctlName + ".h";
std::string sourceFilename = ctlName + ".cc";
@ -270,9 +324,11 @@ void create_controller::createController(const std::string &className, Controlle
if (iHeadFile || iSourceFile)
{
std::cout << "The file you want to create already exists, overwrite it(y/n)?" << std::endl;
std::cout << "The file you want to create already exists, "
"overwrite it(y/n)?"
<< std::endl;
auto in = getchar();
(void)getchar(); //get the return key
(void)getchar(); // get the return key
if (in != 'Y' && in != 'y')
{
std::cout << "Abort!" << std::endl;
@ -295,7 +351,8 @@ void create_controller::createController(const std::string &className, Controlle
}
else if (type == Simple)
{
std::cout << "create a http simple controller:" << className << std::endl;
std::cout << "create a http simple controller:" << className
<< std::endl;
newSimpleControllerHeaderFile(oHeadFile, className);
newSimpleControllerSourceFile(oSourceFile, className, ctlName);
}

34
drogon_ctl/create_controller.h Executable file → Normal file
View File

@ -19,11 +19,15 @@
using namespace drogon;
namespace drogon_ctl
{
class create_controller : public DrObject<create_controller>, public CommandHandler
class create_controller : public DrObject<create_controller>,
public CommandHandler
{
public:
virtual void handleCommand(std::vector<std::string> &parameters) override;
virtual std::string script() override { return "create controller files"; }
virtual std::string script() override
{
return "create controller files";
}
protected:
enum ControllerType
@ -33,16 +37,26 @@ class create_controller : public DrObject<create_controller>, public CommandHand
WebSocket
};
void createController(std::vector<std::string> &httpClasses, ControllerType type);
void createController(std::vector<std::string> &httpClasses,
ControllerType type);
void createController(const std::string &className, ControllerType type);
void newSimpleControllerHeaderFile(std::ofstream &file, const std::string &className);
void newSimpleControllerSourceFile(std::ofstream &file, const std::string &className, const std::string &filename);
void newSimpleControllerHeaderFile(std::ofstream &file,
const std::string &className);
void newSimpleControllerSourceFile(std::ofstream &file,
const std::string &className,
const std::string &filename);
void newWebsockControllerHeaderFile(std::ofstream &file, const std::string &className);
void newWebsockControllerSourceFile(std::ofstream &file, const std::string &className, const std::string &filename);
void newWebsockControllerHeaderFile(std::ofstream &file,
const std::string &className);
void newWebsockControllerSourceFile(std::ofstream &file,
const std::string &className,
const std::string &filename);
void newHttpControllerHeaderFile(std::ofstream &file, const std::string &className);
void newHttpControllerSourceFile(std::ofstream &file, const std::string &className, const std::string &filename);
void newHttpControllerHeaderFile(std::ofstream &file,
const std::string &className);
void newHttpControllerSourceFile(std::ofstream &file,
const std::string &className,
const std::string &filename);
};
} // namespace drogon_ctl
} // namespace drogon_ctl

View File

@ -7,7 +7,7 @@
* 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
*
*/
@ -27,7 +27,9 @@
using namespace drogon_ctl;
static void createFilterHeaderFile(std::ofstream &file, const std::string &className, const std::string &fileName)
static void createFilterHeaderFile(std::ofstream &file,
const std::string &className,
const std::string &fileName)
{
auto templ = drogon::DrTemplateBase::newTemplate("filter_h");
HttpViewData data;
@ -46,7 +48,9 @@ static void createFilterHeaderFile(std::ofstream &file, const std::string &class
file << templ->genText(data);
}
static void createFilterSourceFile(std::ofstream &file, const std::string &className, const std::string &fileName)
static void createFilterSourceFile(std::ofstream &file,
const std::string &className,
const std::string &fileName)
{
auto templ = drogon::DrTemplateBase::newTemplate("filter_cc");
HttpViewData data;
@ -72,19 +76,23 @@ void create_filter::handleCommand(std::vector<std::string> &parameters)
for (auto className : parameters)
{
std::regex regex("::");
std::string fileName = std::regex_replace(className, regex, std::string("_"));
std::string fileName =
std::regex_replace(className, regex, std::string("_"));
std::string headFileName = fileName + ".h";
std::string sourceFilename = fileName + ".cc";
{
std::ifstream iHeadFile(headFileName.c_str(), std::ifstream::in);
std::ifstream iSourceFile(sourceFilename.c_str(), std::ifstream::in);
std::ifstream iSourceFile(sourceFilename.c_str(),
std::ifstream::in);
if (iHeadFile || iSourceFile)
{
std::cout << "The file you want to create already exists, overwrite it(y/n)?" << std::endl;
std::cout << "The file you want to create already exists, "
"overwrite it(y/n)?"
<< std::endl;
auto in = getchar();
(void)getchar(); //get the return key
(void)getchar(); // get the return key
if (in != 'Y' && in != 'y')
{
std::cout << "Abort!" << std::endl;

View File

@ -23,9 +23,12 @@ class create_filter : public DrObject<create_filter>, public CommandHandler
{
public:
virtual void handleCommand(std::vector<std::string> &parameters) override;
virtual std::string script() override { return "create filter class files"; }
virtual std::string script() override
{
return "create filter class files";
}
protected:
std::string _outputPath = ".";
};
} // namespace drogon_ctl
} // namespace drogon_ctl

View File

@ -61,7 +61,9 @@ std::string nameTransform(const std::string &origName, bool isType)
}
#if USE_POSTGRESQL
void create_model::createModelClassFromPG(const std::string &path, const DbClientPtr &client, const std::string &tableName)
void create_model::createModelClassFromPG(const std::string &path,
const DbClientPtr &client,
const std::string &tableName)
{
auto className = nameTransform(tableName, true);
HttpViewData data;
@ -80,7 +82,10 @@ void create_model::createModelClassFromPG(const std::string &path, const DbClien
[&](const Result &r) {
if (r.size() == 0)
{
std::cout << " ---Can't create model from the table " << tableName << ", please check privileges on the table." << std::endl;
std::cout << " ---Can't create model from the table "
<< tableName
<< ", please check privileges on the table."
<< std::endl;
return;
}
for (size_t i = 0; i < r.size(); i++)
@ -107,7 +112,9 @@ void create_model::createModelClassFromPG(const std::string &path, const DbClien
info._colType = "int32_t";
info._colLength = 4;
}
else if (type == "bigint" || type == "numeric") ///TODO:Use int64 to represent numeric type?
else if (type == "bigint" ||
type == "numeric") /// TODO:Use int64 to represent
/// numeric type?
{
info._colType = "int64_t";
info._colLength = 8;
@ -126,7 +133,8 @@ void create_model::createModelClassFromPG(const std::string &path, const DbClien
{
info._colType = "std::string";
if (!row["character_maximum_length"].isNull())
info._colLength = row["character_maximum_length"].as<ssize_t>();
info._colLength =
row["character_maximum_length"].as<ssize_t>();
}
else if (type == "boolean")
{
@ -176,12 +184,14 @@ void create_model::createModelClassFromPG(const std::string &path, const DbClien
WHERE \
pg_class.relname = $1 \
AND pg_constraint.contype = 'p'"
<< tableName
<< Mode::Blocking >>
[&](bool isNull, const std::string &pkName, const std::vector<std::shared_ptr<short>> &pk) {
<< tableName << Mode::Blocking >>
[&](bool isNull,
const std::string &pkName,
const std::vector<std::shared_ptr<short>> &pk) {
if (!isNull)
{
//std::cout << tableName << " Primary key = " << pk.size() << std::endl;
// std::cout << tableName << " Primary key = " << pk.size() <<
// std::endl;
pkNumber = pk.size();
}
} >>
@ -237,13 +247,11 @@ void create_model::createModelClassFromPG(const std::string &path, const DbClien
AND pg_attribute.attnum = pg_constraint.conkey [ $1 ] \
INNER JOIN pg_type ON pg_type.oid = pg_attribute.atttypid \
WHERE pg_class.relname = $2 and pg_constraint.contype='p'"
<< (int)i
<< tableName
<< Mode::Blocking >>
<< (int)i << tableName << Mode::Blocking >>
[&](bool isNull, std::string colName, const std::string &type) {
if (isNull)
return;
//std::cout << "primary key name=" << colName << std::endl;
// std::cout << "primary key name=" << colName << std::endl;
pkNames.push_back(colName);
for (auto &col : cols)
{
@ -265,23 +273,30 @@ void create_model::createModelClassFromPG(const std::string &path, const DbClien
data["columns"] = cols;
std::ofstream headerFile(path + "/" + className + ".h", std::ofstream::out);
std::ofstream sourceFile(path + "/" + className + ".cc", std::ofstream::out);
std::ofstream sourceFile(path + "/" + className + ".cc",
std::ofstream::out);
auto templ = DrTemplateBase::newTemplate("model_h.csp");
headerFile << templ->genText(data);
templ = DrTemplateBase::newTemplate("model_cc.csp");
sourceFile << templ->genText(data);
}
void create_model::createModelFromPG(const std::string &path, const DbClientPtr &client)
void create_model::createModelFromPG(const std::string &path,
const DbClientPtr &client)
{
*client << "SELECT a.oid,"
"a.relname AS name,"
"b.description AS comment "
"FROM pg_class a "
"LEFT OUTER JOIN pg_description b ON b.objsubid = 0 AND a.oid = b.objoid "
"WHERE a.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public') "
"LEFT OUTER JOIN pg_description b ON b.objsubid = 0 AND a.oid = "
"b.objoid "
"WHERE a.relnamespace = (SELECT oid FROM pg_namespace WHERE "
"nspname = 'public') "
"AND a.relkind = 'r' ORDER BY a.relname"
<< Mode::Blocking >>
[&](bool isNull, size_t oid, const std::string &tableName, const std::string &comment) {
[&](bool isNull,
size_t oid,
const std::string &tableName,
const std::string &comment) {
if (!isNull)
{
std::cout << "table name:" << tableName << std::endl;
@ -296,7 +311,9 @@ void create_model::createModelFromPG(const std::string &path, const DbClientPtr
#endif
#if USE_MYSQL
void create_model::createModelClassFromMysql(const std::string &path, const DbClientPtr &client, const std::string &tableName)
void create_model::createModelClassFromMysql(const std::string &path,
const DbClientPtr &client,
const std::string &tableName)
{
auto className = nameTransform(tableName, true);
HttpViewData data;
@ -309,7 +326,13 @@ void create_model::createModelClassFromMysql(const std::string &path, const DbCl
std::vector<ColumnInfo> cols;
int i = 0;
*client << "desc " + tableName << Mode::Blocking >>
[&i,&cols](bool isNull, const std::string &field, const std::string &type, const std::string &isNullAble, const std::string &key, const std::string &defaultVal, const std::string &extra) {
[&i, &cols](bool isNull,
const std::string &field,
const std::string &type,
const std::string &isNullAble,
const std::string &key,
const std::string &defaultVal,
const std::string &extra) {
if (!isNull)
{
ColumnInfo info;
@ -351,7 +374,8 @@ void create_model::createModelClassFromMysql(const std::string &path, const DbCl
info._colType = "double";
info._colLength = sizeof(double);
}
else if (type.find("date") == 0 || type.find("datetime") == 0 || type.find("timestamp") == 0)
else if (type.find("date") == 0 || type.find("datetime") == 0 ||
type.find("timestamp") == 0)
{
info._colType = "::trantor::Date";
}
@ -405,13 +429,15 @@ void create_model::createModelClassFromMysql(const std::string &path, const DbCl
}
data["columns"] = cols;
std::ofstream headerFile(path + "/" + className + ".h", std::ofstream::out);
std::ofstream sourceFile(path + "/" + className + ".cc", std::ofstream::out);
std::ofstream sourceFile(path + "/" + className + ".cc",
std::ofstream::out);
auto templ = DrTemplateBase::newTemplate("model_h.csp");
headerFile << templ->genText(data);
templ = DrTemplateBase::newTemplate("model_cc.csp");
sourceFile << templ->genText(data);
}
void create_model::createModelFromMysql(const std::string &path, const DbClientPtr &client)
void create_model::createModelFromMysql(const std::string &path,
const DbClientPtr &client)
{
*client << "show tables" << Mode::Blocking >>
[&](bool isNull, const std::string &tableName) {
@ -428,11 +454,13 @@ void create_model::createModelFromMysql(const std::string &path, const DbClientP
}
#endif
#if USE_SQLITE3
void create_model::createModelClassFromSqlite3(const std::string &path, const DbClientPtr &client, const std::string &tableName)
void create_model::createModelClassFromSqlite3(const std::string &path,
const DbClientPtr &client,
const std::string &tableName)
{
*client << "SELECT sql FROM sqlite_master WHERE name=? and (type='table' or type='view');"
<< tableName
<< Mode::Blocking >>
*client << "SELECT sql FROM sqlite_master WHERE name=? and (type='table' "
"or type='view');"
<< tableName << Mode::Blocking >>
[=](bool isNull, std::string sql) {
if (!isNull)
{
@ -452,22 +480,28 @@ void create_model::createModelClassFromSqlite3(const std::string &path, const Db
data["primaryKeyName"] = "";
data["dbName"] = "sqlite3";
data["rdbms"] = std::string("sqlite3");
//std::cout << sql << std::endl;
// std::cout << sql << std::endl;
auto columns = utils::splitString(sql, ",");
int i = 0;
std::vector<ColumnInfo> cols;
for (auto &column : columns)
{
std::transform(column.begin(), column.end(), column.begin(), tolower);
std::transform(column.begin(),
column.end(),
column.begin(),
tolower);
auto columnVector = utils::splitString(column, " ");
auto field = columnVector[0];
auto type = columnVector[1];
bool notnull = (column.find("not null") != std::string::npos);
bool autoVal = (column.find("autoincrement") != std::string::npos);
bool primary = (column.find("primary key") != std::string::npos);
bool notnull =
(column.find("not null") != std::string::npos);
bool autoVal =
(column.find("autoincrement") != std::string::npos);
bool primary =
(column.find("primary key") != std::string::npos);
//std::cout << "field:" << field << std::endl;
// std::cout << "field:" << field << std::endl;
ColumnInfo info;
info._index = i;
info._dbType = "sqlite3";
@ -484,11 +518,13 @@ void create_model::createModelClassFromSqlite3(const std::string &path, const Db
info._colType = "uint64_t";
info._colLength = 8;
}
else if (type.find("char") != std::string::npos || type == "text" || type == "clob")
else if (type.find("char") != std::string::npos ||
type == "text" || type == "clob")
{
info._colType = "std::string";
}
else if (type.find("double") != std::string::npos || type == "real" || type == "float")
else if (type.find("double") != std::string::npos ||
type == "real" || type == "float")
{
info._colType = "double";
info._colLength = sizeof(double);
@ -526,8 +562,10 @@ void create_model::createModelClassFromSqlite3(const std::string &path, const Db
data["primaryKeyType"] = pkTypes;
}
data["columns"] = cols;
std::ofstream headerFile(path + "/" + className + ".h", std::ofstream::out);
std::ofstream sourceFile(path + "/" + className + ".cc", std::ofstream::out);
std::ofstream headerFile(path + "/" + className + ".h",
std::ofstream::out);
std::ofstream sourceFile(path + "/" + className + ".cc",
std::ofstream::out);
auto templ = DrTemplateBase::newTemplate("model_h.csp");
headerFile << templ->genText(data);
templ = DrTemplateBase::newTemplate("model_cc.csp");
@ -535,7 +573,8 @@ void create_model::createModelClassFromSqlite3(const std::string &path, const Db
}
else
{
std::cout << "The sql for creating table is wrong!" << std::endl;
std::cout << "The sql for creating table is wrong!"
<< std::endl;
exit(1);
}
}
@ -545,9 +584,11 @@ void create_model::createModelClassFromSqlite3(const std::string &path, const Db
exit(1);
};
}
void create_model::createModelFromSqlite3(const std::string &path, const DbClientPtr &client)
void create_model::createModelFromSqlite3(const std::string &path,
const DbClientPtr &client)
{
*client << "SELECT name FROM sqlite_master WHERE name!='sqlite_sequence' and (type='table' or type='view') ORDER BY name;"
*client << "SELECT name FROM sqlite_master WHERE name!='sqlite_sequence' "
"and (type='table' or type='view') ORDER BY name;"
<< Mode::Blocking >>
[=](bool isNull, const std::string &tableName) {
if (!isNull)
@ -563,7 +604,8 @@ void create_model::createModelFromSqlite3(const std::string &path, const DbClien
}
#endif
void create_model::createModel(const std::string &path, const Json::Value &config)
void create_model::createModel(const std::string &path,
const Json::Value &config)
{
auto dbType = config.get("rdbms", "no dbms").asString();
std::transform(dbType.begin(), dbType.end(), dbType.begin(), tolower);
@ -576,19 +618,26 @@ void create_model::createModel(const std::string &path, const Json::Value &confi
auto dbname = config.get("dbname", "").asString();
if (dbname == "")
{
std::cerr << "Please configure dbname in " << path << "/model.json " << std::endl;
std::cerr << "Please configure dbname in " << path << "/model.json "
<< std::endl;
exit(1);
}
_dbname = dbname;
auto user = config.get("user", "").asString();
if (user == "")
{
std::cerr << "Please configure user in " << path << "/model.json " << std::endl;
std::cerr << "Please configure user in " << path << "/model.json "
<< std::endl;
exit(1);
}
auto password = config.get("passwd", "").asString();
auto connStr = utils::formattedString("host=%s port=%u dbname=%s user=%s", host.c_str(), port, dbname.c_str(), user.c_str());
auto connStr =
utils::formattedString("host=%s port=%u dbname=%s user=%s",
host.c_str(),
port,
dbname.c_str(),
user.c_str());
if (!password.empty())
{
connStr += " password=";
@ -596,7 +645,8 @@ void create_model::createModel(const std::string &path, const Json::Value &confi
}
DbClientPtr client = drogon::orm::DbClient::newPgClient(connStr, 1);
std::cout << "Connect to server..." << std::endl;
std::cout << "Source files in the " << path << " folder will be overwritten, continue(y/n)?\n";
std::cout << "Source files in the " << path
<< " folder will be overwritten, continue(y/n)?\n";
auto in = getchar();
if (in != 'Y' && in != 'y')
{
@ -616,7 +666,10 @@ void create_model::createModel(const std::string &path, const Json::Value &confi
}
}
#else
std::cerr << "Drogon does not support PostgreSQL, please install PostgreSQL development environment before installing drogon" << std::endl;
std::cerr
<< "Drogon does not support PostgreSQL, please install PostgreSQL "
"development environment before installing drogon"
<< std::endl;
#endif
}
else if (dbType == "mysql")
@ -628,19 +681,26 @@ void create_model::createModel(const std::string &path, const Json::Value &confi
auto dbname = config.get("dbname", "").asString();
if (dbname == "")
{
std::cerr << "Please configure dbname in " << path << "/model.json " << std::endl;
std::cerr << "Please configure dbname in " << path << "/model.json "
<< std::endl;
exit(1);
}
_dbname = dbname;
auto user = config.get("user", "").asString();
if (user == "")
{
std::cerr << "Please configure user in " << path << "/model.json " << std::endl;
std::cerr << "Please configure user in " << path << "/model.json "
<< std::endl;
exit(1);
}
auto password = config.get("passwd", "").asString();
auto connStr = utils::formattedString("host=%s port=%u dbname=%s user=%s", host.c_str(), port, dbname.c_str(), user.c_str());
auto connStr =
utils::formattedString("host=%s port=%u dbname=%s user=%s",
host.c_str(),
port,
dbname.c_str(),
user.c_str());
if (!password.empty())
{
connStr += " password=";
@ -648,7 +708,8 @@ void create_model::createModel(const std::string &path, const Json::Value &confi
}
DbClientPtr client = drogon::orm::DbClient::newMysqlClient(connStr, 1);
std::cout << "Connect to server..." << std::endl;
std::cout << "Source files in the " << path << " folder will be overwritten, continue(y/n)?\n";
std::cout << "Source files in the " << path
<< " folder will be overwritten, continue(y/n)?\n";
auto in = getchar();
if (in != 'Y' && in != 'y')
{
@ -668,7 +729,9 @@ void create_model::createModel(const std::string &path, const Json::Value &confi
}
}
#else
std::cerr << "Drogon does not support Mysql, please install MariaDB development environment before installing drogon" << std::endl;
std::cerr << "Drogon does not support Mysql, please install MariaDB "
"development environment before installing drogon"
<< std::endl;
#endif
}
else if (dbType == "sqlite3")
@ -677,13 +740,16 @@ void create_model::createModel(const std::string &path, const Json::Value &confi
auto filename = config.get("filename", "").asString();
if (filename == "")
{
std::cerr << "Please configure filename in " << path << "/model.json " << std::endl;
std::cerr << "Please configure filename in " << path
<< "/model.json " << std::endl;
exit(1);
}
std::string connStr = "filename=" + filename;
DbClientPtr client = drogon::orm::DbClient::newSqlite3Client(connStr, 1);
DbClientPtr client =
drogon::orm::DbClient::newSqlite3Client(connStr, 1);
std::cout << "Connect..." << std::endl;
std::cout << "Source files in the " << path << " folder will be overwritten, continue(y/n)?\n";
std::cout << "Source files in the " << path
<< " folder will be overwritten, continue(y/n)?\n";
auto in = getchar();
if (in != 'Y' && in != 'y')
{
@ -706,7 +772,8 @@ void create_model::createModel(const std::string &path, const Json::Value &confi
}
else if (dbType == "no dbms")
{
std::cerr << "Please configure Model in " << path << "/model.json " << std::endl;
std::cerr << "Please configure Model in " << path << "/model.json "
<< std::endl;
exit(1);
}
else
@ -732,7 +799,8 @@ void create_model::createModel(const std::string &path)
}
if (access(configFile.c_str(), R_OK) != 0)
{
std::cerr << "No permission to read config file " << configFile << std::endl;
std::cerr << "No permission to read config file " << configFile
<< std::endl;
exit(1);
}
@ -747,7 +815,8 @@ void create_model::createModel(const std::string &path)
}
catch (const std::exception &exception)
{
std::cerr << "Configuration file format error! in " << configFile << ":" << std::endl;
std::cerr << "Configuration file format error! in " << configFile
<< ":" << std::endl;
std::cerr << exception.what() << std::endl;
exit(1);
}
@ -767,7 +836,9 @@ void create_model::handleCommand(std::vector<std::string> &parameters)
createModel(path);
}
#else
std::cout << "No database can be found in your system, please install one first!" << std::endl;
std::cout
<< "No database can be found in your system, please install one first!"
<< std::endl;
exit(1);
#endif
}

View File

@ -26,47 +26,56 @@ using namespace drogon::orm;
using namespace drogon;
namespace drogon_ctl
{
struct ColumnInfo
{
std::string _colName;
std::string _colValName;
std::string _colTypeName;
std::string _colType;
std::string _colDatabaseType;
std::string _dbType;
ssize_t _colLength = 0;
size_t _index = 0;
bool _isAutoVal = false;
bool _isPrimaryKey = false;
bool _notNull = false;
bool _hasDefaultVal = false;
std::string _colName;
std::string _colValName;
std::string _colTypeName;
std::string _colType;
std::string _colDatabaseType;
std::string _dbType;
ssize_t _colLength = 0;
size_t _index = 0;
bool _isAutoVal = false;
bool _isPrimaryKey = false;
bool _notNull = false;
bool _hasDefaultVal = false;
};
class create_model : public DrObject<create_model>, public CommandHandler
{
public:
virtual void handleCommand(std::vector<std::string> &parameters) override;
virtual std::string script() override { return "create Model classes files"; }
public:
virtual void handleCommand(std::vector<std::string> &parameters) override;
virtual std::string script() override
{
return "create Model classes files";
}
protected:
void createModel(const std::string &path);
void createModel(const std::string &path, const Json::Value &config);
protected:
void createModel(const std::string &path);
void createModel(const std::string &path, const Json::Value &config);
#if USE_POSTGRESQL
void createModelClassFromPG(const std::string &path, const DbClientPtr &client, const std::string &tableName);
void createModelFromPG(const std::string &path, const DbClientPtr &client);
void createModelClassFromPG(const std::string &path,
const DbClientPtr &client,
const std::string &tableName);
void createModelFromPG(const std::string &path, const DbClientPtr &client);
#endif
#if USE_MYSQL
void createModelClassFromMysql(const std::string &path, const DbClientPtr &client, const std::string &tableName);
void createModelFromMysql(const std::string &path, const DbClientPtr &client);
void createModelClassFromMysql(const std::string &path,
const DbClientPtr &client,
const std::string &tableName);
void createModelFromMysql(const std::string &path,
const DbClientPtr &client);
#endif
#if USE_SQLITE3
void createModelClassFromSqlite3(const std::string &path, const DbClientPtr &client, const std::string &tableName);
void createModelFromSqlite3(const std::string &path, const DbClientPtr &client);
void createModelClassFromSqlite3(const std::string &path,
const DbClientPtr &client,
const std::string &tableName);
void createModelFromSqlite3(const std::string &path,
const DbClientPtr &client);
#endif
std::string _dbname;
std::string _dbname;
};
} // namespace drogon_ctl
} // namespace drogon_ctl

View File

@ -7,7 +7,7 @@
* 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
*
*/
@ -27,7 +27,9 @@
using namespace drogon_ctl;
static void createPluginHeaderFile(std::ofstream &file, const std::string &className, const std::string &fileName)
static void createPluginHeaderFile(std::ofstream &file,
const std::string &className,
const std::string &fileName)
{
auto templ = drogon::DrTemplateBase::newTemplate("plugin_h");
HttpViewData data;
@ -46,7 +48,9 @@ static void createPluginHeaderFile(std::ofstream &file, const std::string &class
file << templ->genText(data);
}
static void createPluginSourceFile(std::ofstream &file, const std::string &className, const std::string &fileName)
static void createPluginSourceFile(std::ofstream &file,
const std::string &className,
const std::string &fileName)
{
auto templ = drogon::DrTemplateBase::newTemplate("plugin_cc");
HttpViewData data;
@ -72,19 +76,23 @@ void create_plugin::handleCommand(std::vector<std::string> &parameters)
for (auto className : parameters)
{
std::regex regex("::");
std::string fileName = std::regex_replace(className, regex, std::string("_"));
std::string fileName =
std::regex_replace(className, regex, std::string("_"));
std::string headFileName = fileName + ".h";
std::string sourceFilename = fileName + ".cc";
{
std::ifstream iHeadFile(headFileName.c_str(), std::ifstream::in);
std::ifstream iSourceFile(sourceFilename.c_str(), std::ifstream::in);
std::ifstream iSourceFile(sourceFilename.c_str(),
std::ifstream::in);
if (iHeadFile || iSourceFile)
{
std::cout << "The file you want to create already exists, overwrite it(y/n)?" << std::endl;
std::cout << "The file you want to create already exists, "
"overwrite it(y/n)?"
<< std::endl;
auto in = getchar();
(void)getchar(); //get the return key
(void)getchar(); // get the return key
if (in != 'Y' && in != 'y')
{
std::cout << "Abort!" << std::endl;

View File

@ -23,9 +23,12 @@ class create_plugin : public DrObject<create_plugin>, public CommandHandler
{
public:
virtual void handleCommand(std::vector<std::string> &parameters) override;
virtual std::string script() override { return "create plugin class files"; }
virtual std::string script() override
{
return "create plugin class files";
}
protected:
std::string _outputPath = ".";
};
} // namespace drogon_ctl
} // namespace drogon_ctl

View File

@ -32,33 +32,34 @@ void create_project::handleCommand(std::vector<std::string> &parameters)
auto pName = parameters[0];
createProject(pName);
}
static void newCmakeFile(std::ofstream &cmakeFile, const std::string &projectName)
static void newCmakeFile(std::ofstream &cmakeFile,
const std::string &projectName)
{
HttpViewData data;
data.insert("ProjectName",projectName);
auto templ=DrTemplateBase::newTemplate("cmake.csp");
data.insert("ProjectName", projectName);
auto templ = DrTemplateBase::newTemplate("cmake.csp");
cmakeFile << templ->genText(data);
}
static void newMainFile(std::ofstream &mainFile)
{
auto templ=DrTemplateBase::newTemplate("demoMain");
auto templ = DrTemplateBase::newTemplate("demoMain");
mainFile << templ->genText();
}
static void newGitIgFile(std::ofstream &gitFile)
{
auto templ=DrTemplateBase::newTemplate("gitignore.csp");
auto templ = DrTemplateBase::newTemplate("gitignore.csp");
gitFile << templ->genText();
}
static void newUuidFindFile(std::ofstream &uuidFile)
{
auto templ=DrTemplateBase::newTemplate("FindUUID.csp");
auto templ = DrTemplateBase::newTemplate("FindUUID.csp");
uuidFile << templ->genText();
}
static void newJsonFindFile(std::ofstream &jsonFile)
{
auto templ=DrTemplateBase::newTemplate("FindJsoncpp.csp");
auto templ = DrTemplateBase::newTemplate("FindJsoncpp.csp");
jsonFile << templ->genText();
}
@ -76,7 +77,7 @@ static void newSQLite3FindFile(std::ofstream &sqlite3File)
static void newConfigFile(std::ofstream &configFile)
{
auto templ=DrTemplateBase::newTemplate("config");
auto templ = DrTemplateBase::newTemplate("config");
configFile << templ->genText();
}
static void newModelConfigFile(std::ofstream &configFile)
@ -86,15 +87,16 @@ static void newModelConfigFile(std::ofstream &configFile)
}
void create_project::createProject(const std::string &projectName)
{
if (access(projectName.data(), 0) == 0)
{
std::cerr << "The directory already exists, please use another project name!" << std::endl;
std::cerr
<< "The directory already exists, please use another project name!"
<< std::endl;
exit(1);
}
std::cout << "create a project named " << projectName << std::endl;
mkdir(projectName.data(), 0755);
//1.create CMakeLists.txt
// 1.create CMakeLists.txt
auto r = chdir(projectName.data());
(void)(r);
std::ofstream cmakeFile("CMakeLists.txt", std::ofstream::out);
@ -108,13 +110,16 @@ void create_project::createProject(const std::string &projectName)
mkdir("build", 0755);
mkdir("models", 0755);
mkdir("cmake_modules", 0755);
std::ofstream jsonFile("cmake_modules/FindJsoncpp.cmake", std::ofstream::out);
std::ofstream jsonFile("cmake_modules/FindJsoncpp.cmake",
std::ofstream::out);
newJsonFindFile(jsonFile);
std::ofstream uuidFile("cmake_modules/FindUUID.cmake", std::ofstream::out);
newUuidFindFile(uuidFile);
std::ofstream mysqlFile("cmake_modules/FindMySQL.cmake", std::ofstream::out);
std::ofstream mysqlFile("cmake_modules/FindMySQL.cmake",
std::ofstream::out);
newMySQLFindFile(mysqlFile);
std::ofstream sqlite3File("cmake_modules/FindSQLite3.cmake", std::ofstream::out);
std::ofstream sqlite3File("cmake_modules/FindSQLite3.cmake",
std::ofstream::out);
newSQLite3FindFile(sqlite3File);
std::ofstream gitFile(".gitignore", std::ofstream::out);

View File

@ -22,10 +22,13 @@ class create_project : public DrObject<create_project>, public CommandHandler
{
public:
virtual void handleCommand(std::vector<std::string> &parameters) override;
virtual std::string script() override { return "create a project"; }
virtual std::string script() override
{
return "create a project";
}
protected:
std::string _outputPath = ".";
void createProject(const std::string &projectName);
};
} // namespace drogon_ctl
} // namespace drogon_ctl

152
drogon_ctl/create_view.cc Executable file → Normal file
View File

@ -32,14 +32,15 @@ static const std::string sub_view_end = "%>";
using namespace drogon_ctl;
static std::string &replace_all(std::string &str, const std::string &old_value, const std::string &new_value)
static std::string &replace_all(std::string &str,
const std::string &old_value,
const std::string &new_value)
{
std::string::size_type pos(0);
while (true)
{
//std::cout<<str<<endl;
//std::cout<<"pos="<<pos<<endl;
// std::cout<<str<<endl;
// std::cout<<"pos="<<pos<<endl;
if ((pos = str.find(old_value, pos)) != std::string::npos)
{
str = str.replace(pos, old_value.length(), new_value);
@ -51,9 +52,11 @@ static std::string &replace_all(std::string &str, const std::string &old_value,
}
return str;
}
static void parseCxxLine(std::ofstream &oSrcFile, const std::string &line, const std::string &streamName, const std::string &viewDataName)
static void parseCxxLine(std::ofstream &oSrcFile,
const std::string &line,
const std::string &streamName,
const std::string &viewDataName)
{
if (line.length() > 0)
{
std::string tmp = line;
@ -62,29 +65,47 @@ static void parseCxxLine(std::ofstream &oSrcFile, const std::string &line, const
oSrcFile << tmp << "\n";
}
}
static void outputVal(std::ofstream &oSrcFile, const std::string &streamName, const std::string &viewDataName, const std::string &keyName)
static void outputVal(std::ofstream &oSrcFile,
const std::string &streamName,
const std::string &viewDataName,
const std::string &keyName)
{
oSrcFile << "{\n";
oSrcFile << " auto & val=" << viewDataName << "[\"" << keyName << "\"];\n";
oSrcFile << " auto & val=" << viewDataName << "[\"" << keyName
<< "\"];\n";
oSrcFile << " if(val.type()==typeid(const char *)){\n";
oSrcFile << " " << streamName << "<<*any_cast<const char *>(&val);\n";
oSrcFile << " }else if(val.type()==typeid(std::string)||val.type()==typeid(const std::string)){\n";
oSrcFile << " " << streamName << "<<*any_cast<const std::string>(&val);\n";
oSrcFile << " " << streamName
<< "<<*any_cast<const char *>(&val);\n";
oSrcFile << " }else "
"if(val.type()==typeid(std::string)||val.type()==typeid(const "
"std::string)){\n";
oSrcFile << " " << streamName
<< "<<*any_cast<const std::string>(&val);\n";
oSrcFile << " }\n";
oSrcFile << "}\n";
}
static void outputSubView(std::ofstream &oSrcFile, const std::string &streamName, const std::string &viewDataName, const std::string &keyName)
static void outputSubView(std::ofstream &oSrcFile,
const std::string &streamName,
const std::string &viewDataName,
const std::string &keyName)
{
oSrcFile << "{\n";
oSrcFile << " auto templ=DrTemplateBase::newTemplate(\"" << keyName << "\");\n";
oSrcFile << " auto templ=DrTemplateBase::newTemplate(\"" << keyName
<< "\");\n";
oSrcFile << " if(templ){\n";
oSrcFile << " " << streamName << "<< templ->genText(" << viewDataName << ");\n";
oSrcFile << " " << streamName << "<< templ->genText(" << viewDataName
<< ");\n";
oSrcFile << " }\n";
oSrcFile << "}\n";
}
static void parseLine(std::ofstream &oSrcFile, std::string &line, const std::string &streamName, const std::string &viewDataName, int &cxx_flag, int returnFlag = 1)
static void parseLine(std::ofstream &oSrcFile,
std::string &line,
const std::string &streamName,
const std::string &viewDataName,
int &cxx_flag,
int returnFlag = 1)
{
std::string::size_type pos(0);
// std::cout<<line<<"("<<line.length()<<")\n";
@ -98,23 +119,30 @@ static void parseLine(std::ofstream &oSrcFile, std::string &line, const std::str
}
if (cxx_flag == 0)
{
//find cxx lang begin
// find cxx lang begin
if ((pos = line.find(cxx_lang)) != std::string::npos)
{
std::string oldLine = line.substr(0, pos);
if (oldLine.length() > 0)
parseLine(oSrcFile, oldLine, streamName, viewDataName, cxx_flag, 0);
parseLine(
oSrcFile, oldLine, streamName, viewDataName, cxx_flag, 0);
std::string newLine = line.substr(pos + cxx_lang.length());
cxx_flag = 1;
if (newLine.length() > 0)
parseLine(oSrcFile, newLine, streamName, viewDataName, cxx_flag, returnFlag);
parseLine(oSrcFile,
newLine,
streamName,
viewDataName,
cxx_flag,
returnFlag);
}
else
{
if ((pos = line.find(cxx_val_start)) != std::string::npos)
{
std::string oldLine = line.substr(0, pos);
parseLine(oSrcFile, oldLine, streamName, viewDataName, cxx_flag, 0);
parseLine(
oSrcFile, oldLine, streamName, viewDataName, cxx_flag, 0);
std::string newLine = line.substr(pos + cxx_val_start.length());
if ((pos = newLine.find(cxx_val_end)) != std::string::npos)
{
@ -127,8 +155,14 @@ static void parseLine(std::ofstream &oSrcFile, std::string &line, const std::str
iterEnd++;
keyName = std::string(iter, iterEnd);
outputVal(oSrcFile, streamName, viewDataName, keyName);
std::string tailLine = newLine.substr(pos + cxx_val_end.length());
parseLine(oSrcFile, tailLine, streamName, viewDataName, cxx_flag, returnFlag);
std::string tailLine =
newLine.substr(pos + cxx_val_end.length());
parseLine(oSrcFile,
tailLine,
streamName,
viewDataName,
cxx_flag,
returnFlag);
}
else
{
@ -139,8 +173,10 @@ static void parseLine(std::ofstream &oSrcFile, std::string &line, const std::str
else if ((pos = line.find(sub_view_start)) != std::string::npos)
{
std::string oldLine = line.substr(0, pos);
parseLine(oSrcFile, oldLine, streamName, viewDataName, cxx_flag, 0);
std::string newLine = line.substr(pos + sub_view_start.length());
parseLine(
oSrcFile, oldLine, streamName, viewDataName, cxx_flag, 0);
std::string newLine =
line.substr(pos + sub_view_start.length());
if ((pos = newLine.find(sub_view_end)) != std::string::npos)
{
std::string keyName = newLine.substr(0, pos);
@ -152,8 +188,14 @@ static void parseLine(std::ofstream &oSrcFile, std::string &line, const std::str
iterEnd++;
keyName = std::string(iter, iterEnd);
outputSubView(oSrcFile, streamName, viewDataName, keyName);
std::string tailLine = newLine.substr(pos + sub_view_end.length());
parseLine(oSrcFile, tailLine, streamName, viewDataName, cxx_flag, returnFlag);
std::string tailLine =
newLine.substr(pos + sub_view_end.length());
parseLine(oSrcFile,
tailLine,
streamName,
viewDataName,
cxx_flag,
returnFlag);
}
else
{
@ -185,7 +227,12 @@ static void parseLine(std::ofstream &oSrcFile, std::string &line, const std::str
std::string oldLine = line.substr(pos + cxx_end.length());
cxx_flag = 0;
if (oldLine.length() > 0)
parseLine(oSrcFile, oldLine, streamName, viewDataName, cxx_flag, returnFlag);
parseLine(oSrcFile,
oldLine,
streamName,
viewDataName,
cxx_flag,
returnFlag);
}
else
{
@ -219,7 +266,6 @@ void create_view::handleCommand(std::vector<std::string> &parameters)
}
void create_view::createViewFiles(std::vector<std::string> &cspFileNames)
{
for (auto const &file : cspFileNames)
{
std::cout << "create view:" << file << std::endl;
@ -228,7 +274,8 @@ void create_view::createViewFiles(std::vector<std::string> &cspFileNames)
}
int create_view::createViewFile(const std::string &script_filename)
{
std::cout << "create HttpView Class file by " << script_filename << std::endl;
std::cout << "create HttpView Class file by " << script_filename
<< std::endl;
std::ifstream infile(script_filename.c_str(), std::ifstream::in);
if (infile)
{
@ -244,7 +291,8 @@ int create_view::createViewFile(const std::string &script_filename)
std::string headFileName = _outputPath + "/" + className + ".h";
std::string sourceFilename = _outputPath + "/" + className + ".cc";
std::ofstream oHeadFile(headFileName.c_str(), std::ofstream::out);
std::ofstream oSourceFile(sourceFilename.c_str(), std::ofstream::out);
std::ofstream oSourceFile(sourceFilename.c_str(),
std::ofstream::out);
if (!oHeadFile || !oSourceFile)
return -1;
@ -261,20 +309,26 @@ int create_view::createViewFile(const std::string &script_filename)
}
return 0;
}
void create_view::newViewHeaderFile(std::ofstream &file, const std::string &className)
void create_view::newViewHeaderFile(std::ofstream &file,
const std::string &className)
{
file << "//this file is generated by program automatically,don't modify it!\n";
file << "//this file is generated by program automatically,don't modify "
"it!\n";
file << "#include <drogon/DrTemplate.h>\n";
file << "using namespace drogon;\n";
file << "class " << className << ":public DrTemplate<" << className << ">\n";
file << "{\npublic:\n\t" << className << "(){};\n\tvirtual ~"
<< className << "(){};\n\t"
"virtual std::string genText(const DrTemplateData &) override;\n};";
file << "class " << className << ":public DrTemplate<" << className
<< ">\n";
file << "{\npublic:\n\t" << className << "(){};\n\tvirtual ~" << className
<< "(){};\n\t"
"virtual std::string genText(const DrTemplateData &) override;\n};";
}
void create_view::newViewSourceFile(std::ofstream &file, const std::string &className, std::ifstream &infile)
void create_view::newViewSourceFile(std::ofstream &file,
const std::string &className,
std::ifstream &infile)
{
file << "//this file is generated by program(drogon_ctl) automatically,don't modify it!\n";
file << "//this file is generated by program(drogon_ctl) "
"automatically,don't modify it!\n";
file << "#include \"" << className << ".h\"\n";
file << "#include <drogon/config.h>\n";
file << "#include <string>\n";
@ -308,10 +362,13 @@ void create_view::newViewSourceFile(std::ofstream &file, const std::string &clas
if (!import_flag)
{
std::string lowerBuffer = buffer;
std::transform(lowerBuffer.begin(), lowerBuffer.end(), lowerBuffer.begin(), ::tolower);
std::transform(lowerBuffer.begin(),
lowerBuffer.end(),
lowerBuffer.begin(),
::tolower);
if ((pos = lowerBuffer.find(cxx_include)) != std::string::npos)
{
//std::cout<<"haha find it!"<<endl;
// std::cout<<"haha find it!"<<endl;
std::string newLine = buffer.substr(pos + cxx_include.length());
import_flag = 1;
if ((pos = newLine.find(cxx_end)) != std::string::npos)
@ -328,7 +385,7 @@ void create_view::newViewSourceFile(std::ofstream &file, const std::string &clas
}
else
{
//std::cout<<buffer<<endl;
// std::cout<<buffer<<endl;
if ((pos = buffer.find(cxx_end)) != std::string::npos)
{
std::string newLine = buffer.substr(0, pos);
@ -338,27 +395,28 @@ void create_view::newViewSourceFile(std::ofstream &file, const std::string &clas
}
else
{
//std::cout<<"to source file"<<buffer<<endl;
// std::cout<<"to source file"<<buffer<<endl;
file << buffer << "\n";
}
}
}
//std::cout<<"import_flag="<<import_flag<<std::endl;
// std::cout<<"import_flag="<<import_flag<<std::endl;
if (import_flag == 0)
{
infile.clear();
infile.seekg(0, std::ifstream::beg);
}
//std::cout<<"file pos:"<<infile.tellg()<<std::endl;
// std::cout<<"file pos:"<<infile.tellg()<<std::endl;
std::string viewDataName = className + "_view_data";
//virtual std::string genText(const DrTemplateData &)
file << "std::string " << className << "::genText(const DrTemplateData& " << viewDataName << ")\n{\n";
//std::string bodyName=className+"_bodystr";
// virtual std::string genText(const DrTemplateData &)
file << "std::string " << className << "::genText(const DrTemplateData& "
<< viewDataName << ")\n{\n";
// std::string bodyName=className+"_bodystr";
std::string streamName = className + "_tmp_stream";
//oSrcFile <<"\tstd::string "<<bodyName<<";\n";
// oSrcFile <<"\tstd::string "<<bodyName<<";\n";
file << "\tstd::stringstream " << streamName << ";\n";
int cxx_flag = 0;
while (infile.getline(line, sizeof(line)))

11
drogon_ctl/create_view.h Executable file → Normal file
View File

@ -23,13 +23,18 @@ class create_view : public DrObject<create_view>, public CommandHandler
{
public:
virtual void handleCommand(std::vector<std::string> &parameters) override;
virtual std::string script() override { return "create view class files"; }
virtual std::string script() override
{
return "create view class files";
}
protected:
std::string _outputPath = ".";
void createViewFiles(std::vector<std::string> &cspFileNames);
int createViewFile(const std::string &script_filename);
void newViewHeaderFile(std::ofstream &file, const std::string &className);
void newViewSourceFile(std::ofstream &file, const std::string &className, std::ifstream &infile);
void newViewSourceFile(std::ofstream &file,
const std::string &className,
std::ifstream &infile);
};
} // namespace drogon_ctl
} // namespace drogon_ctl

12
drogon_ctl/help.cc Executable file → Normal file
View File

@ -25,10 +25,12 @@ void help::handleCommand(std::vector<std::string> &parameters)
std::cout << "commands list:" << std::endl;
for (auto &className : drogon::DrClassMap::getAllClassName())
{
auto classPtr = std::shared_ptr<DrObjectBase>(drogon::DrClassMap::newObject(className));
auto classPtr = std::shared_ptr<DrObjectBase>(
drogon::DrClassMap::newObject(className));
if (classPtr)
{
auto cmdHdlPtr = std::dynamic_pointer_cast<CommandHandler>(classPtr);
auto cmdHdlPtr =
std::dynamic_pointer_cast<CommandHandler>(classPtr);
if (cmdHdlPtr)
{
if (!cmdHdlPtr->isTopCommand())
@ -49,10 +51,12 @@ void help::handleCommand(std::vector<std::string> &parameters)
{
auto cmd = std::string("drogon_ctl::") + parameters[0];
auto classPtr = std::shared_ptr<DrObjectBase>(drogon::DrClassMap::newObject(cmd));
auto classPtr =
std::shared_ptr<DrObjectBase>(drogon::DrClassMap::newObject(cmd));
if (classPtr)
{
auto cmdHdlPtr = std::dynamic_pointer_cast<CommandHandler>(classPtr);
auto cmdHdlPtr =
std::dynamic_pointer_cast<CommandHandler>(classPtr);
if (cmdHdlPtr)
{
if (cmdHdlPtr->isTopCommand())

12
drogon_ctl/help.h Executable file → Normal file
View File

@ -23,7 +23,13 @@ class help : public DrObject<help>, public CommandHandler
{
public:
virtual void handleCommand(std::vector<std::string> &parameters) override;
virtual std::string script() override { return "display this message"; }
virtual bool isTopCommand() override { return true; }
virtual std::string script() override
{
return "display this message";
}
virtual bool isTopCommand() override
{
return true;
}
};
} // namespace drogon_ctl
} // namespace drogon_ctl

16
drogon_ctl/version.cc Executable file → Normal file
View File

@ -18,12 +18,13 @@
#include <iostream>
using namespace drogon_ctl;
static const char banner[] = " _ \n"
" __| |_ __ ___ __ _ ___ _ __ \n"
" / _` | '__/ _ \\ / _` |/ _ \\| '_ \\ \n"
"| (_| | | | (_) | (_| | (_) | | | |\n"
" \\__,_|_| \\___/ \\__, |\\___/|_| |_|\n"
" |___/ \n";
static const char banner[] =
" _ \n"
" __| |_ __ ___ __ _ ___ _ __ \n"
" / _` | '__/ _ \\ / _` |/ _ \\| '_ \\ \n"
"| (_| | | | (_) | (_| | (_) | | | |\n"
" \\__,_|_| \\___/ \\__, |\\___/|_| |_|\n"
" |___/ \n";
void version::handleCommand(std::vector<std::string> &parameters)
{
@ -31,5 +32,6 @@ void version::handleCommand(std::vector<std::string> &parameters)
std::cout << "drogon ctl tools" << std::endl;
std::cout << "version:" << VERSION << std::endl;
std::cout << "git commit:" << VERSION_MD5 << std::endl;
std::cout << "compile config:" << compileFlags <<" "<< includeDirs << std::endl;
std::cout << "compile config:" << compileFlags << " " << includeDirs
<< std::endl;
}

16
drogon_ctl/version.h Executable file → Normal file
View File

@ -23,8 +23,16 @@ class version : public DrObject<version>, public CommandHandler
{
public:
virtual void handleCommand(std::vector<std::string> &parameters) override;
virtual std::string script() override { return "display version of this tool"; }
virtual bool isTopCommand() override { return true; }
version() {}
virtual std::string script() override
{
return "display version of this tool";
}
virtual bool isTopCommand() override
{
return true;
}
version()
{
}
};
} // namespace drogon_ctl
} // namespace drogon_ctl

View File

@ -1,7 +1,9 @@
#include "BenchmarkCtrl.h"
void BenchmarkCtrl::asyncHandleHttpRequest(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback)
void BenchmarkCtrl::asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
//write your application logic here
// write your application logic here
auto resp = HttpResponse::newHttpResponse();
resp->setBody("<p>Hello, world!</p>");
resp->setExpiredTime(0);

View File

@ -1,11 +1,13 @@
#pragma once
#include <drogon/HttpSimpleController.h>
using namespace drogon;
class BenchmarkCtrl:public drogon::HttpSimpleController<BenchmarkCtrl>
class BenchmarkCtrl : public drogon::HttpSimpleController<BenchmarkCtrl>
{
public:
virtual void asyncHandleHttpRequest(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback)override;
public:
virtual void asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback) override;
PATH_LIST_BEGIN
PATH_ADD("/benchmark",Get);
PATH_ADD("/benchmark", Get);
PATH_LIST_END
};

View File

@ -1,5 +1,7 @@
#include "JsonCtrl.h"
void JsonCtrl::asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback)
void JsonCtrl::asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
Json::Value ret;
ret["message"] = "Hello, World!";

View File

@ -4,9 +4,11 @@ using namespace drogon;
class JsonCtrl : public drogon::HttpSimpleController<JsonCtrl>
{
public:
virtual void asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback) override;
virtual void asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback) override;
PATH_LIST_BEGIN
//list path definitions here;
// list path definitions here;
PATH_ADD("/json", Get);
PATH_LIST_END
};

View File

@ -6,7 +6,7 @@ using namespace drogon;
int main()
{
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
{
int count = 0;
auto client = HttpClient::newHttpClient("http://www.baidu.com");
@ -17,18 +17,23 @@ int main()
for (int i = 0; i < 10; i++)
{
client->sendRequest(req, [&count](ReqResult result, const HttpResponsePtr &response) {
std::cout << "receive response!" << std::endl;
//auto headers=response.
count++;
std::cout << response->getBody() << std::endl;
auto cookies = response->cookies();
for (auto const &cookie : cookies)
{
std::cout << cookie.first << "=" << cookie.second.value() << ":domain=" << cookie.second.domain() << std::endl;
}
std::cout << "count=" << count << std::endl;
});
client->sendRequest(
req,
[&count](ReqResult result, const HttpResponsePtr &response) {
std::cout << "receive response!" << std::endl;
// auto headers=response.
count++;
std::cout << response->getBody() << std::endl;
auto cookies = response->cookies();
for (auto const &cookie : cookies)
{
std::cout << cookie.first << "="
<< cookie.second.value()
<< ":domain=" << cookie.second.domain()
<< std::endl;
}
std::cout << "count=" << count << std::endl;
});
}
}

View File

@ -1,5 +1,5 @@
#include "CustomCtrl.h"
//add definition of your processing function here
// add definition of your processing function here
void CustomCtrl::hello(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,

View File

@ -5,13 +5,20 @@ class CustomCtrl : public drogon::HttpController<CustomCtrl, false>
{
public:
METHOD_LIST_BEGIN
//use METHOD_ADD to add your custom processing function here;
METHOD_ADD(CustomCtrl::hello, "/{1}", Get, "CustomHeaderFilter"); //path is /customctrl/{arg1}
// use METHOD_ADD to add your custom processing function here;
METHOD_ADD(CustomCtrl::hello,
"/{1}",
Get,
"CustomHeaderFilter"); // path is /customctrl/{arg1}
METHOD_LIST_END
explicit CustomCtrl(const std::string &greetings) : _greetings(greetings) {}
explicit CustomCtrl(const std::string &greetings) : _greetings(greetings)
{
}
void hello(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, const std::string &userName) const;
void hello(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
const std::string &userName) const;
private:
std::string _greetings;

View File

@ -14,11 +14,11 @@ void CustomHeaderFilter::doFilter(const HttpRequestPtr &req,
{
if (req->getHeader(_field) == _value)
{
//Passed
// Passed
fccb();
return;
}
//Check failed
// Check failed
auto res = drogon::HttpResponse::newHttpResponse();
res->setStatusCode(k500InternalServerError);
fcb(res);

View File

@ -13,8 +13,9 @@ class CustomHeaderFilter : public HttpFilter<CustomHeaderFilter, false>
{
public:
CustomHeaderFilter(const std::string &field, const std::string &value)
: _field(field),
_value(value) {}
: _field(field), _value(value)
{
}
virtual void doFilter(const HttpRequestPtr &req,
FilterCallback &&fcb,
FilterChainCallback &&fccb) override;

View File

@ -13,7 +13,7 @@ void DoNothingPlugin::initAndStart(const Json::Value &config)
/// Initialize and start the plugin
}
void DoNothingPlugin::shutdown()
void DoNothingPlugin::shutdown()
{
/// Shutdown the plugin
}

View File

@ -9,11 +9,12 @@
#include <drogon/plugins/Plugin.h>
using namespace drogon;
class DoNothingPlugin : public Plugin<DoNothingPlugin>
{
public:
DoNothingPlugin() {}
DoNothingPlugin()
{
}
/// This method must be called by drogon to initialize and start the plugin.
/// It must be implemented by the user.
virtual void initAndStart(const Json::Value &config) override;
@ -22,4 +23,3 @@ class DoNothingPlugin : public Plugin<DoNothingPlugin>
/// It must be implemented by the user.
virtual void shutdown() override;
};

View File

@ -1,8 +1,13 @@
#include "ForwardCtrl.h"
void ForwardCtrl::asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback)
void ForwardCtrl::asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
req->setPath("/repos/an-tao/drogon/git/refs/heads/master");
app().forward(req, [callback = std::move(callback)](const HttpResponsePtr &resp) {
callback(resp);
},"https://api.github.com");
app().forward(
req,
[callback = std::move(callback)](const HttpResponsePtr &resp) {
callback(resp);
},
"https://api.github.com");
}

View File

@ -1,12 +1,14 @@
#pragma once
#include <drogon/HttpSimpleController.h>
using namespace drogon;
class ForwardCtrl:public drogon::HttpSimpleController<ForwardCtrl>
class ForwardCtrl : public drogon::HttpSimpleController<ForwardCtrl>
{
public:
virtual void asyncHandleHttpRequest(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback) override;
public:
virtual void asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback) override;
PATH_LIST_BEGIN
//list path definitions here;
PATH_ADD("/forward",Get);
// list path definitions here;
PATH_ADD("/forward", Get);
PATH_LIST_END
};

4
examples/simple_example/JsonTestController.cc Executable file → Normal file
View File

@ -1,6 +1,8 @@
#include "JsonTestController.h"
#include <json/json.h>
void JsonTestController::asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback)
void JsonTestController::asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
Json::Value json;
json["path"] = "json";

9
examples/simple_example/JsonTestController.h Executable file → Normal file
View File

@ -3,11 +3,14 @@
#include <drogon/HttpSimpleController.h>
using namespace drogon;
class JsonTestController : public drogon::HttpSimpleController<JsonTestController>
class JsonTestController
: public drogon::HttpSimpleController<JsonTestController>
{
public:
//TestController(){}
virtual void asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback) override;
// TestController(){}
virtual void asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback) override;
PATH_LIST_BEGIN
PATH_ADD("/json", Get, "drogon::LocalHostFilter");

9
examples/simple_example/ListParaCtl.cc Executable file → Normal file
View File

@ -1,10 +1,13 @@
#include "ListParaCtl.h"
void ListParaCtl::asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback)
void ListParaCtl::asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
//write your application logic here
// write your application logic here
HttpViewData data;
data.insert("title", "list parameters");
data.insert("parameters", req->getParameters());
auto res = drogon::HttpResponse::newHttpViewResponse("ListParaView.csp", data);
auto res =
drogon::HttpResponse::newHttpViewResponse("ListParaView.csp", data);
callback(res);
}

10
examples/simple_example/ListParaCtl.h Executable file → Normal file
View File

@ -4,10 +4,12 @@ using namespace drogon;
class ListParaCtl : public drogon::HttpSimpleController<ListParaCtl>
{
public:
virtual void asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback) override;
virtual void asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback) override;
PATH_LIST_BEGIN
//list path definations here;
//PATH_ADD("/path","filter1","filter2",...);
PATH_ADD("/listpara",Get);
// list path definations here;
// PATH_ADD("/path","filter1","filter2",...);
PATH_ADD("/listpara", Get);
PATH_LIST_END
};

View File

@ -2,16 +2,19 @@
#include <trantor/net/EventLoop.h>
#include <atomic>
void PipeliningTest::asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback)
void PipeliningTest::asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
static std::atomic<int> counter{0};
int c = counter.fetch_add(1);
double delay = ((double)(10 - (c % 10))) / 10.0;
trantor::EventLoop::getEventLoopOfCurrentThread()->runAfter(delay, [c, callback]() {
auto resp = HttpResponse::newHttpResponse();
auto str = utils::formattedString("<P>the %dth response</P>", c);
resp->addHeader("counter", utils::formattedString("%d", c));
resp->setBody(std::move(str));
callback(resp);
});
trantor::EventLoop::getEventLoopOfCurrentThread()->runAfter(
delay, [c, callback]() {
auto resp = HttpResponse::newHttpResponse();
auto str = utils::formattedString("<P>the %dth response</P>", c);
resp->addHeader("counter", utils::formattedString("%d", c));
resp->setBody(std::move(str));
callback(resp);
});
}

View File

@ -4,9 +4,11 @@ using namespace drogon;
class PipeliningTest : public drogon::HttpSimpleController<PipeliningTest>
{
public:
virtual void asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback) override;
virtual void asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback) override;
PATH_LIST_BEGIN
//list path definitions here;
// list path definitions here;
PATH_ADD("/pipe", Get);
PATH_LIST_END
};

6
examples/simple_example/TestController.cc Executable file → Normal file
View File

@ -1,8 +1,10 @@
#include "TestController.h"
using namespace example;
void TestController::asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback)
void TestController::asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
//write your application logic here
// write your application logic here
LOG_WARN << req->matchedPathPattern();
auto resp = HttpResponse::newHttpResponse();
resp->setBody("<p>Hello, world!</p>");

10
examples/simple_example/TestController.h Executable file → Normal file
View File

@ -6,10 +6,12 @@ namespace example
class TestController : public drogon::HttpSimpleController<TestController>
{
public:
virtual void asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback) override;
virtual void asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback) override;
PATH_LIST_BEGIN
//list path definations here;
//PATH_ADD("/path","filter1","filter2",...);
// list path definations here;
// PATH_ADD("/path","filter1","filter2",...);
PATH_ADD("/", Get);
PATH_ADD("/Test", "nonFilter");
PATH_ADD("/tpost", Post, Options);
@ -20,4 +22,4 @@ class TestController : public drogon::HttpSimpleController<TestController>
LOG_DEBUG << "TestController constructor";
}
};
} // namespace example
} // namespace example

View File

@ -12,11 +12,11 @@ using namespace drogon;
void TestPlugin::initAndStart(const Json::Value &config)
{
/// Initialize and start the plugin
if(config.isNull())
if (config.isNull())
LOG_DEBUG << "Configuration not defined";
_interval = config.get("heartbeat_interval", 1).asInt();
_workThread = std::thread([this]() {
while(!_stop)
while (!_stop)
{
LOG_DEBUG << "TestPlugin heartbeat!";
sleep(_interval);
@ -24,7 +24,7 @@ void TestPlugin::initAndStart(const Json::Value &config)
});
}
void TestPlugin::shutdown()
void TestPlugin::shutdown()
{
/// Shutdown the plugin
_stop = true;

View File

@ -12,7 +12,9 @@ using namespace drogon;
class TestPlugin : public Plugin<TestPlugin>
{
public:
TestPlugin() {}
TestPlugin()
{
}
/// This method must be called by drogon to initialize and start the plugin.
/// It must be implemented by the user.
virtual void initAndStart(const Json::Value &config) override;

6
examples/simple_example/TestViewCtl.cc Executable file → Normal file
View File

@ -1,7 +1,9 @@
#include "TestViewCtl.h"
void TestViewCtl::asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback)
void TestViewCtl::asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
//write your application logic here
// write your application logic here
drogon::HttpViewData data;
data.insert("title", std::string("TestView"));
auto res = drogon::HttpResponse::newHttpViewResponse("TestView", data);

8
examples/simple_example/TestViewCtl.h Executable file → Normal file
View File

@ -4,10 +4,12 @@ using namespace drogon;
class TestViewCtl : public drogon::HttpSimpleController<TestViewCtl>
{
public:
virtual void asyncHandleHttpRequest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback) override;
virtual void asyncHandleHttpRequest(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback) override;
PATH_LIST_BEGIN
//list path definations here;
//PATH_ADD("/path","filter1","filter2",...);
// list path definations here;
// PATH_ADD("/path","filter1","filter2",...);
PATH_ADD("/view");
PATH_ADD("/", Post);
PATH_LIST_END

View File

@ -1,8 +1,10 @@
#include "WebSocketTest.h"
using namespace example;
void WebSocketTest::handleNewMessage(const WebSocketConnectionPtr &wsConnPtr, std::string &&message, const WebSocketMessageType &type)
void WebSocketTest::handleNewMessage(const WebSocketConnectionPtr &wsConnPtr,
std::string &&message,
const WebSocketMessageType &type)
{
//write your application logic here
// write your application logic here
LOG_DEBUG << "new websocket message:" << message;
if (type == WebSocketMessageType::Ping)
{

View File

@ -9,11 +9,13 @@ class WebSocketTest : public drogon::WebSocketController<WebSocketTest>
virtual void handleNewMessage(const WebSocketConnectionPtr &,
std::string &&,
const WebSocketMessageType &) override;
virtual void handleConnectionClosed(const WebSocketConnectionPtr &) override;
virtual void handleNewConnection(const HttpRequestPtr &, const WebSocketConnectionPtr &) override;
virtual void handleConnectionClosed(
const WebSocketConnectionPtr &) override;
virtual void handleNewConnection(const HttpRequestPtr &,
const WebSocketConnectionPtr &) override;
WS_PATH_LIST_BEGIN
//list path definations here;
// list path definations here;
WS_PATH_ADD("/chat");
WS_PATH_LIST_END
};
} // namespace example
} // namespace example

View File

@ -2,7 +2,7 @@
#include <fstream>
using namespace api;
//add definition of your processing function here
// add definition of your processing function here
void Attachment::get(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
@ -16,18 +16,14 @@ void Attachment::upload(const HttpRequestPtr &req,
MultiPartParser fileUpload;
if (fileUpload.parse(req) == 0)
{
//LOG_DEBUG << "upload good!";
// LOG_DEBUG << "upload good!";
auto files = fileUpload.getFiles();
//LOG_DEBUG << "file num=" << files.size();
// LOG_DEBUG << "file num=" << files.size();
for (auto const &file : files)
{
LOG_DEBUG << "file:"
<< file.getFileName()
<< "(len="
<< file.fileLength()
<< ",md5="
<< file.getMd5()
<< ")";
LOG_DEBUG << "file:" << file.getFileName()
<< "(len=" << file.fileLength()
<< ",md5=" << file.getMd5() << ")";
file.save();
file.save("123");
file.saveAs("456/hehe");
@ -47,15 +43,16 @@ void Attachment::upload(const HttpRequestPtr &req,
return;
}
LOG_DEBUG << "upload error!";
//LOG_DEBUG<<req->con
// LOG_DEBUG<<req->con
Json::Value json;
json["result"] = "failed";
auto resp = HttpResponse::newHttpJsonResponse(json);
callback(resp);
}
void Attachment::download(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
void Attachment::download(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
auto resp = HttpResponse::newFileResponse("./drogon.jpg", "", CT_IMAGE_JPG);
callback(resp);

View File

@ -7,12 +7,12 @@ class Attachment : public drogon::HttpController<Attachment>
{
public:
METHOD_LIST_BEGIN
//use METHOD_ADD to add your custom processing function here;
METHOD_ADD(Attachment::get, "", Get); //Path is '/api/attachment'
// use METHOD_ADD to add your custom processing function here;
METHOD_ADD(Attachment::get, "", Get); // Path is '/api/attachment'
METHOD_ADD(Attachment::upload, "/upload", Post);
METHOD_ADD(Attachment::download, "/download", Get);
METHOD_LIST_END
//your declaration of processing function maybe like this:
// your declaration of processing function maybe like this:
void get(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback);
void upload(const HttpRequestPtr &req,
@ -20,4 +20,4 @@ class Attachment : public drogon::HttpController<Attachment>
void download(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback);
};
} // namespace api
} // namespace api

649
examples/simple_example/api_v1_ApiTest.cc Executable file → Normal file
View File

@ -1,13 +1,15 @@
#include "api_v1_ApiTest.h"
using namespace api::v1;
//add definition of your processing function here
void ApiTest::rootGet(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback)
// add definition of your processing function here
void ApiTest::rootGet(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
auto res = HttpResponse::newHttpResponse();
res->setBody("ROOT Get!!!");
callback(res);
}
void ApiTest::rootPost(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback)
void ApiTest::rootPost(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
std::thread([=]() {
auto res = HttpResponse::newHttpResponse();
@ -15,7 +17,10 @@ void ApiTest::rootPost(const HttpRequestPtr &req, std::function<void(const HttpR
callback(res);
}).detach();
}
void ApiTest::get(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, int p1, std::string &&p2)
void ApiTest::get(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int p1,
std::string &&p2)
{
HttpViewData data;
data.insert("title", std::string("ApiTest::get"));
@ -27,7 +32,11 @@ void ApiTest::get(const HttpRequestPtr &req, std::function<void(const HttpRespon
callback(res);
}
void ApiTest::your_method_name(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, double p1, int p2) const
void ApiTest::your_method_name(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
double p1,
int p2) const
{
LOG_WARN << req->matchedPathPattern();
HttpViewData data;
@ -35,327 +44,344 @@ void ApiTest::your_method_name(const HttpRequestPtr &req, std::function<void(con
std::map<std::string, std::string> para;
para["p1"] = std::to_string(p1);
para["p2"] = std::to_string(p2);
para["p3"] = HttpViewData::htmlTranslate("<script>alert(\" This should not be displayed in a browser alert box.\");</script>");
para["p3"] = HttpViewData::htmlTranslate(
"<script>alert(\" This should not be displayed in a browser alert "
"box.\");</script>");
data.insert("parameters", para);
auto res = HttpResponse::newHttpViewResponse("ListParaView", data);
callback(res);
}
void ApiTest::staticApi(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback)
void ApiTest::staticApi(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
auto resp = HttpResponse::newHttpResponse();
resp->setBody("staticApi,hello!!");
resp->setExpiredTime(0); //cache the response forever;
resp->setExpiredTime(0); // cache the response forever;
callback(resp);
}
void ApiTest::get2(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, std::string &&p1)
void ApiTest::get2(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
std::string &&p1)
{
//test gzip feature
// test gzip feature
auto res = HttpResponse::newHttpResponse();
res->setBody("Applications\n"
"Developer\n"
"Library\n"
"Network\n"
"System\n"
"Users\n"
"Volumes\n"
"bin\n"
"cores\n"
"dev\n"
"etc\n"
"home\n"
"installer.failurerequests\n"
"net\n"
"opt\n"
"private\n"
"sbin\n"
"tmp\n"
"usb\n"
"usr\n"
"var\n"
"vm\n"
"用户信息\n"
"\n"
"/Applications:\n"
"Adobe\n"
"Adobe Creative Cloud\n"
"Adobe Photoshop CC\n"
"AirPlayer Pro.app\n"
"Android Studio.app\n"
"App Store.app\n"
"Autodesk\n"
"Automator.app\n"
"Axure RP Pro 7.0.app\n"
"BaiduNetdisk_mac.app\n"
"CLion.app\n"
"Calculator.app\n"
"Calendar.app\n"
"Chess.app\n"
"CleanApp.app\n"
"Contacts.app\n"
"DVD Player.app\n"
"Dashboard.app\n"
"Dictionary.app\n"
"Docs for Xcode.app\n"
"FaceTime.app\n"
"FinalShell\n"
"Firefox.app\n"
"Folx.app\n"
"Font Book.app\n"
"GitHub.app\n"
"Google Chrome.app\n"
"Grammarly.app\n"
"Image Capture.app\n"
"Lantern.app\n"
"Launchpad.app\n"
"License.rtf\n"
"MacPorts\n"
"Mail.app\n"
"Maps.app\n"
"Messages.app\n"
"Microsoft Excel.app\n"
"Microsoft Office 2011\n"
"Microsoft OneNote.app\n"
"Microsoft Outlook.app\n"
"Microsoft PowerPoint.app\n"
"Microsoft Word.app\n"
"Mindjet MindManager.app\n"
"Mission Control.app\n"
"Mockplus.app\n"
"MyEclipse 2015\n"
"Notes.app\n"
"OmniGraffle.app\n"
"PP助手.app\n"
"Pages.app\n"
"Photo Booth.app\n"
"Photos.app\n"
"Preview.app\n"
"QJVPN.app\n"
"QQ.app\n"
"QuickTime Player.app\n"
"RAR Extractor Lite.app\n"
"Reminders.app\n"
"Remote Desktop Connection.app\n"
"Renee Undeleter.app\n"
"Sabaki.app\n"
"Safari.app\n"
"ShadowsocksX.app\n"
"Siri.app\n"
"SogouInputPad.app\n"
"Stickies.app\n"
"System Preferences.app\n"
"TeX\n"
"Telegram.app\n"
"Termius.app\n"
"Tesumego - How to Make a Professional Go Player.app\n"
"TextEdit.app\n"
"Thunder.app\n"
"Time Machine.app\n"
"Tunnelblick.app\n"
"Utilities\n"
"VPN Shield.appdownload\n"
"VirtualBox.app\n"
"WeChat.app\n"
"WinOnX2.app\n"
"Wireshark.app\n"
"Xcode.app\n"
"Yose.app\n"
"YoudaoNote.localized\n"
"finalshelldata\n"
"iBooks.app\n"
"iPhoto.app\n"
"iTools.app\n"
"iTunes.app\n"
"pgAdmin 4.app\n"
"wechatwebdevtools.app\n"
"搜狐影音.appdownload\n"
"网易有道词典.app\n"
"万能数据恢复大师.app\n"
"\n"
"/Applications/Adobe:\n"
"Flash Player\n"
"\n"
"/Applications/Adobe/Flash Player:\n"
"AddIns\n"
"\n"
"/Applications/Adobe/Flash Player/AddIns:\n"
"airappinstaller\n"
"\n"
"/Applications/Adobe/Flash Player/AddIns/airappinstaller:\n"
"airappinstaller\n"
"digest.s\n"
"\n"
"/Applications/Adobe Creative Cloud:\n"
"Adobe Creative Cloud\n"
"Icon\n"
"Uninstall Adobe Creative Cloud\n"
"\n"
"/Applications/Adobe Photoshop CC:\n"
"Adobe Photoshop CC.app\n"
"Configuration\n"
"Icon\n"
"Legal\n"
"LegalNotices.pdf\n"
"Locales\n"
"Plug-ins\n"
"Presets\n"
"卸载 Adobe Photoshop CC\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app:\n"
"Contents\n"
"Linguistics\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents:\n"
"Application Data\n"
"Frameworks\n"
"Info.plist\n"
"MacOS\n"
"PkgInfo\n"
"Required\n"
"Resources\n"
"_CodeSignature\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data:\n"
"Custom File Info Panels\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels:\n"
"4.0\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels/4.0:\n"
"bin\n"
"custom\n"
"panels\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels/4.0/bin:\n"
"FileInfoFoundation.swf\n"
"FileInfoUI.swf\n"
"framework.swf\n"
"loc\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels/4.0/bin/loc:\n"
"FileInfo_ar_AE.dat\n"
"FileInfo_bg_BG.dat\n"
"FileInfo_cs_CZ.dat\n"
"FileInfo_da_DK.dat\n"
"FileInfo_de_DE.dat\n"
"FileInfo_el_GR.dat\n"
"FileInfo_en_US.dat\n"
"FileInfo_es_ES.dat\n"
"FileInfo_et_EE.dat\n"
"FileInfo_fi_FI.dat\n"
"FileInfo_fr_FR.dat\n"
"FileInfo_he_IL.dat\n"
"FileInfo_hr_HR.dat\n"
"FileInfo_hu_HU.dat\n"
"FileInfo_it_IT.dat\n"
"FileInfo_ja_JP.dat\n"
"FileInfo_ko_KR.dat\n"
"FileInfo_lt_LT.dat\n"
"FileInfo_lv_LV.dat\n"
"FileInfo_nb_NO.dat\n"
"FileInfo_nl_NL.dat\n"
"FileInfo_pl_PL.dat\n"
"FileInfo_pt_BR.dat\n"
"FileInfo_ro_RO.dat\n"
"FileInfo_ru_RU.dat\n"
"FileInfo_sk_SK.dat\n"
"FileInfo_sl_SI.dat\n"
"FileInfo_sv_SE.dat\n"
"FileInfo_tr_TR.dat\n"
"FileInfo_uk_UA.dat\n"
"FileInfo_zh_CN.dat\n"
"FileInfo_zh_TW.dat\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels/4.0/custom:\n"
"DICOM.xml\n"
"Mobile.xml\n"
"loc\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels/4.0/custom/loc:\n"
"DICOM_ar_AE.dat\n"
"DICOM_bg_BG.dat\n"
"DICOM_cs_CZ.dat\n"
"DICOM_da_DK.dat\n"
"DICOM_de_DE.dat\n"
"DICOM_el_GR.dat\n"
"DICOM_en_US.dat\n"
"DICOM_es_ES.dat\n"
"DICOM_et_EE.dat\n"
"DICOM_fi_FI.dat\n"
"DICOM_fr_FR.dat\n"
"DICOM_he_IL.dat\n"
"DICOM_hr_HR.dat\n"
"DICOM_hu_HU.dat\n"
"DICOM_it_IT.dat\n"
"DICOM_ja_JP.dat\n"
"DICOM_ko_KR.dat\n"
"DICOM_lt_LT.dat\n"
"DICOM_lv_LV.dat\n"
"DICOM_nb_NO.dat\n"
"DICOM_nl_NL.dat\n"
"DICOM_pl_PL.dat\n"
"DICOM_pt_BR.dat\n"
"DICOM_ro_RO.dat\n"
"DICOM_ru_RU.dat\n"
"DICOM_sk_SK.dat\n"
"DICOM_sl_SI.dat\n"
"DICOM_sv_SE.dat\n"
"DICOM_tr_TR.dat\n"
"DICOM_uk_UA.dat\n"
"DICOM_zh_CN.dat\n"
"DICOM_zh_TW.dat\n"
"Mobile_ar_AE.dat\n"
"Mobile_bg_BG.dat\n"
"Mobile_cs_CZ.dat\n"
"Mobile_da_DK.dat\n"
"Mobile_de_DE.dat\n"
"Mobile_el_GR.dat\n"
"Mobile_en_US.dat\n"
"Mobile_es_ES.dat\n"
"Mobile_et_EE.dat\n"
"Mobile_fi_FI.dat\n"
"Mobile_fr_FR.dat\n"
"Mobile_he_IL.dat\n"
"Mobile_hr_HR.dat\n"
"Mobile_hu_HU.dat\n"
"Mobile_it_IT.dat\n"
"Mobile_ja_JP.dat\n"
"Mobile_ko_KR.dat\n"
"Mobile_lt_LT.dat\n"
"Mobile_lv_LV.dat\n"
"Mobile_nb_NO.dat\n"
"Mobile_nl_NL.dat\n"
"Mobile_pl_PL.dat\n"
"Mobile_pt_BR.dat\n"
"Mobile_ro_RO.dat\n"
"Mobile_ru_RU.dat\n"
"Mobile_sk_SK.dat\n"
"Mobile_sl_SI.dat\n"
"Mobile_sv_SE.dat\n"
"Mobile_tr_TR.dat\n"
"Mobile_uk_UA.dat\n"
"Mobile_zh_CN.dat\n"
"Mobile_zh_TW.dat\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents/Application Data/Custom File Info Panels/4.0/panels:\n"
"IPTC\n"
"IPTCExt\n"
"advanced\n"
"audioData\n"
"camera\n"
"categories\n"
"description\n"
"dicom\n"
"gpsData\n"
"history\n"
"mobile\n"
"origin\n"
"rawpacket");
res->setBody(
"Applications\n"
"Developer\n"
"Library\n"
"Network\n"
"System\n"
"Users\n"
"Volumes\n"
"bin\n"
"cores\n"
"dev\n"
"etc\n"
"home\n"
"installer.failurerequests\n"
"net\n"
"opt\n"
"private\n"
"sbin\n"
"tmp\n"
"usb\n"
"usr\n"
"var\n"
"vm\n"
"用户信息\n"
"\n"
"/Applications:\n"
"Adobe\n"
"Adobe Creative Cloud\n"
"Adobe Photoshop CC\n"
"AirPlayer Pro.app\n"
"Android Studio.app\n"
"App Store.app\n"
"Autodesk\n"
"Automator.app\n"
"Axure RP Pro 7.0.app\n"
"BaiduNetdisk_mac.app\n"
"CLion.app\n"
"Calculator.app\n"
"Calendar.app\n"
"Chess.app\n"
"CleanApp.app\n"
"Contacts.app\n"
"DVD Player.app\n"
"Dashboard.app\n"
"Dictionary.app\n"
"Docs for Xcode.app\n"
"FaceTime.app\n"
"FinalShell\n"
"Firefox.app\n"
"Folx.app\n"
"Font Book.app\n"
"GitHub.app\n"
"Google Chrome.app\n"
"Grammarly.app\n"
"Image Capture.app\n"
"Lantern.app\n"
"Launchpad.app\n"
"License.rtf\n"
"MacPorts\n"
"Mail.app\n"
"Maps.app\n"
"Messages.app\n"
"Microsoft Excel.app\n"
"Microsoft Office 2011\n"
"Microsoft OneNote.app\n"
"Microsoft Outlook.app\n"
"Microsoft PowerPoint.app\n"
"Microsoft Word.app\n"
"Mindjet MindManager.app\n"
"Mission Control.app\n"
"Mockplus.app\n"
"MyEclipse 2015\n"
"Notes.app\n"
"OmniGraffle.app\n"
"PP助手.app\n"
"Pages.app\n"
"Photo Booth.app\n"
"Photos.app\n"
"Preview.app\n"
"QJVPN.app\n"
"QQ.app\n"
"QuickTime Player.app\n"
"RAR Extractor Lite.app\n"
"Reminders.app\n"
"Remote Desktop Connection.app\n"
"Renee Undeleter.app\n"
"Sabaki.app\n"
"Safari.app\n"
"ShadowsocksX.app\n"
"Siri.app\n"
"SogouInputPad.app\n"
"Stickies.app\n"
"System Preferences.app\n"
"TeX\n"
"Telegram.app\n"
"Termius.app\n"
"Tesumego - How to Make a Professional Go Player.app\n"
"TextEdit.app\n"
"Thunder.app\n"
"Time Machine.app\n"
"Tunnelblick.app\n"
"Utilities\n"
"VPN Shield.appdownload\n"
"VirtualBox.app\n"
"WeChat.app\n"
"WinOnX2.app\n"
"Wireshark.app\n"
"Xcode.app\n"
"Yose.app\n"
"YoudaoNote.localized\n"
"finalshelldata\n"
"iBooks.app\n"
"iPhoto.app\n"
"iTools.app\n"
"iTunes.app\n"
"pgAdmin 4.app\n"
"wechatwebdevtools.app\n"
"搜狐影音.appdownload\n"
"网易有道词典.app\n"
"万能数据恢复大师.app\n"
"\n"
"/Applications/Adobe:\n"
"Flash Player\n"
"\n"
"/Applications/Adobe/Flash Player:\n"
"AddIns\n"
"\n"
"/Applications/Adobe/Flash Player/AddIns:\n"
"airappinstaller\n"
"\n"
"/Applications/Adobe/Flash Player/AddIns/airappinstaller:\n"
"airappinstaller\n"
"digest.s\n"
"\n"
"/Applications/Adobe Creative Cloud:\n"
"Adobe Creative Cloud\n"
"Icon\n"
"Uninstall Adobe Creative Cloud\n"
"\n"
"/Applications/Adobe Photoshop CC:\n"
"Adobe Photoshop CC.app\n"
"Configuration\n"
"Icon\n"
"Legal\n"
"LegalNotices.pdf\n"
"Locales\n"
"Plug-ins\n"
"Presets\n"
"卸载 Adobe Photoshop CC\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app:\n"
"Contents\n"
"Linguistics\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop CC.app/Contents:\n"
"Application Data\n"
"Frameworks\n"
"Info.plist\n"
"MacOS\n"
"PkgInfo\n"
"Required\n"
"Resources\n"
"_CodeSignature\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop "
"CC.app/Contents/Application Data:\n"
"Custom File Info Panels\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop "
"CC.app/Contents/Application Data/Custom File Info Panels:\n"
"4.0\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop "
"CC.app/Contents/Application Data/Custom File Info Panels/4.0:\n"
"bin\n"
"custom\n"
"panels\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop "
"CC.app/Contents/Application Data/Custom File Info Panels/4.0/bin:\n"
"FileInfoFoundation.swf\n"
"FileInfoUI.swf\n"
"framework.swf\n"
"loc\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop "
"CC.app/Contents/Application Data/Custom File Info "
"Panels/4.0/bin/loc:\n"
"FileInfo_ar_AE.dat\n"
"FileInfo_bg_BG.dat\n"
"FileInfo_cs_CZ.dat\n"
"FileInfo_da_DK.dat\n"
"FileInfo_de_DE.dat\n"
"FileInfo_el_GR.dat\n"
"FileInfo_en_US.dat\n"
"FileInfo_es_ES.dat\n"
"FileInfo_et_EE.dat\n"
"FileInfo_fi_FI.dat\n"
"FileInfo_fr_FR.dat\n"
"FileInfo_he_IL.dat\n"
"FileInfo_hr_HR.dat\n"
"FileInfo_hu_HU.dat\n"
"FileInfo_it_IT.dat\n"
"FileInfo_ja_JP.dat\n"
"FileInfo_ko_KR.dat\n"
"FileInfo_lt_LT.dat\n"
"FileInfo_lv_LV.dat\n"
"FileInfo_nb_NO.dat\n"
"FileInfo_nl_NL.dat\n"
"FileInfo_pl_PL.dat\n"
"FileInfo_pt_BR.dat\n"
"FileInfo_ro_RO.dat\n"
"FileInfo_ru_RU.dat\n"
"FileInfo_sk_SK.dat\n"
"FileInfo_sl_SI.dat\n"
"FileInfo_sv_SE.dat\n"
"FileInfo_tr_TR.dat\n"
"FileInfo_uk_UA.dat\n"
"FileInfo_zh_CN.dat\n"
"FileInfo_zh_TW.dat\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop "
"CC.app/Contents/Application Data/Custom File Info Panels/4.0/custom:\n"
"DICOM.xml\n"
"Mobile.xml\n"
"loc\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop "
"CC.app/Contents/Application Data/Custom File Info "
"Panels/4.0/custom/loc:\n"
"DICOM_ar_AE.dat\n"
"DICOM_bg_BG.dat\n"
"DICOM_cs_CZ.dat\n"
"DICOM_da_DK.dat\n"
"DICOM_de_DE.dat\n"
"DICOM_el_GR.dat\n"
"DICOM_en_US.dat\n"
"DICOM_es_ES.dat\n"
"DICOM_et_EE.dat\n"
"DICOM_fi_FI.dat\n"
"DICOM_fr_FR.dat\n"
"DICOM_he_IL.dat\n"
"DICOM_hr_HR.dat\n"
"DICOM_hu_HU.dat\n"
"DICOM_it_IT.dat\n"
"DICOM_ja_JP.dat\n"
"DICOM_ko_KR.dat\n"
"DICOM_lt_LT.dat\n"
"DICOM_lv_LV.dat\n"
"DICOM_nb_NO.dat\n"
"DICOM_nl_NL.dat\n"
"DICOM_pl_PL.dat\n"
"DICOM_pt_BR.dat\n"
"DICOM_ro_RO.dat\n"
"DICOM_ru_RU.dat\n"
"DICOM_sk_SK.dat\n"
"DICOM_sl_SI.dat\n"
"DICOM_sv_SE.dat\n"
"DICOM_tr_TR.dat\n"
"DICOM_uk_UA.dat\n"
"DICOM_zh_CN.dat\n"
"DICOM_zh_TW.dat\n"
"Mobile_ar_AE.dat\n"
"Mobile_bg_BG.dat\n"
"Mobile_cs_CZ.dat\n"
"Mobile_da_DK.dat\n"
"Mobile_de_DE.dat\n"
"Mobile_el_GR.dat\n"
"Mobile_en_US.dat\n"
"Mobile_es_ES.dat\n"
"Mobile_et_EE.dat\n"
"Mobile_fi_FI.dat\n"
"Mobile_fr_FR.dat\n"
"Mobile_he_IL.dat\n"
"Mobile_hr_HR.dat\n"
"Mobile_hu_HU.dat\n"
"Mobile_it_IT.dat\n"
"Mobile_ja_JP.dat\n"
"Mobile_ko_KR.dat\n"
"Mobile_lt_LT.dat\n"
"Mobile_lv_LV.dat\n"
"Mobile_nb_NO.dat\n"
"Mobile_nl_NL.dat\n"
"Mobile_pl_PL.dat\n"
"Mobile_pt_BR.dat\n"
"Mobile_ro_RO.dat\n"
"Mobile_ru_RU.dat\n"
"Mobile_sk_SK.dat\n"
"Mobile_sl_SI.dat\n"
"Mobile_sv_SE.dat\n"
"Mobile_tr_TR.dat\n"
"Mobile_uk_UA.dat\n"
"Mobile_zh_CN.dat\n"
"Mobile_zh_TW.dat\n"
"\n"
"/Applications/Adobe Photoshop CC/Adobe Photoshop "
"CC.app/Contents/Application Data/Custom File Info Panels/4.0/panels:\n"
"IPTC\n"
"IPTCExt\n"
"advanced\n"
"audioData\n"
"camera\n"
"categories\n"
"description\n"
"dicom\n"
"gpsData\n"
"history\n"
"mobile\n"
"origin\n"
"rawpacket");
res->setExpiredTime(0);
callback(res);
}
void ApiTest::jsonTest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback)
void ApiTest::jsonTest(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
auto json = req->getJsonObject();
Json::Value ret;
@ -371,7 +397,8 @@ void ApiTest::jsonTest(const HttpRequestPtr &req, std::function<void(const HttpR
callback(resp);
}
void ApiTest::formTest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback)
void ApiTest::formTest(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
auto parameters = req->getParameters();
Json::Value ret;

64
examples/simple_example/api_v1_ApiTest.h Executable file → Normal file
View File

@ -9,27 +9,55 @@ class ApiTest : public drogon::HttpController<ApiTest>
{
public:
METHOD_LIST_BEGIN
//use METHOD_ADD to add your custom processing function here;
METHOD_ADD(ApiTest::rootGet, "", "TimeFilter", Get, Options, "drogon::LocalHostFilter", "drogon::IntranetIpFilter");
// use METHOD_ADD to add your custom processing function here;
METHOD_ADD(ApiTest::rootGet,
"",
"TimeFilter",
Get,
Options,
"drogon::LocalHostFilter",
"drogon::IntranetIpFilter");
METHOD_ADD(ApiTest::rootPost, "", Post, Options);
METHOD_ADD(ApiTest::get, "/get/{2}/{1}", Get); //path is /api/v1/apitest/get/{arg2}/{arg1}
METHOD_ADD(ApiTest::your_method_name, "/{1}/List?P2={2}", Get); //path is /api/v1/apitest/{arg1}/list
METHOD_ADD(ApiTest::staticApi, "/static", Get, Options); //CORS
METHOD_ADD(ApiTest::get,
"/get/{2}/{1}",
Get); // path is /api/v1/apitest/get/{arg2}/{arg1}
METHOD_ADD(ApiTest::your_method_name,
"/{1}/List?P2={2}",
Get); // path is /api/v1/apitest/{arg1}/list
METHOD_ADD(ApiTest::staticApi, "/static", Get, Options); // CORS
METHOD_ADD(ApiTest::staticApi, "/static", Post, Put, Delete);
METHOD_ADD(ApiTest::get2, "/get/{1}", Get); //path is /api/v1/apitest/get/{arg1}
ADD_METHOD_TO(ApiTest::get2, "/absolute/{1}", Get); //path is /absolute/{arg1}
METHOD_ADD(ApiTest::get2,
"/get/{1}",
Get); // path is /api/v1/apitest/get/{arg1}
ADD_METHOD_TO(ApiTest::get2,
"/absolute/{1}",
Get); // path is /absolute/{arg1}
METHOD_ADD(ApiTest::jsonTest, "/json", Post);
METHOD_ADD(ApiTest::formTest, "/form", Post);
METHOD_LIST_END
//your declaration of processing function maybe like this:
void get(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, int p1, std::string &&p2);
void your_method_name(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, double p1, int p2) const;
void staticApi(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback);
void get2(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, std::string &&p1);
void rootGet(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback);
void rootPost(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback);
void jsonTest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback);
void formTest(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback);
// your declaration of processing function maybe like this:
void get(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int p1,
std::string &&p2);
void your_method_name(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
double p1,
int p2) const;
void staticApi(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback);
void get2(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
std::string &&p1);
void rootGet(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback);
void rootPost(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback);
void jsonTest(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback);
void formTest(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback);
public:
ApiTest()
@ -37,5 +65,5 @@ class ApiTest : public drogon::HttpController<ApiTest>
LOG_DEBUG << "ApiTest constructor!";
}
};
} // namespace v1
} // namespace api
} // namespace v1
} // namespace api

179
examples/simple_example/main.cc Executable file → Normal file
View File

@ -9,10 +9,13 @@ using namespace drogon;
using namespace std::chrono_literals;
class A : public DrObjectBase
{
public:
public:
void handle(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int p1, const std::string &p2, const std::string &p3, int p4) const
int p1,
const std::string &p2,
const std::string &p3,
int p4) const
{
HttpViewData data;
data.insert("title", std::string("ApiTest::get"));
@ -26,9 +29,13 @@ public:
auto res = HttpResponse::newHttpViewResponse("ListParaView", data);
callback(res);
}
static void staticHandle(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int p1, const std::string &p2, const std::string &p3, int p4)
static void staticHandle(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int p1,
const std::string &p2,
const std::string &p3,
int p4)
{
HttpViewData data;
data.insert("title", std::string("ApiTest::get"));
@ -45,8 +52,11 @@ public:
};
class B : public DrObjectBase
{
public:
void operator()(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, int p1, int p2)
public:
void operator()(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int p1,
int p2)
{
HttpViewData data;
data.insert("title", std::string("ApiTest::get"));
@ -64,12 +74,19 @@ namespace v1
{
class Test : public HttpController<Test>
{
public:
public:
METHOD_LIST_BEGIN
METHOD_ADD(Test::get, "get/{2}/{1}", Get); //path is /api/v1/test/get/{arg2}/{arg1}
METHOD_ADD(Test::list, "/{2}/info", Get); //path is /api/v1/test/{arg2}/info
METHOD_ADD(Test::get,
"get/{2}/{1}",
Get); // path is /api/v1/test/get/{arg2}/{arg1}
METHOD_ADD(Test::list,
"/{2}/info",
Get); // path is /api/v1/test/{arg2}/info
METHOD_LIST_END
void get(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, int p1, int p2) const
void get(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int p1,
int p2) const
{
HttpViewData data;
data.insert("title", std::string("ApiTest::get"));
@ -80,7 +97,10 @@ public:
auto res = HttpResponse::newHttpViewResponse("ListParaView", data);
callback(res);
}
void list(const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, int p1, int p2) const
void list(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int p1,
int p2) const
{
HttpViewData data;
data.insert("title", std::string("ApiTest::get"));
@ -92,75 +112,87 @@ public:
callback(res);
}
};
} // namespace v1
} // namespace api
} // namespace v1
} // namespace api
using namespace std::placeholders;
using namespace drogon;
int main()
{
std::cout << banner << std::endl;
//app().addListener("::1", 8848);
// app().addListener("::1", 8848);
app().addListener("0.0.0.0", 8848);
#ifdef USE_OPENSSL
//https
drogon::HttpAppFramework::instance().setSSLFiles("server.pem", "server.pem");
//drogon::HttpAppFramework::instance().addListener("::1", 8849, true);
drogon::HttpAppFramework::instance().addListener("0.0.0.0", 8849, true);
// https
drogon::app().setSSLFiles("server.pem", "server.pem");
// drogon::app().addListener("::1", 8849, true);
drogon::app().addListener("0.0.0.0", 8849, true);
#endif
//app().setThreadNum(4);
// app().setThreadNum(4);
// trantor::Logger::setLogLevel(trantor::Logger::TRACE);
//class function
// class function
app().registerHandler("/api/v1/handle1/{1}/{2}/?p3={3}&p4={4}", &A::handle);
app().registerHandler("/api/v1/handle11/{1}/{2}/?p3={3}&p4={4}", &A::staticHandle);
//lambda example
app().registerHandler("/api/v1/handle2/{1}/{2}", [](const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> &&callback, int a, float b) {
// LOG_DEBUG << "int a=" << a;
// LOG_DEBUG << "float b=" << b;
HttpViewData data;
data.insert("title", std::string("ApiTest::get"));
std::map<std::string, std::string> para;
para["a"] = std::to_string(a);
para["b"] = std::to_string(b);
data.insert("parameters", para);
auto res = HttpResponse::newHttpViewResponse("ListParaView", data);
callback(res);
});
app().registerHandler("/api/v1/handle11/{1}/{2}/?p3={3}&p4={4}",
&A::staticHandle);
// lambda example
app().registerHandler(
"/api/v1/handle2/{1}/{2}",
[](const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
int a,
float b) {
// LOG_DEBUG << "int a=" << a;
// LOG_DEBUG << "float b=" << b;
HttpViewData data;
data.insert("title", std::string("ApiTest::get"));
std::map<std::string, std::string> para;
para["a"] = std::to_string(a);
para["b"] = std::to_string(b);
data.insert("parameters", para);
auto res = HttpResponse::newHttpViewResponse("ListParaView", data);
callback(res);
});
B b;
//functor example
// functor example
app().registerHandler("/api/v1/handle3/{1}/{2}", b);
A tmp;
std::function<void(const HttpRequestPtr &, std::function<void(const HttpResponsePtr &)> &&, int, const std::string &, const std::string &, int)>
std::function<void(const HttpRequestPtr &,
std::function<void(const HttpResponsePtr &)> &&,
int,
const std::string &,
const std::string &,
int)>
func = std::bind(&A::handle, &tmp, _1, _2, _3, _4, _5, _6);
//api example for std::function
// api example for std::function
app().registerHandler("/api/v1/handle4/{4}/{3}/{1}", func);
app().setDocumentRoot("./");
app().enableSession(60);
//start app framework
//drogon::HttpAppFramework::instance().enableDynamicViewsLoading({"/tmp/views"});
// start app framework
// drogon::app().enableDynamicViewsLoading({"/tmp/views"});
app().loadConfigFile("config.example.json");
auto &json = app().getCustomConfig();
if (json.empty())
{
std::cout << "empty custom config!" << std::endl;
}
//Install custom controller
// Install custom controller
auto ctrlPtr = std::make_shared<CustomCtrl>("Hi");
app().registerController(ctrlPtr);
//Install custom filter
auto filterPtr = std::make_shared<CustomHeaderFilter>("custom_header", "yes");
// Install custom filter
auto filterPtr =
std::make_shared<CustomHeaderFilter>("custom_header", "yes");
app().registerFilter(filterPtr);
app().setIdleConnectionTimeout(30s);
//Test AOP
app().registerBeginningAdvice([]() {
LOG_DEBUG << "Event loop is running!";
});
app().registerNewConnectionAdvice([](const trantor::InetAddress &peer, const trantor::InetAddress &local) {
LOG_DEBUG << "New connection: " << peer.toIpPort() << "-->" << local.toIpPort();
// Test AOP
app().registerBeginningAdvice(
[]() { LOG_DEBUG << "Event loop is running!"; });
app().registerNewConnectionAdvice([](const trantor::InetAddress &peer,
const trantor::InetAddress &local) {
LOG_DEBUG << "New connection: " << peer.toIpPort() << "-->"
<< local.toIpPort();
return true;
});
app().registerPreRoutingAdvice([](const drogon::HttpRequestPtr &req,
@ -185,9 +217,10 @@ int main()
// return;
accb();
});
app().registerPostHandlingAdvice([](const drogon::HttpRequestPtr &, const drogon::HttpResponsePtr &) {
LOG_DEBUG << "postHandling1";
});
app().registerPostHandlingAdvice(
[](const drogon::HttpRequestPtr &, const drogon::HttpResponsePtr &) {
LOG_DEBUG << "postHandling1";
});
app().registerPreRoutingAdvice([](const drogon::HttpRequestPtr &req) {
LOG_DEBUG << "preRouting observer";
});
@ -203,26 +236,26 @@ int main()
std::cout << std::get<0>(info);
switch (std::get<1>(info))
{
case Get:
std::cout << " (GET) ";
break;
case Post:
std::cout << " (POST) ";
break;
case Delete:
std::cout << " (DELETE) ";
break;
case Put:
std::cout << " (PUT) ";
break;
case Options:
std::cout << " (OPTIONS) ";
break;
case Head:
std::cout << " (Head) ";
break;
default:
break;
case Get:
std::cout << " (GET) ";
break;
case Post:
std::cout << " (POST) ";
break;
case Delete:
std::cout << " (DELETE) ";
break;
case Put:
std::cout << " (PUT) ";
break;
case Options:
std::cout << " (OPTIONS) ";
break;
case Head:
std::cout << " (Head) ";
break;
default:
break;
}
std::cout << std::get<2>(info) << std::endl;
}

45
examples/simple_example_test/HttpPipeliningTest.cc Executable file → Normal file
View File

@ -15,33 +15,34 @@ int main()
int n = 0;
for (int i = 0; i < 20; i++)
{
client->sendRequest(request, [&counter, &n](ReqResult r, const HttpResponsePtr &resp) {
if (r == ReqResult::Ok)
{
auto counterHeader = resp->getHeader("counter");
int c = atoi(counterHeader.data());
if (c <= counter)
client->sendRequest(
request, [&counter, &n](ReqResult r, const HttpResponsePtr &resp) {
if (r == ReqResult::Ok)
{
LOG_ERROR << "The response was received in the wrong order!";
exit(-1);
auto counterHeader = resp->getHeader("counter");
int c = atoi(counterHeader.data());
if (c <= counter)
{
LOG_ERROR
<< "The response was received in the wrong order!";
exit(-1);
}
else
{
counter = c;
n++;
if (n == 20)
{
LOG_DEBUG << "Good!";
app().getLoop()->quit();
}
}
}
else
{
counter = c;
n++;
if(n==20)
{
LOG_DEBUG << "Good!";
app().getLoop()->quit();
}
exit(-1);
}
}
else
{
exit(-1);
}
});
});
}
app().run();
}

View File

@ -18,7 +18,9 @@ int main(int argc, char *argv[])
continually = false;
}
req->setPath("/chat");
wsPtr->setMessageHandler([continually](const std::string &message, const WebSocketClientPtr &wsPtr, const WebSocketMessageType &type) {
wsPtr->setMessageHandler([continually](const std::string &message,
const WebSocketClientPtr &wsPtr,
const WebSocketMessageType &type) {
std::cout << "new message:" << message << std::endl;
if (type == WebSocketMessageType::Pong)
{
@ -32,22 +34,26 @@ int main(int argc, char *argv[])
wsPtr->setConnectionClosedHandler([](const WebSocketClientPtr &wsPtr) {
std::cout << "ws closed!" << std::endl;
});
wsPtr->connectToServer(req, [continually](ReqResult r, const HttpResponsePtr &resp, const WebSocketClientPtr &wsPtr) {
if (r == ReqResult::Ok)
{
std::cout << "ws connected!" << std::endl;
wsPtr->getConnection()->setPingMessage("", 2s);
wsPtr->getConnection()->send("hello!");
}
else
{
std::cout << "ws failed!" << std::endl;
if (!continually)
{
exit(-1);
}
}
});
wsPtr->connectToServer(req,
[continually](ReqResult r,
const HttpResponsePtr &resp,
const WebSocketClientPtr &wsPtr) {
if (r == ReqResult::Ok)
{
std::cout << "ws connected!" << std::endl;
wsPtr->getConnection()->setPingMessage("",
2s);
wsPtr->getConnection()->send("hello!");
}
else
{
std::cout << "ws failed!" << std::endl;
if (!continually)
{
exit(-1);
}
}
});
app().getLoop()->runAfter(5.0, [continually]() {
if (!continually)
{

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,3 @@
#!/bin/sh
find lib orm_lib -name *.h -o -name *.cc|xargs clang-format -i -style=file
find lib orm_lib examples drogon_ctl -name *.h -o -name *.cc|xargs clang-format -i -style=file

View File

@ -51,12 +51,9 @@ class DrClassMap
{
std::size_t len = 0;
int status = 0;
std::unique_ptr<char, decltype(&std::free)>
ptr(__cxxabiv1::__cxa_demangle(mangled_name,
nullptr,
&len,
&status),
&std::free);
std::unique_ptr<char, decltype(&std::free)> ptr(
__cxxabiv1::__cxa_demangle(mangled_name, nullptr, &len, &status),
&std::free);
if (status == 0)
{
return std::string(ptr.get());

View File

@ -314,8 +314,9 @@ class HttpAppFramework : public trantor::NonCopyable
* FOR EXAMPLE:
* app.registerHandler("/hello?username={1}",
* [](const HttpRequestPtr& req,
* const std::function<void (const HttpResponsePtr
* &)> & callback, const std::string &name)
* std::function<void (const HttpResponsePtr
* &)> &&callback,
* const std::string &name)
* {
* Json::Value json;
* json["result"]="ok";
@ -367,11 +368,8 @@ class HttpAppFramework : public trantor::NonCopyable
exit(1);
}
}
registerHttpController(pathPattern,
binder,
validMethods,
filters,
handlerName);
registerHttpController(
pathPattern, binder, validMethods, filters, handlerName);
}
/// Register a WebSocketController into the framework.
@ -411,12 +409,11 @@ class HttpAppFramework : public trantor::NonCopyable
template <typename T>
void registerController(const std::shared_ptr<T> &ctrlPtr)
{
static_assert(internal::IsSubClass<T, HttpControllerBase>::value ||
internal::IsSubClass<T, HttpSimpleControllerBase>::
value ||
internal::IsSubClass<T,
WebSocketControllerBase>::value,
"Error! Only controller objects can be registered here");
static_assert(
internal::IsSubClass<T, HttpControllerBase>::value ||
internal::IsSubClass<T, HttpSimpleControllerBase>::value ||
internal::IsSubClass<T, WebSocketControllerBase>::value,
"Error! Only controller objects can be registered here");
static_assert(!T::isAutoCreation,
"Controllers created and initialized "
"automatically by drogon cannot be "

View File

@ -140,12 +140,10 @@ class HttpBinder : public HttpBinderBase
{
// call this function recursively until parameter's count equals to the
// count of target function parameters
static_assert(BinderArgTypeTraits<
nth_argument_type<sizeof...(Values)>>::isValid,
"your handler argument type must be value type or const "
"left "
"reference "
"type or right reference type");
static_assert(
BinderArgTypeTraits<nth_argument_type<sizeof...(Values)>>::isValid,
"your handler argument type must be value type or const left "
"reference type or right reference type");
typedef typename std::remove_cv<typename std::remove_reference<
nth_argument_type<sizeof...(Values)>>::type>::type ValueType;
ValueType value = ValueType();

View File

@ -58,11 +58,8 @@ class HttpSimpleController : public DrObject<T>, public HttpSimpleControllerBase
LOG_TRACE << "register simple controller("
<< HttpSimpleController<T>::classTypeName()
<< ") on path:" << path;
HttpAppFramework::instance()
.registerHttpSimpleController(path,
HttpSimpleController<
T>::classTypeName(),
filtersAndMethods);
app().registerHttpSimpleController(
path, HttpSimpleController<T>::classTypeName(), filtersAndMethods);
}
private:

View File

@ -76,11 +76,10 @@ class WebSocketController : public DrObject<T>, public WebSocketControllerBase
LOG_TRACE << "register websocket controller ("
<< WebSocketController<T>::classTypeName()
<< ") on path:" << path.first;
HttpAppFramework::instance()
.registerWebSocketController(path.first,
WebSocketController<
T>::classTypeName(),
path.second);
app().registerWebSocketController(
path.first,
WebSocketController<T>::classTypeName(),
path.second);
}
}

View File

@ -169,11 +169,8 @@ void HttpAppFrameworkImpl::registerHttpController(
assert(!pathPattern.empty());
assert(binder);
assert(!_running);
_httpCtrlsRouter.addHttpPath(pathPattern,
binder,
validMethods,
filters,
handlerName);
_httpCtrlsRouter.addHttpPath(
pathPattern, binder, validMethods, filters, handlerName);
}
void HttpAppFrameworkImpl::setThreadNum(size_t threadNum)
{
@ -345,23 +342,17 @@ void HttpAppFrameworkImpl::run()
"drogonPortTest",
true,
false);
serverPtr =
std::make_shared<HttpServer>(loopThreadPtr->getLoop(),
InetAddress(ip,
std::get<1>(
listener),
isIpv6),
"drogon");
serverPtr = std::make_shared<HttpServer>(
loopThreadPtr->getLoop(),
InetAddress(ip, std::get<1>(listener), isIpv6),
"drogon");
}
else
{
serverPtr =
std::make_shared<HttpServer>(loopThreadPtr->getLoop(),
InetAddress(ip,
std::get<1>(
listener),
isIpv6),
"drogon");
serverPtr = std::make_shared<HttpServer>(
loopThreadPtr->getLoop(),
InetAddress(ip, std::get<1>(listener), isIpv6),
"drogon");
}
if (std::get<2>(listener))
@ -385,12 +376,8 @@ void HttpAppFrameworkImpl::run()
}
serverPtr->setHttpAsyncCallback(
std::bind(&HttpAppFrameworkImpl::onAsyncRequest, this, _1, _2));
serverPtr->setNewWebsocketCallback(
std::bind(&HttpAppFrameworkImpl::onNewWebsockRequest,
this,
_1,
_2,
_3));
serverPtr->setNewWebsocketCallback(std::bind(
&HttpAppFrameworkImpl::onNewWebsockRequest, this, _1, _2, _3));
serverPtr->setConnectionCallback(
std::bind(&HttpAppFrameworkImpl::onConnection, this, _1));
serverPtr->kickoffIdleConnections(_idleConnectionTimeout);
@ -407,12 +394,10 @@ void HttpAppFrameworkImpl::run()
loopThreads.push_back(loopThreadPtr);
auto ip = std::get<0>(listener);
bool isIpv6 = ip.find(":") == std::string::npos ? false : true;
auto serverPtr =
std::make_shared<HttpServer>(loopThreadPtr->getLoop(),
InetAddress(ip,
std::get<1>(listener),
isIpv6),
"drogon");
auto serverPtr = std::make_shared<HttpServer>(
loopThreadPtr->getLoop(),
InetAddress(ip, std::get<1>(listener), isIpv6),
"drogon");
if (std::get<2>(listener))
{
#ifdef USE_OPENSSL
@ -434,12 +419,8 @@ void HttpAppFrameworkImpl::run()
serverPtr->setIoLoopNum(_threadNum);
serverPtr->setHttpAsyncCallback(
std::bind(&HttpAppFrameworkImpl::onAsyncRequest, this, _1, _2));
serverPtr->setNewWebsocketCallback(
std::bind(&HttpAppFrameworkImpl::onNewWebsockRequest,
this,
_1,
_2,
_3));
serverPtr->setNewWebsocketCallback(std::bind(
&HttpAppFrameworkImpl::onNewWebsockRequest, this, _1, _2, _3));
serverPtr->setConnectionCallback(
std::bind(&HttpAppFrameworkImpl::onConnection, this, _1));
serverPtr->kickoffIdleConnections(_idleConnectionTimeout);
@ -485,10 +466,8 @@ void HttpAppFrameworkImpl::run()
}
}
_sessionMapPtr = std::unique_ptr<CacheMap<std::string, SessionPtr>>(
new CacheMap<std::string, SessionPtr>(getLoop(),
1.0,
wheelNum,
bucketNum));
new CacheMap<std::string, SessionPtr>(
getLoop(), 1.0, wheelNum, bucketNum));
}
else if (_sessionTimeout == 0)
{
@ -498,12 +477,12 @@ void HttpAppFrameworkImpl::run()
}
_responseCachingMap =
std::unique_ptr<CacheMap<std::string, HttpResponsePtr>>(
new CacheMap<std::string,
HttpResponsePtr>(getLoop(),
1.0,
4,
50)); // Max timeout up to about 70
// days;
new CacheMap<std::string, HttpResponsePtr>(
getLoop(),
1.0,
4,
50)); // Max timeout up to about 70
// days;
// Initialize plugins
const auto &pluginConfig = _jsonConfig["plugins"];
@ -544,10 +523,8 @@ void HttpAppFrameworkImpl::createDbClients(
{
_dbFastClientsMap[dbInfo._name][loop] =
std::shared_ptr<drogon::orm::DbClient>(
new drogon::orm::
DbClientLockFree(dbInfo._connectionInfo,
loop,
dbInfo._dbType));
new drogon::orm::DbClientLockFree(
dbInfo._connectionInfo, loop, dbInfo._dbType));
}
}
}
@ -557,25 +534,24 @@ void HttpAppFrameworkImpl::createDbClients(
{
#if USE_POSTGRESQL
_dbClientsMap[dbInfo._name] =
drogon::orm::DbClient::newPgClient(dbInfo._connectionInfo,
dbInfo
._connectionNumber);
drogon::orm::DbClient::newPgClient(
dbInfo._connectionInfo, dbInfo._connectionNumber);
#endif
}
else if (dbInfo._dbType == drogon::orm::ClientType::Mysql)
{
#if USE_MYSQL
_dbClientsMap[dbInfo._name] = drogon::orm::DbClient::
newMysqlClient(dbInfo._connectionInfo,
dbInfo._connectionNumber);
_dbClientsMap[dbInfo._name] =
drogon::orm::DbClient::newMysqlClient(
dbInfo._connectionInfo, dbInfo._connectionNumber);
#endif
}
else if (dbInfo._dbType == drogon::orm::ClientType::Sqlite3)
{
#if USE_SQLITE3
_dbClientsMap[dbInfo._name] = drogon::orm::DbClient::
newSqlite3Client(dbInfo._connectionInfo,
dbInfo._connectionNumber);
_dbClientsMap[dbInfo._name] =
drogon::orm::DbClient::newSqlite3Client(
dbInfo._connectionInfo, dbInfo._connectionNumber);
#endif
}
}
@ -849,10 +825,8 @@ void HttpAppFrameworkImpl::onAsyncRequest(
std::ifstream infile(gzipFileName, std::ifstream::binary);
if (infile)
{
resp = HttpResponse::newFileResponse(gzipFileName,
"",
drogon::getContentType(
filePath));
resp = HttpResponse::newFileResponse(
gzipFileName, "", drogon::getContentType(filePath));
resp->addHeader("Content-Encoding", "gzip");
}
}
@ -869,8 +843,8 @@ void HttpAppFrameworkImpl::onAsyncRequest(
if (_staticFilesCacheTime >= 0)
{
resp->setExpiredTime(_staticFilesCacheTime);
_responseCachingMap
->insert(filePath, resp, resp->expiredTime(), [=]() {
_responseCachingMap->insert(
filePath, resp, resp->expiredTime(), [=]() {
std::lock_guard<std::mutex> guard(
_staticFilesCacheMutex);
_staticFilesCache.erase(filePath);
@ -923,33 +897,28 @@ void HttpAppFrameworkImpl::onAsyncRequest(
std::make_shared<std::function<void(const HttpResponsePtr &)>>(
std::move(callback));
auto sessionIdPtr = std::make_shared<std::string>(std::move(sessionId));
doAdvicesChain(_preRoutingAdvices,
0,
req,
std::make_shared<
std::function<void(const HttpResponsePtr &)>>(
[callbackPtr, needSetJsessionid, sessionIdPtr](
const HttpResponsePtr &resp) {
if (!needSetJsessionid ||
resp->statusCode() == k404NotFound)
(*callbackPtr)(resp);
else
{
resp->addCookie("JSESSIONID", *sessionIdPtr);
(*callbackPtr)(resp);
}
}),
[this,
callbackPtr,
req,
needSetJsessionid,
sessionIdPtr]() {
_httpSimpleCtrlsRouter.route(req,
std::move(*callbackPtr),
needSetJsessionid,
std::move(
*sessionIdPtr));
});
doAdvicesChain(
_preRoutingAdvices,
0,
req,
std::make_shared<std::function<void(const HttpResponsePtr &)>>(
[callbackPtr, needSetJsessionid, sessionIdPtr](
const HttpResponsePtr &resp) {
if (!needSetJsessionid ||
resp->statusCode() == k404NotFound)
(*callbackPtr)(resp);
else
{
resp->addCookie("JSESSIONID", *sessionIdPtr);
(*callbackPtr)(resp);
}
}),
[this, callbackPtr, req, needSetJsessionid, sessionIdPtr]() {
_httpSimpleCtrlsRouter.route(req,
std::move(*callbackPtr),
needSetJsessionid,
std::move(*sessionIdPtr));
});
}
}
@ -1079,33 +1048,30 @@ void HttpAppFrameworkImpl::forward(
}
else
{
clientPtr = std::make_shared<
HttpClientImpl>(trantor::EventLoop::
getEventLoopOfCurrentThread()
? trantor::EventLoop::
getEventLoopOfCurrentThread()
: getLoop(),
hostString);
clientPtr = std::make_shared<HttpClientImpl>(
trantor::EventLoop::getEventLoopOfCurrentThread()
? trantor::EventLoop::getEventLoopOfCurrentThread()
: getLoop(),
hostString);
clientsMap[hostString] = clientPtr;
}
}
clientPtr->sendRequest(req,
[callback = std::move(
callback)](ReqResult result,
const HttpResponsePtr &resp) {
if (result == ReqResult::Ok)
{
resp->removeHeader("server");
resp->removeHeader("date");
resp->removeHeader("content-length");
resp->removeHeader("transfer-encoding");
callback(resp);
}
else
{
callback(
HttpResponse::newNotFoundResponse());
}
});
clientPtr->sendRequest(
req,
[callback = std::move(callback)](ReqResult result,
const HttpResponsePtr &resp) {
if (result == ReqResult::Ok)
{
resp->removeHeader("server");
resp->removeHeader("date");
resp->removeHeader("content-length");
resp->removeHeader("transfer-encoding");
callback(resp);
}
else
{
callback(HttpResponse::newNotFoundResponse());
}
});
}
}

View File

@ -224,9 +224,9 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req,
thisPtr->_pipeliningDepth &&
!thisPtr->_requestsBuffer.empty())
{
thisPtr->sendReq(connPtr,
thisPtr->_requestsBuffer.front()
.first);
thisPtr->sendReq(
connPtr,
thisPtr->_requestsBuffer.front().first);
thisPtr->_pipeliningCallbacks.push(std::move(
thisPtr->_requestsBuffer.front().second));
thisPtr->_requestsBuffer.pop();
@ -379,12 +379,10 @@ HttpClientPtr HttpClient::newHttpClient(const std::string &ip,
trantor::EventLoop *loop)
{
bool isIpv6 = ip.find(":") == std::string::npos ? false : true;
return std::make_shared<HttpClientImpl>(loop == nullptr ? app().getLoop()
: loop,
trantor::InetAddress(ip,
port,
isIpv6),
useSSL);
return std::make_shared<HttpClientImpl>(
loop == nullptr ? app().getLoop() : loop,
trantor::InetAddress(ip, port, isIpv6),
useSSL);
}
HttpClientPtr HttpClient::newHttpClient(const std::string &hostString,

View File

@ -90,11 +90,8 @@ HttpControllersRouter::getHandlersInfo() const
item._binders[i]->_binderPtr->handlerName()
: std::string("HttpController: ") +
item._binders[i]->_handlerName;
auto info = std::tuple<std::string,
HttpMethod,
std::string>(item._pathPattern,
(HttpMethod)i,
std::move(description));
auto info = std::tuple<std::string, HttpMethod, std::string>(
item._pathPattern, (HttpMethod)i, std::move(description));
ret.emplace_back(std::move(info));
}
}
@ -279,14 +276,13 @@ void HttpControllersRouter::route(
needSetJsessionid,
sessionIdPtr,
[=, &binder, &routerItem]() {
doPreHandlingAdvices(binder,
routerItem,
req,
std::move(
*callbackPtr),
needSetJsessionid,
std::move(
*sessionIdPtr));
doPreHandlingAdvices(
binder,
routerItem,
req,
std::move(*callbackPtr),
needSetJsessionid,
std::move(*sessionIdPtr));
});
}
else
@ -322,23 +318,21 @@ void HttpControllersRouter::route(
auto sessionIdPtr =
std::make_shared<std::string>(
std::move(sessionId));
FiltersFunction::
doFilters(filters,
req,
callbackPtr,
needSetJsessionid,
sessionIdPtr,
[=, &binder, &routerItem]() {
doPreHandlingAdvices(
binder,
routerItem,
req,
std::move(
*callbackPtr),
needSetJsessionid,
std::move(
*sessionIdPtr));
});
FiltersFunction::doFilters(
filters,
req,
callbackPtr,
needSetJsessionid,
sessionIdPtr,
[=, &binder, &routerItem]() {
doPreHandlingAdvices(
binder,
routerItem,
req,
std::move(*callbackPtr),
needSetJsessionid,
std::move(*sessionIdPtr));
});
}
else
{
@ -436,56 +430,44 @@ void HttpControllersRouter::doControllerHandler(
LOG_TRACE << p;
paraList.push_back(std::move(p));
}
ctrlBinderPtr->_binderPtr
->handleHttpRequest(paraList,
req,
[=,
callback = std::move(callback),
sessionId = std::move(sessionId)](
const HttpResponsePtr &resp) {
LOG_TRACE << "http resp:needSetJsessionid="
<< needSetJsessionid
<< ";JSESSIONID=" << sessionId;
auto newResp = resp;
if (resp->expiredTime() >= 0)
{
// cache the response;
std::dynamic_pointer_cast<HttpResponseImpl>(
resp)
->makeHeaderString();
auto loop = req->getLoop();
if (loop->isInLoopThread())
{
ctrlBinderPtr->_responsePtrMap[loop] =
resp;
}
else
{
req->getLoop()->queueInLoop(
[loop, resp, ctrlBinderPtr]() {
ctrlBinderPtr
->_responsePtrMap[loop] =
resp;
});
}
}
if (needSetJsessionid &&
resp->statusCode() != k404NotFound)
{
if (resp->expiredTime() >= 0)
{
// make a copy
newResp =
std::make_shared<HttpResponseImpl>(
*std::dynamic_pointer_cast<
HttpResponseImpl>(resp));
newResp->setExpiredTime(
-1); // make it temporary
}
newResp->addCookie("JSESSIONID", sessionId);
}
invokeCallback(callback, req, newResp);
});
ctrlBinderPtr->_binderPtr->handleHttpRequest(
paraList,
req,
[=, callback = std::move(callback), sessionId = std::move(sessionId)](
const HttpResponsePtr &resp) {
LOG_TRACE << "http resp:needSetJsessionid=" << needSetJsessionid
<< ";JSESSIONID=" << sessionId;
auto newResp = resp;
if (resp->expiredTime() >= 0)
{
// cache the response;
std::dynamic_pointer_cast<HttpResponseImpl>(resp)
->makeHeaderString();
auto loop = req->getLoop();
if (loop->isInLoopThread())
{
ctrlBinderPtr->_responsePtrMap[loop] = resp;
}
else
{
req->getLoop()->queueInLoop([loop, resp, ctrlBinderPtr]() {
ctrlBinderPtr->_responsePtrMap[loop] = resp;
});
}
}
if (needSetJsessionid && resp->statusCode() != k404NotFound)
{
if (resp->expiredTime() >= 0)
{
// make a copy
newResp = std::make_shared<HttpResponseImpl>(
*std::dynamic_pointer_cast<HttpResponseImpl>(resp));
newResp->setExpiredTime(-1); // make it temporary
}
newResp->addCookie("JSESSIONID", sessionId);
}
invokeCallback(callback, req, newResp);
});
return;
}
@ -545,35 +527,35 @@ void HttpControllersRouter::doPreHandlingAdvices(
std::make_shared<std::function<void(const HttpResponsePtr &)>>(
std::move(callback));
auto sessionIdPtr = std::make_shared<std::string>(std::move(sessionId));
doAdvicesChain(_preHandlingAdvices,
0,
req,
std::make_shared<
std::function<void(const HttpResponsePtr &)>>(
[callbackPtr, needSetJsessionid, sessionIdPtr](
const HttpResponsePtr &resp) {
if (!needSetJsessionid ||
resp->statusCode() == k404NotFound)
(*callbackPtr)(resp);
else
{
resp->addCookie("JSESSIONID", *sessionIdPtr);
(*callbackPtr)(resp);
}
}),
[this,
ctrlBinderPtr,
&routerItem,
req,
callbackPtr,
needSetJsessionid,
sessionIdPtr]() {
doControllerHandler(ctrlBinderPtr,
routerItem,
req,
std::move(*callbackPtr),
needSetJsessionid,
std::move(*sessionIdPtr));
});
doAdvicesChain(
_preHandlingAdvices,
0,
req,
std::make_shared<std::function<void(const HttpResponsePtr &)>>(
[callbackPtr, needSetJsessionid, sessionIdPtr](
const HttpResponsePtr &resp) {
if (!needSetJsessionid ||
resp->statusCode() == k404NotFound)
(*callbackPtr)(resp);
else
{
resp->addCookie("JSESSIONID", *sessionIdPtr);
(*callbackPtr)(resp);
}
}),
[this,
ctrlBinderPtr,
&routerItem,
req,
callbackPtr,
needSetJsessionid,
sessionIdPtr]() {
doControllerHandler(ctrlBinderPtr,
routerItem,
req,
std::move(*callbackPtr),
needSetJsessionid,
std::move(*sessionIdPtr));
});
}
}

View File

@ -229,8 +229,7 @@ void HttpServer::onRequest(const TcpConnectionPtr &conn,
std::dynamic_pointer_cast<HttpResponseImpl>(newResp)
->sendfileName();
if (HttpAppFramework::instance().isGzipEnabled() &&
sendfileName.empty() &&
if (app().isGzipEnabled() && sendfileName.empty() &&
req->getHeaderBy("accept-encoding").find("gzip") !=
std::string::npos &&
std::dynamic_pointer_cast<HttpResponseImpl>(response)

View File

@ -134,21 +134,20 @@ void HttpSimpleControllersRouter::route(
auto callbackPtr = std::make_shared<
std::function<void(const HttpResponsePtr &)>>(
std::move(callback));
FiltersFunction::
doFilters(filters,
req,
callbackPtr,
needSetJsessionid,
sessionIdPtr,
[=, &binder]() mutable {
doPreHandlingAdvices(binder,
ctrlInfo,
req,
std::move(*callbackPtr),
needSetJsessionid,
std::move(
*sessionIdPtr));
});
FiltersFunction::doFilters(filters,
req,
callbackPtr,
needSetJsessionid,
sessionIdPtr,
[=, &binder]() mutable {
doPreHandlingAdvices(
binder,
ctrlInfo,
req,
std::move(*callbackPtr),
needSetJsessionid,
std::move(*sessionIdPtr));
});
}
else
{
@ -166,51 +165,48 @@ void HttpSimpleControllersRouter::route(
auto callbackPtr =
std::make_shared<std::function<void(const HttpResponsePtr &)>>(
std::move(callback));
doAdvicesChain(_postRoutingAdvices,
0,
req,
callbackPtr,
[callbackPtr,
&filters,
sessionId = std::move(sessionId),
doAdvicesChain(
_postRoutingAdvices,
0,
req,
callbackPtr,
[callbackPtr,
&filters,
sessionId = std::move(sessionId),
req,
needSetJsessionid,
&ctrlInfo,
this,
&binder]() mutable {
if (!filters.empty())
{
auto sessionIdPtr =
std::make_shared<std::string>(std::move(sessionId));
FiltersFunction::doFilters(
filters,
req,
callbackPtr,
needSetJsessionid,
&ctrlInfo,
this,
&binder]() mutable {
if (!filters.empty())
{
auto sessionIdPtr =
std::make_shared<std::string>(
std::move(sessionId));
FiltersFunction::
doFilters(filters,
req,
callbackPtr,
needSetJsessionid,
sessionIdPtr,
[=, &binder]() mutable {
doPreHandlingAdvices(
binder,
ctrlInfo,
req,
std::move(
*callbackPtr),
needSetJsessionid,
std::move(
*sessionIdPtr));
});
}
else
{
doPreHandlingAdvices(binder,
ctrlInfo,
req,
std::move(*callbackPtr),
needSetJsessionid,
std::move(sessionId));
}
});
sessionIdPtr,
[=, &binder]() mutable {
doPreHandlingAdvices(binder,
ctrlInfo,
req,
std::move(*callbackPtr),
needSetJsessionid,
std::move(*sessionIdPtr));
});
}
else
{
doPreHandlingAdvices(binder,
ctrlInfo,
req,
std::move(*callbackPtr),
needSetJsessionid,
std::move(sessionId));
}
});
}
return;
}
@ -318,15 +314,11 @@ HttpSimpleControllersRouter::getHandlersInfo() const
{
if (item.second._binders[i])
{
auto info =
std::tuple<std::string,
HttpMethod,
std::string>(item.first,
(HttpMethod)i,
std::string(
"HttpSimpleController: ") +
item.second._binders[i]
->_controllerName);
auto info = std::tuple<std::string, HttpMethod, std::string>(
item.first,
(HttpMethod)i,
std::string("HttpSimpleController: ") +
item.second._binders[i]->_controllerName);
ret.emplace_back(std::move(info));
}
}
@ -412,35 +404,35 @@ void HttpSimpleControllersRouter::doPreHandlingAdvices(
std::make_shared<std::function<void(const HttpResponsePtr &)>>(
std::move(callback));
auto sessionIdPtr = std::make_shared<std::string>(std::move(sessionId));
doAdvicesChain(_preHandlingAdvices,
0,
req,
std::make_shared<
std::function<void(const HttpResponsePtr &)>>(
[callbackPtr, needSetJsessionid, sessionIdPtr](
const HttpResponsePtr &resp) {
if (!needSetJsessionid ||
resp->statusCode() == k404NotFound)
(*callbackPtr)(resp);
else
{
resp->addCookie("JSESSIONID", *sessionIdPtr);
(*callbackPtr)(resp);
}
}),
[this,
ctrlBinderPtr,
&routerItem,
req,
callbackPtr,
needSetJsessionid,
sessionIdPtr]() {
doControllerHandler(ctrlBinderPtr,
routerItem,
req,
std::move(*callbackPtr),
needSetJsessionid,
std::move(*sessionIdPtr));
});
doAdvicesChain(
_preHandlingAdvices,
0,
req,
std::make_shared<std::function<void(const HttpResponsePtr &)>>(
[callbackPtr, needSetJsessionid, sessionIdPtr](
const HttpResponsePtr &resp) {
if (!needSetJsessionid ||
resp->statusCode() == k404NotFound)
(*callbackPtr)(resp);
else
{
resp->addCookie("JSESSIONID", *sessionIdPtr);
(*callbackPtr)(resp);
}
}),
[this,
ctrlBinderPtr,
&routerItem,
req,
callbackPtr,
needSetJsessionid,
sessionIdPtr]() {
doControllerHandler(ctrlBinderPtr,
routerItem,
req,
std::move(*callbackPtr),
needSetJsessionid,
std::move(*sessionIdPtr));
});
}
}

View File

@ -80,77 +80,75 @@ void SharedLibManager::managerLibs()
{
for (auto const &libPath : _libPaths)
{
forEachFileIn(libPath,
[=](const std::string &filename, const struct stat &st) {
auto pos = filename.rfind(".");
if (pos != std::string::npos)
{
auto exName = filename.substr(pos + 1);
if (exName == "csp")
{
// compile
auto lockFile = filename + ".lock";
std::ifstream fin(lockFile);
if (fin)
{
return;
}
forEachFileIn(
libPath, [=](const std::string &filename, const struct stat &st) {
auto pos = filename.rfind(".");
if (pos != std::string::npos)
{
auto exName = filename.substr(pos + 1);
if (exName == "csp")
{
// compile
auto lockFile = filename + ".lock";
std::ifstream fin(lockFile);
if (fin)
{
return;
}
void *oldHandle = nullptr;
if (_dlMap.find(filename) != _dlMap.end())
{
void *oldHandle = nullptr;
if (_dlMap.find(filename) != _dlMap.end())
{
#ifdef __linux__
if (st.st_mtim.tv_sec >
_dlMap[filename].mTime.tv_sec)
if (st.st_mtim.tv_sec >
_dlMap[filename].mTime.tv_sec)
#else
if (st.st_mtimespec.tv_sec >
_dlMap[filename].mTime.tv_sec)
#endif
{
LOG_TRACE << "new csp file:"
<< filename;
oldHandle = _dlMap[filename].handle;
}
else
return;
}
{
LOG_TRACE << "new csp file:" << filename;
oldHandle = _dlMap[filename].handle;
}
else
return;
}
{
std::ofstream fout(lockFile);
}
std::string cmd = "drogon_ctl create view ";
cmd.append(filename).append(" -o ").append(
libPath);
LOG_TRACE << cmd;
auto r = system(cmd.c_str());
// TODO: handle r
(void)(r);
auto srcFile = filename.substr(0, pos);
srcFile.append(".cc");
DLStat dlStat;
dlStat.handle = loadLibs(srcFile, oldHandle);
{
std::ofstream fout(lockFile);
}
std::string cmd = "drogon_ctl create view ";
cmd.append(filename).append(" -o ").append(libPath);
LOG_TRACE << cmd;
auto r = system(cmd.c_str());
// TODO: handle r
(void)(r);
auto srcFile = filename.substr(0, pos);
srcFile.append(".cc");
DLStat dlStat;
dlStat.handle = loadLibs(srcFile, oldHandle);
#ifdef __linux__
dlStat.mTime = st.st_mtim;
dlStat.mTime = st.st_mtim;
#else
dlStat.mTime = st.st_mtimespec;
#endif
if (dlStat.handle)
{
_dlMap[filename] = dlStat;
}
else
{
dlStat.handle = _dlMap[filename].handle;
_dlMap[filename] = dlStat;
}
_loop->runAfter(3.5, [=]() {
LOG_TRACE << "remove file " << lockFile;
if (unlink(lockFile.c_str()) == -1)
perror("");
});
}
}
});
if (dlStat.handle)
{
_dlMap[filename] = dlStat;
}
else
{
dlStat.handle = _dlMap[filename].handle;
_dlMap[filename] = dlStat;
}
_loop->runAfter(3.5, [=]() {
LOG_TRACE << "remove file " << lockFile;
if (unlink(lockFile.c_str()) == -1)
perror("");
});
}
}
});
}
}
void *SharedLibManager::loadLibs(const std::string &sourceFile, void *oldHld)

View File

@ -325,21 +325,16 @@ WebSocketClientPtr WebSocketClient::newWebSocketClient(const std::string &ip,
trantor::EventLoop *loop)
{
bool isIpv6 = ip.find(":") == std::string::npos ? false : true;
return std::make_shared<WebSocketClientImpl>(loop == nullptr
? app().getLoop()
: loop,
trantor::InetAddress(ip,
port,
isIpv6),
useSSL);
return std::make_shared<WebSocketClientImpl>(
loop == nullptr ? app().getLoop() : loop,
trantor::InetAddress(ip, port, isIpv6),
useSSL);
}
WebSocketClientPtr WebSocketClient::newWebSocketClient(
const std::string &hostString,
trantor::EventLoop *loop)
{
return std::make_shared<WebSocketClientImpl>(loop == nullptr
? app().getLoop()
: loop,
hostString);
return std::make_shared<WebSocketClientImpl>(
loop == nullptr ? app().getLoop() : loop, hostString);
}

View File

@ -67,28 +67,24 @@ void WebsocketControllersRouter::route(
auto callbackPtr = std::make_shared<
std::function<void(const HttpResponsePtr &)>>(
std::move(callback));
FiltersFunction::
doFilters(filters,
req,
callbackPtr,
false,
nullptr,
[=]() mutable {
doControllerHandler(ctrlPtr,
wsKey,
req,
std::move(
*callbackPtr),
wsConnPtr);
});
FiltersFunction::doFilters(filters,
req,
callbackPtr,
false,
nullptr,
[=]() mutable {
doControllerHandler(
ctrlPtr,
wsKey,
req,
std::move(*callbackPtr),
wsConnPtr);
});
}
else
{
doControllerHandler(ctrlPtr,
wsKey,
req,
std::move(callback),
wsConnPtr);
doControllerHandler(
ctrlPtr, wsKey, req, std::move(callback), wsConnPtr);
}
return;
}
@ -105,13 +101,11 @@ WebsocketControllersRouter::getHandlersInfo() const
std::vector<std::tuple<std::string, HttpMethod, std::string>> ret;
for (auto &item : _websockCtrlMap)
{
auto info =
std::tuple<std::string,
HttpMethod,
std::string>(item.first,
Get,
std::string("WebsocketController: ") +
item.second._controller->className());
auto info = std::tuple<std::string, HttpMethod, std::string>(
item.first,
Get,
std::string("WebsocketController: ") +
item.second._controller->className());
ret.emplace_back(std::move(info));
}
return ret;

View File

@ -47,11 +47,8 @@ unsigned char *SHA1(const unsigned char *data,
unsigned int nbyte = dataLen;
static unsigned int words[80];
unsigned int H[5] = {0x67452301,
0xEFCDAB89,
0x98BADCFE,
0x10325476,
0xC3D2E1F0};
unsigned int H[5] = {
0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0};
unsigned int a, b, c, d, e, f, k, temp, bitlen[2], word;
unsigned int i, j, index, p1, p2, maxlen;
unsigned char spec[4] = {0};

View File

@ -176,17 +176,19 @@ class CallbackHolder : public CallbackHolderBase
_function(result);
}
template <typename... Values, std::size_t Boundary = argumentCount>
typename std::enable_if<(sizeof...(Values) < Boundary), void>::type
run(const Row *const row, bool isNull, Values &&... values)
typename std::enable_if<(sizeof...(Values) < Boundary), void>::type run(
const Row *const row,
bool isNull,
Values &&... values)
{
// call this function recursively until parameter's count equals to the
// count of target function parameters
static_assert(CallbackArgTypeTraits<
NthArgumentType<sizeof...(Values)>>::isValid,
"your sql callback function argument type must be value "
"type or "
"const "
"left-reference type");
static_assert(
CallbackArgTypeTraits<NthArgumentType<sizeof...(Values)>>::isValid,
"your sql callback function argument type must be value "
"type or "
"const "
"left-reference type");
typedef typename std::remove_cv<typename std::remove_reference<
NthArgumentType<sizeof...(Values)>>::type>::type ValueType;
ValueType value = ValueType();
@ -204,8 +206,10 @@ class CallbackHolder : public CallbackHolderBase
run(row, isNull, std::forward<Values>(values)..., std::move(value));
}
template <typename... Values, std::size_t Boundary = argumentCount>
typename std::enable_if<(sizeof...(Values) == Boundary), void>::type
run(const Row *const row, bool isNull, Values &&... values)
typename std::enable_if<(sizeof...(Values) == Boundary), void>::type run(
const Row *const row,
bool isNull,
Values &&... values)
{
_function(isNull, std::move(values)...);
}

View File

@ -259,49 +259,43 @@ void DbClientImpl::makeTrans(
std::function<void(const std::shared_ptr<Transaction> &)> &&callback)
{
std::weak_ptr<DbClientImpl> weakThis = shared_from_this();
auto trans = std::shared_ptr<TransactionImpl>(
new TransactionImpl(_type,
conn,
std::function<void(bool)>(),
[weakThis, conn]() {
auto thisPtr = weakThis.lock();
if (!thisPtr)
return;
if (conn->status() == ConnectStatus_Bad)
{
return;
}
{
std::lock_guard<std::mutex> guard(
thisPtr->_connectionsMutex);
if (thisPtr->_connections.find(conn) ==
thisPtr->_connections.end() &&
thisPtr->_busyConnections.find(conn) ==
thisPtr->_busyConnections.find(
conn))
{
// connection is broken and removed
return;
}
}
conn->loop()->queueInLoop([weakThis, conn]() {
auto thisPtr = weakThis.lock();
if (!thisPtr)
return;
std::weak_ptr<DbConnection> weakConn = conn;
conn->setIdleCallback(
[weakThis, weakConn]() {
auto thisPtr = weakThis.lock();
if (!thisPtr)
return;
auto connPtr = weakConn.lock();
if (!connPtr)
return;
thisPtr->handleNewTask(connPtr);
});
thisPtr->handleNewTask(conn);
});
}));
auto trans = std::shared_ptr<TransactionImpl>(new TransactionImpl(
_type, conn, std::function<void(bool)>(), [weakThis, conn]() {
auto thisPtr = weakThis.lock();
if (!thisPtr)
return;
if (conn->status() == ConnectStatus_Bad)
{
return;
}
{
std::lock_guard<std::mutex> guard(thisPtr->_connectionsMutex);
if (thisPtr->_connections.find(conn) ==
thisPtr->_connections.end() &&
thisPtr->_busyConnections.find(conn) ==
thisPtr->_busyConnections.find(conn))
{
// connection is broken and removed
return;
}
}
conn->loop()->queueInLoop([weakThis, conn]() {
auto thisPtr = weakThis.lock();
if (!thisPtr)
return;
std::weak_ptr<DbConnection> weakConn = conn;
conn->setIdleCallback([weakThis, weakConn]() {
auto thisPtr = weakThis.lock();
if (!thisPtr)
return;
auto connPtr = weakConn.lock();
if (!connPtr)
return;
thisPtr->handleNewTask(connPtr);
});
thisPtr->handleNewTask(conn);
});
}));
trans->doBegin();
conn->loop()->queueInLoop(
[callback = std::move(callback), trans]() { callback(trans); });

View File

@ -174,57 +174,49 @@ void DbClientLockFree::makeTrans(
std::function<void(const std::shared_ptr<Transaction> &)> &&callback)
{
std::weak_ptr<DbClientLockFree> weakThis = shared_from_this();
auto trans = std::shared_ptr<TransactionImpl>(
new TransactionImpl(_type,
conn,
std::function<void(bool)>(),
[weakThis, conn]() {
auto thisPtr = weakThis.lock();
if (!thisPtr)
return;
auto trans = std::shared_ptr<TransactionImpl>(new TransactionImpl(
_type, conn, std::function<void(bool)>(), [weakThis, conn]() {
auto thisPtr = weakThis.lock();
if (!thisPtr)
return;
if (conn->status() == ConnectStatus_Bad)
{
return;
}
if (!thisPtr->_transCallbacks.empty())
{
auto callback = std::move(
thisPtr->_transCallbacks.front());
thisPtr->_transCallbacks.pop();
thisPtr->makeTrans(conn,
std::move(callback));
return;
}
if (conn->status() == ConnectStatus_Bad)
{
return;
}
if (!thisPtr->_transCallbacks.empty())
{
auto callback = std::move(thisPtr->_transCallbacks.front());
thisPtr->_transCallbacks.pop();
thisPtr->makeTrans(conn, std::move(callback));
return;
}
for (auto &connPtr : thisPtr->_connections)
{
if (connPtr == conn)
{
conn->loop()->queueInLoop([weakThis,
conn]() {
auto thisPtr = weakThis.lock();
if (!thisPtr)
return;
std::weak_ptr<DbConnection>
weakConn = conn;
conn->setIdleCallback([weakThis,
weakConn]() {
auto thisPtr = weakThis.lock();
if (!thisPtr)
return;
auto connPtr = weakConn.lock();
if (!connPtr)
return;
thisPtr->handleNewTask(connPtr);
});
thisPtr->_transSet.erase(conn);
thisPtr->handleNewTask(conn);
});
break;
}
}
}));
for (auto &connPtr : thisPtr->_connections)
{
if (connPtr == conn)
{
conn->loop()->queueInLoop([weakThis, conn]() {
auto thisPtr = weakThis.lock();
if (!thisPtr)
return;
std::weak_ptr<DbConnection> weakConn = conn;
conn->setIdleCallback([weakThis, weakConn]() {
auto thisPtr = weakThis.lock();
if (!thisPtr)
return;
auto connPtr = weakConn.lock();
if (!connPtr)
return;
thisPtr->handleNewTask(connPtr);
});
thisPtr->_transSet.erase(conn);
thisPtr->handleNewTask(conn);
});
break;
}
}
}));
_transSet.insert(conn);
trans->doBegin();
conn->loop()->queueInLoop(

View File

@ -112,13 +112,8 @@ void Sqlite3Connection::execSql(
format = std::move(format),
rcb = std::move(rcb),
exceptCallback = std::move(exceptCallback)]() mutable {
thisPtr->execSqlInQueue(sql,
paraNum,
parameters,
length,
format,
rcb,
exceptCallback);
thisPtr->execSqlInQueue(
sql, paraNum, parameters, length, format, rcb, exceptCallback);
});
}
@ -204,18 +199,12 @@ void Sqlite3Connection::execSqlInQueue(
sqlite3_bind_double(stmt, i + 1, *(double *)parameters[i]);
break;
case Sqlite3TypeText:
bindRet = sqlite3_bind_text(stmt,
i + 1,
parameters[i],
-1,
SQLITE_STATIC);
bindRet = sqlite3_bind_text(
stmt, i + 1, parameters[i], -1, SQLITE_STATIC);
break;
case Sqlite3TypeBlob:
bindRet = sqlite3_bind_blob(stmt,
i + 1,
parameters[i],
length[i],
SQLITE_STATIC);
bindRet = sqlite3_bind_blob(
stmt, i + 1, parameters[i], length[i], SQLITE_STATIC);
break;
case Sqlite3TypeNull:
bindRet = sqlite3_bind_null(stmt, i + 1);
@ -294,12 +283,9 @@ int Sqlite3Connection::stmtStep(
std::to_string(sqlite3_column_double(stmt, i))));
break;
case SQLITE_TEXT:
row.push_back(
std::make_shared<
std::string>((const char *)sqlite3_column_text(stmt,
i),
(size_t)sqlite3_column_bytes(stmt,
i)));
row.push_back(std::make_shared<std::string>(
(const char *)sqlite3_column_text(stmt, i),
(size_t)sqlite3_column_bytes(stmt, i)));
break;
case SQLITE_BLOB:
{

View File

@ -25,17 +25,17 @@ const std::string Groups::primaryKeyName = "group_id";
const bool Groups::hasPrimaryKey = true;
const std::string Groups::tableName = "GROUPS";
const std::vector<typename Groups::MetaData> Groups::_metaData =
{{"group_id", "uint64_t", "integer", 8, 1, 1, 0},
{"group_name", "std::string", "text", 0, 0, 0, 0},
{"creater_id", "uint64_t", "integer", 8, 0, 0, 0},
{"create_time", "std::string", "text", 0, 0, 0, 0},
{"inviting", "uint64_t", "integer", 8, 0, 0, 0},
{"inviting_user_id", "uint64_t", "integer", 8, 0, 0, 0},
{"avatar_id", "std::string", "text", 0, 0, 0, 0},
{"uuu", "double", "double", 8, 0, 0, 0},
{"text", "std::string", "varchar(255)", 0, 0, 0, 0},
{"avatar", "std::vector<char>", "blob", 0, 0, 0, 0}};
const std::vector<typename Groups::MetaData> Groups::_metaData = {
{"group_id", "uint64_t", "integer", 8, 1, 1, 0},
{"group_name", "std::string", "text", 0, 0, 0, 0},
{"creater_id", "uint64_t", "integer", 8, 0, 0, 0},
{"create_time", "std::string", "text", 0, 0, 0, 0},
{"inviting", "uint64_t", "integer", 8, 0, 0, 0},
{"inviting_user_id", "uint64_t", "integer", 8, 0, 0, 0},
{"avatar_id", "std::string", "text", 0, 0, 0, 0},
{"uuu", "double", "double", 8, 0, 0, 0},
{"text", "std::string", "varchar(255)", 0, 0, 0, 0},
{"avatar", "std::vector<char>", "blob", 0, 0, 0, 0}};
const std::string &Groups::getColumnName(size_t index) noexcept(false)
{
assert(index < _metaData.size());
@ -580,10 +580,8 @@ Json::Value Groups::toJson() const
}
if (getAvatar())
{
ret["avatar"] =
drogon::utils::base64Encode((const unsigned char *)getAvatar()
->data(),
getAvatar()->size());
ret["avatar"] = drogon::utils::base64Encode(
(const unsigned char *)getAvatar()->data(), getAvatar()->size());
}
else
{

View File

@ -25,16 +25,16 @@ const std::string Users::primaryKeyName = "id";
const bool Users::hasPrimaryKey = true;
const std::string Users::tableName = "users";
const std::vector<typename Users::MetaData> Users::_metaData =
{{"user_id", "std::string", "character varying", 32, 0, 0, 0},
{"user_name", "std::string", "character varying", 64, 0, 0, 0},
{"password", "std::string", "character varying", 64, 0, 0, 0},
{"org_name", "std::string", "character varying", 20, 0, 0, 0},
{"signature", "std::string", "character varying", 50, 0, 0, 0},
{"avatar_id", "std::string", "character varying", 32, 0, 0, 0},
{"id", "int32_t", "integer", 4, 1, 1, 1},
{"salt", "std::string", "character varying", 20, 0, 0, 0},
{"admin", "bool", "boolean", 1, 0, 0, 0}};
const std::vector<typename Users::MetaData> Users::_metaData = {
{"user_id", "std::string", "character varying", 32, 0, 0, 0},
{"user_name", "std::string", "character varying", 64, 0, 0, 0},
{"password", "std::string", "character varying", 64, 0, 0, 0},
{"org_name", "std::string", "character varying", 20, 0, 0, 0},
{"signature", "std::string", "character varying", 50, 0, 0, 0},
{"avatar_id", "std::string", "character varying", 32, 0, 0, 0},
{"id", "int32_t", "integer", 4, 1, 1, 1},
{"salt", "std::string", "character varying", 20, 0, 0, 0},
{"admin", "bool", "boolean", 1, 0, 0, 0}};
const std::string &Users::getColumnName(size_t index) noexcept(false)
{
assert(index < _metaData.size());

View File

@ -41,11 +41,11 @@ int main()
{
trantor::Logger::setLogLevel(trantor::Logger::DEBUG);
#if USE_POSTGRESQL
auto clientPtr = DbClient::
newPgClient("host=127.0.0.1 port=5432 dbname=postgres user=antao", 1);
auto clientPtr = DbClient::newPgClient(
"host=127.0.0.1 port=5432 dbname=postgres user=antao", 1);
#elif USE_MYSQL
auto clientPtr = DbClient::
newMysqlClient("host=127.0.0.1 port=3306 dbname=test user=root", 1);
auto clientPtr = DbClient::newMysqlClient(
"host=127.0.0.1 port=3306 dbname=test user=root", 1);
#else
DbClientPtr clientPtr;
return -1;