#include "Database.h" #include "../server/Global.h" #include "../server/Performance_Monitor.h" #include #include #include Aircraft::Aircraft(const std::string &icao) : Aircraft_Info(icao) { auto size = Global::instance()->mode_acs.max_track_point_size.load(); air_pos_track_list.init(size); surface_pos_track_list.init(size); } void Aircraft::refresh_external_database_info() { auto& manager = Global::instance()->external_resources_manager; if (!external_database_info_loaded) { external_database_info = manager.query_aircraft_external_databases(icao); external_database_info_loaded = true; } auto callsign = flight(); if (!callsign) callsign = bds20_call_sign(); if (last_external_database_callsign == callsign) { return; } callsign_external_database_info = manager.query_callsign_external_databases(callsign); last_external_database_callsign = std::move(callsign); } std::shared_ptr DataBase::get_aircraft(const std::string& icao) { return aircraft_map.get(icao); } std::shared_ptr DataBase::create_aircraft(const std::string& icao) { auto ret = aircraft_map.create(icao); ret->refresh_external_database_info(); return ret; } void DataBase::delete_timeout_aircraft() { aircraft_map.remove_cond([](const std::shared_ptr& item) { if (item->timestamp == 0) { std::cout << "未初始化的 timestamp " << LOG_POS << std::endl; } long long time = std::time(nullptr) - item->timestamp; return time > Global::instance()->mode_acs.timeout_seconds; }); } JSON DataBase::get_aircraftlist() { JSON json = JSON::array(); for (auto& it : aircraft_map.values()) { auto o = Aircraft_List_JSON_Service_O::to_That(this, it.get()); json.children.push_back(o.toJson()); } return json; } Psc::JSON DataBase::get_aircraftlist(int limit_msg_num) { JSON json = JSON::array(); for (auto& it : aircraft_map.values()) { if (it->times < limit_msg_num) continue; auto o = Aircraft_List_JSON_Service_O::to_That(this, it.get()); json.children.push_back(o.toJson()); } return json; } JSON DataBase::get_all_aircraft_json() { JSON json = JSON::array(); auto g = Global::instance(); size_t num = 0; for (auto& it : aircraft_map.values()) { auto vto = Flight_VTO::to_VTO(it.get()); bool have_pos = !it.get()->air_pos_track_list.empty(); if (have_pos) { json.children.push_back(vto.toJson()); num++; } } have_pos_aircraft_num = num; return json; } JSON DataBase::get_aircraft_list_after(time_t timestamp) { JSON json = JSON::array(); auto g = Global::instance(); for (auto& it : aircraft_map.values()) { auto vto = Flight_VTO::to_VTO(it.get()); bool have_pos = !it.get()->air_pos_track_list.empty(); if (have_pos && vto.time_stamp > timestamp) { json.children.push_back(vto.toJson()); } } return json; } #ifdef Cache_Some_Mode_S Psc::JSON DataBase::get_limit_mode_s_msg_info() { JSON ret = JSON::object(); JSON list = JSON::array(); std::map map; std::map num_test; for (auto& air : aircraft_map.values()) { if (air->total_num > Cache_Some_Mode_S_Num) continue; Psc::JSON air_json = Psc::JSON::object(); { Psc::JSON ms = Psc::JSON::array(); int n = air->cache.size(); for (auto msg : air->cache) { Psc::JSON cur = Psc::JSON::object({ {"hex", msg->msg_hex}, {"df", to_string(msg->df)} }); if (msg->df == Downlink_Format::Extended_Squitter_17) { auto tc = type_code(msg->msg_bin); cur.children.push_back({"tc", tc}); map[tc]++; num_test[air->total_num] = n; } ms.append(cur); } air_json.children.push_back({"icao", air->icao}); air_json.children.push_back({"total_num", air->total_num}); air_json.children.push_back({"ms", ms}); } list.children.push_back(air_json); } ret.children.push_back({"key", key}); for (auto pair : map) { ret.children.push_back({std::to_string(pair.first), pair.second}); } Psc::JSON t = Psc::JSON::object(); for (auto pair : num_test) { t.children.push_back({std::to_string(pair.first), pair.second}); } ret.children.push_back({"数量统计", t}); ret.children.push_back({"list", list}); return ret; } #endif size_t DataBase::get_aircraft_num() { return aircraft_map.size(); } #define _init_db \ HTTP_REQUIRE_VALUE(data_source_key, params.try_get_string("data_source_key")) \ auto db = Global::instance()->source(data_source_key); \ if (db == nullptr) { \ res->setStatusCode(drogon::k503ServiceUnavailable); \ JSON ret; \ res->setBody(ret.to_json_string()); \ return; \ } void database_server(Global* g) { auto& svr = g->svr; auto& api = g->api; // g->load_aircraft_csv(g->mode_acs.aircraft_csv_path); g->external_resources_manager.load_sqlite_db( Psc::get_abs_path(g->external_resources_manager.ecap_sqlite_path)); #ifdef Cache_Some_Mode_S svr.Post(api + "get_cache_some_mode_s_info", [](HTTP_Param) { CHECK_JSON_PARAM _init_db auto g = Global::instance(); auto ret = JSON::object(); if (db) { ret = db->get_limit_mode_s_msg_info(); } res->setBody(warp(ret).to_json_string()); }); #endif svr.Post(api + "get_base_station_location", [](HTTP_Param) { CHECK_JSON_PARAM _init_db auto g = Global::instance(); auto ret = JSON::object(); if (db) { ret = db->base_station.to_Json(); } res->setBody(warp(ret).to_json_string()); }); svr.Post(api + "get_aircraft_base_info", [](HTTP_Param) { CHECK_JSON_PARAM _init_db HTTP_REQUIRE_VALUE(icao, params.try_get_string("icao")) auto aircraft = db->get_aircraft(icao); JSON ret; if (aircraft != nullptr) { auto vto = Flight_VTO::to_VTO(aircraft.get()); ret = vto.toJson(); } res->setBody(ret.to_json_string()); }); svr.Post(api + "get_aircraft_detail_info", [](HTTP_Param) { CHECK_JSON_PARAM _init_db HTTP_REQUIRE_VALUE(icao, params.try_get_string("icao")) auto aircraft = db->get_aircraft(icao); JSON ret; if (aircraft != nullptr) { ret = aircraft->toJson(); } res->setBody(ret.to_json_string()); }); svr.Post(api + "get_aircraft_track_list", [](HTTP_Param) { CHECK_JSON_PARAM _init_db HTTP_REQUIRE_VALUE(icao, params.try_get_string("icao")) HTTP_REQUIRE_VALUE(last_size, params.try_get_number("last_size")) auto aircraft = db->get_aircraft(icao); JSON ret; if (aircraft != nullptr) { ret = aircraft->air_pos_track_list.get_last_array_json(last_size); ret.children.insert(ret.children.begin(), JSON("ds", data_source_key)); ret.children.insert(ret.children.begin(), JSON("icao", icao)); } res->setBody(ret.to_json_string()); }); svr.Post(api + "get_aircraft_list_after", [](HTTP_Param) { CHECK_JSON_PARAM _init_db HTTP_REQUIRE_VALUE(timestamp, params.try_get_number("timestamp")) auto ret = db->get_aircraft_list_after(timestamp); res->setBody(ret.to_json_string()); }); svr.Post(api + "aircraft_change_list", [](HTTP_Param) { CHECK_JSON_PARAM _init_db JSON ret = JSON::array(); if (db) { ret = db->get_all_aircraft_json(); } else { } res->setBody(warp(ret).to_json_string()); }); svr.Get(R"(/aircraftlist.json)", [](HTTP_Param) { auto list = Global::instance()->mode_acs.data_source_config.map.list(); std::shared_ptr ts = nullptr; auto ret = JSON::array(); for (const auto& li : list) { if (li->enable) { ret = li->get_aircraftlist(); break; } } res->setBody(ret.to_json_string("", "\n", "")); }); // aircraftlist.json 的带数据源版本 svr.Post(api + "aircraft_list", [](HTTP_Param) { CHECK_JSON_PARAM auto g = Global::instance(); HTTP_REQUIRE_VALUE(data_source_key, params.try_get_string("data_source_key")) std::shared_ptr db; { db = g->source(data_source_key); } if (db == nullptr) { res->setStatusCode(drogon::k503ServiceUnavailable); JSON ret; res->setBody(ret.to_json_string()); return; } auto limit_msg_num = g->mode_acs.default_min_aircraft_list_num.load(); auto t = params.get("limit_msg_num"); if (t) { HTTP_REQUIRE_VALUE(requested_limit_msg_num, t->try_number_val()) limit_msg_num = requested_limit_msg_num; } JSON ret = JSON::array(); { Scope_Timer timer( "aircraft_list.db_query", g->http_monitor_config.slow_scope_threshold_ms); ret = db->get_aircraftlist(limit_msg_num); } std::string body; { Scope_Timer timer( "aircraft_list.json_serialization", g->http_monitor_config.slow_scope_threshold_ms); body = warp(ret).to_json_string(); } res->setBody(body); }); } static std::string output; static void log_i(const std::string& label, const std::string& value, const std::string& unit = "") { std::ostringstream oss; // Format the label and value oss << std::left << std::setw(30) << label << ": " << value; // Add unit if not empty if (!unit.empty()) { oss << " " << unit << "\n"; } else { oss << "\n"; } // Append formatted string to output output += oss.str(); } static void log_i(const std::string& label, double value, const std::string& unit = "") { log_i(label, std::to_string(value), unit); }