### Add Simple Example: Metadata Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example for retrieving metadata, passing regular arguments. ```cmake add_simple_example(metadata ARGS ${REGULAR_ARGS}) ``` -------------------------------- ### Add Simple Example: Callbacks Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example demonstrating the use of callbacks, passing regular arguments. ```cmake add_simple_example(callbacks ARGS ${REGULAR_ARGS}) ``` -------------------------------- ### Add Tutorial Example: Basic Synchronization Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a tutorial example for basic synchronization, linking common libraries and passing regular arguments. ```cmake add_tutorial(tutorial_sync 1_sync.cpp ARGS ${REGULAR_ARGS}) ``` -------------------------------- ### Add Simple Example: Pipeline Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example demonstrating pipelining of commands, passing regular arguments and a specific value. ```cmake add_simple_example(pipeline ARGS ${REGULAR_ARGS} "HGS") ``` -------------------------------- ### Add Tutorial Example: With Parameters Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a tutorial example for using parameters in queries, linking common libraries and passing regular arguments along with a parameter value. ```cmake add_tutorial(tutorial_with_params 3_with_params.cpp ARGS ${REGULAR_ARGS} 1) ``` -------------------------------- ### Add Simple Example: UNIX Sockets Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example for using UNIX domain sockets, passing user and password arguments. This example is only added on non-Windows systems. ```cmake if (NOT WIN32) add_simple_example(unix_socket ARGS example_user example_password) endif() ``` -------------------------------- ### Function to Add Tutorial Example Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt A CMake function that simplifies adding tutorial examples by calling `add_example` with a predefined source path prefix. ```cmake function(add_tutorial EXAMPLE_NAME EXAMPLE_PATH) add_example(${EXAMPLE_NAME} SOURCES "1_tutorial/${EXAMPLE_PATH}" ${ARGN}) endfunction() ``` -------------------------------- ### Add Simple Example: Inserts Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example for performing insert operations, passing regular arguments and specific values for insertion. ```cmake add_simple_example(inserts ARGS ${REGULAR_ARGS} "John" "Doe" "HGS") ``` -------------------------------- ### Add Tutorial Example: Updates and Transactions Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a tutorial example for handling updates and transactions, linking common libraries, passing regular arguments, and requiring the Boost.PFR library. ```cmake add_tutorial(tutorial_updates_transactions 5_updates_transactions.cpp ARGS ${REGULAR_ARGS} 1 "John" LIBS Boost::pfr) ``` -------------------------------- ### Add Simple Example: Prepared Statements Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example for using prepared statements, passing regular arguments and a specific value. ```cmake add_simple_example(prepared_statements ARGS ${REGULAR_ARGS} "HGS") ``` -------------------------------- ### Define Regular Arguments for Examples Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Sets up a list of common arguments used for many examples, including user, password, and the server host. ```cmake set(REGULAR_ARGS example_user example_password ${SERVER_HOST}) ``` -------------------------------- ### Add Tutorial Example: Connection Pool Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a tutorial example for connection pooling, specifying the server host, a Python runner script, and requiring the Boost.PFR library. ```cmake add_tutorial(tutorial_connection_pool 6_connection_pool.cpp ARGS ${SERVER_HOST} LIBS Boost::pfr PYTHON_RUNNER run_tutorial_connection_pool.py) ``` -------------------------------- ### Add Simple Example: Source Script Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example that executes commands from a source script, passing regular arguments and the path to the SQL script. ```cmake add_simple_example(source_script ARGS ${REGULAR_ARGS} ${CMAKE_CURRENT_SOURCE_DIR}/private/test_script.sql) ``` -------------------------------- ### Add Tutorial Example: Static Interface Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a tutorial example showcasing the static interface, linking common libraries, passing regular arguments, and requiring the Boost.PFR library. ```cmake add_tutorial(tutorial_static_interface 4_static_interface.cpp ARGS ${REGULAR_ARGS} 1 LIBS Boost::pfr) ``` -------------------------------- ### Add Simple Example: Deletes Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example for performing delete operations, passing regular arguments and a value for deletion. ```cmake add_simple_example(deletes ARGS ${REGULAR_ARGS} 20) ``` -------------------------------- ### Add Simple Example: TLS Certificate Verification Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example for TLS certificate verification, passing regular arguments. ```cmake add_simple_example(tls_certificate_verification ARGS ${REGULAR_ARGS}) ``` -------------------------------- ### Add Simple Example: Multi-Function Calls Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example for making multiple function calls, passing regular arguments. ```cmake add_simple_example(multi_function ARGS ${REGULAR_ARGS}) ``` -------------------------------- ### Add Simple Example: Disable TLS Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example for disabling TLS encryption, passing regular arguments. ```cmake add_simple_example(disable_tls ARGS ${REGULAR_ARGS}) ``` -------------------------------- ### Add Tutorial Example: Asynchronous Operations Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a tutorial example demonstrating asynchronous operations, linking common libraries and passing regular arguments. ```cmake add_tutorial(tutorial_async 2_async.cpp ARGS ${REGULAR_ARGS}) ``` -------------------------------- ### Function to Add Simple Example Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt A CMake function that simplifies adding simple examples by calling `add_example` with a predefined source path prefix. ```cmake function(add_simple_example EXAMPLE_NAME) add_example(${EXAMPLE_NAME} SOURCES "2_simple/${EXAMPLE_NAME}.cpp" ${ARGN}) endfunction() ``` -------------------------------- ### Add Simple Example: Batch Inserts Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example for batch inserts, specifying the server host, a Python runner script, and requiring the Boost.JSON library. ```cmake add_simple_example(batch_inserts ARGS ${SERVER_HOST} PYTHON_RUNNER run_batch_inserts.py LIBS Boost::json) ``` -------------------------------- ### Common Interface Library for Examples Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Defines an INTERFACE library for common settings used by Boost.MySQL examples, linking against the compiled Boost.MySQL library. ```cmake add_library(boost_mysql_examples_common INTERFACE) target_link_libraries( boost_mysql_examples_common INTERFACE boost_mysql_compiled ) ``` -------------------------------- ### Add Simple Example: Dynamic Filters Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example demonstrating dynamic filters, specifying the server host and a Python runner script. ```cmake add_simple_example(dynamic_filters ARGS ${SERVER_HOST} PYTHON_RUNNER run_dynamic_filters.py) ``` -------------------------------- ### Add Simple Example: Patch Updates Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example for patch updates, specifying the server host and a Python runner script. ```cmake add_simple_example(patch_updates ARGS ${SERVER_HOST} PYTHON_RUNNER run_patch_updates.py) ``` -------------------------------- ### Add Simple Example: Generic Batch Inserts Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example for generic batch inserts, specifying the server host, a Python runner script, and requiring the Boost.JSON library. ```cmake add_simple_example(batch_inserts_generic ARGS ${SERVER_HOST} PYTHON_RUNNER run_batch_inserts.py LIBS Boost::json) ``` -------------------------------- ### Add Simple Example: C++11 Coroutines Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a simple example utilizing C++11 coroutines, passing regular arguments and requiring the Boost.Context library. ```cmake add_simple_example(coroutines_cpp11 ARGS ${REGULAR_ARGS} LIBS Boost::context) ``` -------------------------------- ### Add Tutorial Example: Error Handling Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Adds a tutorial example for error handling, specifying the server host, a Python runner script, and requiring the Boost.PFR library. Includes a flag for testing errors. ```cmake add_tutorial(tutorial_error_handling 7_error_handling.cpp ARGS ${SERVER_HOST} --test-errors LIBS Boost::pfr PYTHON_RUNNER run_tutorial_connection_pool.py) ``` -------------------------------- ### CMake: Basic Project Setup Source: https://github.com/boostorg/mysql/blob/develop/test/cmake_b2_separate_compilation_test/CMakeLists.txt Initializes the CMake project, specifying the minimum required version and project name. It also finds and includes necessary packages like Boost, Threads, and OpenSSL. ```cmake cmake_minimum_required(VERSION 3.5...3.22) project(boost_mysql_example LANGUAGES CXX) find_package(Boost REQUIRED COMPONENTS headers charconv) find_package(Threads REQUIRED) find_package(OpenSSL REQUIRED) ``` -------------------------------- ### Executable and Test Setup Source: https://github.com/boostorg/mysql/blob/develop/test/cmake_b2_test/CMakeLists.txt Defines the main executable for the project and sets up a CTest to run it. This allows for easy building and testing of the application. ```cmake add_executable(main main.cpp) ``` ```cmake include(CTest) add_test(NAME main COMMAND main) ``` -------------------------------- ### Function to Add Example Executable Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt A CMake function to add an executable for a Boost.MySQL example. It handles sources, libraries, arguments, and test integration, with an option for Python runners. ```cmake function(add_example EXAMPLE_NAME) # Parse the arguments set(ONE_VALUE_ARGS PYTHON_RUNNER) set(MULTI_VALUE_ARGS SOURCES LIBS ARGS) cmake_parse_arguments(ADD_EXAMPLE "" "${ONE_VALUE_ARGS}" "${MULTI_VALUE_ARGS}" ${ARGN}) # Create the target set(TARGET_NAME "boost_mysql_example_${EXAMPLE_NAME}") add_executable(${TARGET_NAME} ${ADD_EXAMPLE_SOURCES}) target_link_libraries(${TARGET_NAME} PRIVATE boost_mysql_examples_common) boost_mysql_test_target_settings(${TARGET_NAME}) target_link_libraries(${TARGET_NAME} PRIVATE ${ADD_EXAMPLE_LIBS}) # Add it as a test if (ADD_EXAMPLE_PYTHON_RUNNER) add_test( NAME ${TARGET_NAME} COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/private/${ADD_EXAMPLE_PYTHON_RUNNER} $ ${ADD_EXAMPLE_ARGS} ) else() add_test( NAME ${TARGET_NAME} COMMAND ${TARGET_NAME} ${ADD_EXAMPLE_ARGS} ) endif() endfunction() ``` -------------------------------- ### Define MySQL Server Host Source: https://github.com/boostorg/mysql/blob/develop/example/CMakeLists.txt Sets the MySQL server host for examples. It checks for the BOOST_MYSQL_SERVER_HOST environment variable or defaults to '127.0.0.1'. ```cmake if(DEFINED ENV{BOOST_MYSQL_SERVER_HOST}) set(SERVER_HOST $ENV{BOOST_MYSQL_SERVER_HOST}) else() set(SERVER_HOST "127.0.0.1") endif() ``` -------------------------------- ### Synchronous Operations with `any_connection` Source: https://context7.com/boostorg/mysql/llms.txt Demonstrates how to establish a connection, execute a text query, and close the connection using synchronous operations with `any_connection`. This example uses a try-catch block to handle potential `error_with_diagnostics` exceptions. ```APIDOC ## Synchronous Operations with `any_connection` ### Description This section shows how to use the `any_connection` object for synchronous database operations, including connecting, executing queries, and closing the connection. It highlights error handling using exceptions. ### Method Synchronous ### Endpoint N/A (Library API) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```cpp #include #include #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; int main() { asio::io_context ctx; mysql::any_connection conn(ctx); // Configure connection parameters mysql::connect_params params; params.server_address.emplace_host_and_port("localhost"); params.username = "myuser"; params.password = "mypassword"; params.database = "mydb"; try { conn.connect(params); // Establish TCP + TLS + MySQL handshake mysql::results result; conn.execute("SELECT 'Hello world!'", result); // Run a text query std::cout << result.rows().at(0).at(0) << "\n"; // Output: Hello world! conn.close(); // Graceful disconnect } catch (const mysql::error_with_diagnostics& err) { std::cerr << "Error: " << err.what() << "\n" << "Server message: " << err.get_diagnostics().server_message() << "\n"; return 1; } } ``` ### Response #### Success Response (N/A - Library API) #### Response Example Output: Hello world! ``` -------------------------------- ### CMakeLists.txt Configuration for Boost.MySQL Source: https://github.com/boostorg/mysql/blob/develop/README.md This CMakeLists.txt file sets up a C++ project to use Boost.MySQL. Ensure Boost 1.82 or higher is installed. It requires linking against Boost.Charconv, Threads, and OpenSSL. ```cmake 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) ``` -------------------------------- ### CMake Project Configuration Source: https://github.com/boostorg/mysql/blob/develop/test/cmake_b2_test/CMakeLists.txt Sets the minimum required CMake version and defines the project name and language. This is a standard starting point for CMake projects. ```cmake cmake_minimum_required(VERSION 3.5...3.22) project(boost_mysql_example LANGUAGES CXX) ``` -------------------------------- ### Asynchronous Operations with C++20 Coroutines Source: https://context7.com/boostorg/mysql/llms.txt Illustrates asynchronous database operations using C++20 coroutines with `any_connection`. This example shows `async_connect`, `async_execute`, and `async_close` using `co_await`. ```APIDOC ## Asynchronous Operations with C++20 Coroutines ### Description This section demonstrates asynchronous database operations using C++20 coroutines. It covers `async_connect`, `async_execute`, and `async_close` on the `any_connection` object, utilizing `co_await` for non-blocking execution. ### Method Asynchronous (C++20 Coroutines) ### Endpoint N/A (Library API) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```cpp #include #include #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; asio::awaitable run(mysql::any_connection& conn, std::string_view host, std::string_view user, std::string_view pass) { mysql::connect_params params; params.server_address.emplace_host_and_port(std::string(host)); params.username = user; params.password = pass; co_await conn.async_connect(params); // Resolves hostname, connects, handshakes mysql::results result; co_await conn.async_execute("SELECT 'Hello world!'", result); std::cout << result.rows().at(0).at(0) << "\n"; // Hello world! co_await conn.async_close(); } int main() { asio::io_context ctx; mysql::any_connection conn(ctx); asio::co_spawn(ctx, [&] { return run(conn, "localhost", "myuser", "mypassword"); }, [](std::exception_ptr p) { if (p) std::rethrow_exception(p); }); ctx.run(); } ``` ### Response #### Success Response (N/A - Library API) #### Response Example Output: Hello world! ``` -------------------------------- ### Boost.MySQL Connection Pooling for Concurrent Servers Source: https://context7.com/boostorg/mysql/llms.txt Use `connection_pool` to manage a set of `any_connection` objects for concurrent servers. `async_get_connection` returns a `pooled_connection` RAII handle. The pool must be started with `async_run` before use. ```cpp #include #include #include #include #include #include #include #include #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; struct employee { std::string first_name; std::string last_name; }; asio::awaitable query_employee(mysql::connection_pool& pool, std::int64_t employee_id) { // Obtain a healthy connection; fail if none available within 1 second mysql::pooled_connection conn = co_await pool.async_get_connection( asio::cancel_after(std::chrono::seconds(1)) ); // Use like an any_connection (operator-> dereferences to any_connection&) mysql::static_results> result; co_await conn->async_execute( mysql::with_params("SELECT first_name, last_name FROM employee WHERE id = {}", employee_id), result ); if (result.rows().empty()) co_return "NOT_FOUND"; const auto& emp = result.rows()[0]; co_return emp.first_name + " " + emp.last_name; // pooled_connection destroyed here -> connection returned to pool } int main() { asio::io_context ctx; mysql::pool_params params; params.server_address.emplace_host_and_port("localhost"); params.username = "myuser"; params.password = "mypassword"; params.database = "mydb"; mysql::connection_pool pool(ctx, std::move(params)); pool.async_run(asio::detached); // Must be called once before use asio::co_spawn(ctx, [&pool] -> asio::awaitable { auto name = co_await query_employee(pool, 42); std::cout << "Employee: " << name << "\n"; }, [](std::exception_ptr p) { if (p) std::rethrow_exception(p); }); ctx.run(); } ``` -------------------------------- ### Finding and Linking Dependencies Source: https://github.com/boostorg/mysql/blob/develop/test/cmake_b2_test/CMakeLists.txt Finds and links necessary external libraries for the project, including Boost components, Threads, and OpenSSL. Ensure these libraries are installed and discoverable by CMake. ```cmake find_package(Boost REQUIRED COMPONENTS headers charconv) find_package(Threads REQUIRED) find_package(OpenSSL REQUIRED) ``` ```cmake target_link_libraries(main PRIVATE Boost::charconv Threads::Threads OpenSSL::Crypto OpenSSL::SSL) ``` -------------------------------- ### Synchronous Connect and Query with any_connection Source: https://context7.com/boostorg/mysql/llms.txt Demonstrates establishing a TCP connection, executing a text query, and closing the connection using synchronous operations. Errors are handled by exceptions, including `error_with_diagnostics`. ```cpp #include #include #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; int main() { asio::io_context ctx; mysql::any_connection conn(ctx); // Configure connection parameters mysql::connect_params params; params.server_address.emplace_host_and_port("localhost"); params.username = "myuser"; params.password = "mypassword"; params.database = "mydb"; try { conn.connect(params); // Establish TCP + TLS + MySQL handshake mysql::results result; conn.execute("SELECT 'Hello world!'", result); // Run a text query std::cout << result.rows().at(0).at(0) << "\n"; // Output: Hello world! conn.close(); // Graceful disconnect } catch (const mysql::error_with_diagnostics& err) { std::cerr << "Error: " << err.what() << "\n" << "Server message: " << err.get_diagnostics().server_message() << "\n"; return 1; } } ``` -------------------------------- ### CMake: Set Up Executable for Separate Compilation Source: https://github.com/boostorg/mysql/blob/develop/test/cmake_b2_separate_compilation_test/CMakeLists.txt Defines the main executable and includes Boost.MySQL sources via a header. List any other .cpp files your executable requires. ```cmake add_executable( main # Contains Boost.MySQL sources via #include boost_mysql.cpp # List any other .cpp your exe has here main.cpp ) ``` -------------------------------- ### Find and Import libmysqlclient Source: https://github.com/boostorg/mysql/blob/develop/bench/CMakeLists.txt Locates the libmysqlclient header files and library binary. It then imports the library as a shared target, setting its properties and include directories, and linking it with OpenSSL. ```cmake find_path(LIBMYSQLCLIENT_INCLUDE_DIR mysql/mysql.h) if (NOT LIBMYSQLCLIENT_INCLUDE_DIR) message(FATAL_ERROR "Could not find libmysqlclient includes") endif() find_library(LIBMYSQLCLIENT_LIBRARY mysqlclient) if (NOT LIBMYSQLCLIENT_LIBRARY) message(FATAL_ERROR "Could not find the libmysqlclient library binary") endif() add_library(boost_mysql_libmysqlclient SHARED IMPORTED) set_property(TARGET boost_mysql_libmysqlclient PROPERTY IMPORTED_LOCATION ${LIBMYSQLCLIENT_LIBRARY}) target_include_directories(boost_mysql_libmysqlclient INTERFACE ${LIBMYSQLCLIENT_INCLUDE_DIR}) target_link_libraries(boost_mysql_libmysqlclient INTERFACE OpenSSL::SSL OpenSSL::Crypto) ``` -------------------------------- ### Add Connection Pool Benchmark Source: https://github.com/boostorg/mysql/blob/develop/bench/CMakeLists.txt Adds a benchmark target for connection pooling, linking against the main Boost.MySQL library. ```cmake add_bench(connection_pool boost_mysql) ``` -------------------------------- ### Add Protocol Benchmarks Source: https://github.com/boostorg/mysql/blob/develop/bench/CMakeLists.txt Adds benchmark targets for testing protocol performance with different row sizes and client libraries. Each benchmark is linked against the appropriate Boost.MySQL or client library. ```cmake add_bench(one_small_row_boost boost_mysql) add_bench(one_small_row_libmysqlclient boost_mysql_libmysqlclient) add_bench(one_small_row_libmariadb boost_mysql_libmariadb) add_bench(one_big_row_boost boost_mysql) add_bench(one_big_row_libmysqlclient boost_mysql_libmysqlclient) add_bench(one_big_row_libmariadb boost_mysql_libmariadb) add_bench(many_rows_boost boost_mysql) add_bench(many_rows_libmysqlclient boost_mysql_libmysqlclient) add_bench(many_rows_libmariadb boost_mysql_libmariadb) add_bench(stmt_params_boost boost_mysql) add_bench(stmt_params_libmysqlclient boost_mysql_libmysqlclient) add_bench(stmt_params_libmariadb boost_mysql_libmariadb) ``` -------------------------------- ### Find and Import libmariadb Source: https://github.com/boostorg/mysql/blob/develop/bench/CMakeLists.txt Locates the libmariadb header files and library binary. It imports the library as a shared target, configuring its properties, include directories, and linking it with OpenSSL. ```cmake find_path(LIBMARIADB_INCLUDE_DIR mariadb/mysql.h) if (NOT LIBMARIADB_INCLUDE_DIR) message(FATAL_ERROR "Could not find libmariadb includes") endif() find_library(LIBMARIADB_LIBRARY mariadb) if (NOT LIBMARIADB_LIBRARY) message(FATAL_ERROR "Could not find the libmariadb library binary") endif() add_library(boost_mysql_libmariadb SHARED IMPORTED) set_property(TARGET boost_mysql_libmariadb PROPERTY IMPORTED_LOCATION ${LIBMARIADB_LIBRARY}) target_include_directories(boost_mysql_libmariadb INTERFACE ${LIBMARIADB_INCLUDE_DIR}) target_link_libraries(boost_mysql_libmariadb INTERFACE OpenSSL::SSL OpenSSL::Crypto) ``` -------------------------------- ### Server-Side Prepared Statements with `prepare_statement` and `bind` Source: https://context7.com/boostorg/mysql/llms.txt Utilize server-side prepared statements for efficiency when executing the same query multiple times with different parameters. This method uses MySQL's binary protocol. The statement is deallocated server-side upon connection close. ```cpp #include #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; asio::awaitable use_prepared_statement(mysql::any_connection& conn, std::string_view company_id) { // Prepare the statement: ? is the placeholder mysql::statement stmt = co_await conn.async_prepare_statement( "SELECT first_name, last_name, salary FROM employee WHERE company_id = ?" ); // Execute: bind() pairs the statement with its arguments mysql::results result; co_await conn.async_execute(stmt.bind(company_id), result); for (mysql::row_view emp : result.rows()) std::cout << emp.at(0) << " " << emp.at(1) << " earns " << emp.at(2) << "\n"; // Deallocate the statement server-side (optional; also cleaned up on connection close) co_await conn.async_close_statement(stmt); co_await conn.async_close(); } ``` -------------------------------- ### Asynchronous Operations with C++20 Coroutines Source: https://context7.com/boostorg/mysql/llms.txt Shows how to perform connect, execute, and close operations asynchronously using C++20 coroutines. The `with_diagnostics(asio::deferred)` completion token ensures that `co_await` throws `error_with_diagnostics` on error, similar to the synchronous API. ```cpp #include #include #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; asio::awaitable run(mysql::any_connection& conn, std::string_view host, std::string_view user, std::string_view pass) { mysql::connect_params params; params.server_address.emplace_host_and_port(std::string(host)); params.username = user; params.password = pass; co_await conn.async_connect(params); // Resolves hostname, connects, handshakes mysql::results result; co_await conn.async_execute("SELECT 'Hello world!'", result); std::cout << result.rows().at(0).at(0) << "\n"; // Hello world! co_await conn.async_close(); } int main() { asio::io_context ctx; mysql::any_connection conn(ctx); asio::co_spawn(ctx, [&] { return run(conn, "localhost", "myuser", "mypassword"); }, [](std::exception_ptr p) { if (p) std::rethrow_exception(p); }); ctx.run(); } ``` -------------------------------- ### Load and Prepare Benchmark Data Source: https://github.com/boostorg/mysql/blob/develop/bench/bench.ipynb Loads benchmark results from a text file into a pandas DataFrame and reshapes it for plotting. Update the file path '../private/benchmark-results.txt' as needed. ```python import pandas as pd from matplotlib import pyplot as plt df = pd.read_csv('../private/benchmark-results.txt', header=None) # Update file path as required df = df.set_index(df.index.map(lambda x: x % df.groupby(0).size()[0])) df = df.pivot(columns=[0], values=[1]) df.columns = df.columns.get_level_values(0) df ``` -------------------------------- ### Connection Maintenance Operations Source: https://context7.com/boostorg/mysql/llms.txt Demonstrates the usage of `async_ping`, `async_set_character_set`, and `async_reset_connection` for managing database connections. ```APIDOC ## `ping` / `reset_connection` / `set_character_set` — Connection maintenance `ping` checks server liveness. `reset_connection` resets all server-side session state (variables, prepared statements, transactions) faster than a full reconnect. `set_character_set` changes the connection's character encoding and updates the client-tracked charset. ### Usage Example ```cpp #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; asio::awaitable maintain_connection(mysql::any_connection& conn) { // Check if the server is still responsive co_await conn.async_ping(); std::cout << "Server is alive\n"; // Ensure the connection uses UTF-8 co_await conn.async_set_character_set(mysql::utf8mb4_charset); // Reset all session state: rolls back transactions, drops temp tables, // resets session variables, closes prepared statements co_await conn.async_reset_connection(); // After reset, re-set the character set because reset reverts it to server default co_await conn.async_set_character_set(mysql::utf8mb4_charset); std::cout << "Connection is TLS: " << conn.uses_ssl() << "\n"; std::cout << "Connection ID: " << conn.connection_id().value_or(0) << "\n"; } ``` ### Methods - **`async_ping()`**: Checks if the server is responsive. - **`async_reset_connection()`**: Resets all server-side session state. - **`async_set_character_set(character_set)`**: Changes the connection's character encoding. ``` -------------------------------- ### Stream Large Result Sets with Boost.MySQL Source: https://context7.com/boostorg/mysql/llms.txt Use `start_execution` to send a query without fetching rows, and `read_some_rows` to read data in memory-efficient batches. The loop continues as long as `execution_state::should_read_rows()` returns true. ```cpp #include #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; asio::awaitable stream_all_employees(mysql::any_connection& conn) { // Sends the query and reads column metadata, but NOT rows yet mysql::execution_state st; co_await conn.async_start_execution( "SELECT first_name, last_name, salary FROM employee", st ); std::size_t total = 0; while (st.should_read_rows()) { // Returns a view into the connection's internal buffer. // Valid until the next async operation on this connection. mysql::rows_view batch = co_await conn.async_read_some_rows(st); for (auto row : batch) { std::cout << row.at(0) << " " << row.at(1) << " salary=" << row.at(2) << "\n"; ++total; } } std::cout << "Total rows: " << total << "\n"; } ``` -------------------------------- ### Maintain MySQL Connection State Source: https://context7.com/boostorg/mysql/llms.txt Demonstrates how to check server liveness, set character set, and reset session state on a MySQL connection. Ensure the character set is re-applied after resetting the connection as it reverts to the server's default. ```cpp #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; asio::awaitable maintain_connection(mysql::any_connection& conn) { // Check if the server is still responsive co_await conn.async_ping(); std::cout << "Server is alive\n"; // Ensure the connection uses UTF-8 co_await conn.async_set_character_set(mysql::utf8mb4_charset); // Reset all session state: rolls back transactions, drops temp tables, // resets session variables, closes prepared statements co_await conn.async_reset_connection(); // After reset, re-set the character set because reset reverts it to server default co_await conn.async_set_character_set(mysql::utf8mb4_charset); std::cout << "Connection is TLS: " << conn.uses_ssl() << "\n"; std::cout << "Connection ID: " << conn.connection_id().value_or(0) << "\n"; } ``` -------------------------------- ### Client-Side SQL Composition with Boost.MySQL Source: https://context7.com/boostorg/mysql/llms.txt Safely compose SQL strings using `format_sql_to` with a `format_context`. This enables conditional clauses and proper escaping for identifiers (`{:i}`), raw SQL (`{:r}`), or literals. ```cpp #include #include #include #include #include #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; asio::awaitable dynamic_query(mysql::any_connection& conn, std::optional company_filter, std::optional order_by_column) { // format_opts() returns the options needed to correctly escape for this connection mysql::format_context ctx(conn.format_opts().value()); // Start with a fixed base query mysql::format_sql_to(ctx, "SELECT id, first_name, salary FROM employee"); // Conditionally add WHERE clause if (company_filter) mysql::format_sql_to(ctx, " WHERE company_id = {}", *company_filter); // Conditionally add ORDER BY clause, using {:i} to safely quote the column name if (order_by_column) mysql::format_sql_to(ctx, " ORDER BY {:i}", *order_by_column); std::string query = std::move(ctx).get().value(); // throws if any arg was invalid mysql::results result; co_await conn.async_execute(std::string_view(query), result); for (auto row : result.rows()) std::cout << "id=" << row.at(0) << " name=" << row.at(1) << " salary=" << row.at(2) << "\n"; } ``` -------------------------------- ### Add Boost.MySQL Test Executable Source: https://github.com/boostorg/mysql/blob/develop/test/unit/CMakeLists.txt Defines a C++ executable for testing Boost.MySQL functionality. It explicitly excludes OpenSSL library linking. ```cmake add_executable( boost_mysql_test_csha2p_encrypt_password_errors test_csha2p_encrypt_password_errors.cpp ) target_include_directories( boost_mysql_test_csha2p_encrypt_password_errors PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../include # our own includes ${OPENSSL_INCLUDE_DIR} # we only need the includes ) target_link_libraries( boost_mysql_test_csha2p_encrypt_password_errors PRIVATE Boost::unit_test_framework Boost::assert Boost::config Boost::container Boost::core Boost::system ) target_compile_features( boost_mysql_test_csha2p_encrypt_password_errors INTERFACE cxx_std_11 ) boost_mysql_test_target_settings(boost_mysql_test_csha2p_encrypt_password_errors) add_test( NAME boost_mysql_test_csha2p_encrypt_password_errors COMMAND boost_mysql_test_csha2p_encrypt_password_errors ) ``` -------------------------------- ### Execute Transaction with Multi-Queries in Boost.MySQL Source: https://context7.com/boostorg/mysql/llms.txt Use `async_execute` with `connect_params::multi_queries` set to true to send multiple semicolon-separated SQL statements. Each statement generates a separate resultset, useful for atomic transactions. Ensure `multi_queries` is enabled in connection parameters. ```cpp #include #include #include #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; struct employee { std::string first_name; std::string last_name; }; asio::awaitable update_in_transaction(mysql::any_connection& conn, std::int64_t id, std::string_view new_name) { // multi_queries must be true in connect_params to use this feature // Each statement generates a separate resultset: // [0] START TRANSACTION -> no rows (std::tuple<> // [1] UPDATE -> no rows // [2] SELECT -> employee rows // [3] COMMIT -> no rows mysql::static_results< std::tuple<>, std::tuple<>, mysql::pfr_by_name, std::tuple<> > result; co_await conn.async_execute( mysql::with_params( "START TRANSACTION;" "UPDATE employee SET first_name = {0} WHERE id = {1};" "SELECT first_name, last_name FROM employee WHERE id = {1};" "COMMIT", new_name, id ), result ); auto employees = result.rows<2>(); // Rows from the 3rd resultset (index 2) if (employees.empty()) std::cout << "Employee " << id << " not found\n"; else std::cout << "Updated to: " << employees[0].first_name << " " << employees[0].last_name << "\n"; } ``` -------------------------------- ### Handling errors with error_code and asio::as_tuple Source: https://context7.com/boostorg/mysql/llms.txt Use the `asio::as_tuple` completion token with asynchronous operations to receive results as a tuple of (error_code, result...) instead of throwing exceptions. This pattern is useful for explicit error checking. ```cpp #include #include #include #include #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; struct employee { std::string first_name; std::string last_name; }; asio::awaitable safe_get_employee(mysql::connection_pool& pool, std::int64_t employee_id) { mysql::diagnostics diag; // as_tuple delivers (error_code, result...) rather than throwing auto [ec, conn] = co_await pool.async_get_connection(diag, asio::as_tuple); if (ec) { std::cerr << "Pool error: " << ec.message(); if (!diag.server_message().empty()) std::cerr << ": " << diag.server_message(); std::cerr << "\n"; co_return "ERROR"; } mysql::static_results> result; auto [ec2] = co_await conn->async_execute( mysql::with_params("SELECT first_name, last_name FROM employee WHERE id = ?", employee_id), result, diag, asio::as_tuple ); if (ec2) { std::cerr << "Query error: " << ec2.message() << ": " << diag.server_message() << "\n"; co_return "ERROR"; } if (result.rows().empty()) co_return "NOT_FOUND"; const auto& emp = result.rows()[0]; co_return emp.first_name + " " + emp.last_name; } ``` -------------------------------- ### CMake: Add Test Source: https://github.com/boostorg/mysql/blob/develop/test/cmake_b2_separate_compilation_test/CMakeLists.txt Configures CTest to add a test named 'main' that executes the 'main' command. This is used for testing the compiled executable. ```cmake include(CTest) add_test(NAME main COMMAND main) ``` -------------------------------- ### Batching multiple SQL statements with the pipeline API Source: https://context7.com/boostorg/mysql/llms.txt Use the pipeline API to batch prepare statements, execute them within a transaction, and close them in separate round-trips. All stages in a pipeline request are always executed, regardless of earlier failures. ```cpp #include #include #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; asio::awaitable pipeline_inserts(mysql::any_connection& conn, std::string_view company_id) { // Step 1: Batch-prepare two statements in one round-trip mysql::pipeline_request prep_req; prep_req.add_prepare_statement( "INSERT INTO employee (company_id, first_name, last_name) VALUES (?, ?, ?)" ); prep_req.add_prepare_statement("INSERT INTO audit_log (msg) VALUES (?)"); std::vector prep_res; co_await conn.async_run_pipeline(prep_req, prep_res); mysql::statement emp_stmt = prep_res.at(0).get_statement(); mysql::statement log_stmt = prep_res.at(1).get_statement(); // Step 2: Execute inserts inside a transaction (all in one batch except COMMIT) mysql::pipeline_request exec_req; exec_req.add_execute("START TRANSACTION") .add_execute(emp_stmt, company_id, "Juan", "Lopez") .add_execute(emp_stmt, company_id, "Pepito", "Rodriguez") .add_execute(log_stmt, "Inserted 2 new employees"); std::vector exec_res; co_await conn.async_run_pipeline(exec_req, exec_res); auto id1 = exec_res.at(1).as_results().last_insert_id(); auto id2 = exec_res.at(2).as_results().last_insert_id(); // Step 3: Commit and close statements mysql::pipeline_request finish_req; finish_req.add_execute("COMMIT") .add_close_statement(emp_stmt) .add_close_statement(log_stmt); std::vector finish_res; co_await conn.async_run_pipeline(finish_req, finish_res); std::cout << "Inserted employee IDs: " << id1 << ", " << id2 << "\n"; } ``` -------------------------------- ### Find OpenSSL Source: https://github.com/boostorg/mysql/blob/develop/bench/CMakeLists.txt Finds the OpenSSL library, which is required for secure connections. This is a prerequisite for linking against client libraries. ```cmake find_package(OpenSSL REQUIRED) ``` -------------------------------- ### Define Benchmark Target Function Source: https://github.com/boostorg/mysql/blob/develop/bench/CMakeLists.txt Defines a CMake function `add_bench` to simplify the creation of benchmark executables. It takes the C++ source file name and any libraries to link against as arguments. ```cmake function (add_bench cpp_name) set(target_name "boost_mysql_bench_${cpp_name}") add_executable(${target_name} ${cpp_name}.cpp) target_link_libraries(${target_name} PUBLIC ${ARGN}) boost_mysql_common_target_settings(${target_name}) add_dependencies(boost_mysql_bench ${target_name}) endfunction() ``` -------------------------------- ### Safe Parameterized Queries with `with_params` Source: https://context7.com/boostorg/mysql/llms.txt Use `with_params` to prevent SQL injection by automatically escaping values. This is the recommended approach for user-supplied data when server-side prepared statements are not used. ```cpp #include #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; asio::awaitable find_employee(mysql::any_connection& conn, std::int64_t employee_id) { mysql::results result; // {} placeholders are replaced and escaped; prevents SQL injection co_await conn.async_execute( mysql::with_params( "SELECT first_name, last_name FROM employee WHERE id =ержа", employee_id // Automatically escaped ), result ); if (result.rows().empty()) std::cout << "Not found\n"; else { auto row = result.rows().at(0); std::cout << "Name: " << row.at(0) << " " << row.at(1) << "\n"; } } ``` -------------------------------- ### Mapping Results to C++ Structs with `static_results` and `pfr_by_name` Source: https://context7.com/boostorg/mysql/llms.txt Leverage `static_results` with `pfr_by_name` (C++20) to map query results directly to C++ structs by matching column names to struct fields. This provides compile-time checks and avoids manual column indexing. Ensure struct field names exactly match the SELECT column names. ```cpp #include #include #include #include #include #include namespace mysql = boost::mysql; namespace asio = boost::asio; // Field names must match the SELECT column names struct employee { std::string first_name; std::string last_name; double salary{}; }; asio::awaitable get_employees(mysql::any_connection& conn, std::string_view company_id) { // static_results> maps columns to struct members by name mysql::static_results> result; co_await conn.async_execute( mysql::with_params( "SELECT first_name, last_name, salary FROM employee WHERE company_id =ержа", company_id ), result ); // result.rows() returns a span for (const employee& emp : result.rows()) std::cout << emp.first_name << " " << emp.last_name << " earns $" << emp.salary << "\n"; } ``` -------------------------------- ### CMake: Link Libraries and Define Separate Compilation Source: https://github.com/boostorg/mysql/blob/develop/test/cmake_b2_separate_compilation_test/CMakeLists.txt Links the necessary Boost.MySQL libraries and defines BOOST_MYSQL_SEPARATE_COMPILATION for the target. This is crucial for using Boost.MySQL in separate-build mode. ```cmake target_link_libraries(main PRIVATE Boost::charconv Threads::Threads OpenSSL::Crypto OpenSSL::SSL) ``` ```cmake # We need to define BOOST_MYSQL_SEPARATE_COMPILATION in any code using Boost.MySQL in separate-build mode target_compile_definitions(main PRIVATE BOOST_MYSQL_SEPARATE_COMPILATION) ``` -------------------------------- ### Plot Benchmark Results Source: https://github.com/boostorg/mysql/blob/develop/bench/bench.ipynb Defines a function to plot benchmark results for different libraries and then uses it to generate box plots for various benchmarks. The plots visualize the time taken in milliseconds. ```python def plot_result(df: pd.DataFrame, bench: str, title: str, ax): cols = [f'{bench}_boost', f'{bench}_libmysqlclient', f'{bench}_libmariadb'] df = df[cols].rename(columns={ f'{bench}_boost': 'Boost.MySQL', f'{bench}_libmysqlclient': 'libmysqlclient', f'{bench}_libmariadb': 'libmariadb' }) mean_val = round(df.mean().mean()) df.plot.box(ylim=(mean_val-150, mean_val+150), ax=ax, title=title, ylabel='Time (ms)') fig, _ = plt.subplots(2, 2, figsize=(15, 15)) plot_result(df, bench='one_small_row', title='Reading one small row', ax=fig.axes[0]) plot_result(df, bench='one_big_row', title='Reading one big row', ax=fig.axes[1]) plot_result(df, bench='many_rows', title='Reading 5k rows', ax=fig.axes[2]) plot_result(df, bench='stmt_params', title='Statement with params', ax=fig.axes[3]) ```