...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
You may encounter code using connection
or its aliases, tcp_connection
,
tcp_ssl_connection
,
unix_connection
.
This was the main way to create client connections until Boost 1.87, when
any_connection
became stable.
connection
is not deprecated,
but we don't recommend using it in new code. any_connection
is simpler to use and provides the same level of efficiency.
connection
is templated on the Stream
class, which implements the transport layer to read and write wire bytes.
The library provides helper type aliases for the most common cases:
Transport |
Stream type |
Type alias |
---|---|---|
SSL over TCP |
|
|
Plaintext TCP |
|
|
UNIX sockets |
|
Only available if |
In contrast, any_connection
is not templated. The same three transports above can be used with any_connection
.
connection
's constructor takes
the same arguments as the underlying Stream
constructor. For a tcp_ssl_connection
,
we need to pass an execution context and a asio::ssl::context
:
// The execution context, required for all I/O operations asio::io_context ctx; // The SSL context, required for connections that use TLS. asio::ssl::context ssl_ctx(asio::ssl::context::tlsv12_client); // Construct the connection. The arguments are forwarded // to the stream type (asio::ssl::stream<asio::ip::tcp::socket>). mysql::tcp_ssl_connection conn(ctx, ssl_ctx);
Use connection::connect
or connection::async_connect
to perform connection establishment. This function takes two parameters:
asio::asio::ip::tcp::endpoint
,
which holds an IP address and a port. For UNIX sockets, it'd be an asio::asio::local::stream_protocol::endpoint
,
holding a UNIX path.
handshake_params
instance, containing all the parameters required to perform the MySQL handshake.
If you're using TCP, you must perform hostname resolution yourself. For example:
// Resolve the hostname to get a collection of endpoints. // default_port_string is MySQL's default port, 3306 // Hostname resolution may yield more than one host asio::ip::tcp::resolver resolver(ctx); auto endpoints = resolver.resolve(server_hostname, mysql::default_port_string); // Parameters specifying how to perform the MySQL handshake operation. // Similar to connect_params, but doesn't contain the server address and is non-owning mysql::handshake_params params( mysql_username, mysql_password, "boost_mysql_examples" // database to use ); // Connect to the server using the first endpoint returned by the resolver conn.connect(*endpoints.begin(), params);
As opposed to connect_params
,
handshake_params
does not own the strings it contains (like the username and the password).
It's your responsibility to keep them alive until the connect operation completes.
All functionality in handshake_params
has an equivalent in connect_params
.
See the reference table
for more info.
Once connected, connection
and any_connection
can be used almost equivalently:
// Issue a query, as you would with any_connection mysql::results result; conn.execute("SELECT 1", result);
Some differences:
async_set_character_set
and async_run_pipeline
,
are not present in connection
.
connection
's
completion token is asio::deferred
instead of mysql::with_diagnostics(asio::deferred)
.
When using coroutines with exceptions, you need to pass mysql::with_diagnostics
explicitly if you want exceptions with extra info.
As with any_connection
, use
connection::close
or async_close
:
To use TLS, you must use a connection
with a Stream
that supports TLS. A TLS-enabled stream must inherit from
asio::ssl::stream_base
.
The most common is asio::ssl::stream
(used by tcp_ssl_connection
).
When using a stream type that does not support TLS, like tcp_connection
or unix_connection
,
handshake_params::ssl
is ignored.
To use UNIX sockets, use unix_connection
:
// The execution context, required for all I/O operations asio::io_context ctx; // A UNIX connection requires only an execution context mysql::unix_connection conn(ctx); // The socket path where the server is listening asio::local::stream_protocol::endpoint ep("/var/run/mysqld/mysqld.sock"); // MySQL handshake parameters, as in the TCP case. mysql::handshake_params params( mysql_username, mysql_password, "boost_mysql_examples" // database to use ); // Connect to the server conn.connect(ep, params); // Use the connection normally
In addition to connect
and close
,
connection
exposes two additional
I/O operations:
connection::handshake
is like connect
, but doesn't
connect the underlying Stream
.
connection::quit
is like close
, but doesn't
close the underlying Stream
.
You can use them like this:
// The execution context, required for all I/O operations asio::io_context ctx; // The SSL context, required for connections that use TLS. asio::ssl::context ssl_ctx(asio::ssl::context::tlsv12_client); // We're using TLS over TCP mysql::tcp_ssl_connection conn(ctx, ssl_ctx); // Resolve the server hostname into endpoints asio::ip::tcp::resolver resolver(ctx); auto endpoints = resolver.resolve(server_hostname, mysql::default_port_string); // Connect the underlying stream manually. // asio::connect tries every endpoint in the passed sequence // until one succeeds. any_connection uses this internally. // lowest_layer obtains the underlying socket from the ssl::stream asio::connect(conn.stream().lowest_layer(), endpoints); // Perform MySQL session establishment. // This will also perform the TLS handshake, if required. mysql::handshake_params params( mysql_username, mysql_password, "boost_mysql_examples" // database to use ); conn.handshake(params); // Use the connection normally mysql::results result; conn.execute("SELECT 1", result); // Terminate the connection. This also performs the TLS shutdown. conn.quit(); // Close the underlying stream. // The connection's destructor also closes the socket, // but doing it explicitly will throw in case of error. conn.stream().lowest_layer().close();
These functions can be useful in the following cases:
asio::connect
overloads, as in the example above.
Stream
type. connect
and close
can only be used if the Stream
type satisfies SocketStream
- that is, when its lowest layer type is a socket. This holds for all the
stream types in the table above, but is not the case for asio::windows::stream_handle
.
The reconnection capabilities of connection
are more limited than those of any_connection
.
Concretely, when using TLS-capable streams, a connection
can't be re-used after it's closed or encounters a fatal error. This is because
asio::ssl::stream
can't be re-used. This limitation is not present in any_connection
.
If you are using tcp_connection
or unix_connection
,
or any other stream supporting reconnection, and you want to re-use a connection:
connection::close
,
or manually close the underlying stream, even if you encountered a fatal
error.
connection::connect
normally, even if the close operation failed.
connection::connect
operation failed, you can try opening it again by simply calling connection::connect
again.
If your Stream
type doesn't
fulfill the SocketStream
concept, you need to use handshake
and quit
instead of connect
and close
, and perform transport connection establishment
yourself.
As with any_connection
, connection
doesn't perform any built-in retry
strategy.
We recommend migrating code using templated connections to any_connection
.
In most cases, you only need to change connection establishment code to use
connect_params
instead of handshake_params
.
The following table summarizes all the differences between the two connection types, and provides migration paths for each feature you may use:
Feature |
any_connection |
connection |
---|---|---|
Hostname resolution |
Performed by |
Needs to be performed manually |
Credentials |
||
Database to use |
||
Setting TLS options |
Pass a |
|
TLS negotiation |
|
|
Connection collation |
||
Enabling multi-queries |
||
UNIX sockets |
Use a UNIX socket path in |
Use |
Windows named pipes |
Not available yet |
Use |
Changing the initial size of the internal network buffer |
Pass a |
|
Changing the network buffer size limit |
Not available: no limit on the network buffer size |
|
Access the underlying stream |
Unavailable |
|
Raw handshake and quit |
Unavailable |
|
Reconnection |
|
Requires closing the current connection first. Unavailable for |
Changing the connection's character set |
Unavailable |
|
Running pipelines |
Unavailable |
|
Including diagnostics in coroutine exceptions |
Enabled by default |
co_await conn.async_execute("SELECT 1", result, mysql::with_diagnostics(asio::deferred)); |
Connection pooling |
Unavailable |