#include #include #include #include #include #include namespace DCR { namespace ihd { using std::string; using std::vector; namespace { thread_local Connection local_conn; } auto read_conn_config_maybe() -> maybe { return fp::lift_maybe( [](nlohmann::json config_json) { Connection::Config conn_config; // 如果配置信息不为空,则根据配置信息初始化连接配置 snprintf(conn_config.hd3_conn.szAddress, sizeof(conn_config.hd3_conn.szAddress), "%s", config_json.at("ip_address").get().c_str()); conn_config.hd3_conn.nPort = config_json.at("port").get(); conn_config.hd3_conn.nTimeout = config_json.at("time_out").get(); conn_config.username = config_json.at("username").get(); conn_config.password = config_json.at("password").get(); return conn_config; }, read_config_maybe("utility", "ihyper_db")); } auto init_conn_maybe(maybe&& conn_config_maybe) -> maybe { // connect to ihyperDB return fwd::apply( conn_config_maybe, fwd::lift_maybe([](Connection::Config conn_config) { nt3_connect(&conn_config.hd3_conn); return conn_config; }), fwd::lift_maybe([](Connection::Config conn_config) { auto ret_code = sc3_login(conn_config.username.c_str(), conn_config.password.c_str()); if (ret_code != RD_SUCCESS) { return Connection{.state = Connection::State::disconnected, .tid = std::this_thread::get_id()}; } return Connection{.state = Connection::State::connected, .tid = std::this_thread::get_id()}; })); } auto disconnect_maybe(maybe conn_maybe) -> maybe { return fp::lift_maybe( [](Connection conn) { if (conn.state == Connection::State::connected) { auto ret_code = nt3_disconnect(); if (ret_code == RD_SUCCESS) { conn.state = Connection::State::disconnected; } return conn; } return conn; }, conn_maybe); } auto connect_maybe(maybe conn_maybe) -> maybe { return fp::lift_maybe( [](Connection conn) { if (conn.state == Connection::State::disconnected) { auto ret_code = nt3_connect(&conn.config.hd3_conn); if (ret_code == RD_SUCCESS) { ret_code = sc3_login(conn.config.username.c_str(), conn.config.password.c_str()); if (ret_code == RD_SUCCESS) { conn.state = Connection::State::connected; } } } return conn; }, conn_maybe); } auto read_conn_state() -> Connection::State { return local_conn.state; } auto read_conn() -> Connection { return local_conn; } auto store_conn_to_local(Connection& conn) -> Connection { local_conn = conn; return local_conn; } auto auto_connect() -> maybe { if (read_conn_state() == Connection::State::disconnected) { auto conn_maybe = init_conn_maybe(read_conn_config_maybe()); return fp::lift_maybe( [](Connection conn) { store_conn_to_local(conn); return store_conn_to_local(conn); }, conn_maybe); } return read_conn(); } } // namespace ihd } // namespace DCR