update hkuserver

This commit is contained in:
fasiondog 2021-04-25 01:53:22 +08:00
parent 570c675fd9
commit 6f91ab960c
21 changed files with 254 additions and 33 deletions

View File

@ -121,7 +121,7 @@ public:
Datetime operator-(TimeDelta d) const;
/**
* YYYYMMDDhhmmss格式的数字便
* YYYYMMDDhhmm格式的数字便
* Null<Datetime>() number Null<unsigned long long>
*/
unsigned long long number() const noexcept;

View File

@ -14,5 +14,6 @@
#include "SQLStatementBase.h"
#include "TransAction.h"
#include "TableMacro.h"
#include "DBUpgrade.h"
#endif /* HIKYUU_DB_CONNECT_H */

View File

@ -8,16 +8,15 @@
#pragma once
#include <hikyuu/utilities/IniParser.h>
#include <hikyuu/utilities/db_connect/DBUpgrade.h>
#include "../common/log.h"
#include "db.h"
#include "sqlite/sqlitedb.h"
namespace hku {
std::unique_ptr<ConnectPool<SQLiteConnect>> DB::ms_sqlite_pool;
std::unique_ptr<ConnectPool<MySQLConnect>> DB::ms_mysql_pool;
DB::snowflake_t DB::ms_user_id_generator;
DB::snowflake_t DB::ms_td_id_generator;
DB::snowflake_t DB::ms_sta_id_generator;
@ -26,6 +25,7 @@ void DB::init(const std::string& config_file) {
return;
}
ms_user_id_generator.init(1, 1);
ms_td_id_generator.init(1, 1);
ms_sta_id_generator.init(1, 1);
@ -47,8 +47,6 @@ void DB::initSqlite(const Parameter& param) {
sqlite_param.set<int>("flags",
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX);
ms_sqlite_pool = std::make_unique<ConnectPool<SQLiteConnect>>(sqlite_param);
auto con = ms_sqlite_pool->getAndWait();
DBUpgrade(con, "td", {}, 2, g_sqlite_create_db);
}
void DB::initMysql(const Parameter& param) {

View File

@ -9,6 +9,7 @@
#include <memory>
#include <hikyuu/utilities/ConnectPool.h>
#include <hikyuu/utilities/db_connect/DBConnect.h>
#include <hikyuu/utilities/db_connect/sqlite/SQLiteConnect.h>
#include <hikyuu/utilities/db_connect/mysql/MySQLConnect.h>
#include "../common/snowflake.h"
@ -24,6 +25,18 @@ public:
static bool isValidEumValue(const std::string &table, const std::string &field,
const std::string &val);
static bool isSQLite() {
return bool(ms_sqlite_pool);
}
static bool isMySQL() {
return bool(ms_mysql_pool);
}
static int64_t getNewUserId() {
return ms_user_id_generator.nextid();
}
static int64_t getNewTdId() {
return ms_td_id_generator.nextid();
}
@ -42,6 +55,7 @@ private:
static std::unique_ptr<ConnectPool<MySQLConnect>> ms_mysql_pool;
using snowflake_t = snowflake<1618243200000L, std::mutex>;
static snowflake_t ms_user_id_generator;
static snowflake_t ms_td_id_generator;
static snowflake_t ms_sta_id_generator;
};

View File

@ -116,13 +116,11 @@ public:
}
void setResData(const json &data) {
std::string x = data.dump();
setResData(x);
setResData(data.dump());
}
void setResData(const ordered_json &data) {
std::string x = data.dump();
setResData(x);
setResData(data.dump());
}
void operator()();

View File

@ -64,7 +64,7 @@ void HttpServer::start() {
#endif
for (;;) {
std::this_thread::sleep_for(std::chrono::seconds(5));
std::this_thread::sleep_for(std::chrono::seconds(2));
}
}

View File

@ -18,15 +18,16 @@ using namespace hku;
int main(int argc, char* argv[]) {
init_server_logger();
DB::init(fmt::format("{}/.hikyuu/trade.ini", getUserHome()));
LOG_INFO("start server ... You can press Ctrl-C stop");
HttpServer server("http://*", 9001);
try {
UserService login(HKU_SERVICE_API(user));
login.bind(&server);
DB::init(fmt::format("{}/.hikyuu/trade.ini", getUserHome()));
UserService usr_service(HKU_SERVICE_API(user));
usr_service.bind(&server);
AssistService assist(HKU_SERVICE_API(assist));
assist.bind(&server);

View File

@ -9,6 +9,17 @@
namespace hku {
enum TradeErrorCode { TD_ACCOUNT_REPETITION = 20000, TD_ACCOUNT_INVALD_TYPE };
enum RestErrorCode {
REST_INVALID_VALUE = 10000,
};
}
enum UserErrorCode {
USER_NAME_REPETITION = 20000,
};
enum TradeErrorCode {
TD_ACCOUNT_REPETITION = 30000,
TD_ACCOUNT_INVALD_TYPE,
};
} // namespace hku

View File

@ -8,6 +8,7 @@
#pragma once
#include "http/HttpHandle.h"
#include "db/db.h" // 这里统一引入
#include "RestErrorCode.h"
namespace hku {
@ -20,12 +21,12 @@ inline void AuthorizeFilter(HttpHandle *handle) {
HttpErrorCode::UNAUTHORIZED, "Failed authorize!");
}
class RestHandle : public HttpHandle {
CLASS_LOGGER(RestHandle)
class NoAuthRestHandle : public HttpHandle {
CLASS_LOGGER(NoAuthRestHandle)
public:
RestHandle(nng_aio *aio) : HttpHandle(aio) {
addFilter(AuthorizeFilter);
NoAuthRestHandle(nng_aio *aio) : HttpHandle(aio) {
// addFilter(AuthorizeFilter);
}
virtual void before_run() override {
@ -39,7 +40,7 @@ public:
}*/
protected:
void check_missing(const char *param) {
void check_missing_param(const char *param) {
if (!req.contains(param)) {
throw HttpError(HttpErrorCode::MISS_PARAMETER,
fmt::format(R"(Missing param "{}")", param));
@ -49,8 +50,8 @@ protected:
template <typename ModelTable>
void check_enum_field(const std::string &field, const std::string &value) {
if (!DB::isValidEumValue(ModelTable::getTableName(), field, value)) {
throw HttpError(TradeErrorCode::TD_ACCOUNT_INVALD_TYPE,
fmt::format("Invalid trade account type: {}", value));
throw HttpError(RestErrorCode::REST_INVALID_VALUE,
fmt::format("Invalid field({}) value: {}", field, value));
}
}
@ -58,6 +59,19 @@ protected:
json req; // 子类在 run 方法中直接使用次req
};
class RestHandle : public NoAuthRestHandle {
CLASS_LOGGER(RestHandle)
public:
RestHandle(nng_aio *aio) : NoAuthRestHandle(aio) {
addFilter(AuthorizeFilter);
}
};
#define NO_AUTH_REST_HANDLE_IMP(cls) \
public: \
cls(nng_aio *aio) : NoAuthRestHandle(aio) {}
#define REST_HANDLE_IMP(cls) \
public: \
cls(nng_aio *aio) : RestHandle(aio) {}

View File

@ -13,13 +13,11 @@
namespace hku {
class TradeService;
class AddTradeAccountHandle : public RestHandle {
REST_HANDLE_IMP(AddTradeAccountHandle)
virtual void run() override {
check_missing("name");
check_missing("type");
check_missing_param("name");
check_missing_param("type");
TradeAccountModel account;
std::string name = req["name"].get<std::string>();
std::string td_type = req["type"].get<std::string>();

View File

@ -8,6 +8,7 @@
#pragma once
#include "http/HttpService.h"
#include "sql/sqlite/sqlitedb.h"
#include "WalletHandle.h"
#include "TradeAccountHandle.h"
@ -18,7 +19,12 @@ class TradeService : public HttpService {
public:
TradeService() = delete;
TradeService(const char* url) : HttpService(url) {}
TradeService(const char* url) : HttpService(url) {
auto con = DB::getConnect();
if (DB::isSQLite()) {
DBUpgrade(con, "td", {}, 2, g_sqlite_create_td_db);
}
}
virtual void regHandle() override {
GET<WalletHandle>("wallet");

View File

@ -9,7 +9,7 @@
namespace hku {
const char *g_sqlite_create_db{
const char *g_sqlite_create_td_db{
R"(
CREATE TABLE "td_account" (
"id" INTEGER NOT NULL UNIQUE,

View File

@ -12,7 +12,7 @@
namespace hku {
extern const char *g_sqlite_create_db;
extern std::vector<std::string> g_sqlite_upgrade_db;
extern const char *g_sqlite_create_td_db;
extern std::vector<std::string> g_sqlite_upgrade_td_db;
} // namespace hku

View File

@ -9,6 +9,6 @@
namespace hku {
std::vector<std::string> g_sqlite_upgrade_db{};
std::vector<std::string> g_sqlite_upgrade_td_db{};
} // namespace hku

View File

@ -8,6 +8,7 @@
#pragma once
#include "../RestHandle.h"
#include "model/UserModel.h"
namespace hku {
@ -15,7 +16,7 @@ class LoginHandle : public RestHandle {
REST_HANDLE_IMP(LoginHandle)
virtual void run() override {
check_missing("user");
check_missing_param("user");
setResHeader("Content-Type", "application/json; charset=UTF-8");
setResData(
R"({"hku_token":"7c98806c0711cf996d602890e0ab9119d9a86afe04296ba69a16f0d9d76be755"})");

View File

@ -0,0 +1,39 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-04-25
* Author: fasiondog
*/
#pragma once
#include "../RestHandle.h"
#include "model/UserModel.h"
namespace hku {
class SignupHandle : public NoAuthRestHandle {
NO_AUTH_REST_HANDLE_IMP(SignupHandle)
virtual void run() override {
check_missing_param("user");
check_missing_param("password");
UserModel user;
user.setName(req["user"].get<string>());
user.setPassword(req["password"].get<string>());
user.setCreateTime(Datetime::now());
user.setToken("7c98806c0711cf996d602890e0ab9119d9a86afe04296ba69a16f0d9d76be755");
{
auto con = DB::getConnect();
TransAction trans(con);
int count = con->queryInt(fmt::format(R"(select count(id) from {} where name="{}")",
UserModel::getTableName(), user.getName()));
HTTP_CHECK(count == 0, UserErrorCode::USER_NAME_REPETITION, "Duplicate user name");
user.setUserId(DB::getNewUserId());
con->save(user, false);
}
setResData(
R"({"hku_token":"7c98806c0711cf996d602890e0ab9119d9a86afe04296ba69a16f0d9d76be755"})");
}
};
} // namespace hku

View File

@ -8,15 +8,25 @@
#pragma once
#include "http/HttpService.h"
#include "db/db.h"
#include "sql/sqlite/sqlitedb.h"
#include "UserHandle.h"
#include "LoginHandle.h"
#include "LogoutHandle.h"
namespace hku {
class UserService : public HttpService {
HTTP_SERVICE_IMP(UserService)
public:
UserService(const char *url) : HttpService(url) {
auto con = DB::getConnect();
if (DB::isSQLite()) {
DBUpgrade(con, "usr", {}, 2, g_sqlite_create_usr_db);
}
}
virtual void regHandle() override {
POST<SignupHandle>("signup");
POST<LoginHandle>("login");
POST<LogoutHandle>("logout");
}

View File

@ -0,0 +1,68 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-04-24
* Author: fasiondog
*/
#pragma once
#include <string_view>
#include <hikyuu/utilities/db_connect/TableMacro.h>
namespace hku {
class UserModel {
TABLE_BIND6(user, user_id, name, password, create_time, token, expire_time)
public:
int64_t getUserId() const {
return user_id;
}
void setUserId(int64_t id) {
user_id = id;
}
std::string getName() const {
return name;
}
void setName(const std::string& name) {
this->name = name;
}
std::string getPassword() const {
return password;
}
void setPassword(const std::string& password) {
this->password = password;
}
Datetime getCreateTime() const {
return Datetime(create_time);
}
void setCreateTime(Datetime time) {
create_time = time.number();
}
std::string getToken() const {
return token;
}
void setToken(std::string_view token) {
this->token = token;
}
private:
int64_t user_id; // 用户id
std::string name; // 用户名
std::string password; // 用户密码
uint64_t create_time; // 用户创建时间
std::string token;
uint64_t expire_time; // token 过期时间
};
} // namespace hku

View File

@ -0,0 +1,30 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-04-08
* Author: fasiondog
*/
#include "sqlitedb.h"
namespace hku {
const char *g_sqlite_create_usr_db{
R"(
CREATE TABLE "user" (
"id" INTEGER NOT NULL UNIQUE,
"user_id" INTEGER NOT NULL UNIQUE,
"name" TEXT NOT NULL UNIQUE,
"password" TEXT NOT NULL,
"create_time" INTEGER NOT NULL,
"token" TEXT,
"expire_time" INTEGER,
PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE INDEX "ix_on_user_by_user_id" ON "user" (
"user_id"
);
INSERT INTO "main"."user" ("id", "user_id", "name", "password", "create_time") VALUES ('1', '4374148134604800', 'admin', 'admin', '202104250141');
)"};
}

View File

@ -0,0 +1,18 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-04-08
* Author: fasiondog
*/
#pragma once
#include <string>
#include <vector>
namespace hku {
extern const char *g_sqlite_create_usr_db;
extern std::vector<std::string> g_sqlite_upgrade_usr_db;
} // namespace hku

View File

@ -0,0 +1,14 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-04-10
* Author: fasiondog
*/
#include "sqlitedb.h"
namespace hku {
std::vector<std::string> g_sqlite_upgrade_usr_db{};
} // namespace hku