Boost.MySQL

repository·develop·Indexed 43 days ago

https://github.com/boostorg/mysql

A C++11 client for MySQL and MariaDB database servers built on Boost.Asio. It supports text queries, prepared statements, stored procedures, and multiple asynchronous models including C++20 coroutines. The library provides features for connection pooling, TLS encryption, and support for both TCP and UNIX socket transports. Requires Boost 1.82 or higher and OpenSSL.

Tokens
1.8K
Snippets
5
Records
13
Agent score
5%

What's inside Boost.MySQL

  1. Core features of Boost.MySQL

    develop

    Boost.MySQL provides a C++11 client for MySQL and MariaDB servers with the following capabilities:

    • Text queries: Execution of text SQL queries and data retrieval using the MySQL "text protocol".
    • Prepared statements: Execution of prepared statements using the MySQL "binary protocol".
    • Stored procedures: Support for calling stored procedures.
    • Authentication: Supports mysql_native_password and caching_sha2_password authentication plugins.
    • Security: Encrypted connections via TLS.
    • Transports: Support for both TCP and UNIX socket transports.
    • Connection Management: Includes connection pools.
    • SQL Generation: Friendly client-side generated SQL.
    • Pipelines: Experimental support for pipelines.
  2. Handle query results and row-by-row reading

    develop

    Resultsets as I/O objects have been removed. There are now two primary ways to handle query results:

    1. Read all rows into memory: Use connection::query or connection::execute_statement. These return a results object (a plain data object containing all rows). This replaces the old pattern of calling .read_all() on a resultset.
    2. Row-by-row reading: If your application requires streaming rows (e.g., using read_one or read_many), use connection::start_query or statement::start_execution. These return an execution_state object. To read rows, use conn.read_some_rows(...). Note that there is no specific function to read a single row; you must use the batch-oriented read_some_rows.
    // To read all rows at once (Recommended if memory allows)
    auto results = conn.query("SELECT ...");
    
    // To read rows one-by-one (Streaming)
    auto execution_state = conn.start_query("SELECT ...");
    // Use conn.read_some_rows(...) to fetch data
  3. How Boost.MySQL integrates with Boost.Asio

    develop

    Boost.MySQL is built on top of Boost.Asio and is designed to be fully compatible with the Boost.Asio ecosystem (such as Boost.Beast). It supports Boost.Asio's universal asynchronous model, allowing developers to use various concurrency patterns:

    • Callbacks
    • Futures
    • Coroutines (including C++20 coroutines)
  4. Migrate from 0.2.x to 1.82+

    develop
    Upgrading from version 0.2.x to 1.82 (and subsequent versions) is a major upgrade involving significant API changes. Key changes include the replacement of value with field_view, the transition of statements from I/O objects to connection-managed objects, and changes to how resultsets and error diagnostics are handled.
  5. Install and configure Boost.MySQL with CMake

    develop

    Boost.MySQL is a header-only library, but it requires Boost 1.82 or higher (it does not work with standalone Asio), a C++11 capable compiler, and OpenSSL.

    Since Boost 1.85, you must also link against the compiled Boost::charconv library. If you encounter linking errors, ensure you are linking to the charconv component in your build system.

    project(boost_mysql_example LANGUAGES CXX)
    
    find_package(Boost REQUIRED COMPONENTS charconv)
    find_package(Threads REQUIRED)
    find_package(OpenSSL REQUIRED)
    
    add_executable(main main.cpp)
    target_link_libraries(main PRIVATE Boost::charconv Threads::Threads OpenSSL::Crypto OpenSSL::SSL)
  6. Execute statements via connection

    develop

    Statements are no longer I/O objects. While connection::prepare_statement remains the same, execution and closing must now be performed through the connection object.

    Actions:

    • Replace stmt.execute(...) with conn.execute_statement(stmt, ...).
    • Replace stmt.close() with conn.close_statement(stmt).
    // Old way (0.2.x)
    stmt.execute(params);
    stmt.close();
    
    // New way (1.82+)
    conn.execute_statement(stmt, params);
    conn.close_statement(stmt);
  7. Work with date and datetime types

    develop

    The date and datetime types are now custom types rather than aliases for std::chrono. This allows them to represent zero or invalid dates.

    Action: To convert a date or datetime to a std::chrono::time_point, use the as_time_point or get_time_point methods in conjunction with valid() to ensure the value is usable.

  8. Handle diagnostics and server messages

    develop

    The error_info class has been renamed to diagnostics, and error_info::message() is now diagnostics::server_message().

    Important: The server message is no longer included by default in the what() string of thrown exceptions because it may not be UTF-8 compatible. To retrieve the server message from an exception, catch the error_with_diagnostics exception type.

  9. Pass statement parameters as std::tuple

    develop

    Statement parameters are now passed as a std::tuple to execute_statement instead of a collection.

    Action:

    • Replace stmt.execute(make_values(a, b), ...) with conn.execute_statement(std::make_tuple(a, b), ...).
    • If the number of parameters is unknown at compile-time, refer to the community solution for dynamic parameter handling.
    // Old way (0.2.x)
    stmt.execute(make_values(a, b), ...);
    
    // New way (1.82+)
    conn.execute_statement(std::make_tuple(a, b), ...);
    
    // For no parameters
    conn.execute_statement(std::make_tuple(), ...);
  10. Replace value with field_view

    develop

    The value class has been replaced by field_view. Generic accessors have been replaced by type-specific functions. Conversions, get_optional, and get_std_optional have been removed in favor of an interface similar to json::value.

    To take ownership of a field_view, use the new field class.

  11. Configure metadata retention

    develop

    To save allocations, metadata strings (like column names) are no longer retained by default.

    Action: If your code relies on metadata (e.g., calling metadata::column_name()), you must call conn.set_metadata_mode(metadata_mode::full) before executing your query or statement.

    conn.set_metadata_mode(metadata_mode::full);
    auto results = conn.query("SELECT ...");
    // Now metadata like column names are available