mirror of
https://github.com/quizhizhe/LiteLoaderBDS-1.16.40.git
synced 2025-06-07 04:13:39 +00:00
207 lines
5.9 KiB
C++
207 lines
5.9 KiB
C++
#include <DB/ConnParams.h>
|
|
#include <Utils/StringHelper.h>
|
|
#include <LoggerAPI.h>
|
|
|
|
namespace DB {
|
|
|
|
#pragma region URL_Parser
|
|
|
|
struct URL {
|
|
std::string scheme;
|
|
std::string user;
|
|
std::string password;
|
|
std::string host;
|
|
uint16_t port = 0;
|
|
std::string path;
|
|
std::map<std::string, std::string> query;
|
|
std::string fragment;
|
|
};
|
|
|
|
URL ParseURL(const std::string& url) {
|
|
URL result;
|
|
std::string cur = url;
|
|
|
|
size_t pos = cur.find("://");
|
|
if (pos != std::string::npos) {
|
|
result.scheme = cur.substr(0, pos);
|
|
cur = cur.substr(pos + 3);
|
|
}
|
|
pos = cur.find('@');
|
|
auto pos0 = pos;
|
|
if (pos != std::string::npos) {
|
|
std::string userInfo = cur.substr(0, pos);
|
|
pos = userInfo.find(':');
|
|
if (pos != std::string::npos) {
|
|
result.user = userInfo.substr(0, pos);
|
|
result.password = userInfo.substr(pos + 1);
|
|
} else
|
|
result.user = userInfo;
|
|
cur = cur.substr(pos0 + 1);
|
|
}
|
|
pos = cur.find_first_of("/?#");
|
|
auto pos1 = pos;
|
|
std::string address = cur.substr(0, pos);
|
|
pos = address.find(':');
|
|
if (pos != std::string::npos) {
|
|
result.host = address.substr(0, pos);
|
|
result.port = static_cast<uint16_t>(std::stoi(address.substr(pos + 1)));
|
|
} else
|
|
result.host = address;
|
|
if (pos1 == std::string::npos)
|
|
return result;
|
|
else
|
|
cur = cur.substr(pos1);
|
|
|
|
pos = cur.find_first_of("?#");
|
|
result.path = cur.substr(0, pos);
|
|
if (pos == std::string::npos)
|
|
return result;
|
|
else
|
|
cur = cur.substr(pos);
|
|
if (cur[0] == '?') {
|
|
cur = cur.substr(1);
|
|
pos = cur.find('#');
|
|
std::string query = cur.substr(0, pos);
|
|
if (pos != std::string::npos) {
|
|
result.fragment = cur.substr(pos + 1);
|
|
}
|
|
std::vector<std::string> pairs = SplitStrWithPattern(query, "&");
|
|
for (auto& pair : pairs) {
|
|
std::string k, v;
|
|
pos = pair.find('=');
|
|
if (pos == std::string::npos)
|
|
k = pair;
|
|
else {
|
|
k = pair.substr(0, pos);
|
|
v = pair.substr(pos + 1);
|
|
}
|
|
result.query.emplace(k, v);
|
|
}
|
|
} else if (cur[0] == '#') {
|
|
result.fragment = cur.substr(1);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
extern Logger dbLogger;
|
|
void PrintURL(const URL& url) {
|
|
dbLogger.debug("Parsed URL");
|
|
dbLogger.debug("scheme: {}", url.scheme);
|
|
dbLogger.debug("user: {}", url.user);
|
|
dbLogger.debug("password: {}", url.password);
|
|
dbLogger.debug("host: {}", url.host);
|
|
dbLogger.debug("port: {}", url.port);
|
|
dbLogger.debug("path: {}", url.path);
|
|
dbLogger.debug("query:");
|
|
for (auto& pair : url.query)
|
|
dbLogger.debug("- {}: {}", pair.first, pair.second);
|
|
dbLogger.debug("fragment: {}", url.fragment);
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
ConnParams::ConnParams(const std::initializer_list<Any>& list)
|
|
: std::unordered_map<std::string, Any>() {
|
|
bool key = true;
|
|
std::string keyName;
|
|
for (auto& item : list) {
|
|
if (key) {
|
|
if (item.is_string()) {
|
|
throw std::invalid_argument("ConnParams::ConnParams: Key must be string");
|
|
}
|
|
keyName = item.get<std::string>();
|
|
key = false;
|
|
} else {
|
|
insert({keyName, item});
|
|
key = true;
|
|
}
|
|
}
|
|
auto host = getHost();
|
|
if (host.find(':') != std::string::npos) {
|
|
host = host.substr(0, host.find_last_of(':'));
|
|
auto port = host.substr(host.find_last_of(':') + 1);
|
|
(*this)["host"] = host;
|
|
(*this)["port"] = std::stoi(port);
|
|
}
|
|
}
|
|
ConnParams::ConnParams(const std::initializer_list<std::pair<std::string, Any>>& list)
|
|
: std::unordered_map<std::string, Any>() {
|
|
for (auto& item : list) {
|
|
insert(item);
|
|
}
|
|
auto host = getHost();
|
|
if (host.find(':') != std::string::npos) {
|
|
host = host.substr(0, host.find_last_of(':'));
|
|
auto port = host.substr(host.find_last_of(':') + 1);
|
|
(*this)["host"] = host;
|
|
(*this)["port"] = std::stoi(port);
|
|
}
|
|
}
|
|
ConnParams::ConnParams(const std::string& str)
|
|
: std::unordered_map<std::string, Any>() {
|
|
raw = str;
|
|
auto url = ParseURL(str);
|
|
#if defined(LLDB_DEBUG_MODE)
|
|
PrintURL(url);
|
|
#endif
|
|
|
|
if (!url.scheme.empty())
|
|
insert({"scheme", url.scheme});
|
|
if (!url.host.empty())
|
|
insert({"host", url.host});
|
|
if (url.port)
|
|
insert({"port", url.port});
|
|
if (!url.user.empty())
|
|
insert({"user", url.user});
|
|
if (!url.password.empty())
|
|
insert({"password", url.password});
|
|
if (!url.path.empty()) {
|
|
std::string path = url.path;
|
|
if (path[0] == '/')
|
|
path = path.substr(1);
|
|
insert({"path", path});
|
|
}
|
|
if (!url.fragment.empty())
|
|
insert({"fragment", url.fragment});
|
|
for (auto& pair : url.query) {
|
|
insert({pair.first, Any::str2any(pair.second)});
|
|
}
|
|
}
|
|
ConnParams::ConnParams(const char* str)
|
|
: std::unordered_map<std::string, Any>() {
|
|
*this = ConnParams(std::string(str));
|
|
}
|
|
|
|
std::string ConnParams::getScheme() {
|
|
return get<std::string>({"scheme", "protocol", "type"}, true);
|
|
}
|
|
|
|
std::string ConnParams::getHost() {
|
|
return get<std::string>({"host", "hostname", "server", "server_name", "ip", "address"}, true);
|
|
}
|
|
|
|
uint16_t ConnParams::getPort() {
|
|
return get<uint16_t>({"port", "port_number", "port_num", "port_id", "portid"}, true, 0);
|
|
}
|
|
|
|
std::string ConnParams::getUsername() {
|
|
return get<std::string>({"user", "username", "user_name", "usr", "usrname"}, true);
|
|
}
|
|
|
|
std::string ConnParams::getPassword() {
|
|
return get<std::string>({"password", "pass", "passwd", "pass_word"}, true);
|
|
}
|
|
|
|
std::string ConnParams::getDatabase() {
|
|
return get<std::string>({"database", "db", "db_name", "dbname", "path"}, true);
|
|
}
|
|
|
|
std::string ConnParams::getPath() {
|
|
return get<std::string>({"path", "file", "file_name", "filename"}, true);
|
|
}
|
|
|
|
std::string ConnParams::getRaw() {
|
|
return raw;
|
|
}
|
|
|
|
} // namespace DB
|