Add the create DAO method to drogon_ctl, not completed

This commit is contained in:
antao 2018-10-30 18:43:11 +08:00 committed by an-tao
parent 85664b86fc
commit cae30230c3
9 changed files with 310 additions and 4 deletions

View File

@ -100,6 +100,13 @@ SET(CONFIG_HEADER "${PROJECT_SOURCE_DIR}/config.h")
file(WRITE "${CONFIG_HEADER}" "#pragma once\n")
file(APPEND "${CONFIG_HEADER}" "#include <trantor/utils/config.h>\n")
if(PostgreSQL_FOUND)
file(APPEND "${CONFIG_HEADER}" "#define USE_POSTGRESQL 1")
else()
file(APPEND "${CONFIG_HEADER}" "#define USE_POSTGRESQL 0")
endif()
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
if(CMAKE_BUILD_TYPE_LOWER STREQUAL release)
file(APPEND "${CONFIG_HEADER}" "\n" "const char compileFlags[]=\"" ${CMAKE_CXX_FLAGS_RELEASE} "\";")

View File

@ -32,7 +32,9 @@ std::string create::detail()
"drogon_ctl create project <project_name> //"
"create a project named project_name\n"
"drogon_ctl create filter <class_name> //"
"create a filter named class_name\n";
"create a filter named class_name\n"
"drogon_ctl create dao <dao_path> //"
"create DAO classes in dao_path\n";
}
void create::handleCommand(std::vector<std::string> &parameters)

View File

@ -1,8 +1,7 @@
/**
*
* @file
* @author An Tao
* @section LICENSE
* create_controller.h
* An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* Use of this source code is governed by a MIT license

203
drogon_ctl/create_dao.cc Normal file
View File

@ -0,0 +1,203 @@
/**
*
* create_dao.cc
* An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* @section DESCRIPTION
*
*/
#include "create_dao.h"
#include "cmd.h"
#include <drogon/config.h>
#include <drogon/utils/Utilities.h>
#if USE_POSTGRESQL
#include <drogon/orm/PgClient.h>
#endif
#include <drogon/HttpViewData.h>
#include <drogon/DrTemplateBase.h>
#include <json/json.h>
#include <iostream>
#include <fstream>
#include <regex>
#include <unistd.h>
#include <dirent.h>
#include <dlfcn.h>
#include <fstream>
#include <unistd.h>
using namespace drogon_ctl;
using namespace drogon::orm;
std::string nameTransform(const std::string &origName, bool isType)
{
auto str = origName;
std::transform(str.begin(), str.end(), str.begin(), tolower);
std::string::size_type startPos = 0;
std::string::size_type pos;
std::string ret;
do
{
pos = str.find("_", startPos);
if (pos != std::string::npos)
ret += str.substr(startPos, pos - startPos);
else
{
ret += str.substr(startPos);
break;
}
while (str[pos] == '_')
pos++;
if (str[pos] >= 'a' && str[pos] <= 'z')
str[pos] += ('A' - 'a');
startPos = pos;
} while (1);
if (isType && ret[0] >= 'a' && ret[0] <= 'z')
ret[0] += ('A' - 'a');
return ret;
}
#if USE_POSTGRESQL
void create_dao::createDAOClassFromPG(const std::string &path, PgClient &client, const std::string &tableName)
{
auto className = nameTransform(tableName, true);
HttpViewData data;
data["className"] = className;
data["tableName"] = tableName;
data["hasPrimaryKey"] = true;
data["primaryKeyName"] = "";
data["dbName"] = _dbname;
std::ofstream headerFile(path + "/" + className + ".h", std::ofstream::out);
std::ofstream sourceFile(path + "/" + className + ".cc", std::ofstream::out);
auto templ = DrTemplateBase::newTemplate("dao_h.csp");
headerFile << templ->genText(data);
templ = DrTemplateBase::newTemplate("dao_cc.csp");
sourceFile << templ->genText(data);
}
void create_dao::createDAOFromPG(const std::string &path, PgClient &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') "
"AND a.relkind = 'r' ORDER BY a.relname"
<< Mode::Blocking >>
[&](bool isNull, size_t oid, const std::string &tableName, const std::string &comment) {
if (!isNull)
{
std::cout << "table name:" << tableName << std::endl;
createDAOClassFromPG(path, client, tableName);
}
} >>
[](const DrogonDbException &e) {
std::cerr << e.base().what() << std::endl;
exit(1);
};
}
#endif
void create_dao::createDAO(const std::string &path, const Json::Value &config)
{
auto dbType = config.get("rdbms", "No dbms").asString();
if (dbType == "postgreSQL")
{
#if USE_POSTGRESQL
std::cout << "postgresql" << std::endl;
auto host = config.get("host", "127.0.0.1").asString();
auto port = config.get("port", 5432).asUInt();
auto dbname = config.get("dbname", "").asString();
if (dbname == "")
{
std::cerr << "Please configure dbname in " << path << "/dao.json " << std::endl;
exit(1);
}
_dbname = dbname;
auto user = config.get("user", "").asString();
if (user == "")
{
std::cerr << "Please configure user in " << path << "/dao.json " << std::endl;
exit(1);
}
auto password = config.get("passwd", "").asString();
auto connStr = formattedString("host=%s port=%u dbname=%s user=%s", host.c_str(), port, dbname.c_str(), user.c_str());
if (!password.empty())
{
connStr += " password=";
connStr += password;
}
PgClient client(connStr, 1);
std::cout << "Connect to server..." << std::endl;
sleep(1);
createDAOFromPG(path, client);
#endif
}
else if (dbType == "No dbms")
{
std::cerr << "Please configure DAO in " << path << "/dao.json " << std::endl;
exit(1);
}
else
{
std::cerr << "Does not support " << dbType << std::endl;
exit(1);
}
}
void create_dao::createDAO(const std::string &path)
{
DIR *dp;
if ((dp = opendir(path.c_str())) == NULL)
{
std::cerr << "No such file or directory : " << path << std::endl;
return;
}
closedir(dp);
auto configFile = path + "/dao.json";
if (access(configFile.c_str(), 0) != 0)
{
std::cerr << "Config file " << configFile << " not found!" << std::endl;
exit(1);
}
if (access(configFile.c_str(), R_OK) != 0)
{
std::cerr << "No permission to read config file " << configFile << std::endl;
exit(1);
}
std::ifstream infile(configFile.c_str(), std::ifstream::in);
if (infile)
{
Json::Value configJsonRoot;
try
{
infile >> configJsonRoot;
createDAO(path, configJsonRoot);
}
catch (const std::exception &exception)
{
std::cerr << "Configuration file format error! in " << configFile << ":" << std::endl;
std::cerr << exception.what() << std::endl;
exit(1);
}
}
}
void create_dao::handleCommand(std::vector<std::string> &parameters)
{
std::cout << "Create dao" << std::endl;
if (parameters.size() == 0)
{
std::cerr << "Missing DAO path name!" << std::endl;
}
for (auto path : parameters)
{
createDAO(path);
}
}

45
drogon_ctl/create_dao.h Normal file
View File

@ -0,0 +1,45 @@
/**
*
* create_dao.h
* An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* @section DESCRIPTION
*
*/
#pragma once
#include <drogon/config.h>
#include <json/json.h>
#if USE_POSTGRESQL
#include <drogon/orm/PgClient.h>
#endif
#include <drogon/DrObject.h>
#include "CommandHandler.h"
#include <string>
using namespace drogon;
using namespace drogon::orm;
namespace drogon_ctl
{
class create_dao : public DrObject<create_dao>, public CommandHandler
{
public:
virtual void handleCommand(std::vector<std::string> &parameters) override;
virtual std::string script() override { return "create DAO classes files"; }
protected:
void createDAO(const std::string &path);
void createDAO(const std::string &path, const Json::Value &config);
#if USE_POSTGRESQL
void createDAOClassFromPG(const std::string &path, PgClient &client, const std::string &tableName);
void createDAOFromPG(const std::string &path, PgClient &client);
#endif
std::string _dbname;
};
} // namespace drogon_ctl

View File

@ -52,6 +52,14 @@ find_package(ZLIB REQUIRED)
include_directories(${ZLIB_INCLUDE_DIR})
link_libraries(${ZLIB_LIBRARIES})
#find postgres
find_package(PostgreSQL)
if(PostgreSQL_FOUND)
include_directories(${PostgreSQL_INCLUDE_DIR})
link_libraries(${PostgreSQL_LIBRARIES})
endif()
AUX_SOURCE_DIRECTORY(./ SRC_DIR)
AUX_SOURCE_DIRECTORY(controllers CTL_SRC)
AUX_SOURCE_DIRECTORY(filters FILTER_SRC)

View File

@ -0,0 +1,16 @@
/**
*
* {{className}}.cc
* created by drogon_ctl
*
*/
#include "{{className}}.h"
const std::string User::primaryKeyName = "{{priKeyName}}";
<%c++ if(@@.get<bool>("hasPrimaryKey",false)){%>
const bool User::hasPrimaryKey = true;
<%c++ }else{%>
const bool User::hasPrimaryKey = false;
<%c++}%>
const std::string User::tableName = "{{tableName}}";

View File

@ -0,0 +1,25 @@
/**
*
* {{className}}.h
* Created by drogon_ctl
*
*/
#pragma once
namespace drogon_dao
{
namespace {{dbName}}
{
class {{className}}
{
public:
const static std::string primaryKeyName;
const static bool hasPrimaryKey;
const static std::string tableName;
typedef {{primaryKeyType}} PrimaryKeyType;
{{className}}(const Row &r);
};
} // namespace {{dbName}}
} // namespace drogon_dao

View File

@ -10,6 +10,7 @@
* Definitions for the PostgreSQL client class
*
*/
#pragma once
#include <drogon/orm/DbClient.h>
#include <memory>