boat
C++23 geospatial library
Loading...
Searching...
No Matches
commands.hpp
Go to the documentation of this file.
1// Andrew Naplavkov
2
3#ifndef BOAT_SQL_COMMANDS_HPP
4#define BOAT_SQL_COMMANDS_HPP
5
6#if __has_include(<libpq-fe.h>)
8#else
9#pragma message("no libpq")
10#endif
11#if __has_include(<mysql.h>)
13#else
14#pragma message("no libmysql")
15#endif
16#if __has_include(<sql.h>)
18#else
19#pragma message("no odbc")
20#endif
21#if __has_include(<sqlite3.h>)
23#else
24#pragma message("no sqlite")
25#endif
26#include <boat/detail/string.hpp>
27#include <boat/detail/uri.hpp>
28
29namespace boat::sql {
30
32inline bool supported_url(std::string_view url)
33{
34 return any({"mysql://", "odbc://", "postgres://", "sqlite://"},
35 prefix(url));
36}
37
39inline std::unique_ptr<db::command> make_command(std::string_view url)
40{
41 if (url.starts_with("mysql://"))
42#if __has_include(<mysql.h>)
43 {
44 auto u = uri::parse(url);
45 auto sock = socket_address::parse(u.host_spec);
46 return std::make_unique<libmysql::command>(
47 std::string{u.user}.data(),
48 std::string{u.password}.data(),
49 std::string{sock.host}.data(),
50 sock.port.empty()
51 ? 0
52 : from_chars<int>(sock.port.data(), sock.port.size()),
53 std::string{u.path}.data());
54 }
55#else
56 throw std::runtime_error("compiled without libmysql");
57#endif
58 if (url.starts_with("odbc://"))
59#if __has_include(<sql.h>)
60 {
61 auto u = uri::parse(url);
62 auto sock = socket_address::parse(u.host_spec);
63 auto os = std::ostringstream{};
64 if (!u.user.empty())
65 os << "uid=" << u.user << ';';
66 if (!u.password.empty())
67 os << "pwd=" << u.password << ';';
68 if (!sock.host.empty())
69 os << "server=" << sock.host << ';';
70 if (!sock.port.empty())
71 os << "port=" << sock.port << ';';
72 if (!u.path.empty())
73 os << "database=" << u.path << ';';
74 constexpr auto replace_sep = [](char c) { return c == '&' ? ';' : c; };
75 for (char c : u.query | std::views::transform(replace_sep))
76 os << c;
77 return std::make_unique<odbc::command>(std::move(os).str().data());
78 }
79#else
80 throw std::runtime_error("compiled without odbc");
81#endif
82 if (url.starts_with("postgres://"))
83#if __has_include(<libpq-fe.h>)
84 return std::make_unique<libpq::command>(std::string{url}.data());
85#else
86 throw std::runtime_error("compiled without libpq");
87#endif
88 if (url.starts_with("sqlite://"))
89#if __has_include(<sqlite3.h>)
90 return std::make_unique<sqlite::command>(
91 std::string{uri::parse(url).path}.data());
92#else
93 throw std::runtime_error("compiled without sqlite");
94#endif
95 throw std::runtime_error("sql::make_command");
96}
97
98} // namespace boat::sql
99
100#endif // BOAT_SQL_COMMANDS_HPP
Definition catalog.hpp:9
std::unique_ptr< db::command > make_command(std::string_view url)
Throws if the URL scheme is unknown or its client library is unavailable.
Definition commands.hpp:39
bool supported_url(std::string_view url)
Recognizes SQL URL schemes even without the corresponding client library.
Definition commands.hpp:32