Full Code of boostorg/mysql for AI

develop 4558bb4579dd cached
620 files
4.5 MB
1.2M tokens
5650 symbols
1 requests
Download .txt
Showing preview only (4,852K chars total). Download the full file or copy to clipboard to get everything.
Repository: boostorg/mysql
Branch: develop
Commit: 4558bb4579dd
Files: 620
Total size: 4.5 MB

Directory structure:
gitextract_6ypeo_s4/

├── .clang-format
├── .clangd
├── .codecov.yml
├── .dockerignore
├── .drone.star
├── .github/
│   └── workflows/
│       ├── build-code.yml
│       ├── coverage.yml
│       ├── docker-windows.yml
│       └── fuzz.yml
├── .gitignore
├── CMakeLists.txt
├── LICENSE_1_0.txt
├── README.md
├── bench/
│   ├── CMakeLists.txt
│   ├── bench.ipynb
│   ├── connection_pool.cpp
│   ├── db_setup.sql
│   ├── many_rows_boost.cpp
│   ├── many_rows_libmariadb.cpp
│   ├── many_rows_libmysqlclient.cpp
│   ├── one_big_row_boost.cpp
│   ├── one_big_row_libmariadb.cpp
│   ├── one_big_row_libmysqlclient.cpp
│   ├── one_small_row_boost.cpp
│   ├── one_small_row_libmariadb.cpp
│   ├── one_small_row_libmysqlclient.cpp
│   ├── stmt_params_boost.cpp
│   ├── stmt_params_libmariadb.cpp
│   └── stmt_params_libmysqlclient.cpp
├── build.jam
├── cmake/
│   └── utils.cmake
├── doc/
│   ├── Jamfile
│   ├── config.json
│   ├── doxygen.hpp
│   ├── qbk/
│   │   ├── 00_main.qbk
│   │   ├── 01_intro.qbk
│   │   ├── 02_integrating.qbk
│   │   ├── 03_1_tutorial_sync.qbk
│   │   ├── 03_2_tutorial_async.qbk
│   │   ├── 03_3_tutorial_with_params.qbk
│   │   ├── 03_4_tutorial_static_interface.qbk
│   │   ├── 03_5_tutorial_updates_transactions.qbk
│   │   ├── 03_6_tutorial_connection_pool.qbk
│   │   ├── 03_7_tutorial_error_handling.qbk
│   │   ├── 04_overview.qbk
│   │   ├── 05_connection_establishment.qbk
│   │   ├── 06_text_queries.qbk
│   │   ├── 07_prepared_statements.qbk
│   │   ├── 08_dynamic_interface.qbk
│   │   ├── 09_static_interface.qbk
│   │   ├── 10_multi_resultset.qbk
│   │   ├── 11_multi_function.qbk
│   │   ├── 12_connection_pool.qbk
│   │   ├── 13_1_interfacing_sync_async.qbk
│   │   ├── 13_async.qbk
│   │   ├── 14_error_handling.qbk
│   │   ├── 15_sql_formatting_advanced.qbk
│   │   ├── 16_metadata.qbk
│   │   ├── 17_charsets.qbk
│   │   ├── 18_time_types.qbk
│   │   ├── 19_templated_connection.qbk
│   │   ├── 20_1_benchmarks.qbk
│   │   ├── 20_pipeline.qbk
│   │   ├── 21_examples.qbk
│   │   └── helpers/
│   │       ├── ExecutionRequest.qbk
│   │       ├── ExecutionStateType.qbk
│   │       ├── FieldViewFwdIterator.qbk
│   │       ├── Formattable.qbk
│   │       ├── OutputString.qbk
│   │       ├── ResultsType.qbk
│   │       ├── SocketStream.qbk
│   │       ├── StaticRow.qbk
│   │       ├── Stream.qbk
│   │       ├── WritableFieldTuple.qbk
│   │       └── quickref.xml
│   └── upgrade_1_82.md
├── example/
│   ├── 1_tutorial/
│   │   ├── 1_sync.cpp
│   │   ├── 2_async.cpp
│   │   ├── 3_with_params.cpp
│   │   ├── 4_static_interface.cpp
│   │   ├── 5_updates_transactions.cpp
│   │   ├── 6_connection_pool.cpp
│   │   └── 7_error_handling.cpp
│   ├── 2_simple/
│   │   ├── batch_inserts.cpp
│   │   ├── batch_inserts_generic.cpp
│   │   ├── callbacks.cpp
│   │   ├── coroutines_cpp11.cpp
│   │   ├── deletes.cpp
│   │   ├── disable_tls.cpp
│   │   ├── dynamic_filters.cpp
│   │   ├── inserts.cpp
│   │   ├── metadata.cpp
│   │   ├── multi_function.cpp
│   │   ├── patch_updates.cpp
│   │   ├── pipeline.cpp
│   │   ├── prepared_statements.cpp
│   │   ├── source_script.cpp
│   │   ├── tls_certificate_verification.cpp
│   │   └── unix_socket.cpp
│   ├── 3_advanced/
│   │   ├── http_server_cpp14_coroutines/
│   │   │   ├── handle_request.cpp
│   │   │   ├── handle_request.hpp
│   │   │   ├── main.cpp
│   │   │   ├── repository.cpp
│   │   │   ├── repository.hpp
│   │   │   ├── server.cpp
│   │   │   ├── server.hpp
│   │   │   └── types.hpp
│   │   └── http_server_cpp20/
│   │       ├── db_setup.sql
│   │       ├── error.cpp
│   │       ├── error.hpp
│   │       ├── handle_request.cpp
│   │       ├── handle_request.hpp
│   │       ├── main.cpp
│   │       ├── repository.cpp
│   │       ├── repository.hpp
│   │       ├── server.cpp
│   │       ├── server.hpp
│   │       └── types.hpp
│   ├── CMakeLists.txt
│   ├── Jamfile
│   ├── db_setup.sql
│   └── private/
│       ├── employees_multiple.json
│       ├── employees_single.json
│       ├── launch_server.py
│       ├── run_batch_inserts.py
│       ├── run_dynamic_filters.py
│       ├── run_notes.py
│       ├── run_orders.py
│       ├── run_patch_updates.py
│       ├── run_tutorial_connection_pool.py
│       └── test_script.sql
├── include/
│   └── boost/
│       ├── mysql/
│       │   ├── any_address.hpp
│       │   ├── any_connection.hpp
│       │   ├── bad_field_access.hpp
│       │   ├── blob.hpp
│       │   ├── blob_view.hpp
│       │   ├── buffer_params.hpp
│       │   ├── character_set.hpp
│       │   ├── client_errc.hpp
│       │   ├── column_type.hpp
│       │   ├── common_server_errc.hpp
│       │   ├── connect_params.hpp
│       │   ├── connection.hpp
│       │   ├── connection_pool.hpp
│       │   ├── constant_string_view.hpp
│       │   ├── date.hpp
│       │   ├── datetime.hpp
│       │   ├── days.hpp
│       │   ├── defaults.hpp
│       │   ├── detail/
│       │   │   ├── access.hpp
│       │   │   ├── algo_params.hpp
│       │   │   ├── any_execution_request.hpp
│       │   │   ├── any_resumable_ref.hpp
│       │   │   ├── character_set.hpp
│       │   │   ├── coldef_view.hpp
│       │   │   ├── config.hpp
│       │   │   ├── connect_params_helpers.hpp
│       │   │   ├── connection_impl.hpp
│       │   │   ├── connection_pool_fwd.hpp
│       │   │   ├── datetime.hpp
│       │   │   ├── engine.hpp
│       │   │   ├── engine_impl.hpp
│       │   │   ├── engine_stream_adaptor.hpp
│       │   │   ├── escape_string.hpp
│       │   │   ├── execution_concepts.hpp
│       │   │   ├── execution_processor/
│       │   │   │   ├── execution_processor.hpp
│       │   │   │   ├── execution_state_impl.hpp
│       │   │   │   ├── results_impl.hpp
│       │   │   │   ├── static_execution_state_impl.hpp
│       │   │   │   └── static_results_impl.hpp
│       │   │   ├── field_impl.hpp
│       │   │   ├── flags.hpp
│       │   │   ├── format_sql.hpp
│       │   │   ├── initiation_base.hpp
│       │   │   ├── intermediate_handler.hpp
│       │   │   ├── next_action.hpp
│       │   │   ├── ok_view.hpp
│       │   │   ├── output_string.hpp
│       │   │   ├── pipeline.hpp
│       │   │   ├── rebind_executor.hpp
│       │   │   ├── results_iterator.hpp
│       │   │   ├── resultset_encoding.hpp
│       │   │   ├── row_impl.hpp
│       │   │   ├── rows_iterator.hpp
│       │   │   ├── sequence.hpp
│       │   │   ├── socket_stream.hpp
│       │   │   ├── ssl_fwd.hpp
│       │   │   ├── string_view_offset.hpp
│       │   │   ├── throw_on_error_loc.hpp
│       │   │   ├── typing/
│       │   │   │   ├── meta_check_context.hpp
│       │   │   │   ├── pos_map.hpp
│       │   │   │   ├── readable_field_traits.hpp
│       │   │   │   └── row_traits.hpp
│       │   │   ├── void_t.hpp
│       │   │   └── writable_field_traits.hpp
│       │   ├── diagnostics.hpp
│       │   ├── error_categories.hpp
│       │   ├── error_code.hpp
│       │   ├── error_with_diagnostics.hpp
│       │   ├── escape_string.hpp
│       │   ├── execution_state.hpp
│       │   ├── field.hpp
│       │   ├── field_kind.hpp
│       │   ├── field_view.hpp
│       │   ├── format_sql.hpp
│       │   ├── handshake_params.hpp
│       │   ├── impl/
│       │   │   ├── any_connection.ipp
│       │   │   ├── character_set.ipp
│       │   │   ├── column_type.ipp
│       │   │   ├── connection_impl.ipp
│       │   │   ├── connection_pool.ipp
│       │   │   ├── date.ipp
│       │   │   ├── datetime.ipp
│       │   │   ├── engine_impl_instantiations.ipp
│       │   │   ├── error_categories.ipp
│       │   │   ├── escape_string.ipp
│       │   │   ├── execution_state_impl.ipp
│       │   │   ├── field.ipp
│       │   │   ├── field_kind.ipp
│       │   │   ├── field_view.hpp
│       │   │   ├── field_view.ipp
│       │   │   ├── format_sql.hpp
│       │   │   ├── format_sql.ipp
│       │   │   ├── internal/
│       │   │   │   ├── byte_to_hex.hpp
│       │   │   │   ├── call_next_char.hpp
│       │   │   │   ├── connection_pool/
│       │   │   │   │   ├── connection_node.hpp
│       │   │   │   │   ├── connection_pool_impl.hpp
│       │   │   │   │   ├── internal_pool_params.hpp
│       │   │   │   │   └── sansio_connection_node.hpp
│       │   │   │   ├── coroutine.hpp
│       │   │   │   ├── dt_to_string.hpp
│       │   │   │   ├── error/
│       │   │   │   │   ├── server_error_to_string.hpp
│       │   │   │   │   └── server_error_to_string.ipp
│       │   │   │   ├── next_power_of_two.hpp
│       │   │   │   ├── protocol/
│       │   │   │   │   ├── capabilities.hpp
│       │   │   │   │   ├── db_flavor.hpp
│       │   │   │   │   ├── deserialization.hpp
│       │   │   │   │   ├── frame_header.hpp
│       │   │   │   │   ├── impl/
│       │   │   │   │   │   ├── binary_protocol.hpp
│       │   │   │   │   │   ├── bit_deserialization.hpp
│       │   │   │   │   │   ├── deserialization_context.hpp
│       │   │   │   │   │   ├── null_bitmap.hpp
│       │   │   │   │   │   ├── protocol_field_type.hpp
│       │   │   │   │   │   ├── protocol_types.hpp
│       │   │   │   │   │   ├── serialization_context.hpp
│       │   │   │   │   │   ├── span_string.hpp
│       │   │   │   │   │   └── text_protocol.hpp
│       │   │   │   │   ├── serialization.hpp
│       │   │   │   │   └── static_buffer.hpp
│       │   │   │   ├── sansio/
│       │   │   │   │   ├── auth_plugin_common.hpp
│       │   │   │   │   ├── caching_sha2_password.hpp
│       │   │   │   │   ├── close_connection.hpp
│       │   │   │   │   ├── close_statement.hpp
│       │   │   │   │   ├── connect.hpp
│       │   │   │   │   ├── connection_state.hpp
│       │   │   │   │   ├── connection_state_data.hpp
│       │   │   │   │   ├── csha2p_encrypt_password.hpp
│       │   │   │   │   ├── execute.hpp
│       │   │   │   │   ├── handshake.hpp
│       │   │   │   │   ├── message_reader.hpp
│       │   │   │   │   ├── mysql_native_password.hpp
│       │   │   │   │   ├── ping.hpp
│       │   │   │   │   ├── prepare_statement.hpp
│       │   │   │   │   ├── quit_connection.hpp
│       │   │   │   │   ├── read_buffer.hpp
│       │   │   │   │   ├── read_resultset_head.hpp
│       │   │   │   │   ├── read_some_rows.hpp
│       │   │   │   │   ├── read_some_rows_dynamic.hpp
│       │   │   │   │   ├── reset_connection.hpp
│       │   │   │   │   ├── run_pipeline.hpp
│       │   │   │   │   ├── set_character_set.hpp
│       │   │   │   │   ├── start_execution.hpp
│       │   │   │   │   └── top_level_algo.hpp
│       │   │   │   ├── ssl_context_with_default.hpp
│       │   │   │   └── variant_stream.hpp
│       │   │   ├── is_fatal_error.ipp
│       │   │   ├── meta_check_context.ipp
│       │   │   ├── pfr.hpp
│       │   │   ├── pipeline.ipp
│       │   │   ├── results_impl.ipp
│       │   │   ├── resultset.ipp
│       │   │   ├── row_impl.ipp
│       │   │   ├── statement.hpp
│       │   │   ├── static_execution_state_impl.ipp
│       │   │   ├── static_results_impl.ipp
│       │   │   ├── with_diagnostics.hpp
│       │   │   └── with_params.hpp
│       │   ├── is_fatal_error.hpp
│       │   ├── mariadb_collations.hpp
│       │   ├── mariadb_server_errc.hpp
│       │   ├── metadata.hpp
│       │   ├── metadata_collection_view.hpp
│       │   ├── metadata_mode.hpp
│       │   ├── mysql_collations.hpp
│       │   ├── mysql_server_errc.hpp
│       │   ├── pfr.hpp
│       │   ├── pipeline.hpp
│       │   ├── pool_params.hpp
│       │   ├── results.hpp
│       │   ├── resultset.hpp
│       │   ├── resultset_view.hpp
│       │   ├── row.hpp
│       │   ├── row_view.hpp
│       │   ├── rows.hpp
│       │   ├── rows_view.hpp
│       │   ├── sequence.hpp
│       │   ├── src.hpp
│       │   ├── ssl_mode.hpp
│       │   ├── statement.hpp
│       │   ├── static_execution_state.hpp
│       │   ├── static_results.hpp
│       │   ├── string_view.hpp
│       │   ├── tcp.hpp
│       │   ├── tcp_ssl.hpp
│       │   ├── throw_on_error.hpp
│       │   ├── time.hpp
│       │   ├── underlying_row.hpp
│       │   ├── unix.hpp
│       │   ├── unix_ssl.hpp
│       │   ├── with_diagnostics.hpp
│       │   └── with_params.hpp
│       └── mysql.hpp
├── index.html
├── meta/
│   └── libraries.json
├── test/
│   ├── CMakeLists.txt
│   ├── Jamfile
│   ├── cmake_b2_separate_compilation_test/
│   │   ├── CMakeLists.txt
│   │   ├── boost_mysql.cpp
│   │   └── main.cpp
│   ├── cmake_b2_test/
│   │   ├── CMakeLists.txt
│   │   └── main.cpp
│   ├── cmake_test/
│   │   ├── CMakeLists.txt
│   │   └── main.cpp
│   ├── common/
│   │   ├── include/
│   │   │   └── test_common/
│   │   │       ├── assert_buffer_equals.hpp
│   │   │       ├── buffer_concat.hpp
│   │   │       ├── check_meta.hpp
│   │   │       ├── ci_server.hpp
│   │   │       ├── create_basic.hpp
│   │   │       ├── create_diagnostics.hpp
│   │   │       ├── has_ranges.hpp
│   │   │       ├── io_context_fixture.hpp
│   │   │       ├── netfun_maker.hpp
│   │   │       ├── network_result.hpp
│   │   │       ├── poll_until.hpp
│   │   │       ├── printing.hpp
│   │   │       ├── source_location.hpp
│   │   │       ├── stringize.hpp
│   │   │       ├── tracker_executor.hpp
│   │   │       └── validate_string_contains.hpp
│   │   └── src/
│   │       ├── boost_asio.cpp
│   │       ├── boost_mysql.cpp
│   │       ├── entry_point.cpp
│   │       └── utils.cpp
│   ├── fuzzing/
│   │   ├── Jamfile
│   │   ├── fuzz_auth_switch.cpp
│   │   ├── fuzz_column_definition.cpp
│   │   ├── fuzz_err_packet.cpp
│   │   ├── fuzz_escape_string.cpp
│   │   ├── fuzz_execute_response.cpp
│   │   ├── fuzz_format_args.cpp
│   │   ├── fuzz_format_identifier.cpp
│   │   ├── fuzz_format_sql_injection.cpp
│   │   ├── fuzz_format_strings.cpp
│   │   ├── fuzz_handshake_server_response.cpp
│   │   ├── fuzz_ok_packet.cpp
│   │   ├── fuzz_ok_response.cpp
│   │   ├── fuzz_prepare_stmt_response.cpp
│   │   ├── fuzz_row.cpp
│   │   ├── fuzz_row_message.cpp
│   │   ├── fuzz_server_hello.cpp
│   │   ├── fuzz_text_field.cpp
│   │   └── fuzz_utf8mb4.cpp
│   ├── integration/
│   │   ├── CMakeLists.txt
│   │   ├── Jamfile
│   │   ├── db_setup.sql
│   │   ├── db_setup_mnp.sql
│   │   ├── db_setup_sha256.sql
│   │   ├── include/
│   │   │   └── test_integration/
│   │   │       ├── any_connection_fixture.hpp
│   │   │       ├── connect_params_builder.hpp
│   │   │       ├── metadata_validator.hpp
│   │   │       ├── run_coro.hpp
│   │   │       ├── server_ca.hpp
│   │   │       ├── server_features.hpp
│   │   │       ├── snippets/
│   │   │       │   ├── credentials.hpp
│   │   │       │   ├── describe.hpp
│   │   │       │   ├── get_any_connection.hpp
│   │   │       │   ├── get_connection.hpp
│   │   │       │   └── snippets_fixture.hpp
│   │   │       ├── spotchecks_helpers.hpp
│   │   │       ├── static_rows.hpp
│   │   │       └── tcp_connection_fixture.hpp
│   │   ├── pch.hpp
│   │   ├── src/
│   │   │   ├── metadata_validator.cpp
│   │   │   ├── server_features.cpp
│   │   │   ├── spotchecks_helpers.cpp
│   │   │   └── utils.cpp
│   │   └── test/
│   │       ├── any_connection.cpp
│   │       ├── character_set_tracking.cpp
│   │       ├── connection_id.cpp
│   │       ├── connection_pool.cpp
│   │       ├── crud.cpp
│   │       ├── database_types.cpp
│   │       ├── db_specific.cpp
│   │       ├── execution_requests.cpp
│   │       ├── handshake.cpp
│   │       ├── multi_function.cpp
│   │       ├── multi_queries.cpp
│   │       ├── pipeline.cpp
│   │       ├── prepared_statements.cpp
│   │       ├── reconnect.cpp
│   │       ├── snippets/
│   │       │   ├── charsets.cpp
│   │       │   ├── connection_establishment.cpp
│   │       │   ├── connection_pool.cpp
│   │       │   ├── dynamic_interface.cpp
│   │       │   ├── interfacing_sync_async.cpp
│   │       │   ├── metadata.cpp
│   │       │   ├── multi_function.cpp
│   │       │   ├── multi_resultset.cpp
│   │       │   ├── overview.cpp
│   │       │   ├── pipeline.cpp
│   │       │   ├── prepared_statements.cpp
│   │       │   ├── sql_formatting_advanced.cpp
│   │       │   ├── sql_formatting_advanced_2.cpp
│   │       │   ├── static_interface.cpp
│   │       │   ├── templated_connection.cpp
│   │       │   ├── text_queries.cpp
│   │       │   ├── time_types.cpp
│   │       │   └── tutorials.cpp
│   │       ├── spotchecks.cpp
│   │       ├── static_interface.cpp
│   │       └── stored_procedures.cpp
│   ├── thread_safety/
│   │   ├── Jamfile
│   │   ├── connection_pool.cpp
│   │   ├── connection_pool_cancel.cpp
│   │   ├── connection_pool_cancel_get_connection.cpp
│   │   ├── connection_pool_coroutines.cpp
│   │   ├── connection_pool_external_strand.cpp
│   │   ├── connection_pool_two_contexts.cpp
│   │   └── tsan_pool_common.hpp
│   └── unit/
│       ├── CMakeLists.txt
│       ├── Jamfile
│       ├── include/
│       │   └── test_unit/
│       │       ├── algo_test.hpp
│       │       ├── create_coldef_frame.hpp
│       │       ├── create_err.hpp
│       │       ├── create_execution_processor.hpp
│       │       ├── create_frame.hpp
│       │       ├── create_meta.hpp
│       │       ├── create_ok.hpp
│       │       ├── create_ok_frame.hpp
│       │       ├── create_prepare_statement_response.hpp
│       │       ├── create_query_frame.hpp
│       │       ├── create_row_message.hpp
│       │       ├── create_statement.hpp
│       │       ├── custom_allocator.hpp
│       │       ├── fail_count.hpp
│       │       ├── ff_charset.hpp
│       │       ├── mock_execution_processor.hpp
│       │       ├── mock_message.hpp
│       │       ├── mock_timer.hpp
│       │       ├── printing.hpp
│       │       ├── row_identity.hpp
│       │       ├── serialize_to_vector.hpp
│       │       ├── test_any_connection.hpp
│       │       └── test_stream.hpp
│       ├── pch.hpp
│       ├── src/
│       │   └── utils.cpp
│       ├── test/
│       │   ├── any_address.cpp
│       │   ├── any_connection.cpp
│       │   ├── character_set.cpp
│       │   ├── client_errc.cpp
│       │   ├── column_type.cpp
│       │   ├── common_server_errc.cpp
│       │   ├── connection.cpp
│       │   ├── connection_pool/
│       │   │   ├── connection_pool_impl.cpp
│       │   │   └── sansio_connection_node.cpp
│       │   ├── connection_pool.cpp
│       │   ├── constant_string_view.cpp
│       │   ├── date.cpp
│       │   ├── datetime.cpp
│       │   ├── detail/
│       │   │   ├── connect_params_helpers.cpp
│       │   │   ├── datetime.cpp
│       │   │   ├── engine_impl.cpp
│       │   │   ├── execution_concepts.cpp
│       │   │   ├── intermediate_handler.cpp
│       │   │   ├── output_string.cpp
│       │   │   ├── row_impl.cpp
│       │   │   ├── rows_iterator.cpp
│       │   │   ├── socket_stream.cpp
│       │   │   ├── typing/
│       │   │   │   ├── meta_check_context.cpp
│       │   │   │   ├── pos_map.cpp
│       │   │   │   ├── readable_field_traits.cpp
│       │   │   │   └── row_traits.cpp
│       │   │   └── writable_field_traits.cpp
│       │   ├── diagnostics.cpp
│       │   ├── escape_string.cpp
│       │   ├── execution_processor/
│       │   │   ├── execution_processor.cpp
│       │   │   ├── execution_processor_helpers.hpp
│       │   │   ├── execution_state_impl.cpp
│       │   │   ├── results_impl.cpp
│       │   │   ├── static_execution_processor_helpers.hpp
│       │   │   ├── static_execution_state_impl.cpp
│       │   │   └── static_results_impl.cpp
│       │   ├── execution_state.cpp
│       │   ├── field.cpp
│       │   ├── field_view.cpp
│       │   ├── format_sql/
│       │   │   ├── api.cpp
│       │   │   ├── basic_format_context.cpp
│       │   │   ├── custom_formatter.cpp
│       │   │   ├── format_common.hpp
│       │   │   ├── format_strings.cpp
│       │   │   ├── formattable.cpp
│       │   │   ├── formattable_ref.cpp
│       │   │   ├── individual_value.cpp
│       │   │   ├── ranges.cpp
│       │   │   └── sequence.cpp
│       │   ├── impl/
│       │   │   ├── dt_to_string.cpp
│       │   │   ├── next_power_of_two.cpp
│       │   │   ├── ssl_context_with_default.cpp
│       │   │   └── variant_stream.cpp
│       │   ├── is_fatal_error.cpp
│       │   ├── mariadb_server_errc.cpp
│       │   ├── metadata.cpp
│       │   ├── mysql_server_errc.cpp
│       │   ├── pfr.cpp
│       │   ├── pipeline.cpp
│       │   ├── pool_params.cpp
│       │   ├── protocol/
│       │   │   ├── binary_protocol.cpp
│       │   │   ├── capabilities.cpp
│       │   │   ├── deserialization.cpp
│       │   │   ├── deserialization_context.cpp
│       │   │   ├── frame_header.cpp
│       │   │   ├── null_bitmap.cpp
│       │   │   ├── operators.hpp
│       │   │   ├── protocol_field_type.cpp
│       │   │   ├── protocol_types.cpp
│       │   │   ├── serialization.cpp
│       │   │   ├── serialization_context.cpp
│       │   │   ├── serialization_test.hpp
│       │   │   ├── static_buffer.cpp
│       │   │   └── text_protocol.cpp
│       │   ├── results.cpp
│       │   ├── resultset.cpp
│       │   ├── resultset_view.cpp
│       │   ├── row.cpp
│       │   ├── row_view.cpp
│       │   ├── rows.cpp
│       │   ├── rows_view.cpp
│       │   ├── sansio/
│       │   │   ├── close_connection.cpp
│       │   │   ├── close_statement.cpp
│       │   │   ├── execute.cpp
│       │   │   ├── handshake/
│       │   │   │   ├── handshake.cpp
│       │   │   │   ├── handshake_capabilities.cpp
│       │   │   │   ├── handshake_common.hpp
│       │   │   │   ├── handshake_connection_state_data.cpp
│       │   │   │   ├── handshake_csha2p.cpp
│       │   │   │   ├── handshake_csha2p_encrypt_password.cpp
│       │   │   │   ├── handshake_csha2p_hash_password.cpp
│       │   │   │   ├── handshake_csha2p_keys.hpp
│       │   │   │   ├── handshake_mnp.cpp
│       │   │   │   └── handshake_mnp_hash_password.cpp
│       │   │   ├── message_reader.cpp
│       │   │   ├── ping.cpp
│       │   │   ├── prepare_statement.cpp
│       │   │   ├── quit_connection.cpp
│       │   │   ├── read_buffer.cpp
│       │   │   ├── read_resultset_head.cpp
│       │   │   ├── read_some_rows.cpp
│       │   │   ├── read_some_rows_dynamic.cpp
│       │   │   ├── reset_connection.cpp
│       │   │   ├── run_pipeline.cpp
│       │   │   ├── set_character_set.cpp
│       │   │   ├── start_execution.cpp
│       │   │   └── top_level_algo.cpp
│       │   ├── spotchecks/
│       │   │   ├── connection_use_after_move.cpp
│       │   │   ├── default_completion_tokens.cpp
│       │   │   ├── execution_requests.cpp
│       │   │   ├── misc.cpp
│       │   │   ├── multifn.cpp
│       │   │   └── read_some_rows_static.cpp
│       │   ├── statement.cpp
│       │   ├── static_execution_state.cpp
│       │   ├── static_results.cpp
│       │   ├── throw_on_error.cpp
│       │   └── with_diagnostics.cpp
│       └── test_csha2p_encrypt_password_errors.cpp
└── tools/
    ├── ci/
    │   ├── ci_util/
    │   │   ├── __init__.py
    │   │   ├── b2.py
    │   │   ├── bench.py
    │   │   ├── cmake.py
    │   │   ├── common.py
    │   │   ├── db_setup.py
    │   │   ├── docs.py
    │   │   ├── fuzz.py
    │   │   ├── install_boost.py
    │   │   ├── main.py
    │   │   └── seed_corpus.py
    │   ├── main.py
    │   ├── run_benchmarks.py
    │   └── seed_corpus.py
    ├── docker/
    │   └── build-msvc.dockerfile
    ├── error_codes.csv
    ├── osx-ci.cnf
    ├── scripts/
    │   ├── build_unix_local.sh
    │   ├── build_windows_local.bat
    │   ├── check_links.py
    │   ├── collations.py
    │   ├── corpus_field_table.py
    │   ├── examples_qbk.py
    │   ├── file_headers.py
    │   └── server_errors.py
    ├── seed_corpus/
    │   ├── field_table.csv
    │   ├── protocol_messages.csv
    │   └── sql_injection_payloads.txt
    ├── setup_db_osx.sh
    ├── ssl/
    │   ├── ca-cert.pem
    │   ├── server-cert.pem
    │   └── server-key.pem
    ├── user-config-osx-gha.jam
    ├── valgrind_suppressions.txt
    └── win-ci.cnf

================================================
FILE CONTENTS
================================================

================================================
FILE: .clang-format
================================================
---
Language: Cpp
ColumnLimit: 110
IndentWidth: 4
BreakBeforeBraces: Custom
BraceWrapping:
  AfterCaseLabel: true
  AfterClass: true
  AfterControlStatement: true
  AfterEnum: true
  AfterFunction: true
  AfterNamespace: false
  AfterStruct: true
  AfterUnion: true
  AfterExternBlock: false
  BeforeCatch: true
  BeforeElse: true
  IndentBraces: false
  SplitEmptyFunction: true
  SplitEmptyRecord: true
  SplitEmptyNamespace: true
AccessModifierOffset: -4
BinPackArguments: false
BinPackParameters: false
AlignAfterOpenBracket: BlockIndent
PointerAlignment: Left
IncludeBlocks: Regroup
IncludeCategories:
  - Regex: '^<boost/mysql/impl/.*'
    Priority: -10
    SortPriority: 3
  - Regex: '^<boost/mysql/detail/.*>|^<boost/mysql/impl/.*'
    Priority: -9
    SortPriority: 2
  - Regex: '^<boost/mysql.*\.hpp>'
    Priority: -8
    SortPriority: 1
  - Regex: '^<boost/.*\.hpp>'
    Priority: -7
    SortPriority: 4
  - Regex: "^<.*"
    Priority: -6
    SortPriority: 5
  - Regex: ".*"
    Priority: -5
    SortPriority: 6
IndentCaseLabels: false
AllowShortCaseLabelsOnASingleLine: true
AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlignArrayOfStructures: Left
DerivePointerAlignment: false
PenaltyBreakAssignment: 2000000
PenaltyBreakBeforeFirstCallParameter: 0
PenaltyBreakOpenParenthesis: 0
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200000000

# Defaults (based on Google)
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllConstructorInitializersOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBinaryOperators: None
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
CommentPragmas: '(^ IWYU pragma:)|(^\\copydoc )|(^ ?\\n)'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
  - foreach
  - Q_FOREACH
  - BOOST_FOREACH
IncludeIsMainRegex: null
IncludeIsMainSourceRegex: ""
IndentGotoLabels: true
IndentPPDirectives: None
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ""
MacroBlockEnd: ""
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
RawStringFormats:
  - Language: Cpp
    Delimiters:
      - cc
      - CC
      - cpp
      - Cpp
      - CPP
      - "c++"
      - "C++"
    CanonicalDelimiter: ""
    BasedOnStyle: google
  - Language: TextProto
    Delimiters:
      - pb
      - PB
      - proto
      - PROTO
    EnclosingFunctions:
      - EqualsProto
      - EquivToProto
      - PARSE_PARTIAL_TEXT_PROTO
      - PARSE_TEST_PROTO
      - PARSE_TEXT_PROTO
      - ParseTextOrDie
      - ParseTextProtoOrDie
    CanonicalDelimiter: ""
    BasedOnStyle: google
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Auto
StatementMacros:
  - Q_UNUSED
  - QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
---



================================================
FILE: .clangd
================================================
Diagnostics:
  ClangTidy:
    Remove: bugprone-unused-return-value

================================================
FILE: .codecov.yml
================================================
#
# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#

# Change how pull request comments look
comment:
  layout: "reach,diff,files,footer"
codecov:
  disable_default_path_fixes: true


================================================
FILE: .dockerignore
================================================
.cache/
.cproject
.project
.settings/
.pydevproject
private/
build*/
out/
.vs/
.vscode/
compile_commands.json
.cache/
doc/
include/
__build*/


================================================
FILE: .drone.star
================================================
#
# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#

_triggers = { "branch": [ "master", "develop" ] }
_win_container_tag = 'e7bd656c3515263f9b3c69a2d73d045f6a0fed72'


def _image(name):
    return 'ghcr.io/anarthal/cpp-ci-containers/{}'.format(name)

def _win_image(name):
    return 'ghcr.io/anarthal-containers/{}:{}'.format(name, _win_container_tag)


def _b2_command(
    source_dir,
    toolset,
    cxxstd,
    variant,
    server_host='127.0.0.1',
    stdlib='native',
    address_model='64',
    separate_compilation=1,
    use_ts_executor=0,
    address_sanitizer=0,
    undefined_sanitizer=0,
    valgrind=0,
    fail_if_no_openssl=1
):
    return 'python tools/ci/main.py ' + \
                '--source-dir="{}" '.format(source_dir) + \
                'b2 ' + \
                '--server-host={} '.format(server_host) + \
                '--toolset={} '.format(toolset) + \
                '--cxxstd={} '.format(cxxstd) + \
                '--variant={} '.format(variant) + \
                '--stdlib={} '.format(stdlib) + \
                '--address-model={} '.format(address_model) + \
                '--separate-compilation={} '.format(separate_compilation) + \
                '--use-ts-executor={} '.format(use_ts_executor) + \
                '--address-sanitizer={} '.format(address_sanitizer) + \
                '--undefined-sanitizer={} '.format(undefined_sanitizer) + \
                '--valgrind={} '.format(valgrind) + \
                '--fail-if-no-openssl={} '.format(fail_if_no_openssl)


def _cmake_command(
    source_dir,
    server_host='127.0.0.1',
    generator='Ninja',
    cmake_build_type='Debug',
    build_shared_libs=0,
    cxxstd='20',
    install_test=1
):
    return 'python tools/ci/main.py ' + \
                '--source-dir="{}" '.format(source_dir) + \
                'cmake ' + \
                '--server-host={} '.format(server_host) + \
                '--generator="{}" '.format(generator) + \
                '--cmake-build-type={} '.format(cmake_build_type) + \
                '--build-shared-libs={} '.format(build_shared_libs) + \
                '--cxxstd={} '.format(cxxstd) + \
                '--install-test={} '.format(install_test)


def _find_package_b2_command(source_dir, generator):
    return 'python tools/ci/main.py ' + \
                '--source-dir="{}" '.format(source_dir) + \
                'find-package-b2 ' + \
                '--generator="{}" '.format(generator)


def _pipeline(
    name,
    image,
    os,
    command,
    db,
    arch='amd64',
    disable_aslr=False
):
    steps = []
    if disable_aslr:
        steps.append({
            "name": "Disable ASLR",
            "image": image,
            "pull": "if-not-exists",
            "privileged": True,
            "commands": ["echo 0 | tee /proc/sys/kernel/randomize_va_space"]
        })
    steps.append({
        "name": "Build and run",
        "image": image,
        "pull": "if-not-exists",
        "privileged": arch == "arm64", # TSAN tests fail otherwise (personality syscall)
        "volumes":[{
            "name": "mysql-socket",
            "path": "/var/run/mysqld"
        }] if db != None else [],
        "commands": [command]
    })

    return {
        "name": name,
        "kind": "pipeline",
        "type": "docker",
        "trigger": _triggers,
        "platform": {
            "os": os,
            "arch": arch
        },
        "clone": {
            "retries": 5
        },
        "node": {},
        "steps": steps,
        "services": [{
            "name": "mysql",
            "image": "ghcr.io/anarthal/cpp-ci-containers/{}".format(db),
            "volumes": [{
                "name": "mysql-socket",
                "path": "/var/run/mysqld"
            }]
        }] if db != None else [],
        "volumes": [{
            "name": "mysql-socket",
            "temp": {}
        }] if db != None else []
    }


def linux_b2(
    name,
    image,
    toolset,
    cxxstd,
    variant='debug,release',
    stdlib='native',
    address_model='64',
    separate_compilation=1,
    use_ts_executor = 0,
    address_sanitizer=0,
    undefined_sanitizer=0,
    valgrind=0,
    arch='amd64',
    fail_if_no_openssl=1,
    db='mysql-8_4_1:1',
):
    command = _b2_command(
        source_dir='$(pwd)',
        toolset=toolset,
        cxxstd=cxxstd,
        variant=variant,
        stdlib=stdlib,
        address_model=address_model,
        server_host='mysql',
        separate_compilation=separate_compilation,
        use_ts_executor=use_ts_executor,
        address_sanitizer=address_sanitizer,
        undefined_sanitizer=undefined_sanitizer,
        valgrind=valgrind,
        fail_if_no_openssl=fail_if_no_openssl
    )
    return _pipeline(
        name=name,
        image=image,
        os='linux',
        command=command,
        db=db,
        arch=arch,
        disable_aslr=True
    )


def windows_b2(
    name,
    image,
    toolset,
    cxxstd,
    variant,
    address_model = '64',
    use_ts_executor = 0
):
    command = _b2_command(
        source_dir='$Env:DRONE_WORKSPACE',
        toolset=toolset,
        cxxstd=cxxstd,
        variant=variant,
        address_model=address_model,
        server_host='127.0.0.1',
        use_ts_executor=use_ts_executor
    )
    return _pipeline(name=name, image=image, os='windows', command=command, db=None)


def linux_cmake(
    name,
    image,
    db='mysql-8_4_1:1',
    build_shared_libs=0,
    cmake_build_type='Debug',
    cxxstd='20',
    install_test=1
):
    command = _cmake_command(
        source_dir='$(pwd)',
        build_shared_libs=build_shared_libs,
        cmake_build_type=cmake_build_type,
        cxxstd=cxxstd,
        server_host='mysql',
        install_test=install_test
    )
    return _pipeline(name=name, image=image, os='linux', command=command, db=db)


def linux_cmake_noopenssl(name):
    command = 'python tools/ci/main.py ' + \
                '--source-dir=$(pwd) ' + \
                'cmake-noopenssl ' + \
                '--generator=Ninja '
    return _pipeline(name=name, image=_image('build-noopenssl:1'), os='linux', command=command, db=None)


def linux_cmake_nointeg(name):
    command = 'python tools/ci/main.py ' + \
                '--source-dir=$(pwd) ' + \
                'cmake-nointeg ' + \
                '--generator=Ninja '
    return _pipeline(name=name, image=_image('build-gcc13:1'), os='linux', command=command, db=None)


def windows_cmake(
    name,
    build_shared_libs=0
):
    command = _cmake_command(
        source_dir='$Env:DRONE_WORKSPACE',
        build_shared_libs=build_shared_libs,
        generator='Visual Studio 17 2022',
        server_host='127.0.0.1'
    )
    return _pipeline(
        name=name,
        image=_win_image('build-msvc14_3'),
        os='windows',
        command=command,
        db=None
    )


def find_package_b2_linux(name):
    command = _find_package_b2_command(source_dir='$(pwd)', generator='Ninja')
    return _pipeline(name=name, image=_image('build-gcc13:1'), os='linux', command=command, db=None)


def find_package_b2_windows(name):
    command = _find_package_b2_command(source_dir='$Env:DRONE_WORKSPACE', generator='Visual Studio 17 2022')
    return _pipeline(name=name, image=_win_image('build-msvc14_3'), os='windows', command=command, db=None)


def bench(name):
    command = 'python tools/ci/main.py ' + \
                '--source-dir="$(pwd)" ' + \
                'bench ' + \
                '--server-host=mysql ' + \
                '--connection-pool-iters=1 ' + \
                '--protocol-iters=1 '
    return _pipeline(name=name, image=_image('build-bench:1'), os='linux', command=command, db='mysql-8_4_1:1')


def docs(name):
    return _pipeline(
        name=name,
        image=_image('build-docs'),
        os='linux',
        command='python tools/ci/main.py --source-dir=$(pwd) docs',
        db=None
    )


def main(ctx):
    return [
        # CMake Linux
        linux_cmake('Linux CMake MySQL 5.x',      _image('build-gcc14:1'), db='mysql-5_7_41:1',   build_shared_libs=0),
        linux_cmake('Linux CMake MariaDB',        _image('build-gcc14:1'), db='mariadb-11_4_2:1', build_shared_libs=1),
        linux_cmake('Linux CMake cmake 3.8',      _image('build-cmake3_8:3'), cxxstd='11', install_test=0),
        linux_cmake('Linux CMake gcc Release',    _image('build-gcc14:1'), cmake_build_type='Release'),
        linux_cmake('Linux CMake gcc MinSizeRel', _image('build-gcc14:1'), cmake_build_type='MinSizeRel'),
        linux_cmake_noopenssl('Linux CMake no OpenSSL'),
        linux_cmake_nointeg('Linux CMake without integration tests'),

        # CMake Windows
        windows_cmake('Windows CMake static', build_shared_libs=0),
        windows_cmake('Windows CMake shared', build_shared_libs=1),

        # find_package with B2 distribution
        find_package_b2_linux('Linux find_package b2 distribution'),
        find_package_b2_windows('Windows find_package b2 distribution'),

        # B2 Linux. Please try to keep this below 3 configurations per build so CI doesn't take forever
        # Default Ubuntu compilers:
        #   Ubuntu 16.04: gcc5,  clang 3.8
        #   Ubuntu 18.04: gcc7,  clang 7
        #   Ubuntu 20.04: gcc9,  clang 10
        #   Ubuntu 22.04: gcc11, clang 14
        #   Ubuntu 24.04: gcc13, clang 18
        linux_b2('Linux B2 clang-4',              _image('build-clang4:1'),        toolset='clang-4',   cxxstd='14'),
        linux_b2('Linux B2 clang-5-honly-dbg',    _image('build-clang5:1'),        toolset='clang-5',   cxxstd='14', separate_compilation=0),
        linux_b2('Linux B2 clang-6',              _image('build-clang5:1'),        toolset='clang-5',   cxxstd='14'),
        linux_b2('Linux B2 clang-7',              _image('build-clang7:2'),        toolset='clang-7',   cxxstd='14,17'),
        linux_b2('Linux B2 clang-8',              _image('build-clang8:2'),        toolset='clang-8',   cxxstd='14', variant='debug', address_sanitizer=1, undefined_sanitizer=1),
        linux_b2('Linux B2 clang-9',              _image('build-clang9:2'),        toolset='clang-9',   cxxstd='17', variant='release'),
        linux_b2('Linux B2 clang-10',             _image('build-clang10:2'),       toolset='clang-10',  cxxstd='17,20', variant='debug'),
        linux_b2('Linux B2 clang-11',             _image('build-clang11:2'),       toolset='clang-11',  cxxstd='20'),
        linux_b2('Linux B2 clang-12',             _image('build-clang12:2'),       toolset='clang-12',  cxxstd='20', variant='debug', stdlib='libc++', address_sanitizer=1, undefined_sanitizer=1),
        linux_b2('Linux B2 clang-13',             _image('build-clang13:1'),       toolset='clang-13',  cxxstd='20', db='mysql-9_4_0:1'),
        linux_b2('Linux B2 clang-14',             _image('build-clang14:1'),       toolset='clang-14',  cxxstd='20', variant='debug'),
        linux_b2('Linux B2 clang-15',             _image('build-clang15:1'),       toolset='clang-15',  cxxstd='20', variant='debug'),
        linux_b2('Linux B2 clang-16',             _image('build-clang16:1'),       toolset='clang-16',  cxxstd='20', variant='debug', address_sanitizer=1, undefined_sanitizer=1),
        linux_b2('Linux B2 clang-17-honly-rls',   _image('build-clang17:1'),       toolset='clang-17',  cxxstd='20', variant='release', separate_compilation=0),
        linux_b2('Linux B2 clang-18-honly-dbg',   _image('build-clang18:1'),       toolset='clang-18',  cxxstd='20', variant='debug', separate_compilation=0),
        linux_b2('Linux B2 clang-19-libc++',      _image('build-clang19:1'),       toolset='clang-19',  cxxstd='23', stdlib='libc++'),
        linux_b2('Linux B2 clang-20',             _image('build-clang20:1'),       toolset='clang-20',  cxxstd='23'),
        linux_b2('Linux B2 clang-sanit',          _image('build-clang20:1'),       toolset='clang-20',  cxxstd='20', variant='debug', address_sanitizer=1, undefined_sanitizer=1),
        linux_b2('Linux B2 clang-i386-sanit',     _image('build-clang16-i386:1'),  toolset='clang-16',  cxxstd='20', variant='debug', address_model='32', address_sanitizer=1, undefined_sanitizer=1),

        linux_b2('Linux B2 gcc-5',                _image('build-gcc5:1'),          toolset='gcc-5',     cxxstd='11'), # gcc-5 C++14 doesn't like my constexpr field_view
        linux_b2('Linux B2 gcc-5-ts-executor',    _image('build-gcc5:1'),          toolset='gcc-5',     cxxstd='11', use_ts_executor=1),
        linux_b2('Linux B2 gcc-6-honly-dbg',      _image('build-gcc6:1'),          toolset='gcc-6',     cxxstd='14', variant='debug', separate_compilation=0),
        linux_b2('Linux B2 gcc-7',                _image('build-gcc7:1'),          toolset='gcc-7',     cxxstd='14,17', variant='debug'),
        linux_b2('Linux B2 gcc-8',                _image('build-gcc8:1'),          toolset='gcc-8',     cxxstd='17'),
        linux_b2('Linux B2 gcc-9',                _image('build-gcc9:1'),          toolset='gcc-9',     cxxstd='14,17', variant='debug'),
        linux_b2('Linux B2 gcc-10',               _image('build-gcc10:1'),         toolset='gcc-10',    cxxstd='17'),
        linux_b2('Linux B2 gcc-11',               _image('build-gcc11:1'),         toolset='gcc-11',    cxxstd='20'),
        linux_b2('Linux B2 gcc-12',               _image('build-gcc12:1'),         toolset='gcc-12',    cxxstd='20,23', variant='debug'),
        linux_b2('Linux B2 gcc-13',               _image('build-gcc13:1'),         toolset='gcc-13',    cxxstd='20', db='mysql-9_4_0:1'),
        linux_b2('Linux B2 gcc-14',               _image('build-gcc14:1'),         toolset='gcc-14',    cxxstd='23'),
        linux_b2('Linux B2 gcc-15',               _image('build-gcc15:1'),         toolset='gcc-15',    cxxstd='23'),
        linux_b2('Linux B2 gcc-sanit',            _image('build-gcc14:1'),         toolset='gcc-14',    cxxstd='23', variant='debug', address_sanitizer=1, undefined_sanitizer=1),
        linux_b2('Linux B2 gcc-valgrind',         _image('build-gcc14:1'),         toolset='gcc-14',    cxxstd='23', variant='debug', valgrind=1),
        linux_b2('Linux B2 gcc-11-arm64',         _image('build-gcc11:1'),         toolset='gcc-11',    cxxstd='20', arch='arm64', variant='release'),
        linux_b2('Linux B2 gcc-11-arm64-sanit',   _image('build-gcc11:1'),         toolset='gcc-11',    cxxstd='20', arch='arm64', variant='debug'),
        linux_b2('Linux B2 noopenssl',            _image('build-noopenssl:1'),     toolset='gcc',       cxxstd='11', fail_if_no_openssl=0),

        # B2 Windows
        windows_b2('Windows B2 msvc14.1 32-bit',      _win_image('build-msvc14_1'), toolset='msvc-14.1', cxxstd='11,14,17', variant='release',       address_model='32'),
        windows_b2('Windows B2 msvc14.1 64-bit',      _win_image('build-msvc14_1'), toolset='msvc-14.1', cxxstd='14,17',    variant='release'),
        windows_b2('Windows B2 msvc14.2',             _win_image('build-msvc14_2'), toolset='msvc-14.2', cxxstd='14,17',    variant='release'),
        windows_b2('Windows B2 msvc14.3',             _win_image('build-msvc14_3'), toolset='msvc-14.3', cxxstd='17,20',    variant='debug,release'),
        windows_b2('Windows B2 msvc14.3-ts-executor', _win_image('build-msvc14_3'), toolset='msvc-14.3', cxxstd='20',       variant='release',       use_ts_executor=1),

        # Benchmarks
        bench('Benchmarks'),

        # Docs
        docs('Linux docs')
    ]



================================================
FILE: .github/workflows/build-code.yml
================================================
#
# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#

name: Build

on:
  push:
    branches: [develop, master]
    tags: ['*']
  pull_request:
  workflow_dispatch:


jobs:
  osx:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4
      - run: |
          unlink /usr/local/bin/python || echo "/usr/local/bin/python not found"
          ln -s /usr/local/bin/python3 /usr/local/bin/python
          cp tools/user-config-osx-gha.jam ~/user-config.jam
          python -m pip install requests
          source tools/setup_db_osx.sh
          python tools/ci/main.py \
            --source-dir=$(pwd) \
            b2 \
            --toolset=clang \
            --cxxstd=20 \
            --variant=debug,release


================================================
FILE: .github/workflows/coverage.yml
================================================
#
# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#

name: coverage

on:
  push:
    branches: [develop, master]
    tags: ["*"]
  pull_request:
  workflow_dispatch:

jobs:
  coverage:
    runs-on: ubuntu-latest
    container:
      image: ghcr.io/anarthal/cpp-ci-containers/build-gcc14-lcov:1
      volumes:
        - /var/run/mysqld:/var/run/mysqld
    services:
      mysql:
        image: ghcr.io/anarthal/cpp-ci-containers/mysql-8_4_1:1
        ports:
          - 3306:3306
        volumes:
          - /var/run/mysqld:/var/run/mysqld
    steps:
      - name: Fetch code
        uses: actions/checkout@v4

      - name: Build code
        run: |
          python tools/ci/main.py \
            --source-dir=$(pwd) \
            b2 \
            --server-host=mysql \
            --toolset=gcc \
            --cxxstd=20 \
            --variant=debug \
            --disable-local-sockets=off,on \
            --coverage=1

      - name: Generate coverage reports
        shell: bash
        run: |
          cd ~/boost-root/bin.v2
          lcov \
            --rc branch_coverage=0 \
            --rc geninfo_unexecuted_blocks=1 \
            --ignore-errors mismatch \
            --gcov-tool gcov-14 \
            --directory . \
            --capture \
            --output-file all.info
          lcov \
            --rc branch_coverage=0 \
            --output-file coverage.info \
            --extract all.info '*/boost/mysql*'
          sed "s|^SF:$HOME/boost-root/|SF:include/|g" coverage.info > $GITHUB_WORKSPACE/coverage.info

      - name: Upload coverage reports
        uses: codecov/codecov-action@v4
        with:
          verbose: true
          fail_ci_if_error: true
          token: ${{ secrets.CODECOV_TOKEN }}
          plugins: noop # Don't run gcov again, codecov doesn't know about the filtering we perform
          file: coverage.info
          disable_search: true # Don't upload unwanted files
          disable_file_fixes: true # Default fixes make reports unusable



================================================
FILE: .github/workflows/docker-windows.yml
================================================
#
# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#

name: Build Docker Windows images

on:
  workflow_dispatch:
  push:
    paths:
      - tools/docker/build-msvc.dockerfile


jobs:
  docker-windows:
    strategy:
      matrix:
        include:
          - { image: build-msvc14_1, base-image: "cppalliance/dronevs2017:1" }
          - { image: build-msvc14_2, base-image: "cppalliance/dronevs2019:1" }
          - { image: build-msvc14_3, base-image: "cppalliance/dronevs2022:1" }

    permissions:
      contents: read
      packages: write

    runs-on: windows-2019

    defaults:
      run:
        shell: bash

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Log in to the Container registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: anarthal-containers
          password: ${{ secrets.ANARTHAL_CONTAINERS_TOKEN }}
      
      - name: Build and push Docker image
        run: |
          FULL_IMAGE=ghcr.io/anarthal-containers/${{ matrix.image }}
          docker build -f tools/docker/build-msvc.dockerfile --build-arg BASE_IMAGE=${{ matrix.base-image }} -t $FULL_IMAGE:$GITHUB_SHA -t $FULL_IMAGE:latest .
          docker push $FULL_IMAGE --all-tags

================================================
FILE: .github/workflows/fuzz.yml
================================================
#
# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#

name: fuzz

on:
  push:
    branches: [develop, master]
    tags: ['*']
  pull_request:
  workflow_dispatch:
  schedule:
    - cron: "25 00 * * *"

jobs:
  fuzz:
    runs-on: ubuntu-latest
    container:
      image: ghcr.io/anarthal/cpp-ci-containers/build-clang18:1
      volumes:
        - /var/run/mysqld:/var/run/mysqld
    services:
      mysql:
        image: ghcr.io/anarthal/cpp-ci-containers/mysql-8_4_1:1
        ports:
          - 3306:3306
        volumes:
          - /var/run/mysqld:/var/run/mysqld
    steps:
      - name: Fetch code
        uses: actions/checkout@v4

      - name: Restore corpus
        uses: actions/cache@v4
        with:
          path: /tmp/corpus.tar.gz
          key: corpus-${{ github.run_id }}
          restore-keys: corpus-
        
      # Note: this will take care of using the corpus and updating it
      - name: Build and run the fuzzer
        run: |
          python tools/ci/main.py \
            --source-dir=$(pwd) \
            fuzz \
            --server-host=mysql

      - name: Archive any crashes as an artifact
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: crashes
          path: |
            ~/boost-root/crash-*
            ~/boost-root/leak-*
            ~/boost-root/timeout-*
          if-no-files-found: ignore


================================================
FILE: .gitignore
================================================
/__build/
.cproject
.project
.settings/
.pydevproject
/private/
CMakeSettings.json
out/
.vs/
doc/html/
doc/qbk/reference.qbk
.vscode/
compile_commands.json
.cache/
__build*__/
__pycache__/


================================================
FILE: CMakeLists.txt
================================================
#
# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#

cmake_minimum_required(VERSION 3.8...3.22)

# Project
project(boost_mysql VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)

# Library
add_library(boost_mysql INTERFACE)
add_library(Boost::mysql ALIAS boost_mysql)

# Dependencies. If non-Boost dependencies are not found, we just bail out
find_package(Threads)
if(NOT Threads_FOUND)
    message(STATUS "Boost.MySQL has been disabled, because the required package Threads hasn't been found")
    return()
endif()
find_package(OpenSSL)
if(NOT OpenSSL_FOUND)
    message(STATUS "Boost.MySQL has been disabled, because the required package OpenSSL hasn't been found")
    return()
endif()

# This is generated by boostdep.
# Note that Boost::pfr is not listed because it's a peer dependency
target_link_libraries(
    boost_mysql
    INTERFACE
    Boost::asio
    Boost::assert
    Boost::charconv
    Boost::compat
    Boost::config
    Boost::container
    Boost::core
    Boost::describe
    Boost::endian
    Boost::intrusive
    Boost::mp11
    Boost::optional
    Boost::system
    Boost::throw_exception
    Boost::variant2
    Threads::Threads
    OpenSSL::Crypto
    OpenSSL::SSL
)

# Includes & features
target_include_directories(boost_mysql INTERFACE include)
target_compile_features(boost_mysql INTERFACE cxx_std_11)

# Don't run integration testing unless explicitly requested, since these require a running MySQL server
option(BOOST_MYSQL_INTEGRATION_TESTS OFF "Whether to build and run integration tests or not")
mark_as_advanced(BOOST_MYSQL_INTEGRATION_TESTS)

# List of server features that the CI DB server does not support.
# Disables running some integration tests and examples
set(BOOST_MYSQL_DISABLED_SERVER_FEATURES "" CACHE STRING
    "A CMake list of server features not supported by the CI server, for integration tests"
)
mark_as_advanced(BOOST_MYSQL_DISABLED_SERVER_FEATURES)

# Don't build benchmarks unless explicitly requested, since these require the official
# MySQL and MariaDB client libraries
option(BOOST_MYSQL_BENCH OFF "Whether to build the benchmarks")
mark_as_advanced(BOOST_MYSQL_BENCH)

# Examples and tests
if(BUILD_TESTING)
    # Contains some functions to share code between examples and tests
    include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/utils.cmake)

    # Custom target tests; required by the Boost superproject
    if(NOT TARGET tests)
        add_custom_target(tests)
    endif()

    # Tests
    add_subdirectory(test)
    
    # All examples require a real server to run
    if (BOOST_MYSQL_INTEGRATION_TESTS)
        add_subdirectory(example)
    endif()
endif()

if (BOOST_MYSQL_BENCH)
    include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/utils.cmake)
    add_subdirectory(bench)
endif()


================================================
FILE: LICENSE_1_0.txt
================================================
Boost Software License - Version 1.0 - August 17th, 2003

Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:

The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# Boost.MySQL

Branch | Windows/Linux Build | OSX build | Coverage | Documentation
-------|---------------------|-----------|--------- | -------------
[`master`](https://github.com/boostorg/mysql/tree/master)   | [![Build Status](https://drone.cpp.al/api/badges/boostorg/mysql/status.svg)](https://drone.cpp.al/boostorg/mysql)                        | [![Build Status](https://github.com/boostorg/mysql/actions/workflows/build-code.yml/badge.svg)](https://github.com/boostorg/mysql)                | [![codecov](https://codecov.io/gh/boostorg/mysql/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/mysql/branch/master)   | [Docs for master](https://www.boost.org/doc/libs/master/libs/mysql/doc/html/index.html)
[`develop`](https://github.com/boostorg/mysql/tree/develop) | [![Build Status](https://drone.cpp.al/api/badges/boostorg/mysql/status.svg?ref=refs/heads/develop)](https://drone.cpp.al/boostorg/mysql) | [![Build Status](https://github.com/boostorg/mysql/actions/workflows/build-code.yml/badge.svg?branch=develop)](https://github.com/boostorg/mysql) | [![codecov](https://codecov.io/gh/boostorg/mysql/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/mysql/branch/develop) | [Docs for develop](https://www.boost.org/doc/libs/develop/libs/mysql/doc/html/index.html)

Boost.MySQL is a C++11 client for MySQL and MariaDB database servers, based on Boost.Asio.
Boost.MySQL is part of Boost.

## Breaking changes in Boost 1.85

Boost.MySQL now requires linking with Boost.Charconv, which is a compiled library.
If you're getting link errors, link your executable to the `Boost::charconv` CMake target.
No C++ code changes are required.

## Feedback

Do you have any suggestion? Would you like to share a bad or good experience while using the library?
Please comment [on this issue](https://github.com/boostorg/mysql/issues/140).

## Why another MySQL C++ client?

- It is fully compatible with Boost.Asio and integrates well with any other
  library in the Boost.Asio ecosystem (like Boost.Beast).
- It supports Boost.Asio's universal asynchronous model, which means you can
  go asynchronous using callbacks, futures or coroutines (including C++20 coroutines).
- It is written in C++11 and takes advantage of it.
- It is header only.

## Using the library

To use this library, you need:

- Boost 1.82 or higher (Boost.MySQL doesn't work with standalone Asio).
- A C++11 capable compiler.
- OpenSSL.

The library is header-only, but it depends on other Boost header-only libraries and on OpenSSL.
To use the library, install Boost the way you would normally do (e.g. via `b2 install`), and create
a `CMakeLists.txt` like this (replace `main` by your executable name and `main.cpp` by your list of source files):

```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)
```

## Tested with

Boost.MySQL has been tested with the following compilers:

- gcc 5 to 15.
- clang 4 to 20.
- msvc 14.1, 14.2 and 14.3.

And with the following databases:

- MySQL v5.7.41.
- MySQL v8.4.1.
- MariaDB v11.4.2.

## Features

- Text queries (execution of text SQL queries and data retrieval).
  MySQL refers to this as the "text protocol", as all information is passed using text
  (as opposed to prepared statements, see below).
- Prepared statements. MySQL refers to this as the "binary protocol", as the result
  of executing a prepared statement is sent in binary format rather than in text.
- Stored procedures.
- Authentication methods (authentication plugins): mysql_native_password and
  caching_sha2_password. These are the default methods in MySQL 5/MariaDB and MySQL 8,
  respectively.
- Encrypted connections (TLS).
- TCP and UNIX socket transports.
- Connection pools.
- Friendly client-side generated SQL.
- (Experimental) pipelines.


================================================
FILE: bench/CMakeLists.txt
================================================
#
# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#

# Utility target
add_custom_target(boost_mysql_bench)

# Find libraries required by the official clients
find_package(OpenSSL REQUIRED)

# Find libmysqlclient. This script has only been tested on Ubuntu Linux, where benchmarks are performed.
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)

# Find libmariadb
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)

# Adds a benchmark target - pass the libraries to link to as extra args
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()

# We use the header-only version here because it's slightly faster
# and to avoid dependencies to the test CMake scripts

# Connection pool
add_bench(connection_pool boost_mysql)

# Protocol benchmarks
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)


================================================
FILE: bench/bench.ipynb
================================================
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Benchmark data processing\n",
    "\n",
    "Contains the code required to plot the figures in the docs.\n",
    "\n",
    "* Build the benchmarks with CMake, using the `BOOST_MYSQL_BENCH` CMake option and the `boost_mysql_bench` CMake target.\n",
    "* Run the benchmarks with `tools/ci/run_benchmarks.py`, which leaves a .txt file with the results in the current directory.\n",
    "* Run this notebook to generate the graphs.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "df = pd.read_csv('../private/benchmark-results.txt', header=None) # Update file path as required\n",
    "df = df.set_index(df.index.map(lambda x: x % df.groupby(0).size()[0]))\n",
    "df = df.pivot(columns=[0], values=[1])\n",
    "df.columns = df.columns.get_level_values(0)\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_result(df: pd.DataFrame, bench: str, title: str, ax):\n",
    "    cols = [f'{bench}_boost', f'{bench}_libmysqlclient', f'{bench}_libmariadb']\n",
    "    df = df[cols].rename(columns={\n",
    "        f'{bench}_boost': 'Boost.MySQL',\n",
    "        f'{bench}_libmysqlclient': 'libmysqlclient',\n",
    "        f'{bench}_libmariadb': 'libmariadb'\n",
    "    })\n",
    "    mean_val = round(df.mean().mean())\n",
    "    df.plot.box(ylim=(mean_val-150, mean_val+150), ax=ax, title=title, ylabel='Time (ms)')\n",
    "\n",
    "\n",
    "fig, _ = plt.subplots(2, 2, figsize=(15, 15))\n",
    "\n",
    "plot_result(df, bench='one_small_row', title='Reading one small row', ax=fig.axes[0])\n",
    "plot_result(df, bench='one_big_row', title='Reading one big row', ax=fig.axes[1])\n",
    "plot_result(df, bench='many_rows', title='Reading 5k rows', ax=fig.axes[2])\n",
    "plot_result(df, bench='stmt_params', title='Statement with params', ax=fig.axes[3])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}


================================================
FILE: bench/connection_pool.cpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <boost/mysql/any_address.hpp>
#include <boost/mysql/any_connection.hpp>
#include <boost/mysql/connect_params.hpp>
#include <boost/mysql/connection.hpp>
#include <boost/mysql/connection_pool.hpp>
#include <boost/mysql/diagnostics.hpp>
#include <boost/mysql/error_code.hpp>
#include <boost/mysql/pool_params.hpp>
#include <boost/mysql/results.hpp>
#include <boost/mysql/ssl_mode.hpp>
#include <boost/mysql/statement.hpp>
#include <boost/mysql/string_view.hpp>

#include <boost/asio/any_io_executor.hpp>
#include <boost/asio/coroutine.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/io_context.hpp>

#include <chrono>
#include <cstddef>
#include <iostream>

using boost::mysql::error_code;
using std::chrono::steady_clock;
namespace mysql = boost::mysql;
namespace asio = boost::asio;

namespace {

static constexpr std::size_t num_parallel = 100;
static constexpr std::size_t total = num_parallel * 100;
static constexpr const char* default_unix_path = "/var/run/mysqld/mysqld.sock";

class coordinator
{
    bool finished_{};
    std::size_t remaining_queries_{total};
    std::size_t outstanding_tasks_{num_parallel};
    steady_clock::time_point tp_start_;
    steady_clock::time_point tp_finish_;
    mysql::connection_pool* pool_{};

public:
    coordinator(mysql::connection_pool* pool = nullptr) : pool_(pool) {}
    std::chrono::milliseconds ellapsed() const
    {
        return std::chrono::duration_cast<std::chrono::milliseconds>(tp_finish_ - tp_start_);
    }
    void record_start() { tp_start_ = steady_clock::now(); }
    void on_finish()
    {
        if (--outstanding_tasks_ == 0)
        {
            tp_finish_ = steady_clock::now();
            if (pool_)
                pool_->cancel();
        }
    }
    bool on_loop_finish()
    {
        if (--remaining_queries_ == 0)
            finished_ = true;
        return !finished_;
    }

    bool check_ec(error_code ec, const mysql::diagnostics& diag)
    {
        if (ec)
        {
            finished_ = true;
            std::cout << ec << ", " << diag.server_message() << std::endl;
        }
        return !finished_;
    }
};

class task_nopool
{
    mysql::any_connection conn_;
    mysql::results r_;
    mysql::diagnostics diag_;
    coordinator* coord_{};
    const mysql::connect_params* params_;
    mysql::statement stmt_;
    asio::coroutine coro_;

public:
    task_nopool(asio::any_io_executor ex, coordinator& coord, const mysql::connect_params& params)
        : conn_(ex), coord_(&coord), params_(&params)
    {
    }

    void resume(error_code ec = {})
    {
        // Error checking
        if (!coord_->check_ec(ec, diag_))
        {
            coord_->on_finish();
            return;
        }

        BOOST_ASIO_CORO_REENTER(coro_)
        {
            while (true)
            {
                BOOST_ASIO_CORO_YIELD
                conn_.async_connect(*params_, diag_, [this](error_code ec) { resume(ec); });

                BOOST_ASIO_CORO_YIELD
                conn_.async_prepare_statement(
                    "SELECT data FROM lightweight_data WHERE id = ?",
                    diag_,
                    [this](error_code ec, boost::mysql::statement s) {
                        stmt_ = s;
                        resume(ec);
                    }
                );

                BOOST_ASIO_CORO_YIELD
                conn_.async_execute(stmt_.bind(2), r_, diag_, [this](error_code ec) { resume(ec); });

                BOOST_ASIO_CORO_YIELD
                conn_.async_close(diag_, [this](error_code ec) { resume(ec); });

                if (!coord_->on_loop_finish())
                {
                    coord_->on_finish();
                    return;
                }
            }
        }
    }
};

class task_pool
{
    mysql::connection_pool* pool_;
    mysql::results r_;
    mysql::diagnostics diag_;
    coordinator* coord_{};
    mysql::pooled_connection conn_;
    asio::coroutine coro_;
    mysql::statement stmt_;

    void on_finish()
    {
        conn_ = mysql::pooled_connection();
        coord_->on_finish();
    }

public:
    task_pool(mysql::connection_pool& pool, coordinator& coord) : pool_(&pool), coord_(&coord) {}

    void resume(error_code ec = {})
    {
        // Error checking
        if (!coord_->check_ec(ec, diag_))
        {
            on_finish();
            return;
        }

        BOOST_ASIO_CORO_REENTER(coro_)
        {
            while (true)
            {
                BOOST_ASIO_CORO_YIELD
                pool_->async_get_connection(diag_, [this](error_code ec, mysql::pooled_connection c) {
                    conn_ = std::move(c);
                    resume(ec);
                });

                BOOST_ASIO_CORO_YIELD
                conn_->async_prepare_statement(
                    "SELECT data FROM lightweight_data WHERE id = ?",
                    diag_,
                    [this](error_code ec, boost::mysql::statement s) {
                        stmt_ = s;
                        resume(ec);
                    }
                );

                BOOST_ASIO_CORO_YIELD
                conn_->async_execute(stmt_.bind(2), r_, diag_, [this](error_code ec) { resume(ec); });

                conn_ = boost::mysql::pooled_connection();

                if (!coord_->on_loop_finish())
                {
                    on_finish();
                    return;
                }
            }
        }
    }
};

void run_nopool(mysql::any_address server_addr, bool use_ssl)
{
    // Setup
    asio::io_context ctx;
    mysql::connect_params params;
    params.server_address = std::move(server_addr);
    params.username = "root";
    params.password = "";
    params.database = "boost_mysql_bench";
    params.ssl = use_ssl ? mysql::ssl_mode::require : mysql::ssl_mode::disable;
    std::vector<task_nopool> conns;
    coordinator coord;

    // Create connections
    for (std::size_t i = 0; i < num_parallel; ++i)
        conns.emplace_back(ctx.get_executor(), coord, params);

    // Launch
    coord.record_start();
    for (auto& conn : conns)
        conn.resume(error_code());

    // Run
    ctx.run();

    // Print elapsed time
    std::cout << coord.ellapsed().count() << std::flush;
}

void run_pool(mysql::any_address server_addr, bool use_ssl)
{
    // Setup
    asio::io_context ctx;
    mysql::pool_params params;
    params.server_address = std::move(server_addr);
    params.username = "root";
    params.password = "";
    params.database = "boost_mysql_bench";
    params.max_size = num_parallel;
    params.ssl = use_ssl ? mysql::ssl_mode::require : mysql::ssl_mode::disable;

    mysql::connection_pool pool(ctx, std::move(params));
    pool.async_run(asio::detached);

    std::vector<task_pool> conns;
    coordinator coord(&pool);

    // Create connections
    for (std::size_t i = 0; i < num_parallel; ++i)
        conns.emplace_back(pool, coord);

    // Launch
    coord.record_start();
    for (auto& conn : conns)
        conn.resume(error_code());

    // Run
    ctx.run();

    // Print elapsed time
    std::cout << coord.ellapsed().count() << std::flush;
}

static constexpr const char* options[] = {
    "nopool-tcp",
    "nopool-tcpssl",
    "nopool-unix",
    "pool-tcp",
    "pool-tcpssl",
    "pool-unix",
};

void usage(const char* progname)
{
    std::cerr << "Usage: " << progname << " <benchmark-type> <server-addr>\nAvailable options:\n";
    for (const char* opt : options)
        std::cerr << "    " << opt << "\n";
    exit(1);
}

}  // namespace

int main(int argc, char** argv)
{
    if (argc != 3)
    {
        usage(argv[0]);
    }

    mysql::string_view opt = argv[1];
    mysql::string_view addr = argv[2];
    boost::mysql::host_and_port tcp_addr;

    if (opt == "nopool-tcp")
    {
        tcp_addr.host = addr;
        run_nopool(std::move(tcp_addr), false);
    }
    else if (opt == "nopool-tcpssl")
    {
        tcp_addr.host = addr;
        run_nopool(std::move(tcp_addr), true);
    }
    else if (opt == "nopool-unix")
    {
        run_nopool(mysql::unix_path{default_unix_path}, false);
    }
    else if (opt == "pool-tcp")
    {
        tcp_addr.host = addr;
        run_pool(std::move(tcp_addr), false);
    }
    else if (opt == "pool-tcpssl")
    {
        tcp_addr.host = addr;
        run_pool(std::move(tcp_addr), true);
    }
    else if (opt == "pool-unix")
    {
        run_pool(mysql::unix_path{default_unix_path}, false);
    }
    else
        usage(argv[0]);
}


================================================
FILE: bench/db_setup.sql
================================================
--
-- Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
--
-- Distributed under the Boost Software License, Version 1.0. (See accompanying
-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
--

-- Database
DROP DATABASE IF EXISTS boost_mysql_bench;
CREATE DATABASE boost_mysql_bench;
USE boost_mysql_bench;

-- Required for the WITH RECURSIVE and the amount of rows we're generating
SET SESSION cte_max_recursion_depth = 15000;

-- Having this prevents sporadic CI failures
SET global max_connections = 5000;

-- An arbitrary value to pass to RAND(@seed). RAND(@i) generates a
-- deterministic sequence, vs RAND(@seed)
SET @seed = 3;

-- Table, with a column per major type
CREATE TABLE test_data(
    id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    s8 TINYINT NOT NULL,
    u8 TINYINT UNSIGNED NOT NULL,
    s16 SMALLINT NOT NULL,
    u16 SMALLINT UNSIGNED NOT NULL,
    s32 INT NOT NULL,
    u32 INT UNSIGNED NOT NULL,
    s64 BIGINT NOT NULL,
    u64 BIGINT UNSIGNED NOT NULL,
    s1 VARCHAR(256),
    s2 TEXT,
    b1 VARBINARY(256),
    b2 BLOB,
    flt FLOAT,
    dbl DOUBLE,
    dt DATE,
    dtime DATETIME,
    t TIME
);

-- Generate 10000 random rows
INSERT INTO test_data(
    s8,
    u8,
    s16,
    u16,
    s32,
    u32,
    s64,
    u64,
    s1,
    s2,
    b1,
    b2,
    flt,
    dbl,
    dt,
    dtime,
    t
)
WITH RECURSIVE cte AS (
    SELECT 0 num
    UNION ALL
    SELECT num + 1 FROM cte
    WHERE num < 5000
) SELECT
    FLOOR(RAND(@seed)*(0x7f+0x80+1)-0x80),
    FLOOR(RAND(@seed)*(0xff+1)),
    FLOOR(RAND(@seed)*(0x7fff+0x8000+1)-0x8000),
    FLOOR(RAND(@seed)*(0xffff+1)),
    FLOOR(RAND(@seed)*(0x7fffffff+0x80000000+1)-0x80000000),
    FLOOR(RAND(@seed)*(0xffffffff+1)),
    FLOOR(RAND(@seed)*(0x7fffffffffffffff+0x8000000000000000)-0x7fffffffffffffff),
    FLOOR(RAND(@seed)*(0xffffffffffffffff)),
    REPEAT('a', 180),
    REPEAT('b', FLOOR(RAND(@seed)*(54000-36000+1)+36000)),
    REPEAT('c', 180),
    REPEAT('d', FLOOR(RAND(@seed)*(54000-36000+1)+36000)),
    RAND(@seed),
    RAND(@seed),
    DATE_ADD('2020-01-01', INTERVAL FLOOR(RAND(@seed)*(5000+5000+1)-5000) DAY),
    DATE_ADD('2010-03-20', INTERVAL FLOOR(RAND(@seed)*(3600*24*365*20+3600*24*365*20+1)-3600*24*365*20) SECOND),
    SEC_TO_TIME(RAND(@seed) + FLOOR(RAND(@seed)*(839*3600+839*3600+1)-839*3600))
FROM cte;

-- A lightweight table, for the connection_pool benchmarks
CREATE TABLE lightweight_data(
    id INT NOT NULL PRIMARY KEY,
    data VARCHAR(100) NOT NULL
);

INSERT INTO lightweight_data VALUES
    (1, "Data piece 1"),
    (2, "Another data piece"),
    (3, "Final data piece")
;


================================================
FILE: bench/many_rows_boost.cpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <boost/mysql/any_connection.hpp>
#include <boost/mysql/connect_params.hpp>
#include <boost/mysql/execution_state.hpp>
#include <boost/mysql/results.hpp>
#include <boost/mysql/ssl_mode.hpp>

#include <boost/asio/io_context.hpp>

#include <cassert>
#include <chrono>
#include <cstdlib>
#include <cstring>
#include <iostream>

namespace asio = boost::asio;
namespace mysql = boost::mysql;

int main()
{
    // Setup
    asio::io_context ctx;
    mysql::any_connection conn(ctx);
    mysql::execution_state st;

    // Connect
    mysql::connect_params params;
    params.server_address.emplace_unix_path("/var/run/mysqld/mysqld.sock");
    params.username = "root";
    params.password = "";
    params.database = "boost_mysql_bench";
    params.ssl = mysql::ssl_mode::disable;
    conn.connect(params);

    // Prepare the statement
    auto stmt = conn.prepare_statement("SELECT * FROM test_data");

    // Ensure that nothing gets optimized away
    unsigned num_rows = 0;

    // Benchmark starts here
    auto tbegin = std::chrono::steady_clock::now();

    // start_execution won't copy the strings in the rows (as opposed to execute),
    // so it's preferable when we have big rows, like here
    conn.start_execution(stmt.bind(), st);
    while (!st.complete())
        num_rows += conn.read_some_rows(st).size();

    // Benchmark ends here
    auto tend = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbegin).count() << std::endl;

    // We expect many rows
    return num_rows == 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}

================================================
FILE: bench/many_rows_libmariadb.cpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <cassert>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <mariadb/mysql.h>
#include <string>

int main()
{
    // Initialize
    if (mysql_library_init(0, NULL, NULL))
    {
        fprintf(stderr, "could not initialize MySQL client library\n");
        exit(1);
    }
    MYSQL* con = mysql_init(NULL);
    if (con == NULL)
    {
        fprintf(stderr, "Error initializing connection: %s\n", mysql_error(con));
        exit(1);
    }

    // Connect
    if (mysql_real_connect(con, NULL, "root", "", "boost_mysql_bench", 0, "/var/run/mysqld/mysqld.sock", 0) ==
        NULL)
    {
        fprintf(stderr, "%s\n", mysql_error(con));
        mysql_close(con);
        exit(1);
    }

    // Prepare the statement
    MYSQL_STMT* stmt;
    stmt = mysql_stmt_init(con);
    if (!stmt)
    {
        printf("Could not initialize statement\n");
        exit(1);
    }
    constexpr const char* stmt_str = "SELECT * FROM test_data";
    if (mysql_stmt_prepare(stmt, stmt_str, strlen(stmt_str)))
    {
        fprintf(stderr, "Error preparing statement: %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    // Prepare the bind objects
    long long int out_id = 0;
    MYSQL_BIND binds[18]{};
    binds[0].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[0].buffer = &out_id;
    binds[0].buffer_length = 8;

    signed char s8{};
    binds[1].buffer_type = MYSQL_TYPE_TINY;
    binds[1].buffer = &s8;
    binds[1].buffer_length = 1;
    binds[1].is_unsigned = 0;

    unsigned char u8{};
    binds[2].buffer_type = MYSQL_TYPE_TINY;
    binds[2].buffer = &u8;
    binds[2].buffer_length = 1;
    binds[2].is_unsigned = 1;

    short s16{};
    binds[3].buffer_type = MYSQL_TYPE_SHORT;
    binds[3].buffer = &s16;
    binds[3].buffer_length = 2;
    binds[3].is_unsigned = 0;

    unsigned short u16{};
    binds[4].buffer_type = MYSQL_TYPE_SHORT;
    binds[4].buffer = &u16;
    binds[4].buffer_length = 2;
    binds[4].is_unsigned = 1;

    int s32{};
    binds[5].buffer_type = MYSQL_TYPE_LONG;
    binds[5].buffer = &s32;
    binds[5].buffer_length = 4;
    binds[5].is_unsigned = 0;

    unsigned u32{};
    binds[6].buffer_type = MYSQL_TYPE_LONG;
    binds[6].buffer = &u32;
    binds[6].buffer_length = 4;
    binds[6].is_unsigned = 1;

    long long s64{};
    binds[7].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[7].buffer = &s64;
    binds[7].buffer_length = 8;
    binds[7].is_unsigned = 0;

    unsigned long long u64{};
    binds[8].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[8].buffer = &u64;
    binds[8].buffer_length = 8;
    binds[8].is_unsigned = 1;

    char s1[255]{};
    binds[9].buffer_type = MYSQL_TYPE_STRING;
    binds[9].buffer = s1;
    binds[9].buffer_length = sizeof(s1);

    std::string s2;
    unsigned long s2_length = 0u;
    my_bool s2_truncated{};
    binds[10].buffer_type = MYSQL_TYPE_STRING;
    binds[10].buffer = s2.data();
    binds[10].buffer_length = s2_length;
    binds[10].length = &s2_length;
    binds[10].error = &s2_truncated;

    char b1[255]{};
    binds[11].buffer_type = MYSQL_TYPE_BLOB;
    binds[11].buffer = b1;
    binds[11].buffer_length = sizeof(b1);

    std::string b2;
    unsigned long b2_length = 0u;
    my_bool b2_truncated{};
    binds[12].buffer_type = MYSQL_TYPE_BLOB;
    binds[12].buffer = b2.data();
    binds[12].buffer_length = b2_length;
    binds[12].length = &b2_length;
    binds[12].error = &b2_truncated;

    float flt{};
    binds[13].buffer_type = MYSQL_TYPE_FLOAT;
    binds[13].buffer = &flt;
    binds[13].buffer_length = 4;

    double dbl{};
    binds[14].buffer_type = MYSQL_TYPE_DOUBLE;
    binds[14].buffer = &dbl;
    binds[14].buffer_length = 8;

    MYSQL_TIME dt{};
    binds[15].buffer_type = MYSQL_TYPE_DATE;
    binds[15].buffer = &dt;
    binds[15].buffer_length = sizeof(dt);

    MYSQL_TIME dtime{};
    binds[16].buffer_type = MYSQL_TYPE_DATETIME;
    binds[16].buffer = &dtime;
    binds[16].buffer_length = sizeof(dtime);

    MYSQL_TIME t{};
    binds[17].buffer_type = MYSQL_TYPE_TIME;
    binds[17].buffer = &t;
    binds[17].buffer_length = sizeof(t);

    // Ensure that nothing gets optimized away
    unsigned num_rows = 0;

    // Benchmark starts here
    auto tbegin = std::chrono::steady_clock::now();

    // Execute the statement
    if (mysql_stmt_execute(stmt))
    {
        fprintf(stderr, "Error executing statement: %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    // Bind output
    if (mysql_stmt_bind_result(stmt, binds))
    {
        fprintf(stderr, "Error binding result: %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    // Read the rows
    while (true)
    {
        auto status = mysql_stmt_fetch(stmt);

        if (status == MYSQL_DATA_TRUNCATED)
        {
            // On truncation, resize the buffer and read again
            if (s2_length > s2.size())
            {
                s2.resize(s2_length);
                binds[10].buffer = s2.data();
                binds[10].buffer_length = s2_length;
                if (mysql_stmt_fetch_column(stmt, &binds[10], 10, 0))
                {
                    fprintf(stderr, "Error fetching s2: %s\n", mysql_stmt_error(stmt));
                    exit(1);
                }
            }

            if (b2_length > b2.size())
            {
                b2.resize(b2_length);
                binds[12].buffer = b2.data();
                binds[12].buffer_length = b2_length;
                if (mysql_stmt_fetch_column(stmt, &binds[12], 12, 0))
                {
                    fprintf(stderr, "Error fetching b2: %s\n", mysql_stmt_error(stmt));
                    exit(1);
                }
            }

            ++num_rows;
        }
        else if (status == MYSQL_NO_DATA)
        {
            break;
        }
        else if (status == 1)
        {
            fprintf(stderr, "Error fetching result: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }
        else
        {
            ++num_rows;
        }
    }

    // Benchmark ends here
    auto tend = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbegin).count() << std::endl;

    // Cleanup
    mysql_stmt_close(stmt);
    mysql_close(con);

    // We expect many rows
    return num_rows == 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}

================================================
FILE: bench/many_rows_libmysqlclient.cpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <cassert>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <mysql/field_types.h>
#include <mysql/mysql.h>
#include <mysql/mysql_com.h>
#include <string>

int main()
{
    // Initialize
    if (mysql_library_init(0, NULL, NULL))
    {
        fprintf(stderr, "could not initialize MySQL client library\n");
        exit(1);
    }
    MYSQL* con = mysql_init(NULL);
    if (con == NULL)
    {
        fprintf(stderr, "Error initializing connection: %s\n", mysql_error(con));
        exit(1);
    }

    // Connect
    unsigned mode = SSL_MODE_DISABLED;
    if (mysql_options(con, MYSQL_OPT_SSL_MODE, &mode))
    {
        fprintf(stderr, "Error in mysql_options: %s\n", mysql_error(con));
        exit(1);
    }

    if (mysql_real_connect(con, NULL, "root", "", "boost_mysql_bench", 0, "/var/run/mysqld/mysqld.sock", 0) ==
        NULL)
    {
        fprintf(stderr, "%s\n", mysql_error(con));
        mysql_close(con);
        exit(1);
    }

    // Prepare the statement
    MYSQL_STMT* stmt;
    stmt = mysql_stmt_init(con);
    if (!stmt)
    {
        printf("Could not initialize statement\n");
        exit(1);
    }
    constexpr const char* stmt_str = "SELECT * FROM test_data";
    if (mysql_stmt_prepare(stmt, stmt_str, strlen(stmt_str)))
    {
        fprintf(stderr, "Error preparing statement: %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    // Prepare the bind objects
    long long int out_id = 0;
    MYSQL_BIND binds[18]{};
    binds[0].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[0].buffer = &out_id;
    binds[0].buffer_length = 8;

    signed char s8{};
    binds[1].buffer_type = MYSQL_TYPE_TINY;
    binds[1].buffer = &s8;
    binds[1].buffer_length = 1;
    binds[1].is_unsigned = 0;

    unsigned char u8{};
    binds[2].buffer_type = MYSQL_TYPE_TINY;
    binds[2].buffer = &u8;
    binds[2].buffer_length = 1;
    binds[2].is_unsigned = 1;

    short s16{};
    binds[3].buffer_type = MYSQL_TYPE_SHORT;
    binds[3].buffer = &s16;
    binds[3].buffer_length = 2;
    binds[3].is_unsigned = 0;

    unsigned short u16{};
    binds[4].buffer_type = MYSQL_TYPE_SHORT;
    binds[4].buffer = &u16;
    binds[4].buffer_length = 2;
    binds[4].is_unsigned = 1;

    int s32{};
    binds[5].buffer_type = MYSQL_TYPE_LONG;
    binds[5].buffer = &s32;
    binds[5].buffer_length = 4;
    binds[5].is_unsigned = 0;

    unsigned u32{};
    binds[6].buffer_type = MYSQL_TYPE_LONG;
    binds[6].buffer = &u32;
    binds[6].buffer_length = 4;
    binds[6].is_unsigned = 1;

    long long s64{};
    binds[7].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[7].buffer = &s64;
    binds[7].buffer_length = 8;
    binds[7].is_unsigned = 0;

    unsigned long long u64{};
    binds[8].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[8].buffer = &u64;
    binds[8].buffer_length = 8;
    binds[8].is_unsigned = 1;

    char s1[255]{};
    binds[9].buffer_type = MYSQL_TYPE_STRING;
    binds[9].buffer = s1;
    binds[9].buffer_length = sizeof(s1);

    std::string s2;
    unsigned long s2_length = 0u;
    bool s2_truncated{};
    binds[10].buffer_type = MYSQL_TYPE_STRING;
    binds[10].buffer = s2.data();
    binds[10].buffer_length = s2_length;
    binds[10].length = &s2_length;
    binds[10].error = &s2_truncated;

    char b1[255]{};
    binds[11].buffer_type = MYSQL_TYPE_BLOB;
    binds[11].buffer = b1;
    binds[11].buffer_length = sizeof(b1);

    std::string b2;
    unsigned long b2_length = 0u;
    bool b2_truncated{};
    binds[12].buffer_type = MYSQL_TYPE_BLOB;
    binds[12].buffer = b2.data();
    binds[12].buffer_length = b2_length;
    binds[12].length = &b2_length;
    binds[12].error = &b2_truncated;

    float flt{};
    binds[13].buffer_type = MYSQL_TYPE_FLOAT;
    binds[13].buffer = &flt;
    binds[13].buffer_length = 4;

    double dbl{};
    binds[14].buffer_type = MYSQL_TYPE_DOUBLE;
    binds[14].buffer = &dbl;
    binds[14].buffer_length = 8;

    MYSQL_TIME dt{};
    binds[15].buffer_type = MYSQL_TYPE_DATE;
    binds[15].buffer = &dt;
    binds[15].buffer_length = sizeof(dt);

    MYSQL_TIME dtime{};
    binds[16].buffer_type = MYSQL_TYPE_DATETIME;
    binds[16].buffer = &dtime;
    binds[16].buffer_length = sizeof(dtime);

    MYSQL_TIME t{};
    binds[17].buffer_type = MYSQL_TYPE_TIME;
    binds[17].buffer = &t;
    binds[17].buffer_length = sizeof(t);

    // Ensure that nothing gets optimized away
    unsigned num_rows = 0;

    // Benchmark starts here
    auto tbegin = std::chrono::steady_clock::now();

    // Execute the statement
    if (mysql_stmt_execute(stmt))
    {
        fprintf(stderr, "Error executing statement: %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    // Bind output
    if (mysql_stmt_bind_result(stmt, binds))
    {
        fprintf(stderr, "Error binding result: %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    while (true)
    {
        auto status = mysql_stmt_fetch(stmt);

        // On truncation, resize the buffer and read again
        if (status == MYSQL_DATA_TRUNCATED)
        {
            if (s2_length > s2.size())
            {
                s2.resize(s2_length);
                binds[10].buffer = s2.data();
                binds[10].buffer_length = s2_length;
                if (mysql_stmt_fetch_column(stmt, &binds[10], 10, 0))
                {
                    fprintf(stderr, "Error fetching s2: %s\n", mysql_stmt_error(stmt));
                    exit(1);
                }
            }

            if (b2_length > b2.size())
            {
                b2.resize(b2_length);
                binds[12].buffer = b2.data();
                binds[12].buffer_length = b2_length;
                if (mysql_stmt_fetch_column(stmt, &binds[12], 12, 0))
                {
                    fprintf(stderr, "Error fetching b2: %s\n", mysql_stmt_error(stmt));
                    exit(1);
                }
            }

            ++num_rows;
        }
        else if (status == MYSQL_NO_DATA)
        {
            break;
        }
        else if (status == 1)
        {
            fprintf(stderr, "Error fetching result: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }
        else
        {
            ++num_rows;
        }
    }

    // Benchmark ends here
    auto tend = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbegin).count() << std::endl;

    // Cleanup
    mysql_stmt_close(stmt);
    mysql_close(con);

    // We expect many rows
    return num_rows == 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}

================================================
FILE: bench/one_big_row_boost.cpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <boost/mysql/any_connection.hpp>
#include <boost/mysql/connect_params.hpp>
#include <boost/mysql/execution_state.hpp>
#include <boost/mysql/results.hpp>
#include <boost/mysql/ssl_mode.hpp>

#include <boost/asio/io_context.hpp>

#include <cassert>
#include <chrono>
#include <cstdlib>
#include <cstring>
#include <iostream>

using namespace std;

namespace asio = boost::asio;
namespace mysql = boost::mysql;

int main()
{
    // Setup
    asio::io_context ctx;
    mysql::any_connection conn(ctx);
    mysql::execution_state st;

    // Connect
    mysql::connect_params params;
    params.server_address.emplace_unix_path("/var/run/mysqld/mysqld.sock");
    params.username = "root";
    params.password = "";
    params.database = "boost_mysql_bench";
    params.ssl = mysql::ssl_mode::disable;
    conn.connect(params);

    // Prepare the statement
    auto stmt = conn.prepare_statement("SELECT * FROM test_data WHERE id = 1");

    // Ensure that nothing gets optimized away
    unsigned num_rows = 0;

    // Benchmark starts here
    auto tbegin = std::chrono::steady_clock::now();

    for (int i = 0; i < 10000; ++i)
    {
        // start_execution won't copy the strings in the rows (as opposed to execute),
        // so it's preferable when we have big rows, like here
        conn.start_execution(stmt.bind(), st);
        while (!st.complete())
            num_rows += conn.read_some_rows(st).size();
    }

    // Benchmark ends here
    auto tend = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbegin).count() << std::endl;

    // We expect one row per iteration
    return num_rows == 10000 ? EXIT_SUCCESS : EXIT_FAILURE;
}

================================================
FILE: bench/one_big_row_libmariadb.cpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <cassert>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <mariadb/mysql.h>
#include <string>

int main()
{
    // Initialize
    if (mysql_library_init(0, NULL, NULL))
    {
        fprintf(stderr, "could not initialize MySQL client library\n");
        exit(1);
    }
    MYSQL* con = mysql_init(NULL);
    if (con == NULL)
    {
        fprintf(stderr, "Error initializing connection: %s\n", mysql_error(con));
        exit(1);
    }

    // Connect
    if (mysql_real_connect(con, NULL, "root", "", "boost_mysql_bench", 0, "/var/run/mysqld/mysqld.sock", 0) ==
        NULL)
    {
        fprintf(stderr, "%s\n", mysql_error(con));
        mysql_close(con);
        exit(1);
    }

    // Prepare the statement
    MYSQL_STMT* stmt;
    stmt = mysql_stmt_init(con);
    if (!stmt)
    {
        printf("Could not initialize statement\n");
        exit(1);
    }
    constexpr const char* stmt_str = "SELECT * FROM test_data WHERE id = 1";
    if (mysql_stmt_prepare(stmt, stmt_str, strlen(stmt_str)))
    {
        fprintf(stderr, "Error preparing statement: %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    // Prepare the bind objects
    long long int out_id = 0;
    MYSQL_BIND binds[18]{};
    binds[0].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[0].buffer = &out_id;
    binds[0].buffer_length = 8;

    signed char s8{};
    binds[1].buffer_type = MYSQL_TYPE_TINY;
    binds[1].buffer = &s8;
    binds[1].buffer_length = 1;
    binds[1].is_unsigned = 0;

    unsigned char u8{};
    binds[2].buffer_type = MYSQL_TYPE_TINY;
    binds[2].buffer = &u8;
    binds[2].buffer_length = 1;
    binds[2].is_unsigned = 1;

    short s16{};
    binds[3].buffer_type = MYSQL_TYPE_SHORT;
    binds[3].buffer = &s16;
    binds[3].buffer_length = 2;
    binds[3].is_unsigned = 0;

    unsigned short u16{};
    binds[4].buffer_type = MYSQL_TYPE_SHORT;
    binds[4].buffer = &u16;
    binds[4].buffer_length = 2;
    binds[4].is_unsigned = 1;

    int s32{};
    binds[5].buffer_type = MYSQL_TYPE_LONG;
    binds[5].buffer = &s32;
    binds[5].buffer_length = 4;
    binds[5].is_unsigned = 0;

    unsigned u32{};
    binds[6].buffer_type = MYSQL_TYPE_LONG;
    binds[6].buffer = &u32;
    binds[6].buffer_length = 4;
    binds[6].is_unsigned = 1;

    long long s64{};
    binds[7].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[7].buffer = &s64;
    binds[7].buffer_length = 8;
    binds[7].is_unsigned = 0;

    unsigned long long u64{};
    binds[8].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[8].buffer = &u64;
    binds[8].buffer_length = 8;
    binds[8].is_unsigned = 1;

    char s1[255]{};
    binds[9].buffer_type = MYSQL_TYPE_STRING;
    binds[9].buffer = s1;
    binds[9].buffer_length = sizeof(s1);

    std::string s2;
    unsigned long s2_length = 0u;
    my_bool s2_truncated{};
    binds[10].buffer_type = MYSQL_TYPE_STRING;
    binds[10].buffer = s2.data();
    binds[10].buffer_length = s2_length;
    binds[10].length = &s2_length;
    binds[10].error = &s2_truncated;

    char b1[255]{};
    binds[11].buffer_type = MYSQL_TYPE_BLOB;
    binds[11].buffer = b1;
    binds[11].buffer_length = sizeof(b1);

    std::string b2;
    unsigned long b2_length = 0u;
    my_bool b2_truncated{};
    binds[12].buffer_type = MYSQL_TYPE_BLOB;
    binds[12].buffer = b2.data();
    binds[12].buffer_length = b2_length;
    binds[12].length = &b2_length;
    binds[12].error = &b2_truncated;

    float flt{};
    binds[13].buffer_type = MYSQL_TYPE_FLOAT;
    binds[13].buffer = &flt;
    binds[13].buffer_length = 4;

    double dbl{};
    binds[14].buffer_type = MYSQL_TYPE_DOUBLE;
    binds[14].buffer = &dbl;
    binds[14].buffer_length = 8;

    MYSQL_TIME dt{};
    binds[15].buffer_type = MYSQL_TYPE_DATE;
    binds[15].buffer = &dt;
    binds[15].buffer_length = sizeof(dt);

    MYSQL_TIME dtime{};
    binds[16].buffer_type = MYSQL_TYPE_DATETIME;
    binds[16].buffer = &dtime;
    binds[16].buffer_length = sizeof(dtime);

    MYSQL_TIME t{};
    binds[17].buffer_type = MYSQL_TYPE_TIME;
    binds[17].buffer = &t;
    binds[17].buffer_length = sizeof(t);

    // Ensure that nothing gets optimized away
    unsigned num_rows = 0;

    // Benchmark starts here
    auto tbegin = std::chrono::steady_clock::now();

    for (int i = 0; i < 10000; ++i)
    {
        // Execute the statement
        if (mysql_stmt_execute(stmt))
        {
            fprintf(stderr, "Error executing statement: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Bind output
        if (mysql_stmt_bind_result(stmt, binds))
        {
            fprintf(stderr, "Error binding result: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Read the rows
        while (true)
        {
            auto status = mysql_stmt_fetch(stmt);

            // On truncation, resize the buffer and read again
            if (status == MYSQL_DATA_TRUNCATED)
            {
                if (s2_length > s2.size())
                {
                    s2.resize(s2_length);
                    binds[10].buffer = s2.data();
                    binds[10].buffer_length = s2_length;
                    if (mysql_stmt_fetch_column(stmt, &binds[10], 10, 0))
                    {
                        fprintf(stderr, "Error fetching s2: %s\n", mysql_stmt_error(stmt));
                        exit(1);
                    }
                }

                if (b2_length > b2.size())
                {
                    b2.resize(b2_length);
                    binds[12].buffer = b2.data();
                    binds[12].buffer_length = b2_length;
                    if (mysql_stmt_fetch_column(stmt, &binds[12], 12, 0))
                    {
                        fprintf(stderr, "Error fetching b2: %s\n", mysql_stmt_error(stmt));
                        exit(1);
                    }
                }

                ++num_rows;
            }
            else if (status == MYSQL_NO_DATA)
            {
                break;
            }
            else if (status == 1)
            {
                fprintf(stderr, "Error fetching result: %s\n", mysql_stmt_error(stmt));
                exit(1);
            }
            else
            {
                ++num_rows;
            }
        }
    }

    // Benchmark ends here
    auto tend = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbegin).count() << std::endl;

    // Cleanup
    mysql_stmt_close(stmt);
    mysql_close(con);

    // We expect one row per iteration
    return num_rows == 10000 ? EXIT_SUCCESS : EXIT_FAILURE;
}

================================================
FILE: bench/one_big_row_libmysqlclient.cpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <cassert>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <mysql/field_types.h>
#include <mysql/mysql.h>
#include <mysql/mysql_com.h>
#include <string>

int main()
{
    // Initialize
    if (mysql_library_init(0, NULL, NULL))
    {
        fprintf(stderr, "could not initialize MySQL client library\n");
        exit(1);
    }
    MYSQL* con = mysql_init(NULL);
    if (con == NULL)
    {
        fprintf(stderr, "Error initializing connection: %s\n", mysql_error(con));
        exit(1);
    }

    // Connect
    unsigned mode = SSL_MODE_DISABLED;
    if (mysql_options(con, MYSQL_OPT_SSL_MODE, &mode))
    {
        fprintf(stderr, "Error in mysql_options: %s\n", mysql_error(con));
        exit(1);
    }

    if (mysql_real_connect(con, NULL, "root", "", "boost_mysql_bench", 0, "/var/run/mysqld/mysqld.sock", 0) ==
        NULL)
    {
        fprintf(stderr, "%s\n", mysql_error(con));
        mysql_close(con);
        exit(1);
    }

    // Prepare the statement
    MYSQL_STMT* stmt;
    stmt = mysql_stmt_init(con);
    if (!stmt)
    {
        printf("Could not initialize statement\n");
        exit(1);
    }
    constexpr const char* stmt_str = "SELECT * FROM test_data WHERE id = 1";
    if (mysql_stmt_prepare(stmt, stmt_str, strlen(stmt_str)))
    {
        fprintf(stderr, "Error preparing statement: %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    // Prepare the bind objects
    long long int out_id = 0;
    MYSQL_BIND binds[18]{};
    binds[0].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[0].buffer = &out_id;
    binds[0].buffer_length = 8;

    signed char s8{};
    binds[1].buffer_type = MYSQL_TYPE_TINY;
    binds[1].buffer = &s8;
    binds[1].buffer_length = 1;
    binds[1].is_unsigned = 0;

    unsigned char u8{};
    binds[2].buffer_type = MYSQL_TYPE_TINY;
    binds[2].buffer = &u8;
    binds[2].buffer_length = 1;
    binds[2].is_unsigned = 1;

    short s16{};
    binds[3].buffer_type = MYSQL_TYPE_SHORT;
    binds[3].buffer = &s16;
    binds[3].buffer_length = 2;
    binds[3].is_unsigned = 0;

    unsigned short u16{};
    binds[4].buffer_type = MYSQL_TYPE_SHORT;
    binds[4].buffer = &u16;
    binds[4].buffer_length = 2;
    binds[4].is_unsigned = 1;

    int s32{};
    binds[5].buffer_type = MYSQL_TYPE_LONG;
    binds[5].buffer = &s32;
    binds[5].buffer_length = 4;
    binds[5].is_unsigned = 0;

    unsigned u32{};
    binds[6].buffer_type = MYSQL_TYPE_LONG;
    binds[6].buffer = &u32;
    binds[6].buffer_length = 4;
    binds[6].is_unsigned = 1;

    long long s64{};
    binds[7].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[7].buffer = &s64;
    binds[7].buffer_length = 8;
    binds[7].is_unsigned = 0;

    unsigned long long u64{};
    binds[8].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[8].buffer = &u64;
    binds[8].buffer_length = 8;
    binds[8].is_unsigned = 1;

    char s1[255]{};
    binds[9].buffer_type = MYSQL_TYPE_STRING;
    binds[9].buffer = s1;
    binds[9].buffer_length = sizeof(s1);

    std::string s2;
    unsigned long s2_length = 0u;
    bool s2_truncated{};
    binds[10].buffer_type = MYSQL_TYPE_STRING;
    binds[10].buffer = s2.data();
    binds[10].buffer_length = s2_length;
    binds[10].length = &s2_length;
    binds[10].error = &s2_truncated;

    char b1[255]{};
    binds[11].buffer_type = MYSQL_TYPE_BLOB;
    binds[11].buffer = b1;
    binds[11].buffer_length = sizeof(b1);

    std::string b2;
    unsigned long b2_length = 0u;
    bool b2_truncated{};
    binds[12].buffer_type = MYSQL_TYPE_BLOB;
    binds[12].buffer = b2.data();
    binds[12].buffer_length = b2_length;
    binds[12].length = &b2_length;
    binds[12].error = &b2_truncated;

    float flt{};
    binds[13].buffer_type = MYSQL_TYPE_FLOAT;
    binds[13].buffer = &flt;
    binds[13].buffer_length = 4;

    double dbl{};
    binds[14].buffer_type = MYSQL_TYPE_DOUBLE;
    binds[14].buffer = &dbl;
    binds[14].buffer_length = 8;

    MYSQL_TIME dt{};
    binds[15].buffer_type = MYSQL_TYPE_DATE;
    binds[15].buffer = &dt;
    binds[15].buffer_length = sizeof(dt);

    MYSQL_TIME dtime{};
    binds[16].buffer_type = MYSQL_TYPE_DATETIME;
    binds[16].buffer = &dtime;
    binds[16].buffer_length = sizeof(dtime);

    MYSQL_TIME t{};
    binds[17].buffer_type = MYSQL_TYPE_TIME;
    binds[17].buffer = &t;
    binds[17].buffer_length = sizeof(t);

    // Ensure that nothing gets optimized away
    unsigned num_rows = 0;

    // Benchmark starts here
    auto tbegin = std::chrono::steady_clock::now();

    for (int i = 0; i < 10000; ++i)
    {
        // Execute the statement
        if (mysql_stmt_execute(stmt))
        {
            fprintf(stderr, "Error executing statement: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Bind output
        if (mysql_stmt_bind_result(stmt, binds))
        {
            fprintf(stderr, "Error binding result: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Read the rows
        while (true)
        {
            auto status = mysql_stmt_fetch(stmt);

            if (status == MYSQL_DATA_TRUNCATED)
            {
                // On truncation, resize the buffer and read again
                if (s2_length > s2.size())
                {
                    s2.resize(s2_length);
                    binds[10].buffer = s2.data();
                    binds[10].buffer_length = s2_length;
                    if (mysql_stmt_fetch_column(stmt, &binds[10], 10, 0))
                    {
                        fprintf(stderr, "Error fetching s2: %s\n", mysql_stmt_error(stmt));
                        exit(1);
                    }
                }

                if (b2_length > b2.size())
                {
                    b2.resize(b2_length);
                    binds[12].buffer = b2.data();
                    binds[12].buffer_length = b2_length;
                    if (mysql_stmt_fetch_column(stmt, &binds[12], 12, 0))
                    {
                        fprintf(stderr, "Error fetching b2: %s\n", mysql_stmt_error(stmt));
                        exit(1);
                    }
                }

                ++num_rows;
            }
            else if (status == MYSQL_NO_DATA)
            {
                break;
            }
            else if (status == 1)
            {
                fprintf(stderr, "Error fetching result: %s\n", mysql_stmt_error(stmt));
                exit(1);
            }
            else
            {
                ++num_rows;
            }
        }
    }

    // Benchmark ends here
    auto tend = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbegin).count() << std::endl;

    // Cleanup
    mysql_stmt_close(stmt);
    mysql_close(con);

    // We expect one row per iteration
    return num_rows == 10000 ? EXIT_SUCCESS : EXIT_FAILURE;
}

================================================
FILE: bench/one_small_row_boost.cpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <boost/mysql/any_connection.hpp>
#include <boost/mysql/connect_params.hpp>
#include <boost/mysql/execution_state.hpp>
#include <boost/mysql/results.hpp>
#include <boost/mysql/ssl_mode.hpp>

#include <boost/asio/io_context.hpp>

#include <chrono>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>

namespace asio = boost::asio;
namespace mysql = boost::mysql;

int main()
{
    // Setup
    asio::io_context ctx;
    mysql::any_connection conn(ctx);
    mysql::results r;

    // Connect
    mysql::connect_params params;
    params.server_address.emplace_unix_path("/var/run/mysqld/mysqld.sock");
    params.username = "root";
    params.password = "";
    params.database = "boost_mysql_bench";
    params.ssl = mysql::ssl_mode::disable;
    conn.connect(params);

    // Prepare the statement. Exclude the big TEXT/BLOB fields.
    auto stmt = conn.prepare_statement(
        "SELECT s8, u8, s16, u16, s32, u32, s64, u64, s1, b1, flt, dbl, dt, dtime, t "
        "FROM test_data WHERE id = 1"
    );

    // Ensure that nothing gets optimized away
    unsigned num_rows = 0;

    // Benchmark starts here
    auto tbegin = std::chrono::steady_clock::now();

    for (int i = 0; i < 10000; ++i)
    {
        // Since the rows are small, using execute is recommended
        conn.execute(stmt.bind(), r);
        num_rows += r.rows().size();
    }

    // Benchmark ends here
    auto tend = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbegin).count() << std::endl;

    // We expect one row per iteration
    return num_rows == 10000 ? EXIT_SUCCESS : EXIT_FAILURE;
}

================================================
FILE: bench/one_small_row_libmariadb.cpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <cassert>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <mariadb/mysql.h>

using namespace std;

int main()
{
    // Initialize
    if (mysql_library_init(0, NULL, NULL))
    {
        fprintf(stderr, "could not initialize MySQL client library\n");
        exit(1);
    }
    MYSQL* con = mysql_init(NULL);
    if (con == NULL)
    {
        fprintf(stderr, "Error initializing connection: %s\n", mysql_error(con));
        exit(1);
    }

    // Connect
    if (mysql_real_connect(con, NULL, "root", "", "boost_mysql_bench", 0, "/var/run/mysqld/mysqld.sock", 0) ==
        NULL)
    {
        fprintf(stderr, "%s\n", mysql_error(con));
        mysql_close(con);
        exit(1);
    }

    // Prepare the statement. Exclude the big TEXT/BLOB fields
    MYSQL_STMT* stmt;
    stmt = mysql_stmt_init(con);
    if (!stmt)
    {
        printf("Could not initialize statement\n");
        exit(1);
    }
    constexpr const char* stmt_str =
        "SELECT s8, u8, s16, u16, s32, u32, s64, u64, s1, b1, flt, dbl, dt, dtime, t "
        "FROM test_data WHERE id = 1";
    if (mysql_stmt_prepare(stmt, stmt_str, strlen(stmt_str)))
    {
        fprintf(stderr, "Error preparing statement: %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    // Prepare the bind objects
    MYSQL_BIND binds[15]{};

    signed char s8{};
    binds[0].buffer_type = MYSQL_TYPE_TINY;
    binds[0].buffer = &s8;
    binds[0].buffer_length = 1;
    binds[0].is_unsigned = 0;

    unsigned char u8{};
    binds[1].buffer_type = MYSQL_TYPE_TINY;
    binds[1].buffer = &u8;
    binds[1].buffer_length = 1;
    binds[1].is_unsigned = 1;

    short s16{};
    binds[2].buffer_type = MYSQL_TYPE_SHORT;
    binds[2].buffer = &s16;
    binds[2].buffer_length = 2;
    binds[2].is_unsigned = 0;

    unsigned short u16{};
    binds[3].buffer_type = MYSQL_TYPE_SHORT;
    binds[3].buffer = &u16;
    binds[3].buffer_length = 2;
    binds[3].is_unsigned = 1;

    int s32{};
    binds[4].buffer_type = MYSQL_TYPE_LONG;
    binds[4].buffer = &s32;
    binds[4].buffer_length = 4;
    binds[4].is_unsigned = 0;

    unsigned u32{};
    binds[5].buffer_type = MYSQL_TYPE_LONG;
    binds[5].buffer = &u32;
    binds[5].buffer_length = 4;
    binds[5].is_unsigned = 1;

    long long s64{};
    binds[6].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[6].buffer = &s64;
    binds[6].buffer_length = 8;
    binds[6].is_unsigned = 0;

    unsigned long long u64{};
    binds[7].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[7].buffer = &u64;
    binds[7].buffer_length = 8;
    binds[7].is_unsigned = 1;

    char s1[255]{};
    binds[8].buffer_type = MYSQL_TYPE_STRING;
    binds[8].buffer = s1;
    binds[8].buffer_length = sizeof(s1);

    char b1[255]{};
    binds[9].buffer_type = MYSQL_TYPE_BLOB;
    binds[9].buffer = b1;
    binds[9].buffer_length = sizeof(b1);

    float flt{};
    binds[10].buffer_type = MYSQL_TYPE_FLOAT;
    binds[10].buffer = &flt;
    binds[10].buffer_length = 4;

    double dbl{};
    binds[11].buffer_type = MYSQL_TYPE_DOUBLE;
    binds[11].buffer = &dbl;
    binds[11].buffer_length = 8;

    MYSQL_TIME dt{};
    binds[12].buffer_type = MYSQL_TYPE_DATE;
    binds[12].buffer = &dt;
    binds[12].buffer_length = sizeof(dt);

    MYSQL_TIME dtime{};
    binds[13].buffer_type = MYSQL_TYPE_DATETIME;
    binds[13].buffer = &dtime;
    binds[13].buffer_length = sizeof(dtime);

    MYSQL_TIME t{};
    binds[14].buffer_type = MYSQL_TYPE_TIME;
    binds[14].buffer = &t;
    binds[14].buffer_length = sizeof(t);

    // Ensure that nothing gets optimized away
    unsigned num_rows = 0;

    // Benchmark starts here
    auto tbegin = std::chrono::steady_clock::now();

    for (int i = 0; i < 10000; ++i)
    {
        // Execute the statement
        if (mysql_stmt_execute(stmt))
        {
            fprintf(stderr, "Error executing statement: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Bind output
        if (mysql_stmt_bind_result(stmt, binds))
        {
            fprintf(stderr, "Error binding result: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Read the rows
        while (true)
        {
            auto status = mysql_stmt_fetch(stmt);

            if (status == MYSQL_DATA_TRUNCATED)
            {
                // No truncation is expected here, since we don't have big strings/blobs
                fprintf(stderr, "Data truncation error\n");
                exit(1);
            }
            else if (status == MYSQL_NO_DATA)
            {
                break;
            }
            else if (status == 1)
            {
                fprintf(stderr, "Error fetching result: %s\n", mysql_stmt_error(stmt));
                exit(1);
            }
            else
            {
                ++num_rows;
            }
        }
    }

    // Benchmark ends here
    auto tend = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbegin).count() << std::endl;

    // Cleanup
    mysql_stmt_close(stmt);
    mysql_close(con);

    // We expect one row per iteration
    return num_rows == 10000 ? EXIT_SUCCESS : EXIT_FAILURE;
}

================================================
FILE: bench/one_small_row_libmysqlclient.cpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <cassert>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <mysql/field_types.h>
#include <mysql/mysql.h>
#include <mysql/mysql_com.h>

int main()
{
    // Initialize
    if (mysql_library_init(0, NULL, NULL))
    {
        fprintf(stderr, "could not initialize MySQL client library\n");
        exit(1);
    }
    MYSQL* con = mysql_init(NULL);
    if (con == NULL)
    {
        fprintf(stderr, "Error initializing connection: %s\n", mysql_error(con));
        exit(1);
    }

    // Connect
    unsigned mode = SSL_MODE_DISABLED;
    if (mysql_options(con, MYSQL_OPT_SSL_MODE, &mode))
    {
        fprintf(stderr, "Error in mysql_options: %s\n", mysql_error(con));
        exit(1);
    }

    if (mysql_real_connect(con, NULL, "root", "", "boost_mysql_bench", 0, "/var/run/mysqld/mysqld.sock", 0) ==
        NULL)
    {
        fprintf(stderr, "%s\n", mysql_error(con));
        mysql_close(con);
        exit(1);
    }

    // Prepare the statement. Exclude the big TEXT/BLOB fields
    MYSQL_STMT* stmt;
    stmt = mysql_stmt_init(con);
    if (!stmt)
    {
        printf("Could not initialize statement\n");
        exit(1);
    }
    constexpr const char* stmt_str =
        "SELECT s8, u8, s16, u16, s32, u32, s64, u64, s1, b1, flt, dbl, dt, dtime, t "
        "FROM test_data WHERE id = 1";
    if (mysql_stmt_prepare(stmt, stmt_str, strlen(stmt_str)))
    {
        fprintf(stderr, "Error preparing statement: %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    // Prepare the bind objects
    MYSQL_BIND binds[15]{};

    signed char s8{};
    binds[0].buffer_type = MYSQL_TYPE_TINY;
    binds[0].buffer = &s8;
    binds[0].buffer_length = 1;
    binds[0].is_unsigned = 0;

    unsigned char u8{};
    binds[1].buffer_type = MYSQL_TYPE_TINY;
    binds[1].buffer = &u8;
    binds[1].buffer_length = 1;
    binds[1].is_unsigned = 1;

    short s16{};
    binds[2].buffer_type = MYSQL_TYPE_SHORT;
    binds[2].buffer = &s16;
    binds[2].buffer_length = 2;
    binds[2].is_unsigned = 0;

    unsigned short u16{};
    binds[3].buffer_type = MYSQL_TYPE_SHORT;
    binds[3].buffer = &u16;
    binds[3].buffer_length = 2;
    binds[3].is_unsigned = 1;

    int s32{};
    binds[4].buffer_type = MYSQL_TYPE_LONG;
    binds[4].buffer = &s32;
    binds[4].buffer_length = 4;
    binds[4].is_unsigned = 0;

    unsigned u32{};
    binds[5].buffer_type = MYSQL_TYPE_LONG;
    binds[5].buffer = &u32;
    binds[5].buffer_length = 4;
    binds[5].is_unsigned = 1;

    long long s64{};
    binds[6].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[6].buffer = &s64;
    binds[6].buffer_length = 8;
    binds[6].is_unsigned = 0;

    unsigned long long u64{};
    binds[7].buffer_type = MYSQL_TYPE_LONGLONG;
    binds[7].buffer = &u64;
    binds[7].buffer_length = 8;
    binds[7].is_unsigned = 1;

    char s1[255]{};
    binds[8].buffer_type = MYSQL_TYPE_STRING;
    binds[8].buffer = s1;
    binds[8].buffer_length = sizeof(s1);

    char b1[255]{};
    binds[9].buffer_type = MYSQL_TYPE_BLOB;
    binds[9].buffer = b1;
    binds[9].buffer_length = sizeof(b1);

    float flt{};
    binds[10].buffer_type = MYSQL_TYPE_FLOAT;
    binds[10].buffer = &flt;
    binds[10].buffer_length = 4;

    double dbl{};
    binds[11].buffer_type = MYSQL_TYPE_DOUBLE;
    binds[11].buffer = &dbl;
    binds[11].buffer_length = 8;

    MYSQL_TIME dt{};
    binds[12].buffer_type = MYSQL_TYPE_DATE;
    binds[12].buffer = &dt;
    binds[12].buffer_length = sizeof(dt);

    MYSQL_TIME dtime{};
    binds[13].buffer_type = MYSQL_TYPE_DATETIME;
    binds[13].buffer = &dtime;
    binds[13].buffer_length = sizeof(dtime);

    MYSQL_TIME t{};
    binds[14].buffer_type = MYSQL_TYPE_TIME;
    binds[14].buffer = &t;
    binds[14].buffer_length = sizeof(t);

    // Ensure that nothing gets optimized away
    unsigned num_rows = 0;

    // Benchmark starts here
    auto tbegin = std::chrono::steady_clock::now();

    for (int i = 0; i < 10000; ++i)
    {
        // Execute the statement
        if (mysql_stmt_execute(stmt))
        {
            fprintf(stderr, "Error executing statement: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Bind output
        if (mysql_stmt_bind_result(stmt, binds))
        {
            fprintf(stderr, "Error binding result: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Read the rows
        while (true)
        {
            auto status = mysql_stmt_fetch(stmt);

            if (status == MYSQL_DATA_TRUNCATED)
            {
                // No truncation is expected here, since we don't have big strings/blobs
                fprintf(stderr, "Data truncation error\n");
                exit(1);
            }
            else if (status == MYSQL_NO_DATA)
            {
                break;
            }
            else if (status == 1)
            {
                fprintf(stderr, "Error fetching result: %s\n", mysql_stmt_error(stmt));
                exit(1);
            }
            else
            {
                ++num_rows;
            }
        }
    }

    // Benchmark ends here
    auto tend = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbegin).count() << std::endl;

    // Cleanup
    mysql_stmt_close(stmt);
    mysql_close(con);

    // We expect one row per iteration
    return num_rows == 10000 ? EXIT_SUCCESS : EXIT_FAILURE;
}

================================================
FILE: bench/stmt_params_boost.cpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <boost/mysql/any_connection.hpp>
#include <boost/mysql/blob_view.hpp>
#include <boost/mysql/connect_params.hpp>
#include <boost/mysql/date.hpp>
#include <boost/mysql/datetime.hpp>
#include <boost/mysql/execution_state.hpp>
#include <boost/mysql/results.hpp>
#include <boost/mysql/ssl_mode.hpp>
#include <boost/mysql/string_view.hpp>
#include <boost/mysql/time.hpp>

#include <boost/asio/io_context.hpp>

#include <chrono>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>

namespace asio = boost::asio;
namespace mysql = boost::mysql;

int main()
{
    // Setup
    asio::io_context ctx;
    mysql::any_connection conn(ctx);
    mysql::results r;

    // Connect
    mysql::connect_params params;
    params.server_address.emplace_unix_path("/var/run/mysqld/mysqld.sock");
    params.username = "root";
    params.password = "";
    params.database = "boost_mysql_bench";
    params.ssl = mysql::ssl_mode::disable;
    conn.connect(params);

    // Prepare the statement. It should have many parameters and be a lightweight query.
    // This SELECT is lighter than an INSERT.
    auto stmt = conn.prepare_statement(
        "SELECT id FROM test_data WHERE id = 1 AND s8 = ? AND u8 = ? AND s16 = ? AND u16 = ? AND "
        "s32 = ? AND u32 = ? AND s64 = ? AND u64 = ? AND s1 = ? AND s2 = ? AND b1 = ? AND "
        "b2 = ? AND flt = ? AND dbl = ? AND dt = ? AND dtime = ? AND t = ?"
    );

    // Statement params
    signed char s8 = 64;
    unsigned char u8 = 172;
    short s16 = -129;
    unsigned short u16 = 0xfe21;
    int s32 = 42;
    unsigned u32 = 0xfe8173;
    long long s64 = -1;
    unsigned long long u64 = 98302402;
    std::string s1(200, 'a');
    std::string s2(36000, 'b');
    std::vector<unsigned char> b1(200, 5);
    std::vector<unsigned char> b2(35000, 7);
    float flt = 3.14e10;
    double dbl = 7.1e-150;
    mysql::date dt(2010, 6, 20);
    mysql::datetime dtime(2020, 3, 21, 10, 40, 10, 123456);
    mysql::time t = std::chrono::hours(126) + std::chrono::minutes(18) + std::chrono::seconds(40) +
                    std::chrono::microseconds(123456);

    // Ensure that nothing gets optimized away
    unsigned num_rows = 0;

    // Benchmark starts here
    auto tbegin = std::chrono::steady_clock::now();

    for (int i = 0; i < 1000; ++i)
    {
        // No rows will be matched, so execute() works
        conn.execute(
            stmt.bind(
                s8,
                u8,
                s16,
                u16,
                s32,
                u32,
                s64,
                u64,
                mysql::string_view(s1),
                mysql::string_view(s2),
                mysql::blob_view(b1),
                mysql::blob_view(b2),
                flt,
                dbl,
                dt,
                dtime,
                t
            ),
            r
        );
        num_rows += r.rows().size();
    }

    // Benchmark ends here
    auto tend = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbegin).count() << std::endl;

    // We don't expect any row to be matched
    return num_rows == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

================================================
FILE: bench/stmt_params_libmariadb.cpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <cassert>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <mariadb/mysql.h>
#include <string>
#include <vector>

int main()
{
    // Initialize
    if (mysql_library_init(0, NULL, NULL))
    {
        fprintf(stderr, "could not initialize MySQL client library\n");
        exit(1);
    }
    MYSQL* con = mysql_init(NULL);
    if (con == NULL)
    {
        fprintf(stderr, "Error initializing connection: %s\n", mysql_error(con));
        exit(1);
    }

    // Connect
    if (mysql_real_connect(con, NULL, "root", "", "boost_mysql_bench", 0, "/var/run/mysqld/mysqld.sock", 0) ==
        NULL)
    {
        fprintf(stderr, "%s\n", mysql_error(con));
        mysql_close(con);
        exit(1);
    }

    // Prepare the statement. It should have many parameters and be a lightweight query.
    // This SELECT is lighter than an INSERT.
    MYSQL_STMT* stmt;
    stmt = mysql_stmt_init(con);
    if (!stmt)
    {
        printf("Could not initialize statement\n");
        exit(1);
    }
    constexpr const char* stmt_str =
        "SELECT id FROM test_data WHERE id = 1 AND s8 = ? AND u8 = ? AND s16 = ? AND u16 = ? AND "
        "s32 = ? AND u32 = ? AND s64 = ? AND u64 = ? AND s1 = ? AND s2 = ? AND b1 = ? AND "
        "b2 = ? AND flt = ? AND dbl = ? AND dt = ? AND dtime = ? AND t = ?";
    if (mysql_stmt_prepare(stmt, stmt_str, strlen(stmt_str)))
    {
        fprintf(stderr, "Error preparing statement: %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    // Statement params
    signed char s8 = 64;
    unsigned char u8 = 172;
    short s16 = -129;
    unsigned short u16 = 0xfe21;
    int s32 = 42;
    unsigned u32 = 0xfe8173;
    long long s64 = -1;
    unsigned long long u64 = 98302402;
    std::string s1(200, 'a');
    std::string s2(36000, 'b');
    std::vector<unsigned char> b1(200, 5);
    std::vector<unsigned char> b2(35000, 7);
    float flt = 3.14e10;
    double dbl = 7.1e-150;
    MYSQL_TIME dt{}, dtime{}, t{};

    dt.year = 2010;
    dt.month = 6;
    dt.day = 20;

    dtime.year = 2020;
    dtime.month = 3;
    dtime.day = 21;
    dtime.hour = 10;
    dtime.minute = 40;
    dtime.second = 10;
    dtime.second_part = 123456;

    t.hour = 126;
    t.minute = 18;
    t.second = 40;
    t.second_part = 123456;

    // Prepare the bind objects
    MYSQL_BIND in_binds[17]{};
    in_binds[0].buffer_type = MYSQL_TYPE_TINY;
    in_binds[0].buffer = &s8;
    in_binds[0].buffer_length = 1;
    in_binds[0].is_unsigned = 0;

    in_binds[1].buffer_type = MYSQL_TYPE_TINY;
    in_binds[1].buffer = &u8;
    in_binds[1].buffer_length = 1;
    in_binds[1].is_unsigned = 1;

    in_binds[2].buffer_type = MYSQL_TYPE_SHORT;
    in_binds[2].buffer = &s16;
    in_binds[2].buffer_length = 2;
    in_binds[2].is_unsigned = 0;

    in_binds[3].buffer_type = MYSQL_TYPE_SHORT;
    in_binds[3].buffer = &u16;
    in_binds[3].buffer_length = 2;
    in_binds[3].is_unsigned = 1;

    in_binds[4].buffer_type = MYSQL_TYPE_LONG;
    in_binds[4].buffer = &s32;
    in_binds[4].buffer_length = 4;
    in_binds[4].is_unsigned = 0;

    in_binds[5].buffer_type = MYSQL_TYPE_LONG;
    in_binds[5].buffer = &u32;
    in_binds[5].buffer_length = 4;
    in_binds[5].is_unsigned = 1;

    in_binds[6].buffer_type = MYSQL_TYPE_LONGLONG;
    in_binds[6].buffer = &s64;
    in_binds[6].buffer_length = 8;
    in_binds[6].is_unsigned = 0;

    in_binds[7].buffer_type = MYSQL_TYPE_LONGLONG;
    in_binds[7].buffer = &u64;
    in_binds[7].buffer_length = 8;
    in_binds[7].is_unsigned = 1;

    in_binds[8].buffer_type = MYSQL_TYPE_STRING;
    in_binds[8].buffer = s1.data();
    in_binds[8].buffer_length = s1.size();

    in_binds[9].buffer_type = MYSQL_TYPE_STRING;
    in_binds[9].buffer = s2.data();
    in_binds[9].buffer_length = s2.size();

    in_binds[10].buffer_type = MYSQL_TYPE_BLOB;
    in_binds[10].buffer = b1.data();
    in_binds[10].buffer_length = b1.size();

    in_binds[11].buffer_type = MYSQL_TYPE_BLOB;
    in_binds[11].buffer = b2.data();
    in_binds[11].buffer_length = b2.size();

    in_binds[12].buffer_type = MYSQL_TYPE_FLOAT;
    in_binds[12].buffer = &flt;
    in_binds[12].buffer_length = 4;

    in_binds[13].buffer_type = MYSQL_TYPE_DOUBLE;
    in_binds[13].buffer = &dbl;
    in_binds[13].buffer_length = 8;

    in_binds[14].buffer_type = MYSQL_TYPE_DATE;
    in_binds[14].buffer = &dt;
    in_binds[14].buffer_length = sizeof(dt);

    in_binds[15].buffer_type = MYSQL_TYPE_DATETIME;
    in_binds[15].buffer = &dtime;
    in_binds[15].buffer_length = sizeof(dtime);

    in_binds[16].buffer_type = MYSQL_TYPE_TIME;
    in_binds[16].buffer = &t;
    in_binds[16].buffer_length = sizeof(t);

    // Prepare the output bind objects (only one parameter)
    long long int out_id = 0;
    MYSQL_BIND out_binds[1]{};
    out_binds[0].buffer_type = MYSQL_TYPE_LONGLONG;
    out_binds[0].buffer = &out_id;
    out_binds[0].buffer_length = 8;

    // Ensure that nothing gets optimized away
    unsigned num_rows = 0;

    // Benchmark starts here
    auto tbegin = std::chrono::steady_clock::now();

    for (int i = 0; i < 1000; ++i)
    {
        // Bind the params
        if (mysql_stmt_bind_param(stmt, in_binds))
        {
            fprintf(stderr, "Error binding params: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Execute the statement
        if (mysql_stmt_execute(stmt))
        {
            fprintf(stderr, "Error executing statement: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Bind output
        if (mysql_stmt_bind_result(stmt, out_binds))
        {
            fprintf(stderr, "Error binding result: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Read the rows
        while (true)
        {
            auto status = mysql_stmt_fetch(stmt);
            if (status == MYSQL_DATA_TRUNCATED)
            {
                // No truncation is expected here
                fprintf(stderr, "Data truncation error\n");
                exit(1);
            }
            else if (status == MYSQL_NO_DATA)
            {
                break;
            }
            else if (status == 1)
            {
                fprintf(stderr, "Error fetching result: %s\n", mysql_stmt_error(stmt));
                exit(1);
            }
            else
            {
                ++num_rows;
            }
        }
    }

    // Benchmark ends here
    auto tend = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbegin).count() << std::endl;

    // Cleanup
    mysql_stmt_close(stmt);
    mysql_close(con);

    // We don't expect any rows to be matched
    return num_rows == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

================================================
FILE: bench/stmt_params_libmysqlclient.cpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <mysql/field_types.h>
#include <mysql/mysql.h>
#include <mysql/mysql_time.h>
#include <string>
#include <vector>

int main()
{
    // Initialize
    if (mysql_library_init(0, NULL, NULL))
    {
        fprintf(stderr, "could not initialize MySQL client library\n");
        exit(1);
    }
    MYSQL* con = mysql_init(NULL);
    if (con == NULL)
    {
        fprintf(stderr, "Error initializing connection: %s\n", mysql_error(con));
        exit(1);
    }

    // Connect
    unsigned mode = SSL_MODE_DISABLED;
    if (mysql_options(con, MYSQL_OPT_SSL_MODE, &mode))
    {
        fprintf(stderr, "Error in mysql_options: %s\n", mysql_error(con));
        exit(1);
    }

    if (mysql_real_connect(con, NULL, "root", "", "boost_mysql_bench", 0, "/var/run/mysqld/mysqld.sock", 0) ==
        NULL)
    {
        fprintf(stderr, "%s\n", mysql_error(con));
        mysql_close(con);
        exit(1);
    }

    // Prepare the statement. It should have many parameters and be a lightweight query.
    // This SELECT is lighter than an INSERT.
    MYSQL_STMT* stmt;
    stmt = mysql_stmt_init(con);
    if (!stmt)
    {
        printf("Could not initialize statement\n");
        exit(1);
    }
    constexpr const char* stmt_str =
        "SELECT id FROM test_data WHERE id = 1 AND s8 = ? AND u8 = ? AND s16 = ? AND u16 = ? AND "
        "s32 = ? AND u32 = ? AND s64 = ? AND u64 = ? AND s1 = ? AND s2 = ? AND b1 = ? AND "
        "b2 = ? AND flt = ? AND dbl = ? AND dt = ? AND dtime = ? AND t = ?";
    if (mysql_stmt_prepare(stmt, stmt_str, strlen(stmt_str)))
    {
        fprintf(stderr, "Error preparing statement: %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    // Statement params
    signed char s8 = 64;
    unsigned char u8 = 172;
    short s16 = -129;
    unsigned short u16 = 0xfe21;
    int s32 = 42;
    unsigned u32 = 0xfe8173;
    long long s64 = -1;
    unsigned long long u64 = 98302402;
    std::string s1(200, 'a');
    std::string s2(36000, 'b');
    std::vector<unsigned char> b1(200, 5);
    std::vector<unsigned char> b2(35000, 7);
    float flt = 3.14e10;
    double dbl = 7.1e-150;
    MYSQL_TIME dt{}, dtime{}, t{};

    dt.year = 2010;
    dt.month = 6;
    dt.day = 20;

    dtime.year = 2020;
    dtime.month = 3;
    dtime.day = 21;
    dtime.hour = 10;
    dtime.minute = 40;
    dtime.second = 10;
    dtime.second_part = 123456;

    t.hour = 126;
    t.minute = 18;
    t.second = 40;
    t.second_part = 123456;

    // Prepare the bind objects
    MYSQL_BIND in_binds[17]{};
    in_binds[0].buffer_type = MYSQL_TYPE_TINY;
    in_binds[0].buffer = &s8;
    in_binds[0].buffer_length = 1;
    in_binds[0].is_unsigned = 0;

    in_binds[1].buffer_type = MYSQL_TYPE_TINY;
    in_binds[1].buffer = &u8;
    in_binds[1].buffer_length = 1;
    in_binds[1].is_unsigned = 1;

    in_binds[2].buffer_type = MYSQL_TYPE_SHORT;
    in_binds[2].buffer = &s16;
    in_binds[2].buffer_length = 2;
    in_binds[2].is_unsigned = 0;

    in_binds[3].buffer_type = MYSQL_TYPE_SHORT;
    in_binds[3].buffer = &u16;
    in_binds[3].buffer_length = 2;
    in_binds[3].is_unsigned = 1;

    in_binds[4].buffer_type = MYSQL_TYPE_LONG;
    in_binds[4].buffer = &s32;
    in_binds[4].buffer_length = 4;
    in_binds[4].is_unsigned = 0;

    in_binds[5].buffer_type = MYSQL_TYPE_LONG;
    in_binds[5].buffer = &u32;
    in_binds[5].buffer_length = 4;
    in_binds[5].is_unsigned = 1;

    in_binds[6].buffer_type = MYSQL_TYPE_LONGLONG;
    in_binds[6].buffer = &s64;
    in_binds[6].buffer_length = 8;
    in_binds[6].is_unsigned = 0;

    in_binds[7].buffer_type = MYSQL_TYPE_LONGLONG;
    in_binds[7].buffer = &u64;
    in_binds[7].buffer_length = 8;
    in_binds[7].is_unsigned = 1;

    in_binds[8].buffer_type = MYSQL_TYPE_STRING;
    in_binds[8].buffer = s1.data();
    in_binds[8].buffer_length = s1.size();

    in_binds[9].buffer_type = MYSQL_TYPE_STRING;
    in_binds[9].buffer = s2.data();
    in_binds[9].buffer_length = s2.size();

    in_binds[10].buffer_type = MYSQL_TYPE_BLOB;
    in_binds[10].buffer = b1.data();
    in_binds[10].buffer_length = b1.size();

    in_binds[11].buffer_type = MYSQL_TYPE_BLOB;
    in_binds[11].buffer = b2.data();
    in_binds[11].buffer_length = b2.size();

    in_binds[12].buffer_type = MYSQL_TYPE_FLOAT;
    in_binds[12].buffer = &flt;
    in_binds[12].buffer_length = 4;

    in_binds[13].buffer_type = MYSQL_TYPE_DOUBLE;
    in_binds[13].buffer = &dbl;
    in_binds[13].buffer_length = 8;

    in_binds[14].buffer_type = MYSQL_TYPE_DATE;
    in_binds[14].buffer = &dt;
    in_binds[14].buffer_length = sizeof(dt);

    in_binds[15].buffer_type = MYSQL_TYPE_DATETIME;
    in_binds[15].buffer = &dtime;
    in_binds[15].buffer_length = sizeof(dtime);

    in_binds[16].buffer_type = MYSQL_TYPE_TIME;
    in_binds[16].buffer = &t;
    in_binds[16].buffer_length = sizeof(t);

    // Prepare the output bind objects (only one parameter)
    long long int out_id = 0;
    MYSQL_BIND out_binds[1]{};
    out_binds[0].buffer_type = MYSQL_TYPE_LONGLONG;
    out_binds[0].buffer = &out_id;
    out_binds[0].buffer_length = 8;

    // Ensure that nothing gets optimized away
    unsigned num_rows = 0;

    // Benchmark starts here
    auto tbegin = std::chrono::steady_clock::now();

    for (int i = 0; i < 1000; ++i)
    {
        // Bind the params
        if (mysql_stmt_bind_param(stmt, in_binds))
        {
            fprintf(stderr, "Error binding params: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Execute the statement
        if (mysql_stmt_execute(stmt))
        {
            fprintf(stderr, "Error executing statement: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Bind output
        if (mysql_stmt_bind_result(stmt, out_binds))
        {
            fprintf(stderr, "Error binding result: %s\n", mysql_stmt_error(stmt));
            exit(1);
        }

        // Read the rows
        while (true)
        {
            auto status = mysql_stmt_fetch(stmt);
            if (status == MYSQL_DATA_TRUNCATED)
            {
                // No truncation is expected here
                fprintf(stderr, "Data truncation error\n");
                exit(1);
            }
            else if (status == MYSQL_NO_DATA)
            {
                break;
            }
            else if (status == 1)
            {
                fprintf(stderr, "Error fetching result: %s\n", mysql_stmt_error(stmt));
                exit(1);
            }
            else
            {
                ++num_rows;
            }
        }
    }

    // Benchmark ends here
    auto tend = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbegin).count() << std::endl;

    // Cleanup
    mysql_stmt_close(stmt);
    mysql_close(con);

    // We don't expect any rows to be matched
    return num_rows == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

================================================
FILE: build.jam
================================================
# Copyright René Ferdinand Rivera Morell 2024
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)

require-b2 5.2 ;

constant boost_dependencies :
    /boost/asio//boost_asio
    /boost/assert//boost_assert
    /boost/charconv//boost_charconv
    /boost/compat//boost_compat
    /boost/config//boost_config
    /boost/container//boost_container
    /boost/core//boost_core
    /boost/describe//boost_describe
    /boost/endian//boost_endian
    /boost/intrusive//boost_intrusive
    /boost/mp11//boost_mp11
    /boost/optional//boost_optional
    /boost/pfr//boost_pfr
    /boost/system//boost_system
    /boost/throw_exception//boost_throw_exception
    /boost/variant2//boost_variant2 ;

project /boost/mysql
    : common-requirements
        <include>include
    ;

explicit
    [ alias boost_mysql : : : : <library>$(boost_dependencies) ]
    [ alias all : boost_mysql example test ]
    ;

call-if : boost-library mysql
    ;



================================================
FILE: cmake/utils.cmake
================================================
#
# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#

# Include guard
if (_BOOST_MYSQL_UTILS_INCLUDED)
    return()
endif()
set(_BOOST_MYSQL_UTILS_INCLUDED TRUE)

# Sets _WIN32_WINNT on Windows
function(boost_mysql_set_windows_version TARGET_NAME)
    if(MSVC)
        if(WIN32 AND CMAKE_SYSTEM_VERSION)
            set(WINNT_VERSION ${CMAKE_SYSTEM_VERSION})
            string(REPLACE "." "" WINNT_VERSION ${WINNT_VERSION})
            string(REGEX REPLACE "([0-9])" "0\\1" WINNT_VERSION ${WINNT_VERSION})

            set(WINNT_VERSION "0x${WINNT_VERSION}")
        else()
            set(WINNT_VERSION "0x0601")
        endif()

        target_compile_definitions(
            ${TARGET_NAME}
            PUBLIC
            _WIN32_WINNT=${WINNT_VERSION} # Silence warnings in Windows
        )
    endif()
endfunction()

# Utility function to set warnings and other compile properties of
# our test targets
function(boost_mysql_common_target_settings TARGET_NAME)
    boost_mysql_set_windows_version(${TARGET_NAME})

    if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
        target_compile_definitions(
            ${TARGET_NAME}
            PUBLIC
            _SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING # Warnings in C++17 for Asio
        )
        target_compile_options(${TARGET_NAME} PUBLIC /bigobj) # Prevent failures on Windows
    else()
        # gcc-13 doesn't understand view types
        if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0)
            target_compile_options(${TARGET_NAME} PUBLIC -Wno-dangling-reference -Wno-array-bounds)
        endif()
        target_compile_options(${TARGET_NAME} PUBLIC -Wall -Wextra)
    endif()

    set_target_properties(${TARGET_NAME} PROPERTIES CXX_EXTENSIONS OFF) # disable extensions
endfunction()

function(boost_mysql_test_target_settings TARGET_NAME)
    boost_mysql_common_target_settings(${TARGET_NAME})

    # Follow the Boost convention: don't build test targets by default,
    # and only when explicitly requested by building target tests
    set_target_properties(${TARGET_NAME} PROPERTIES EXCLUDE_FROM_ALL ON)
    add_dependencies(tests ${TARGET_NAME})
endfunction()


================================================
FILE: doc/Jamfile
================================================
#
# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#


project mysql/doc ;

import boostbook ;
import os ;
import path ;
import-search /boost/docca ;
import docca ;


# Note: adding server-specific error codes and collations to the reference
# increases build times a lot without any benefit
local doxygen_exclussions =
    detail
    impl
    mysql_server_errc.hpp
    mariadb_server_errc.hpp
    mysql_collations.hpp
    mariadb_collations.hpp
    src.hpp
;

local include-prefix = [ path.root $(__file__:D) [ path.pwd ] ] ;
include-prefix = [ path.native $(include-prefix:D)/include ] ;

docca.pyreference reference.qbk
    :
        [ glob-tree-ex ../include/boost/mysql : *.hpp : $(doxygen_exclussions) ]
    :
        <doxygen:param>PROJECT_NAME=MySQL
        <doxygen:param>PROJECT_BRIEF="C++ MySQL Client Library"
        <doxygen:param>DISTRIBUTE_GROUP_DOC=YES
        <doxygen:param>ENABLE_PREPROCESSING=YES
        <doxygen:param>MACRO_EXPANSION=YES
        <doxygen:param>EXPAND_ONLY_PREDEF=YES
        <doxygen:param>SEARCH_INCLUDES=NO
        <doxygen:param>STRIP_FROM_PATH=$(include-prefix)
        <doxygen:param>"PREDEFINED=\\
            BOOST_MYSQL_DOXYGEN \\
            __cpp_char8_t \\
            \"BOOST_PFR_ENABLED=1\" \\
            \"BOOST_PFR_CORE_NAME_ENABLED=1\" \\
            \"BOOST_DEPRECATED(a)=\" \\
            \"BOOST_ATTRIBUTE_NODISCARD=[[nodiscard]]\" \\
            \"BOOST_ASIO_INITFN_RESULT_TYPE(t,a)=auto\" \\
            \"BOOST_ASIO_COMPLETION_TOKEN_FOR(sig)=class\" \\
            \"BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct,sig)=auto\" \\
            \"BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(ex)=\" \\
            \"BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(ex)=\" \\
            \"BOOST_MYSQL_RETURN_TYPE(...)=\" \\
            \"protected=private\" \\
            \"BOOST_CXX14_CONSTEXPR=constexpr\" \\
            \"BOOST_INLINE_CONSTEXPR=inline constexpr\" \\
            \"BOOST_MYSQL_CONSTEVAL=consteval\" \\
            \"BOOST_MYSQL_CXX14\" \\
            \"BOOST_MYSQL_WRITABLE_FIELD_TUPLE=class\" \\
            \"BOOST_MYSQL_FIELD_VIEW_FORWARD_ITERATOR=class\" \\
            \"BOOST_MYSQL_EXECUTION_REQUEST=class\" \\
            \"BOOST_MYSQL_RESULTS_TYPE=class\" \\
            \"BOOST_MYSQL_EXECUTION_STATE_TYPE=class\" \\
            \"BOOST_MYSQL_OUTPUT_STRING=class\" \\
            \"BOOST_MYSQL_FORMATTABLE=class\" \\
            \"BOOST_MYSQL_STATIC_ROW=class\" \\
            \"BOOST_MYSQL_PIPELINE_REQUEST_TYPE=class\" \\
            \"BOOST_MYSQL_PIPELINE_STAGE_TYPE=class\" \\
            \"BOOST_MYSQL_WRITABLE_FIELD=class\" \\
            \"BOOST_MYSQL_DECL=\" \\
            \"BOOST_MYSQL_HAS_LOCAL_TIME=\" \\
            \"BOOST_NO_CXX17_DEDUCTION_GUIDES=\" \\
            "
        <doxygen:param>SKIP_FUNCTION_MACROS=NO
        <doxygen:param>OUTPUT_LANGUAGE=English
        <doxygen:param>ABBREVIATE_BRIEF=
        <doxygen:param>AUTOLINK_SUPPORT=NO
        <doxygen:param>EXTRACT_ALL=NO
        <doxygen:param>EXTRACT_PRIVATE=NO
        <doxygen:param>EXTRACT_LOCAL_CLASSES=NO
        <doxygen:param>HIDE_UNDOC_MEMBERS=YES
        <doxygen:param>HIDE_UNDOC_CLASSES=YES
        <doxygen:param>HIDE_FRIEND_COMPOUNDS=YES
        <doxygen:param>CASE_SENSE_NAMES=YES
        <doxygen:param>SHOW_INCLUDE_FILES=NO
        <doxygen:param>INLINE_INFO=NO
        <doxygen:param>SORT_MEMBER_DOCS=NO
        <doxygen:param>SORT_MEMBERS_CTORS_1ST=YES
        <doxygen:param>SHOW_USED_FILES=NO
        <doxygen:param>SHOW_FILES=NO
        <doxygen:param>SHOW_NAMESPACES=NO
        <doxygen:param>QUIET=YES

        <docca:config>config.json
    ;

install images
    :
        [ glob images/*.png images/*.svg ]
    :
        <location>html/mysql/images
    ;

explicit images ;

xml mysql_doc
    :
        qbk/00_main.qbk
    :
        <dependency>reference.qbk
        <dependency>images
    ;

explicit mysql_doc ;


boostbook mysql
    :
        mysql_doc
    :
        <xsl:param>boost.root=../../../..
        <xsl:param>chapter.autolabel=1
        <xsl:param>chunk.section.depth=8                # Depth to which sections should be chunked
        <xsl:param>chunk.first.sections=1               # Chunk the first top-level section?
        <xsl:param>toc.section.depth=8                  # How deep should recursive sections appear in the TOC?
        <xsl:param>toc.max.depth=8                      # How many levels should be created for each TOC?
        <xsl:param>generate.toc="chapter toc,title section nop reference nop part toc"
        <include>../../../tools/boostbook/dtd
    :
        <dependency>images
    ;

# These are used to inform the build system of the
# means to build the integrated and stand-alone docs.

alias boostdoc ;
explicit boostdoc ;

alias boostrelease : mysql ;
explicit boostrelease ;


================================================
FILE: doc/config.json
================================================
{
    "include_private": false,
    "legacy_behavior": false,
    "external_marker": "!EXTERNAL!",
    "link_prefix": "mysql.ref.",
    "default_namespace": "boost::mysql",
    "convenience_header": "boost/mysql.hpp",
    "replace_strings": {
        "__see_below__": "``['see-below]``",
        "\\bclass CompletionToken\\b": "class __CompletionToken__",
        "\\bclass ExecutionContext\\b": "class __ExecutionContext__",
        "\\bclass ExecutionRequest\\b": "class __ExecutionRequest__",
        "\\bclass ExecutionStateType\\b": "class __ExecutionStateType__",
        "\\bclass Executor\\b": "class __Executor__",
        "\\bclass FieldViewFwdIterator\\b": "class __FieldViewFwdIterator__",
        "\\bclass Formattable\\b": "class __Formattable__",
        "\\bclass OutputString\\b": "class __OutputString__",
        "\\bclass ResultsType\\b": "class __ResultsType__",
        "\\bclass SocketStream\\b": "class __SocketStream__",
        "\\bclass StaticRow\\b": "class __StaticRow__",
        "\\bclass Stream\\b": "class __Stream__",
        "\\bclass WritableField\\b": "class __WritableField__",
        "\\bclass WritableFieldTuple\\b": "class __WritableFieldTuple__",
        "\\bBOOST_MYSQL_FORMATTABLE\\b": "class"
    }
}

================================================
FILE: doc/doxygen.hpp
================================================
//
// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef BOOST_MYSQL_DOC_DOXYGEN_HPP
#define BOOST_MYSQL_DOC_DOXYGEN_HPP

/**
 * \brief brief
 * \details
 * description
 *
 * \par Preconditions
 * Only for functions, if they have a precondition (i.e. assert(xxx))
 *
 * \par Exception safety
 * No-throw guarantee.
 * Only for functions. Don't include it in network operations for now.
 * Strong guarantee.
 * Basic guarantee.
 * No-throw guarantee.
 * \throws {exception} {condition}.
 *
 * \par Object lifetimes
 * For async stuff or if the function returns views
 *
 * \par Complexity
 * Include it only for functions in containers or where relevant.
 *      Linear in xxxx.
 *
 * (Include only for async ops)
 * \par Handler signature
 * The handler signature for this operation is `void(boost::mysql::error_code)`
 *
 * \par Per-operation cancellation
 * This operation supports per-operation cancellation. <Describe effects>
 * The following `asio::cancellation_type_t` values are supported:
 *
 *   - `asio::cancellation_type_t::terminal`
 *   - `asio::cancellation_type_t::partial`
 *   - `asio::cancellation_type_t::total`
 *
 * Specify this where it adds any value.
 * \par Thread safety
 * Distinct objects: safe. \n
 * Shared objects: unsafe. \n
 *
 * Specify this for new async operations. Include the error codes that we may return.
 * \par Errors
 * \li \ref client_errc::X when condition Y
 */

#endif


================================================
FILE: doc/qbk/00_main.qbk
================================================
[/
    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
   
    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

[library Boost.MySQL
    [quickbook 1.7]
    [copyright 2019 - 2024 Ruben Perez]
    [id mysql]
    [purpose MySQL client library]
    [license
        Distributed under the Boost Software License, Version 1.0.
        (See accompanying file LICENSE_1_0.txt or copy at
        [@http://www.boost.org/LICENSE_1_0.txt])
    ]
    [authors [Perez, Ruben]]
    [category template]
    [category generic]
]

[template nochunk[] [block '''<?dbhtml stop-chunking?>''']]
[template mdash[] '''&mdash; ''']
[template link_to_file[path][^'''<ulink url="https://github.com/boostorg/mysql/blob/master/'''[path]'''">'''[path]'''</ulink>''']]
[template include_file[path][^<'''<ulink url="https://github.com/boostorg/mysql/blob/master/include/'''[path]'''">'''[path]'''</ulink>'''>]]
[template indexterm1[term1] '''<indexterm><primary>'''[term1]'''</primary></indexterm>''']
[template indexterm2[term1 term2] '''<indexterm><primary>'''[term1]'''</primary><secondary>'''[term2]'''</secondary></indexterm>''']

[template reflink2[id text][link mysql.ref.boost__mysql__[id] [^[text]]]]
[template reflink[id][reflink2 [id] [id]]]
[template refmem[class mem][reflink2 [class].[mem] [class]::[mem]]]
[template refmemunq[class mem][reflink2 [class].[mem] [mem]]]
[template asioreflink[id term][@boost:/doc/html/boost_asio/reference/[id].html [^asio::[term]]]]
[template mysqllink[id text][@https://dev.mysql.com/doc/refman/8.0/en/[id] [text]]]

[def __CompletionToken__ [@boost:/doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.completion_tokens_and_handlers ['CompletionToken]]]
[def __ExecutionContext__ [@boost:/doc/html/boost_asio/reference/ExecutionContext.html ['ExecutionContext]]]
[def __ExecutionRequest__ [reflink2 ExecutionRequest ['ExecutionRequest]]]
[def __ExecutionStateType__ [reflink2 ExecutionStateType ['ExecutionStateType]]]
[def __Executor__ [@boost:/doc/html/boost_asio/reference/Executor1.html ['Executor]]]
[def __FieldViewFwdIterator__ [reflink2 FieldViewFwdIterator ['FieldViewFwdIterator]]]
[def __Formattable__ [reflink2 Formattable ['Formattable]]]
[def __OutputString__ [reflink2 OutputString ['OutputString]]]
[def __ResultsType__ [reflink2 ResultsType ['ResultsType]]]
[def __SocketStream__ [reflink2 SocketStream ['SocketStream]]]
[def __StaticRow__ [reflink2 StaticRow ['StaticRow]]]
[def __Stream__ [reflink2 Stream ['Stream]]]
[def __WritableField__ [reflink2 WritableFieldTuple ['WritableField]]]
[def __WritableFieldTuple__ [reflink2 WritableFieldTuple ['WritableFieldTuple]]]


[def __Boost__ [@https://www.boost.org/ Boost]]
[def __Asio__ [@boost:/libs/asio/index.html Boost.Asio]]
[def __Beast__ [@boost:/libs/beast/index.html Boost.Beast]]
[def __Context__ [@boost:/libs/context/index.html Boost.Context]]
[def __Self__ [@boost:/libs/mysql/index.html Boost.MySQL]]
[def __boost_optional__ [@boost:/libs/optional/index.html `boost::optional`]]
[def __Describe__ [@boost:/libs/describe/index.html Boost.Describe]]
[def __Pfr__ [@boost:/libs/pfr/index.html Boost.Pfr]]
[def __ssl_context__ [asioreflink ssl__context ssl::context]]

[/ MySQL stuff]
[def __Mysql__ [@https://www.mysql.com/ MySQL]]
[def __sql_mode__ [mysqllink sql-mode.html `sql_mode`]]
[def __allow_invalid_dates__ [mysqllink sql-mode.html#sqlmode_allow_invalid_dates `ALLOW_INVALID_DATES`]]
[def __strict_sql__ [mysqllink sql-mode.html#sql-mode-strict strict SQL mode]]
[def __time_zone__ [mysqllink server-system-variables.html#sysvar_time_zone `time_zone`]]
[def __TINYINT__ [mysqllink integer-types.html `TINYINT`]]
[def __SMALLINT__ [mysqllink integer-types.html `SMALLINT`]]
[def __MEDIUMINT__ [mysqllink integer-types.html `MEDIUMINT`]]
[def __INT__ [mysqllink integer-types.html `INT`]]
[def __BIGINT__ [mysqllink integer-types.html `BIGINT`]]
[def __YEAR__ [mysqllink year.html `YEAR`]]
[def __DATE__ [mysqllink datetime.html `DATE`]]
[def __DATETIME__ [mysqllink datetime.html `DATETIME`]]
[def __TIMESTAMP__ [mysqllink datetime.html `TIMESTAMP`]]
[def __TIME__ [mysqllink time.html `TIME`]]
[def __FLOAT__ [mysqllink floating-point-types.html `FLOAT`]]
[def __DOUBLE__ [mysqllink floating-point-types.html `DOUBLE`]]
[def __DECIMAL__ [mysqllink fixed-point-types.html `DECIMAL`]]
[def __NUMERIC__ [mysqllink fixed-point-types.html `NUMERIC`]]
[def __BIT__ [mysqllink bit-type.html `BIT`]]
[def __CHAR__ [mysqllink char.html `CHAR`]]
[def __VARCHAR__ [mysqllink char.html `VARCHAR`]]
[def __BINARY__ [mysqllink binary-varbinary.html `BINARY`]]
[def __VARBINARY__ [mysqllink binary-varbinary.html `VARBINARY`]]
[def __TEXT__ [mysqllink blob.html `TEXT`]]
[def __BLOB__ [mysqllink blob.html `BLOB`]]
[def __ENUM__ [mysqllink enum.html `ENUM`]]
[def __SET__ [mysqllink set.html `SET`]]
[def __JSON__ [mysqllink json.html `JSON`]]
[def __GEOMETRY__ [mysqllink spatial-type-overview.html `GEOMETRY`]]
[def __USE__ [mysqllink use.html `USE`]]

[/  Taken db_setup.sql, because import doesn't work for SQL files - keep in sync.
    Having them in a separate file doesn't work ]
[def __sp_get_employees__
```
CREATE PROCEDURE get_employees(IN pin_company_id CHAR(10))
BEGIN
    START TRANSACTION READ ONLY;
    SELECT id, name, tax_id FROM company WHERE id = pin_company_id;
    SELECT first_name, last_name, salary FROM employee WHERE company_id = pin_company_id;
    COMMIT;
END
```]

[def __sp_create_employee__
```
CREATE PROCEDURE create_employee(
    IN  pin_company_id CHAR(10),
    IN  pin_first_name VARCHAR(100),
    IN  pin_last_name VARCHAR(100),
    OUT pout_employee_id INT
)
BEGIN
    START TRANSACTION;
    INSERT INTO employee (company_id, first_name, last_name)
        VALUES (pin_company_id, pin_first_name, pin_last_name);
    SET pout_employee_id = LAST_INSERT_ID();
    INSERT INTO audit_log (msg) VALUES ('Created new employee...');
    COMMIT;
END
```]

[/ AUTOGENERATED IMPORTS BEGIN ]
[import ../../example/1_tutorial/1_sync.cpp]
[import ../../example/1_tutorial/2_async.cpp]
[import ../../example/1_tutorial/3_with_params.cpp]
[import ../../example/1_tutorial/4_static_interface.cpp]
[import ../../example/1_tutorial/5_updates_transactions.cpp]
[import ../../example/1_tutorial/6_connection_pool.cpp]
[import ../../example/1_tutorial/7_error_handling.cpp]
[import ../../example/2_simple/inserts.cpp]
[import ../../example/2_simple/deletes.cpp]
[import ../../example/2_simple/prepared_statements.cpp]
[import ../../example/2_simple/disable_tls.cpp]
[import ../../example/2_simple/tls_certificate_verification.cpp]
[import ../../example/2_simple/metadata.cpp]
[import ../../example/2_simple/multi_function.cpp]
[import ../../example/2_simple/callbacks.cpp]
[import ../../example/2_simple/coroutines_cpp11.cpp]
[import ../../example/2_simple/unix_socket.cpp]
[import ../../example/2_simple/batch_inserts.cpp]
[import ../../example/2_simple/batch_inserts_generic.cpp]
[import ../../example/2_simple/dynamic_filters.cpp]
[import ../../example/2_simple/patch_updates.cpp]
[import ../../example/2_simple/source_script.cpp]
[import ../../example/2_simple/pipeline.cpp]
[import ../../example/3_advanced/http_server_cpp20/main.cpp]
[import ../../example/3_advanced/http_server_cpp20/types.hpp]
[import ../../example/3_advanced/http_server_cpp20/error.hpp]
[import ../../example/3_advanced/http_server_cpp20/error.cpp]
[import ../../example/3_advanced/http_server_cpp20/repository.hpp]
[import ../../example/3_advanced/http_server_cpp20/repository.cpp]
[import ../../example/3_advanced/http_server_cpp20/handle_request.hpp]
[import ../../example/3_advanced/http_server_cpp20/handle_request.cpp]
[import ../../example/3_advanced/http_server_cpp20/server.hpp]
[import ../../example/3_advanced/http_server_cpp20/server.cpp]
[import ../../example/3_advanced/http_server_cpp14_coroutines/main.cpp]
[import ../../example/3_advanced/http_server_cpp14_coroutines/types.hpp]
[import ../../example/3_advanced/http_server_cpp14_coroutines/repository.hpp]
[import ../../example/3_advanced/http_server_cpp14_coroutines/repository.cpp]
[import ../../example/3_advanced/http_server_cpp14_coroutines/handle_request.hpp]
[import ../../example/3_advanced/http_server_cpp14_coroutines/handle_request.cpp]
[import ../../example/3_advanced/http_server_cpp14_coroutines/server.hpp]
[import ../../example/3_advanced/http_server_cpp14_coroutines/server.cpp]
[import ../../test/integration/test/snippets/prepared_statements.cpp]
[import ../../test/integration/test/snippets/sql_formatting_advanced.cpp]
[import ../../test/integration/test/snippets/connection_establishment.cpp]
[import ../../test/integration/test/snippets/charsets.cpp]
[import ../../test/integration/test/snippets/multi_function.cpp]
[import ../../test/integration/test/snippets/tutorials.cpp]
[import ../../test/integration/test/snippets/text_queries.cpp]
[import ../../test/integration/test/snippets/templated_connection.cpp]
[import ../../test/integration/test/snippets/metadata.cpp]
[import ../../test/integration/test/snippets/connection_pool.cpp]
[import ../../test/integration/test/snippets/time_types.cpp]
[import ../../test/integration/test/snippets/interfacing_sync_async.cpp]
[import ../../test/integration/test/snippets/pipeline.cpp]
[import ../../test/integration/test/snippets/dynamic_interface.cpp]
[import ../../test/integration/test/snippets/overview.cpp]
[import ../../test/integration/test/snippets/static_interface.cpp]
[import ../../test/integration/test/snippets/multi_resultset.cpp]
[import ../../test/integration/test/snippets/sql_formatting_advanced_2.cpp]
[/ AUTOGENERATED IMPORTS END ]
[import ../../test/integration/include/test_integration/snippets/describe.hpp]

[include 01_intro.qbk]
[include 02_integrating.qbk]
[include 03_1_tutorial_sync.qbk]
[include 03_2_tutorial_async.qbk]
[include 03_3_tutorial_with_params.qbk]
[include 03_4_tutorial_static_interface.qbk]
[include 03_5_tutorial_updates_transactions.qbk]
[include 03_6_tutorial_connection_pool.qbk]
[include 03_7_tutorial_error_handling.qbk]
[include 04_overview.qbk]
[include 05_connection_establishment.qbk]
[include 06_text_queries.qbk]
[include 07_prepared_statements.qbk]
[include 08_dynamic_interface.qbk]
[include 09_static_interface.qbk]
[include 10_multi_resultset.qbk]
[include 11_multi_function.qbk]
[include 12_connection_pool.qbk]
[include 13_async.qbk]
[include 13_1_interfacing_sync_async.qbk]
[include 14_error_handling.qbk]
[include 15_sql_formatting_advanced.qbk]
[include 16_metadata.qbk]
[include 17_charsets.qbk]
[include 18_time_types.qbk]
[include 19_templated_connection.qbk]
[include 20_pipeline.qbk]
[include 20_1_benchmarks.qbk]
[include 21_examples.qbk]



[section:ref Reference]
[xinclude helpers/quickref.xml]
[block'''<part label="Two: Reference">''']
[include reference.qbk]
[include helpers/ExecutionRequest.qbk]
[include helpers/ExecutionStateType.qbk]
[include helpers/FieldViewFwdIterator.qbk]
[include helpers/Formattable.qbk]
[include helpers/OutputString.qbk]
[include helpers/ResultsType.qbk]
[include helpers/SocketStream.qbk]
[include helpers/StaticRow.qbk]
[include helpers/Stream.qbk]
[include helpers/WritableFieldTuple.qbk]
[block'''</part>''']
[endsect]


================================================
FILE: doc/qbk/01_intro.qbk
================================================
[/
    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
   
    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

[section:intro Introduction]
[nochunk]

__Self__ is a C++11 client for the __Mysql__ and [@https://mariadb.com/ MariaDB] database servers, based on __Asio__.

[heading Motivation]

MySQL and MariaDB are widespread SQL database servers. MySQL
clients connect to the server in order to issue SQL queries. For this
purpose, MySQL employs a dedicated protocol. __Self__ is an
implementation of the client side of this protocol.

This library is a full implementation of the
[@https://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_PROTOCOL.html MySQL client/server protocol].
It aims to expose the protocol primitives in an efficient but easy-to-use way.
It is similar in scope to the official [@https://dev.mysql.com/doc/c-api/8.0/en/ libmysqlclient],
but interoperable with Asio, safer and more expressive. Note that __Self__
[*does not use libmysqlclient]: it's a full implementation of the MySQL protocol, which makes
it natively compatible with Asio.

This library is relatively low level. It gives you access to text SQL queries and
prepared statements. Don't expect an ORM. [link mysql.overview This section] presents a quick tour
over the main library capabilities.

The design goals of this library are:

* [*Interoperability with Asio]: this library employs the same principles as __Asio__ and __Beast__.
  Users of any of these libraries will immediately understand Boost.MySQL, and will have it easy
  to integrate it in their programs.
* [*Basis for further abstraction]: it allows efficient access to the MySQL client/server protocol
  so it can be used by higher level components as a building block. Do a single thing and do it well.
* [*Efficiency].
* [*Ease of use]: the MySQL protocol is full of pitfalls. We believe in simplicity. While retaining
  control over the important parts, the library hides as much complexity from the protocol as possible.

Non-goals:

* [*Being an ORM].
* [*Being a SQL query generator]. The library doesn't focus on utilities to generate queries.
  Don't expect syntax sugar like `table("orders").select(["id", "quantity"]).where("id", 42)`.
* [*Portability to other SQL databases]. This library focuses on MySQL. It won't work with Postgres
  or SQLite.

[heading When to use]

If any of the following statements is true, you may consider using __Self__:

* Your application uses __Asio__ and you need to access a MySQL server.
* You need asynchronous access to a MySQL server from a C++ application.
* You need efficient access to a MySQL server from a C++ application.
* You need a BSL-licensed library to access your MySQL server.
* You are writing a higher-level database access library, like an ORM.

Use cases may include web servers, ETL processes and IoT systems.

It may not be a good fit for you if:

* You only need synchronous access to a MySQL server and efficiency doesn't matter
  to your application. The official client libraries may be better suited for you, in this case.
* You need homogeneous SQL access to different SQL databases (and not only MySQL access).
  You may find more value in using [@https://github.com/rbock/sqlpp11 sqlpp11] or a similar wrapper
  library.



[heading Tested compilers and systems]

Boost.MySQL is tested under the following compilers:

* gcc 5.4 to gcc 15.0 (Linux)
* clang 4 to clang 20.0 (Linux)
* Apple clang 14.0 (OSX)
* MSVC 14.1 - Visual Studio 2017 (Windows)
* MSVC 14.2 - Visual Studio 2019 (Windows)
* MSVC 14.3 - Visual Studio 2022 (Windows)

And with the following RDBMS systems:

* MySQL v5.7.41.
* MySQL v8.4.1.
* MariaDB v11.4.2.

[heading Acknowledgements]

I would like to specially acknowledge [@https://github.com/madmongo1 Richard Hodges] (hodges.r@gmail.com)
for his invaluable technical guidance during development. Thanks also to
Christian Mazakas for his ideas in early stages, and to
[@https://github.com/klemens-morgenstern Klemens Morgenstern] and
and [@https://github.com/vinniefalco Vinnie Falco] for his technical advice.
Without you, this library would not exist.

Finally, thanks to [@https://github.com/chriskohlhoff Christopher Kohlhoff]
for his awesome __Asio__ library, and to [@https://github.com/HowardHinnant
Howard Hinnant] for his date algorithms, shamelessly copied in this lib.


[endsect] [/intro]

================================================
FILE: doc/qbk/02_integrating.qbk
================================================
[/
    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
   
    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

[section:integrating Integrating Boost.MySQL into your project]
[nochunk]

[note
    [*Breaking change in Boost 1.85]: the compiled library Boost.Charconv is now required.
    If you're upgrading and getting linker errors, link your executable to the `Boost::charconv`
    CMake target.
]

[section:header_only Header-only mode]

The easiest way to start using the library is header-only mode (the default).
You will need the following:

* A C++11 compiler (like gcc >=5.4, clang >=3.6, or Visual Studio 2017 or higher).
* The Boost headers and Boost.Charconv. You can obtain them following the official installation instructions
for [@boost:/more/getting_started/unix-variants.html UNIX-like systems] and for
[@boost:/more/getting_started/windows.html Windows], or from a package manager.
Note that Boost.MySQL does not work with the standalone version of __Asio__.
* The OpenSSL headers and libraries. We recommend using your system package manager to obtain them.
* CMake.

Use the following `CMakeLists.txt`, replacing `main.cpp` with your project's source files:

[!teletype]
```
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)
```

[note
    `Boost::charconv` is only available in Boost 1.85 and higher. If you're using
    an older version, use the `Boost::headers` target, instead.
]

If you're happy with header-only mode, have a look at [link mysql.tutorial_sync the first tutorial]
or [link mysql.examples any of the examples] to learn how to use the library.

[endsect]



[section:separate_compilation Separate compilation mode]

Header-only mode is simple but can make your project's build times high.
If this is the case, we recommend switching to separate compilation mode.

To use it, you must add the following to exactly one `.cpp` file:

```
// Contents of boost_mysql.cpp

// This header file contains all Boost.MySQL implementations.
// It should be included in exactly one .cpp file.
// All code using Boost.MySQL in separate build mode, including this file,
// should define BOOST_MYSQL_SEPARATE_COMPILATION.
#include <boost/mysql/src.hpp>
```

All of your code, including this `.cpp` file, should define the 
`BOOST_MYSQL_SEPARATE_COMPILATION` macro. This is what your `CMakeLists.txt`
could look like:

[!teletype]
```
project(boost_mysql_example LANGUAGES CXX)

find_package(Boost REQUIRED COMPONENTS charconv)
find_package(Threads REQUIRED)
find_package(OpenSSL REQUIRED)

add_executable(
    main
    # Contains Boost.MySQL sources via #include <boost/mysql/src.hpp>
    boost_mysql.cpp
    # List any other .cpp your exe has here
    main.cpp
)
target_link_libraries(main PRIVATE Boost::charconv Threads::Threads OpenSSL::Crypto OpenSSL::SSL)

# 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)
```

Boost.Asio and Boost.Beast offer a very similar separate compilation mode.
If you're using them together with Boost.MySQL, you may consider enabling separate compilation
for them, too.

[endsect]

[endsect]

================================================
FILE: doc/qbk/03_1_tutorial_sync.qbk
================================================
[/
    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
   
    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

[section:tutorial_sync Tutorial 1: hello world!]

In this first tutorial, we will write a simple program
to demonstrate the basic concepts. We will connect to the server
and issue the query `SELECT "Hello World!"`.

To run this tutorial, you need a running MySQL server listening
in localhost on port 3306 (the default one). You should have
the credentials of a valid MySQL user (username and password).
No further setup is needed.

The full program listing for this tutorial can be found [link mysql.examples.tutorial_sync here].

We will follow these steps:

# Create a connection object.
# Establish a session with the server.
# Issue the query.
# Use the rows generated by the query.
# Close the connection.

This tutorial uses synchronous functions with exceptions,
as they're easy to use. In subsequent tutorials, we will
learn how to use asynchronous functions, which are more versatile.

[heading Namespace conventions]

All functions and classes reside within the `boost::mysql` namespace.
To reduce verbosity, all examples and code samples use the following namespace aliases:

[tutorial_sync_namespaces]




[heading Connection object]

Like most Asio-based applications, we need to create a
[asioreflink io_context io_context] object before anything else.
An `io_context` is an execution context: it contains an event loop,
file descriptor states, timers and other items required to perform I/O.
Most applications should only create a single `io_context`, even when
multiple MySQL connections are needed.

We then create an [reflink any_connection], which represents a single connection
to a MySQL server:

[tutorial_sync_connection]




[heading Connecting to the server]

[refmem any_connection connect] establishes a client session with the server.
It takes a [reflink connect_params] object with the required
information to establish a session:

[tutorial_sync_connect]




[heading Issuing the SQL query]

[refmem any_connection execute] accepts a string containing
the SQL query to run and sends it to the server for execution.
It returns a [reflink results] object, containing the rows returned by the query:

[tutorial_sync_query]




[heading Obtaining the results]

[reflink results] is a class that holds the result of a query in memory.
To obtain the value we selected, we can write:

[tutorial_sync_results]

Let's break this into steps:

* [refmem results rows] returns all the rows that this object contains.
  It returns a [reflink rows_view], which is a 2D matrix-like structure.
* `result.rows().at(0)` returns the first row, represented as a [reflink row_view].
* `result.rows().at(0).at(0)` returns the first field in the first row. This is a
  [reflink field_view], a variant-like class that can hold any type allowed in MySQL.
* The obtained `field_view` is streamed to `std::cout`.




[heading Closing the connection]

Once we are done with the connection, we can close it by calling
[refmem any_connection close]. Note that
this will send a final quit packet to the MySQL server to notify
we are closing the connection, and thus may fail.

[tutorial_sync_close]




[heading Next steps]

Full program listing for this tutorial is [link mysql.examples.tutorial_sync here].

You can now proceed to [link mysql.tutorial_async the next tutorial].

[endsect]

================================================
FILE: doc/qbk/03_2_tutorial_async.qbk
================================================
[/
    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
   
    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

[section:tutorial_async Tutorial 2: going async with C++20 coroutines]

In the [link mysql.tutorial_sync previous tutorial] we used
synchronous functions. They are simple, but have a number of limitations:

* They aren't as versatile as async functions. For example, there is no way
  to set a timeout to a sync operation.
* They don't scale well. Since sync functions block the calling thread until they complete,
  you need to create OS threads to achieve parallelism. This doesn't scale well
  and leads to the inherent complexities of multi-threaded programs.
* Some classes (like [reflink connection_pool]) only offer an async interface.

For this reason, we recommend to always use async functions.
All Asio-compatible libraries (including this one) allow async
programming using a variety of styles. In this chapter, we will
explain how to use C++20 coroutines because they are the simplest to use.

[note
  Still not using C++20? Don't worry, you can use
  [link mysql.examples.coroutines_cpp11 stackful coroutines] and
  [link mysql.examples.callbacks callbacks] even in C++11.
]



[heading What is a coroutine?]

Roughly speaking, it's a function that can suspend and resume, keeping local variables
alive in the process. Suspension happens when reaching a `co_await` expression.
These usually appear when the program performs an I/O operation.
When an expression like this is encountered, the following happens:

# The coroutine initiates the I/O operation.
# The coroutine suspends, passing control back to the `io_context` (that is, the event loop).
# While the I/O operation is in progress, the `io_context` may run other operations,
  like other coroutines.
# When the I/O operation completes, the `io_context` resumes the coroutine
  immediately after the `co_await` expression.





[heading Transforming sync code into coroutines]

Recall the following code from our previous tutorial:

[tutorial_sync_main]

To transform this code into a coroutine, we need to:

* Extract it to a separate function returning `boost::asio::awaitable<void>`.
* Replace sync functions (like [refmem any_connection connect]) by async ones
  (like [refmem any_connection async_connect]).
* Place a `co_await` operator in front of each I/O operation.

Doing this, we have:

[tutorial_async_coro]

Note that the coroutine doesn't create or return explicitly any
`boost::asio::awaitable<void>` object - this is handled by the compiler.
The return type actually marks the function as being a coroutine.
`void` here means that the coroutine doesn't return anything.

If any of the above I/O operations fail, an exception is thrown.
You can prevent this by [link mysql.overview.errors using `asio::redirect_error`].




[heading Running our coroutine]

As in the previous tutorial, we first need to create an `io_context` and a connection:

[tutorial_async_connection]

To run a coroutine, use [asioreflink co_spawn co_spawn]:

[tutorial_async_co_spawn]

Note that this will only schedule the coroutine. To actually run
it, we need to call `io_context::run`. This will block the calling
thread until all the scheduled coroutines and I/O operations complete:

[tutorial_async_run]





[heading Next steps]

Full program listing for this tutorial is [link mysql.examples.tutorial_async here].

You can now proceed to [link mysql.tutorial_with_params the next tutorial].

[endsect]

================================================
FILE: doc/qbk/03_3_tutorial_with_params.qbk
================================================
[/
    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
   
    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

[section:tutorial_with_params Tutorial 3: queries with parameters]

Until now, our SQL queries were hard-coded string literals.
However, most real-world use cases involve 
running queries containing user-supplied parameters.

In this tutorial, we will be using an employee database.
You can obtain this sample database by sourcing the `example/db_setup.sql`
file in Boost.MySQL source code repository.

The employee table is defined as:

[!teletype]
```
    CREATE TABLE employee(
        id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
        first_name VARCHAR(100) NOT NULL,
        last_name VARCHAR(100) NOT NULL,
        ... -- other fields not relevant for us
    );
```

We will write a program that retrieves an employee by ID
and prints their full name. The employee ID will be supplied
by the user as a command line argument. In more realistic
examples, you may get it from a file or HTTP request.




[heading Avoiding SQL injection]

We need to build a query like the following:

[!teletype]
```
    SELECT first_name, last_name FROM employee WHERE id = <actual-id>
```

Replacing `<actual-id>` by the value passed by the user.

Since we don't control the employee ID, we must consider it [*untrusted].
We must [*never use raw string concatenation] to build queries.
Otherwise, malicious values can cause SQL injection vulnerabilities,
which are extremely severe.

Boost.MySQL offers two options to deal with this:

# Compose the query dynamically in the client, using specialized tools
  to avoid SQL injection. This option is versatile, simple and
  appropriate for general use.
# Perform parameter substitution server side using
  [link mysql.prepared_statements prepared statements]. This is more complex
  and better suited for cases involving lots of numeric data or
  executing same query repeatedly.

In this tutorial, we will use client-side generation
(termed [link mysql.text_queries client-side SQL formatting] throughout the documentation).




[heading Using with_params]

[refmem any_connection async_execute]
can also deal with queries with parameters.
We need to replace the string literal by a call
to [reflink with_params], passing a query template
and the actual values of the parameters:

[tutorial_with_params_execute]

The query template uses a syntax similar to `std::format`.
You can use numbers, strings,
dates, times and many other types as parameters.
More information about client-side SQL formatting
is available in [link mysql.text_queries this page].



[heading Using the retrieved rows]

Our query might return either one row (if an employee is found)
or none (if no employee with the given ID exists).
Accounting for this:

[tutorial_with_params_results]





[heading Connecting with database]

If you've run `example/db_setup.sql`, the `employee` table
exists within the `boost_mysql_examples` database.
To use this table without qualification, we need to specify
a database name when connecting. This is achieved by
setting [refmem connect_params database]:

[tutorial_with_params_connect_params]





[heading Creating the connection inside the coroutine]

Since we're connecting and closing the connection in our coroutine, it
makes sense to make it a local variable, instead of passing it as parameter.
Recall that we need a reference to an execution context (i.e. `io_context`)
to build a connection. We could pass the `io_context` as a parameter
to our coroutine, but there's a simpler way: coroutines
already hold a reference to where they are executing:

[tutorial_with_params_connection]

The expression `co_await asio::this_coro::executor` retrieves the [*executor]
that our coroutine is using. An executor is a lightweight handle
to an execution context, and can be used to create our connection.

[note
  `co_await asio::this_coro::executor` does not perform any I/O.
  It only retrieves the current coroutine's executor.
]





[heading Wrapping up]

With all these changes, this is how our coroutine looks like:

[tutorial_with_params_coroutine]

Full program listing for this tutorial is [link mysql.examples.tutorial_with_params here].

You can now proceed to [link mysql.tutorial_static_interface the next tutorial].


[endsect]

================================================
FILE: doc/qbk/03_4_tutorial_static_interface.qbk
================================================
[/
    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
   
    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

[section:tutorial_static_interface Tutorial 4: the static interface]

Until now we've read the rows generated by our queries into
[reflink results] objects. As we've seen, `results`
is a 2D structure that contains variant-like values.
Throughout the documentation, these variant-based APIs
are called [link mysql.dynamic_interface the dynamic interface].



[heading Dynamic interface limitations]

Working with variant-like objects can be cumbersome.
Recall the following lines from our previous tutorial,
where we used the retrieved rows:

[tutorial_with_params_results]

An employee is represented here by a [reflink row_view], which is a collection
of [reflink field_view] objects. `field_view` is a variant-like type
that can represent all the types supported by MySQL.

Since `field_view` supports streaming, this code doesn't require
any casting. However, consider refactoring our code to split
the printing logic to a separate function:

[tutorial_static_fn]

Looking at our database schema, we know that both values are
strings. We can use [refmem field_view as_string] to perform the casts:

[tutorial_static_casts]

While this code works, it can create maintenance problems:

* We retrieve fields by position. That is, we know that `employee.at(0)`
  holds the employee's `first_name`.
  However, if we refactor our query, we might forget updating the indices.
* Following a similar reasoning, the casts are error-prone.
* Both `at` and `as_string` throw on error. Attempting to avoid exceptions
  while still performing the required safety checks quickly becomes unmanageable.

If we know the types returned by our queries at compile time,
we can use the static interface, instead. This interface can
parse the rows returned by a query into instances of
a C++ struct defined by us.

[note
  The static interface requires C++14 or later.
]




[heading Using static_results with Boost.Pfr]

In C++20 and later, we can use __Pfr__ and the [reflink static_results]
class to parse the rows. The first step is to define a plain C++
struct with the fields we expect in our query:

[tutorial_static_struct]

We now replace the [reflink results] object by a [reflink static_results].
The marker type [reflink pfr_by_name] indicates Boot.MySQL that it should
use Boost.Pfr for reflection.

[tutorial_static_execute]

Using the retrieved data is now much easier, since [refmem static_results rows]
returns a `span<const employee>`:

[tutorial_static_results]

When using the static interface, `async_execute` will perform a set of
checks on the query results to ensure compatibility between the
C++ types and what MySQL returns. These checks aim to discover
potential problems as early as possible, and are called
[link mysql.static_interface.meta_checks metadata checks].



[heading Using the static interface in C++14]

C++20 makes it possible to use Boost.Pfr as described here,
which is the easiest option. Boost.MySQL also supports __Describe__
and `std::tuple`'s, which can be used in C++14.
The mechanics are quite similar to what's been explained here.



[heading Wrapping up]

[link mysql.static_interface This section] contains more information about the static interface.

Full program listing for this tutorial is [link mysql.examples.tutorial_static_interface here].

You can now proceed to [link mysql.tutorial_updates_transactions the next tutorial].

[endsect]

================================================
FILE: doc/qbk/03_5_tutorial_updates_transactions.qbk
================================================
[/
    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
   
    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

[section:tutorial_updates_transactions Tutorial 5: UPDATEs, transactions and semicolon-separated queries]

All the previous tutorials have only used `SELECT` statements, but
Boost.MySQL is not limited to them. Using [refmemunq any_connection async_execute]
you can run any SQL statement supported by MySQL.

In this tutorial, we will write a program that changes the first name of an
employee, given their ID, and prints the updated employee details.
We will use an `UPDATE` and transaction management statements.
`INSERT` and `DELETE` statements have similar mechanics.



[heading A simple UPDATE]

We can use the same tools and functions as in previous tutorials:

[tutorial_updates_transactions_update]

By default, auto-commit is enabled, meaning that when `async_execute`
returns, the `UPDATE` is visible to other client connections.




[heading Checking that the UPDATE took effect]

The above query will succeed even if there was no employee with the given ID.
We would like to retrieve the updated employee details on success, and emit
a useful error message if no employee was matched.

We may be tempted to use [refmem results affected_rows] at first, but
this doesn't convey the information we're looking for:
a row may be matched but not affected. For example, if you try to
set `first_name` to the same value it already has,
MySQL will count the row as a matched, but not affected.


MySQL does not support the `UPDATE ... RETURNING` syntax, so we will
have to retrieve the employee manually after updating it.
We can add the following after our `UPDATE`:

[tutorial_updates_transactions_select]

However, the code above contains a race condition. Imagine the following situation:

* The `UPDATE` is issued. No employee is matched.
* Before our program sends the `SELECT` query, a different program inserts
  an employee with the ID that we're trying to update.
* Our program runs the `SELECT` statement and retrieves the newly inserted row.

To our program, it looks like we succeeded performing the update, when
we really didn't. Depending on the nature of our program, this may
or may not have serious consequences, but it's something we should avoid.


[heading Avoiding the race condition with a transaction block]

We can fix the race condition using transactions.
In MySQL, a transaction block is opened with `START TRANSACTION`.
Subsequent statements will belong to the transaction block,
until the transaction either commits or is rolled back.
A `COMMIT` statement commits the transaction.
A rollback happens if the connection that initiated the transaction
closes or an explicit `ROLLBACK` statement is used.

We will enclose our `UPDATE` and `SELECT` statements in
a transaction block. This will ensure that the `SELECT`
will get the updated row, if any:

[tutorial_updates_transactions_txn]




[heading Using multi-queries]

While the code we've written is correct, it's not very performant.
We're incurring in 4 round-trips to the server, when our queries don't depend
on the result of previous ones. The round-trips occur within a transaction
block, which causes certain database rows to be locked, increasing contention.
We can improve the situation by running our four statements in a single batch.

Multi-queries are a protocol feature that lets you execute several queries
at once. Individual queries must be separated by semicolons.

Multi-queries are disabled by default. To enable them, set
[refmem connect_params multi_queries] to `true` before connecting:

[tutorial_updates_transactions_connect]

Multi-queries can be composed an executed using the same
functions we've been using:

[tutorial_updates_transactions_multi_queries]

Accessing the results is slightly different. MySQL returns 4 resultsets,
one for each query. In Boost.MySQL, this operation is said to be
[link mysql.multi_resultset multi-resultset].
[reflink results] can actually store more than one resultset.
[refmem results rows] actually accesses the rows in the first resultset,
because it's the most common use case.

We want to get the rows retrieved by the `SELECT` statement,
which corresponds to the third resultset.
[refmem results at] returns a [reflink resultset_view] containing data
for the requested resultset:

[tutorial_updates_transactions_dynamic_results]


[heading Using manual indices in with_params]

Repeating `employee_id` in the parameter list passed to `with_params`
violates the DRY principle.
As with `std::format`, we can refer to a format argument more than once
by using manual indices:

[tutorial_updates_transactions_manual_indices]



[heading Using the static interface with multi-resultset]

Finally, we can rewrite our code to use the static interface so it's safer.
In multi-resultset scenarios, we can pass as many row types
to [reflink static_results] as resultsets we expect.
We can use the empty tuple (`std::tuple<>`) as a row type
for operations that don't return rows, like the `UPDATE`.
Our code becomes:

[tutorial_updates_transactions_static]


[heading Wrapping up]

Full program listing for this tutorial is [link mysql.examples.tutorial_updates_transactions here].

You can now proceed to [link mysql.tutorial_connection_pool the next tutorial].


[endsect]

================================================
FILE: doc/qbk/03_6_tutorial_connection_pool.qbk
================================================
[/
    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
   
    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

[section:tutorial_connection_pool Tutorial 6: Connection pools]

All our programs until now have used one-shot connections.
They also didn't feature any fault tolerance:
if the server is unavailable, our program throws an exception
and terminates. Most real world scenarios require
long-lived, reliable connections, instead.

In this tutorial, we will implement a server for a simple request-reply
protocol. The protocol allows clients to retrieve the full name of
an employee given their ID.
We will use [reflink connection_pool] to maintain a set of healthy connections
that we can use when a client connects to our server.




[heading The protocol]

The protocol is TCP based, and can be described as follows:

* After connecting, the client sends a message containing the employee ID,
  encoded as an 8-byte, big-endian integer.
* The server replies with a string containing the employee full name,
  or "NOT_FOUND", if the ID doesn't match any employee.
* The connection is closed after that.

This protocol is intentionally overly simplistic, and
shouldn't be used in production. See our
[link mysql.examples.http_server_cpp20 HTTP examples]
for more advanced use cases.




[heading Creating a connection pool]

[reflink connection_pool] is an I/O object that contains
[reflink any_connection] objects, and can be
constructed from an execution context and a [reflink pool_params]
config struct:

[tutorial_connection_pool_create]

A single connection pool is usually created per application.

[refmem connection_pool async_run] should be called once per pool:

[tutorial_connection_pool_run]






[heading Using pooled connections]

Let's first write a coroutine that encapsulates database access.
Given an employee ID, it should return the string to be sent as response to the client.
Don't worry about error handling for now - we will take care of it in the next tutorial.

When using a pool, we don't need to explicitly create, connect or close connections.
Instead, we use [refmem connection_pool async_get_connection] to obtain them from the pool:

[tutorial_connection_pool_get_connection]

[reflink pooled_connection] is a wrapper around [reflink any_connection],
with some pool-specific additions. We can use it like a regular connection:

[tutorial_connection_pool_use]

When a [reflink pooled_connection] is destroyed, the connection is returned
to the pool. The underlying connection will be cleaned up using a lightweight
session reset mechanism and recycled.
Subsequent [refmemunq connection_pool async_get_connection]
calls may retrieve the same connection. This improves efficiency,
since session establishment is costly.

[refmemunq connection_pool async_get_connection] waits
for a client connection to become available before completing.
If the server is unavailable or credentials are invalid,
it may wait indefinitely. This is a problem for both development and production.
We can solve this by using [asioreflink cancel_after cancel_after],
which allows setting timeouts to async operations:

[tutorial_connection_pool_get_connection_timeout]

Don't worry if you don't fully understand how this works.
We will go into more detail on [asioreflink cancel_after cancel_after],
cancellations and completion tokens in the next tutorial.

Putting all pieces together, our coroutine becomes:

[tutorial_connection_pool_db]




[heading Handling a client session]

Let's now build a function that handles a client sessions,
invoking the database access logic in the process:

[tutorial_connection_pool_session]




[heading Listening for connections]

We now need logic to accept incoming TCP connections.
We will use an `asio::ip::tcp::acceptor` object
to accomplish it, listening for connections in a loop
until the server is stopped:

[tutorial_connection_pool_listener]




[heading Waiting for signals]

Finally, we need a way to stop our program. We will use an `asio::signal_set` object
to catch signals, and call `io_context::stop` when Ctrl-C is pressed:

[tutorial_connection_pool_signals]

Putting all these pieces together, our main program becomes:

[tutorial_connection_pool_main]




[heading Wrapping up]

Full program listing for this tutorial is [link mysql.examples.tutorial_connection_pool here].

For simplicity, we've left error handling out of this tutorial.
This is usually very important in a server like the one we've written,
and is the topic of our [link mysql.tutorial_error_handling next tutorial].

[endsect]

================================================
FILE: doc/qbk/03_7_tutorial_error_handling.qbk
================================================
[/
    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
   
    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

[section:tutorial_error_handling Tutorial 7: Error handling]

The [link mysql.tutorial_connection_pool previous tutorial]
did not include any error handling. When an error is encountered
while talking to the DB or the client, an exception is thrown and
the program terminates. This is undesirable in server programs like the one we're writing.

To add error handling, we can just add try/catch blocks to prevent exception propagation.
However, many code bases discourage the use of exceptions for non-exceptional circumstances,
like I/O errors. In this tutorial, we will learn how to manage I/O errors without exceptions
by using [asioreflink as_tuple as_tuple] and error codes.


[heading Error handling strategy]

There are two kind of I/O errors that our program can encounter:

* Reading and writing to the client may fail. This can happen if
  the client program is faulty or a network error happens.
  In this case, we should log the problem and close the connection.
* Talking to the database may fail. This can happen if [refmemunq connection_pool async_get_connection]
  is cancelled because of a timeout. In this case, we will return a special string (`"ERROR"`)
  to the client, signalling that we can't fulfill the request, and log the problem.

Additionally, we will modify how we use `asio::cancel_after` to make the system more reliable.




[heading:completion_token Completion tokens]

Before proceeding, we need to understand what a completion token is.
The concepts in this section are not specific to Boost.MySQL, but apply
to Asio and all Asio-compatible libraries. Since Asio docs can be terse,
we explain them here to facilitate the reader.

All asynchronous operations accept an optional, last parameter specifying what
to do when the operation completes.
This last parameter is the operation's
[@boost:/doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.completion_tokens_and_handlers completion token].

Callbacks are valid completion tokens. Taking [refmemunq connection_pool async_get_connection]
as example, the following is valid:

[tutorial_error_handling_callbacks]

We have already been using this when creating coroutines.
`asio::co_spawn` is also an async operation, and the callback we pass
as its last parameter is the completion token.

You might consider using callbacks if your compiler doesn't support coroutines,
or just by personal preference. [link mysql.examples.callbacks This example]
demonstrates how to use them.

If you don't specify a completion token, the operation's [*default completion token]
will be used. This is usually `asio::deferred` or `mysql::with_diagnostics(asio::deferred)`
[footnote [reflink with_diagnostics] is an adapter completion token that enhances
thrown exceptions with a diagnostic string supplied by the server.
`mysql::with_diagnostics(asio::deferred)` is otherwise equivalent to `asio::deferred`.].
These tokens transform asynchronous operations into awaitables,
so we can use them in C++20 coroutines.

The default completion token for [refmemunq connection_pool async_get_connection] is
`mysql::with_diagnostics(asio::deferred)`. This means that the following two are equivalent:

[tutorial_error_handling_default_tokens]

Completion tokens are generic: once you learn how to use one, you can use it
with any Asio-compliant async operation. This includes all functions in Boost.Asio,
Boost.MySQL, Boost.Beast and Boost.Redis. We say that operations in these libraries
are compliant with Asio's universal async model. Writing these is hard, but they're easy to use!





[heading Adapter completion tokens]

Some tokens don't fully specify what to do when the operation completes,
but rather modify some aspect of how the operation executes.
They wrap (or adapt) other completion tokens. The underlying token
determines what to do when the operation completes.

[asioreflink cancel_after cancel_after] is an adapter token.
It modifies how an operation executes by setting a timeout,
but it doesn't specify what to do on completion.

Adapter tokens can be passed an optional completion token
as the last argument. If the token is omitted, the default
one will be used. Continuing with our example:

[tutorial_error_handling_adapter_tokens]


[heading Handler signature and exceptions]

Each async operation has an associated handler signature.
We can find these signatures in the documentation for each operation.
The handler signature is the prototype that a callback function
passed as completion token would need to have to be compatible with the operation.

The handler signature for [refmemunq connection_pool async_get_connection]
is `void(boost::system::error_code, mysql::pooled_connection)`.

However, when we invoke `co_await` on the awaitable returned by `async_get_connection`,
we don't get any `error_code`. This is because `co_await` inspects
the handler signature at compile-time, looking for an `error_code` as first parameter.
If it finds it, `co_await` will remove it from the argument list, returning
only the `pooled_connection`. At runtime, the error code is checked.
If the code indicates a failure, an exception is thrown.

This mechanism is important to understand how `as_tuple` works.




[heading asio::as_tuple]

[asioreflink as_tuple as_tuple] is another adapter completion token
that can be used to prevent exceptions. It modifies the operation's
handler signature, packing all arguments into a `std::tuple`.
This inhibits the automatic error code checks explained in the previous section, 
thus preventing exceptions on I/O failure. Continuing with our example:

[tutorial_error_handling_as_tuple]

In practice, it's usually better to use structured bindings:

[tutorial_error_handling_as_tuple_structured_bindings]

All the properties of adapter completion tokens apply:

[tutorial_error_handling_as_tuple_default_tokens]

Adapter tokens can be combined. To apply a timeout to the operation
while avoiding exceptions, you can use:

[tutorial_error_handling_as_tuple_cancel_after]





[heading Using asio::as_tuple for database code]

Let's apply [asioreflink as_tuple as_tuple] to our database logic.
We will remove timeouts for now - we will add them back later.

[tutorial_error_handling_db_nodiag]






[heading Diagnostics objects]

While what we wrote works, it can be improved. When a database operation fails, the server
may supply an error string with information about what went wrong. Boost.MySQL may also
generate such strings in certain cases. We get this automatically
when using exceptions. Thanks to [reflink with_diagnostics] and default completion tokens,
the library throws [reflink error_with_diagnostics] objects,
which inherit from `boost::system::system_error`
and have a [refmemunq error_with_diagnostics get_diagnostics] member.

When using error codes, we need to handle diagnostics manually.
All functions in Boost.MySQL are overloaded to accept a [reflink diagnostics]
output parameter. It will be populated with extra information in case of error.

Let's update our code to use diagnostics:

[tutorial_error_handling_db]

We also need to write the function to log errors:

[tutorial_error_handling_log_error]

[refmem diagnostics client_message] and [refmem diagnostics server_message] differ
in their origin. Client messages never contain user-supplied input, and can always
be used safely. Server messages may contain user input, and should be treated with
more caution (logging them is fine).





[heading Using asio::as_tuple with client reads and writes]

Since `asio::read` and `asio::write` are compliant async operations,
we can use [asioreflink as_tuple as_tuple] with them, too:

[tutorial_error_handling_session_as_tuple]





[heading Timeouts]

Our session handler has three logical steps:

* Read a request from the client.
* Access the database.
* Write the response to the client.

Each of these steps may take long to complete. We will set a separate timeout
to each one.

Client reads and writes are the easiest ones to handle -
we just need to combine `as_tuple` and `cancel_after`:

[tutorial_error_handling_read_timeout]

The database logic is more involved. Ideally, we would like
to set a timeout to the overall database access operation, rather
than to individual steps. However, a `co_await` expression
isn't an async operation, and can't be passed a completion token.
We can fix this by replacing plain `co_await` by `asio::co_spawn`,
which accepts a completion token:

[tutorial_error_handling_db_timeout]

With these modifications, the session handler becomes:

[tutorial_error_handling_session]

With these modifications, our server is ready!



[heading Wrapping up]

Full program listing for this tutorial is [link mysql.examples.tutorial_error_handling here].

This concludes our tutorial series. You can now look at the [link mysql.overview overview section]
to learn more about the library features, or to the [link mysql.examples example section]
if you prefer to learn by doing.

[endsect]

================================================
FILE: doc/qbk/04_overview.qbk
================================================
[/
    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
   
    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

[section:overview Overview]
[nochunk]


This section briefly explains the library main classes and functions, and how to use them.

Boost.MySQL exposes sync and async functions implementing functionality involving I/O.
As explained [link mysql.tutorial_async in the second tutorial],
it's advisable to use async functions when possible, because they are more flexible.

Boost.MySQL supports the Boost.Asio universal async model. This means that
a variety of async programming paradigms can be used with the library,
including callbacks, stackful coroutines and C++20 coroutines.
We will use C++20 coroutines throughout the document because they're
easy to use.

[note
  Still not using C++20? Don't worry, you can use
  [link mysql.examples.coroutines_cpp11 stackful coroutines] and
  [link mysql.examples.callbacks callbacks] even in C++11.
]





[section Connection establishment]

[reflink any_connection] is the most primitive I/O object in the library.
It can establish and close connections, run queries and manage prepared statements.
Like most I/O objects, `any_connection` can be constructed from an execution context:

[tutorial_sync_connection]

`any_connection` is named like this for historic reasons:
a templated connection class came before it.
We currently recommend using `any_connection` for new
code because it's simpler and more powerful.

The MySQL client/server protocol is session-oriented. Before anything else,
you must perform session establishment by calling [refmem any_connection async_connect]:

[overview_connect]

[refmemunq any_connection async_connect] performs the hostname resolution,
TCP session establishment, TLS handshake and MySQL handshake.
By default, TLS is used if the server supports it.

You can configure a number of parameters here, including
the database to use, TLS options and buffer sizes.
See [link mysql.connection_establishment this section] for more info.

Boost.MySQL also supports
[link mysql.connection_establishment.unix using UNIX-domain sockets].

To cleanly terminate a connection, use [refmemunq any_connection async_close].
This sends a packet informing of the imminent close and shuts down TLS.
The connection destructor will also close the socket, so no leak occurs.

[endsect]





[section Running queries]

The simplest way to run a SQL query is using [refmem any_connection async_execute].
You can execute queries by passing a string as first parameter:

[overview_text_query]

Most queries contain user-supplied input. [*Never use raw string concatenation]
to build queries, since this is vulnerable to SQL injection.
Boost.MySQL provides two interfaces to run queries with parameters:


[table
    [
        [Feature]
        [Code]
    ]
    [
        [
            [link mysql.text_queries Client-side SQL formatting]:

            * Securely expands queries client-side.
            * Text-based protocol.
            * Adequate for general use.
        ]
        [
            [overview_with_params]
        ]
    ]
    [
        [
            [link mysql.prepared_statements Prepared statements]:

            * Parsed and executed in two different operations.
            * Binary protocol.
            * Adequate when running a query several times or retrieving
              lots of numeric data.
        ]
        [
            [overview_statement]
        ]
    ]
]

By default, we recommend using [reflink with_params] because it's
simpler and entails less round-trips to the server.
See [link mysql.text_queries.comparison the comparison section] for more info.

Client-side SQL formatting can also be used to
[link mysql.sql_formatting_advanced.expand expand queries]
without sending them to the server.

[endsect]





[section The dynamic and the static interfaces]

In MySQL, a ['resultset] refers to the results generated by a SQL query.
A resultset is composed of rows, [link mysql.meta metadata] and
additional info, like the last insert ID.

There are two different interfaces to access resultsets.
You can use the [reflink results] class to access rows using a dynamically-typed interface,
using variant-like objects to represent values retrieved from the server. On other other hand,
[reflink static_results] is statically-typed. You specify the shape of your rows at compile-time,
and the library will parse the retrieved values for you into the types you provide.

You can use almost every feature in this library (including text queries and prepared statements) with both interfaces.

For example, given the following table :

[/ (TODO: this code is duplicated.) ]

[!teletype]
```
    CREATE TABLE employee(
        id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
        first_name VARCHAR(100) NOT NULL,
        last_name VARCHAR(100) NOT NULL,
        ... -- other fields not relevant for us
    );
```

This is how you would access its contents using either of the interfaces:

[table
    [
        [Interface]
        [Description]
        [Example]
    ]
    [
        [
            Dynamic interface: [reflink results]
        ]
        [
            * Variant based
            * Available in C++11
            * [link mysql.dynamic_interface Learn more]
        ]
        [
            [overview_ifaces_dynamic]
        ]
    ]
    [
        [
            Static interface: [reflink static_results]
        ]
        [
            * Parses rows into your own types
            * Requires C++20 when using Boost.Pfr, C++14 when using Boost.Describe
            * [link mysql.static_interface Learn more]
        ]
        [
            [overview_static_struct][br]
            [overview_ifaces_static]
        ]
    ]
]

Prefer using the static interface when possible.

[endsect]







[section Running INSERT, UPDATE and DELETE statements]

The same APIs explained above can be used for SQL statements
that don't retrieve data:

[overview_update]

When performing INSERTs, you might find [refmem results last_insert_id]
handy, which retrieves the last AUTO INCREMENT ID generated by the executed statement.

See [link mysql.tutorial_updates_transactions our tutorial on UPDATEs and transactions]
for more info.

[endsect]





[section:async Single outstanding async operation per connection]

At any given point in time, an `any_connection` can only have a single async operation outstanding.
In other words, connections implement no asynchronous locking or queueing, which
keeps code simple and efficient. If you need to perform several operations in parallel,
you can open more connections or use [reflink connection_pool].

Trying to run operations concurrently on a single connection is detected at
runtime and generates a `client_errc::operation_in_progress` error:

[overview_async_parallel]

[endsect]






[section:errors Error handling]

An operation fails if a network error happens,
a protocol violation is encountered, or the server reports an error.
For instance, SQL syntax errors make `async_execute` fail.

When the server reports an error, it provides a diagnostic string
describing what happened. The [reflink diagnostics] class encapsulates
this message. Some library functions generate diagnostics strings, too.

Both the sync functions in [link mysql.tutorial_sync the first tutorial]
and the coroutines in this exposition throw exceptions when they fail.
The exception type is [reflink error_with_diagnostics], which inherits
from `boost::system::system_error` and adds a [reflink diagnostics] object.
Async functions use [reflink with_diagnostics], a completion token adapter,
to transparently include diagnostics in exceptions.

You can avoid exceptions when using coroutines with `asio::redirect_error`:

[overview_no_exceptions]

[reflink2 error_code mysql::error_code] is an alias for `boost::system::error_code`.

[endsect]




[section Multi-function operations]

Until now, we've been using [refmemunq any_connection async_execute], which
executes some SQL and reads all generated data into an in-memory object.

Some use cases may not fit in this simple pattern. For example:

* When reading a very big resultset, it may not be efficient (or even possible) to completely
  load it in memory. Reading rows in batches may be more adequate.
* If rows contain very long `TEXT` or `BLOB` fields, it may not be adequate to copy these values
  from the network buffer into the `results` object. A view-based approach may be better.

For these cases, we can break the execute operation into several steps,
using a ['multi-function operation] (the term is coined by this library). This example reads an entire
table in batches, which can be the case in an ETL process:

[overview_multifn]

[note
    Once you start a multi-function operation with [refmemunq any_connection async_start_execution],
    the server immediately sends all rows to the client. [*You must read all rows] before engaging in further operations.
    If you try to initiate an unrelated operation before reading all rows, you will get a
    `client_errc::engaged_in_multi_function` error.
]

Multi-function operations are powerful but complex. Only use them when there is a strong reason to do so.
Multi-function operations also work with the static interface.
Please refer to [link mysql.multi_function this section] for more information on these operations.

[endsect]



[section Connection pools]

Connection pooling is a technique where several long-lived connections
are re-used for independent logical operations. When compared to
establishing individual connections, it has the following benefits:

* It provides better performance. Please consult [link mysql.connection_pool.benchmarks our benchmarks]
  for more info.
* It simplifies connection management. The connection pool will establish sessions,
  perform retries and apply timeouts out of the box.

This is how you can create a pool of connections:

[connection_pool_create]

[refmem connection_pool async_run] must be called exactly once per pool.
This function takes care of actually keeping connections healthy.

To retrieve a connection, use [refmem connection_pool async_get_connection]:

[connection_pool_get_connection]

For more info, see [link mysql.connection_pool this section].

[endsect]


[endsect]


================================================
FILE: doc/qbk/05_connection_establishment.qbk
================================================
[/
    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
   
    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

[section:connection_establishment Connection establishment and termination]
[nochunk]

This section discusses several aspects regarding the creation,
establishment and termination of client connections.





[section Authentication]

[refmem connect_params username] and [refmem connect_params password]
contain the credentials used during authentication.
The password is sent to the server either hashed or over a secure
channel such as TLS, as mandated by the protocol.

MySQL implements several authentication plugins that can be used
to authenticate a user (see the [mysqllink pluggable-authentication.html
pluggable authentication MySQL docs]).
Each MySQL user is associated to a single authentication
plugin, specified during using creation.
Additionally, servers define a default authentication plugin
(see [mysqllink server-system-variables.html#sysvar_authentication_policy `authentication_policy`] and
[mysqllink server-system-variables.html#sysvar_default_authentication_plugin
`default_authentication_plugin`]). The default plugin will
be used for newly created users, and may affect how the handshake works.

This library implements the two most common authentication plugins:

* [mysqllink native-pluggable-authentication.html `mysql_native_password`].
  Unless otherwise configured, this is the default plugin for
  MySQL 5.7 and MariaDB. It can be used over both TLS and plaintext
  connections. It sends the password hashed, salted by a nonce.
* [mysqllink caching-sha2-pluggable-authentication.html
  `caching_sha2_password`]. This is the default plugin for
  MySQL 8.0+. This plugin used to require using TLS.
  Since Boost 1.89, this is no longer the case, and it can be used
  with plaintext connections, too.


Multi-factor authentication is not yet supported.
If you require support for a plugin not listed above or for MFA,
please file a feature request against the GitHub repository.

[note
    Servers configured with a default authentication plugin
    not implemented in Boost.MySQL are not supported, regardless
    of the actual plugin the concrete user employs. This limitation
    may be lifted in the future.
]

[endsect]



[section Connect with database]

[refmem connect_params database] contains the database name
to connect to. If you specify it, your connection will default to
use that database, as if you had issued a __USE__ statement.
You can leave it blank to select no database.
You can always issue a __USE__ statement using [refmemunq any_connection async_execute]
to select a different database after establishing the connection.

[endsect]




[section:tls TLS support]

TLS encrypted connections are fully supported by Boost.MySQL.
TCP connections established using [reflink any_connection] use TLS by default.

[heading TLS handshake and termination]

The TLS handshake is performed by [refmem any_connection async_connect].
This contrasts with libraries like __Beast__, where the TLS handshake
must be explicitly invoked by the user.
We selected this approach because the TLS handshake is part of the MySQL protocol's handshake:
the client and server exchange several unencrypted messages, then perform the TLS handshake
and continue exchanging encrypted messages, until the connection either succeeds or fails.
This scheme enables the TLS negotiation feature (see below for more info).

If the TLS handshake fails, the entire [refmemunq any_connection a
Download .txt
gitextract_6ypeo_s4/

├── .clang-format
├── .clangd
├── .codecov.yml
├── .dockerignore
├── .drone.star
├── .github/
│   └── workflows/
│       ├── build-code.yml
│       ├── coverage.yml
│       ├── docker-windows.yml
│       └── fuzz.yml
├── .gitignore
├── CMakeLists.txt
├── LICENSE_1_0.txt
├── README.md
├── bench/
│   ├── CMakeLists.txt
│   ├── bench.ipynb
│   ├── connection_pool.cpp
│   ├── db_setup.sql
│   ├── many_rows_boost.cpp
│   ├── many_rows_libmariadb.cpp
│   ├── many_rows_libmysqlclient.cpp
│   ├── one_big_row_boost.cpp
│   ├── one_big_row_libmariadb.cpp
│   ├── one_big_row_libmysqlclient.cpp
│   ├── one_small_row_boost.cpp
│   ├── one_small_row_libmariadb.cpp
│   ├── one_small_row_libmysqlclient.cpp
│   ├── stmt_params_boost.cpp
│   ├── stmt_params_libmariadb.cpp
│   └── stmt_params_libmysqlclient.cpp
├── build.jam
├── cmake/
│   └── utils.cmake
├── doc/
│   ├── Jamfile
│   ├── config.json
│   ├── doxygen.hpp
│   ├── qbk/
│   │   ├── 00_main.qbk
│   │   ├── 01_intro.qbk
│   │   ├── 02_integrating.qbk
│   │   ├── 03_1_tutorial_sync.qbk
│   │   ├── 03_2_tutorial_async.qbk
│   │   ├── 03_3_tutorial_with_params.qbk
│   │   ├── 03_4_tutorial_static_interface.qbk
│   │   ├── 03_5_tutorial_updates_transactions.qbk
│   │   ├── 03_6_tutorial_connection_pool.qbk
│   │   ├── 03_7_tutorial_error_handling.qbk
│   │   ├── 04_overview.qbk
│   │   ├── 05_connection_establishment.qbk
│   │   ├── 06_text_queries.qbk
│   │   ├── 07_prepared_statements.qbk
│   │   ├── 08_dynamic_interface.qbk
│   │   ├── 09_static_interface.qbk
│   │   ├── 10_multi_resultset.qbk
│   │   ├── 11_multi_function.qbk
│   │   ├── 12_connection_pool.qbk
│   │   ├── 13_1_interfacing_sync_async.qbk
│   │   ├── 13_async.qbk
│   │   ├── 14_error_handling.qbk
│   │   ├── 15_sql_formatting_advanced.qbk
│   │   ├── 16_metadata.qbk
│   │   ├── 17_charsets.qbk
│   │   ├── 18_time_types.qbk
│   │   ├── 19_templated_connection.qbk
│   │   ├── 20_1_benchmarks.qbk
│   │   ├── 20_pipeline.qbk
│   │   ├── 21_examples.qbk
│   │   └── helpers/
│   │       ├── ExecutionRequest.qbk
│   │       ├── ExecutionStateType.qbk
│   │       ├── FieldViewFwdIterator.qbk
│   │       ├── Formattable.qbk
│   │       ├── OutputString.qbk
│   │       ├── ResultsType.qbk
│   │       ├── SocketStream.qbk
│   │       ├── StaticRow.qbk
│   │       ├── Stream.qbk
│   │       ├── WritableFieldTuple.qbk
│   │       └── quickref.xml
│   └── upgrade_1_82.md
├── example/
│   ├── 1_tutorial/
│   │   ├── 1_sync.cpp
│   │   ├── 2_async.cpp
│   │   ├── 3_with_params.cpp
│   │   ├── 4_static_interface.cpp
│   │   ├── 5_updates_transactions.cpp
│   │   ├── 6_connection_pool.cpp
│   │   └── 7_error_handling.cpp
│   ├── 2_simple/
│   │   ├── batch_inserts.cpp
│   │   ├── batch_inserts_generic.cpp
│   │   ├── callbacks.cpp
│   │   ├── coroutines_cpp11.cpp
│   │   ├── deletes.cpp
│   │   ├── disable_tls.cpp
│   │   ├── dynamic_filters.cpp
│   │   ├── inserts.cpp
│   │   ├── metadata.cpp
│   │   ├── multi_function.cpp
│   │   ├── patch_updates.cpp
│   │   ├── pipeline.cpp
│   │   ├── prepared_statements.cpp
│   │   ├── source_script.cpp
│   │   ├── tls_certificate_verification.cpp
│   │   └── unix_socket.cpp
│   ├── 3_advanced/
│   │   ├── http_server_cpp14_coroutines/
│   │   │   ├── handle_request.cpp
│   │   │   ├── handle_request.hpp
│   │   │   ├── main.cpp
│   │   │   ├── repository.cpp
│   │   │   ├── repository.hpp
│   │   │   ├── server.cpp
│   │   │   ├── server.hpp
│   │   │   └── types.hpp
│   │   └── http_server_cpp20/
│   │       ├── db_setup.sql
│   │       ├── error.cpp
│   │       ├── error.hpp
│   │       ├── handle_request.cpp
│   │       ├── handle_request.hpp
│   │       ├── main.cpp
│   │       ├── repository.cpp
│   │       ├── repository.hpp
│   │       ├── server.cpp
│   │       ├── server.hpp
│   │       └── types.hpp
│   ├── CMakeLists.txt
│   ├── Jamfile
│   ├── db_setup.sql
│   └── private/
│       ├── employees_multiple.json
│       ├── employees_single.json
│       ├── launch_server.py
│       ├── run_batch_inserts.py
│       ├── run_dynamic_filters.py
│       ├── run_notes.py
│       ├── run_orders.py
│       ├── run_patch_updates.py
│       ├── run_tutorial_connection_pool.py
│       └── test_script.sql
├── include/
│   └── boost/
│       ├── mysql/
│       │   ├── any_address.hpp
│       │   ├── any_connection.hpp
│       │   ├── bad_field_access.hpp
│       │   ├── blob.hpp
│       │   ├── blob_view.hpp
│       │   ├── buffer_params.hpp
│       │   ├── character_set.hpp
│       │   ├── client_errc.hpp
│       │   ├── column_type.hpp
│       │   ├── common_server_errc.hpp
│       │   ├── connect_params.hpp
│       │   ├── connection.hpp
│       │   ├── connection_pool.hpp
│       │   ├── constant_string_view.hpp
│       │   ├── date.hpp
│       │   ├── datetime.hpp
│       │   ├── days.hpp
│       │   ├── defaults.hpp
│       │   ├── detail/
│       │   │   ├── access.hpp
│       │   │   ├── algo_params.hpp
│       │   │   ├── any_execution_request.hpp
│       │   │   ├── any_resumable_ref.hpp
│       │   │   ├── character_set.hpp
│       │   │   ├── coldef_view.hpp
│       │   │   ├── config.hpp
│       │   │   ├── connect_params_helpers.hpp
│       │   │   ├── connection_impl.hpp
│       │   │   ├── connection_pool_fwd.hpp
│       │   │   ├── datetime.hpp
│       │   │   ├── engine.hpp
│       │   │   ├── engine_impl.hpp
│       │   │   ├── engine_stream_adaptor.hpp
│       │   │   ├── escape_string.hpp
│       │   │   ├── execution_concepts.hpp
│       │   │   ├── execution_processor/
│       │   │   │   ├── execution_processor.hpp
│       │   │   │   ├── execution_state_impl.hpp
│       │   │   │   ├── results_impl.hpp
│       │   │   │   ├── static_execution_state_impl.hpp
│       │   │   │   └── static_results_impl.hpp
│       │   │   ├── field_impl.hpp
│       │   │   ├── flags.hpp
│       │   │   ├── format_sql.hpp
│       │   │   ├── initiation_base.hpp
│       │   │   ├── intermediate_handler.hpp
│       │   │   ├── next_action.hpp
│       │   │   ├── ok_view.hpp
│       │   │   ├── output_string.hpp
│       │   │   ├── pipeline.hpp
│       │   │   ├── rebind_executor.hpp
│       │   │   ├── results_iterator.hpp
│       │   │   ├── resultset_encoding.hpp
│       │   │   ├── row_impl.hpp
│       │   │   ├── rows_iterator.hpp
│       │   │   ├── sequence.hpp
│       │   │   ├── socket_stream.hpp
│       │   │   ├── ssl_fwd.hpp
│       │   │   ├── string_view_offset.hpp
│       │   │   ├── throw_on_error_loc.hpp
│       │   │   ├── typing/
│       │   │   │   ├── meta_check_context.hpp
│       │   │   │   ├── pos_map.hpp
│       │   │   │   ├── readable_field_traits.hpp
│       │   │   │   └── row_traits.hpp
│       │   │   ├── void_t.hpp
│       │   │   └── writable_field_traits.hpp
│       │   ├── diagnostics.hpp
│       │   ├── error_categories.hpp
│       │   ├── error_code.hpp
│       │   ├── error_with_diagnostics.hpp
│       │   ├── escape_string.hpp
│       │   ├── execution_state.hpp
│       │   ├── field.hpp
│       │   ├── field_kind.hpp
│       │   ├── field_view.hpp
│       │   ├── format_sql.hpp
│       │   ├── handshake_params.hpp
│       │   ├── impl/
│       │   │   ├── any_connection.ipp
│       │   │   ├── character_set.ipp
│       │   │   ├── column_type.ipp
│       │   │   ├── connection_impl.ipp
│       │   │   ├── connection_pool.ipp
│       │   │   ├── date.ipp
│       │   │   ├── datetime.ipp
│       │   │   ├── engine_impl_instantiations.ipp
│       │   │   ├── error_categories.ipp
│       │   │   ├── escape_string.ipp
│       │   │   ├── execution_state_impl.ipp
│       │   │   ├── field.ipp
│       │   │   ├── field_kind.ipp
│       │   │   ├── field_view.hpp
│       │   │   ├── field_view.ipp
│       │   │   ├── format_sql.hpp
│       │   │   ├── format_sql.ipp
│       │   │   ├── internal/
│       │   │   │   ├── byte_to_hex.hpp
│       │   │   │   ├── call_next_char.hpp
│       │   │   │   ├── connection_pool/
│       │   │   │   │   ├── connection_node.hpp
│       │   │   │   │   ├── connection_pool_impl.hpp
│       │   │   │   │   ├── internal_pool_params.hpp
│       │   │   │   │   └── sansio_connection_node.hpp
│       │   │   │   ├── coroutine.hpp
│       │   │   │   ├── dt_to_string.hpp
│       │   │   │   ├── error/
│       │   │   │   │   ├── server_error_to_string.hpp
│       │   │   │   │   └── server_error_to_string.ipp
│       │   │   │   ├── next_power_of_two.hpp
│       │   │   │   ├── protocol/
│       │   │   │   │   ├── capabilities.hpp
│       │   │   │   │   ├── db_flavor.hpp
│       │   │   │   │   ├── deserialization.hpp
│       │   │   │   │   ├── frame_header.hpp
│       │   │   │   │   ├── impl/
│       │   │   │   │   │   ├── binary_protocol.hpp
│       │   │   │   │   │   ├── bit_deserialization.hpp
│       │   │   │   │   │   ├── deserialization_context.hpp
│       │   │   │   │   │   ├── null_bitmap.hpp
│       │   │   │   │   │   ├── protocol_field_type.hpp
│       │   │   │   │   │   ├── protocol_types.hpp
│       │   │   │   │   │   ├── serialization_context.hpp
│       │   │   │   │   │   ├── span_string.hpp
│       │   │   │   │   │   └── text_protocol.hpp
│       │   │   │   │   ├── serialization.hpp
│       │   │   │   │   └── static_buffer.hpp
│       │   │   │   ├── sansio/
│       │   │   │   │   ├── auth_plugin_common.hpp
│       │   │   │   │   ├── caching_sha2_password.hpp
│       │   │   │   │   ├── close_connection.hpp
│       │   │   │   │   ├── close_statement.hpp
│       │   │   │   │   ├── connect.hpp
│       │   │   │   │   ├── connection_state.hpp
│       │   │   │   │   ├── connection_state_data.hpp
│       │   │   │   │   ├── csha2p_encrypt_password.hpp
│       │   │   │   │   ├── execute.hpp
│       │   │   │   │   ├── handshake.hpp
│       │   │   │   │   ├── message_reader.hpp
│       │   │   │   │   ├── mysql_native_password.hpp
│       │   │   │   │   ├── ping.hpp
│       │   │   │   │   ├── prepare_statement.hpp
│       │   │   │   │   ├── quit_connection.hpp
│       │   │   │   │   ├── read_buffer.hpp
│       │   │   │   │   ├── read_resultset_head.hpp
│       │   │   │   │   ├── read_some_rows.hpp
│       │   │   │   │   ├── read_some_rows_dynamic.hpp
│       │   │   │   │   ├── reset_connection.hpp
│       │   │   │   │   ├── run_pipeline.hpp
│       │   │   │   │   ├── set_character_set.hpp
│       │   │   │   │   ├── start_execution.hpp
│       │   │   │   │   └── top_level_algo.hpp
│       │   │   │   ├── ssl_context_with_default.hpp
│       │   │   │   └── variant_stream.hpp
│       │   │   ├── is_fatal_error.ipp
│       │   │   ├── meta_check_context.ipp
│       │   │   ├── pfr.hpp
│       │   │   ├── pipeline.ipp
│       │   │   ├── results_impl.ipp
│       │   │   ├── resultset.ipp
│       │   │   ├── row_impl.ipp
│       │   │   ├── statement.hpp
│       │   │   ├── static_execution_state_impl.ipp
│       │   │   ├── static_results_impl.ipp
│       │   │   ├── with_diagnostics.hpp
│       │   │   └── with_params.hpp
│       │   ├── is_fatal_error.hpp
│       │   ├── mariadb_collations.hpp
│       │   ├── mariadb_server_errc.hpp
│       │   ├── metadata.hpp
│       │   ├── metadata_collection_view.hpp
│       │   ├── metadata_mode.hpp
│       │   ├── mysql_collations.hpp
│       │   ├── mysql_server_errc.hpp
│       │   ├── pfr.hpp
│       │   ├── pipeline.hpp
│       │   ├── pool_params.hpp
│       │   ├── results.hpp
│       │   ├── resultset.hpp
│       │   ├── resultset_view.hpp
│       │   ├── row.hpp
│       │   ├── row_view.hpp
│       │   ├── rows.hpp
│       │   ├── rows_view.hpp
│       │   ├── sequence.hpp
│       │   ├── src.hpp
│       │   ├── ssl_mode.hpp
│       │   ├── statement.hpp
│       │   ├── static_execution_state.hpp
│       │   ├── static_results.hpp
│       │   ├── string_view.hpp
│       │   ├── tcp.hpp
│       │   ├── tcp_ssl.hpp
│       │   ├── throw_on_error.hpp
│       │   ├── time.hpp
│       │   ├── underlying_row.hpp
│       │   ├── unix.hpp
│       │   ├── unix_ssl.hpp
│       │   ├── with_diagnostics.hpp
│       │   └── with_params.hpp
│       └── mysql.hpp
├── index.html
├── meta/
│   └── libraries.json
├── test/
│   ├── CMakeLists.txt
│   ├── Jamfile
│   ├── cmake_b2_separate_compilation_test/
│   │   ├── CMakeLists.txt
│   │   ├── boost_mysql.cpp
│   │   └── main.cpp
│   ├── cmake_b2_test/
│   │   ├── CMakeLists.txt
│   │   └── main.cpp
│   ├── cmake_test/
│   │   ├── CMakeLists.txt
│   │   └── main.cpp
│   ├── common/
│   │   ├── include/
│   │   │   └── test_common/
│   │   │       ├── assert_buffer_equals.hpp
│   │   │       ├── buffer_concat.hpp
│   │   │       ├── check_meta.hpp
│   │   │       ├── ci_server.hpp
│   │   │       ├── create_basic.hpp
│   │   │       ├── create_diagnostics.hpp
│   │   │       ├── has_ranges.hpp
│   │   │       ├── io_context_fixture.hpp
│   │   │       ├── netfun_maker.hpp
│   │   │       ├── network_result.hpp
│   │   │       ├── poll_until.hpp
│   │   │       ├── printing.hpp
│   │   │       ├── source_location.hpp
│   │   │       ├── stringize.hpp
│   │   │       ├── tracker_executor.hpp
│   │   │       └── validate_string_contains.hpp
│   │   └── src/
│   │       ├── boost_asio.cpp
│   │       ├── boost_mysql.cpp
│   │       ├── entry_point.cpp
│   │       └── utils.cpp
│   ├── fuzzing/
│   │   ├── Jamfile
│   │   ├── fuzz_auth_switch.cpp
│   │   ├── fuzz_column_definition.cpp
│   │   ├── fuzz_err_packet.cpp
│   │   ├── fuzz_escape_string.cpp
│   │   ├── fuzz_execute_response.cpp
│   │   ├── fuzz_format_args.cpp
│   │   ├── fuzz_format_identifier.cpp
│   │   ├── fuzz_format_sql_injection.cpp
│   │   ├── fuzz_format_strings.cpp
│   │   ├── fuzz_handshake_server_response.cpp
│   │   ├── fuzz_ok_packet.cpp
│   │   ├── fuzz_ok_response.cpp
│   │   ├── fuzz_prepare_stmt_response.cpp
│   │   ├── fuzz_row.cpp
│   │   ├── fuzz_row_message.cpp
│   │   ├── fuzz_server_hello.cpp
│   │   ├── fuzz_text_field.cpp
│   │   └── fuzz_utf8mb4.cpp
│   ├── integration/
│   │   ├── CMakeLists.txt
│   │   ├── Jamfile
│   │   ├── db_setup.sql
│   │   ├── db_setup_mnp.sql
│   │   ├── db_setup_sha256.sql
│   │   ├── include/
│   │   │   └── test_integration/
│   │   │       ├── any_connection_fixture.hpp
│   │   │       ├── connect_params_builder.hpp
│   │   │       ├── metadata_validator.hpp
│   │   │       ├── run_coro.hpp
│   │   │       ├── server_ca.hpp
│   │   │       ├── server_features.hpp
│   │   │       ├── snippets/
│   │   │       │   ├── credentials.hpp
│   │   │       │   ├── describe.hpp
│   │   │       │   ├── get_any_connection.hpp
│   │   │       │   ├── get_connection.hpp
│   │   │       │   └── snippets_fixture.hpp
│   │   │       ├── spotchecks_helpers.hpp
│   │   │       ├── static_rows.hpp
│   │   │       └── tcp_connection_fixture.hpp
│   │   ├── pch.hpp
│   │   ├── src/
│   │   │   ├── metadata_validator.cpp
│   │   │   ├── server_features.cpp
│   │   │   ├── spotchecks_helpers.cpp
│   │   │   └── utils.cpp
│   │   └── test/
│   │       ├── any_connection.cpp
│   │       ├── character_set_tracking.cpp
│   │       ├── connection_id.cpp
│   │       ├── connection_pool.cpp
│   │       ├── crud.cpp
│   │       ├── database_types.cpp
│   │       ├── db_specific.cpp
│   │       ├── execution_requests.cpp
│   │       ├── handshake.cpp
│   │       ├── multi_function.cpp
│   │       ├── multi_queries.cpp
│   │       ├── pipeline.cpp
│   │       ├── prepared_statements.cpp
│   │       ├── reconnect.cpp
│   │       ├── snippets/
│   │       │   ├── charsets.cpp
│   │       │   ├── connection_establishment.cpp
│   │       │   ├── connection_pool.cpp
│   │       │   ├── dynamic_interface.cpp
│   │       │   ├── interfacing_sync_async.cpp
│   │       │   ├── metadata.cpp
│   │       │   ├── multi_function.cpp
│   │       │   ├── multi_resultset.cpp
│   │       │   ├── overview.cpp
│   │       │   ├── pipeline.cpp
│   │       │   ├── prepared_statements.cpp
│   │       │   ├── sql_formatting_advanced.cpp
│   │       │   ├── sql_formatting_advanced_2.cpp
│   │       │   ├── static_interface.cpp
│   │       │   ├── templated_connection.cpp
│   │       │   ├── text_queries.cpp
│   │       │   ├── time_types.cpp
│   │       │   └── tutorials.cpp
│   │       ├── spotchecks.cpp
│   │       ├── static_interface.cpp
│   │       └── stored_procedures.cpp
│   ├── thread_safety/
│   │   ├── Jamfile
│   │   ├── connection_pool.cpp
│   │   ├── connection_pool_cancel.cpp
│   │   ├── connection_pool_cancel_get_connection.cpp
│   │   ├── connection_pool_coroutines.cpp
│   │   ├── connection_pool_external_strand.cpp
│   │   ├── connection_pool_two_contexts.cpp
│   │   └── tsan_pool_common.hpp
│   └── unit/
│       ├── CMakeLists.txt
│       ├── Jamfile
│       ├── include/
│       │   └── test_unit/
│       │       ├── algo_test.hpp
│       │       ├── create_coldef_frame.hpp
│       │       ├── create_err.hpp
│       │       ├── create_execution_processor.hpp
│       │       ├── create_frame.hpp
│       │       ├── create_meta.hpp
│       │       ├── create_ok.hpp
│       │       ├── create_ok_frame.hpp
│       │       ├── create_prepare_statement_response.hpp
│       │       ├── create_query_frame.hpp
│       │       ├── create_row_message.hpp
│       │       ├── create_statement.hpp
│       │       ├── custom_allocator.hpp
│       │       ├── fail_count.hpp
│       │       ├── ff_charset.hpp
│       │       ├── mock_execution_processor.hpp
│       │       ├── mock_message.hpp
│       │       ├── mock_timer.hpp
│       │       ├── printing.hpp
│       │       ├── row_identity.hpp
│       │       ├── serialize_to_vector.hpp
│       │       ├── test_any_connection.hpp
│       │       └── test_stream.hpp
│       ├── pch.hpp
│       ├── src/
│       │   └── utils.cpp
│       ├── test/
│       │   ├── any_address.cpp
│       │   ├── any_connection.cpp
│       │   ├── character_set.cpp
│       │   ├── client_errc.cpp
│       │   ├── column_type.cpp
│       │   ├── common_server_errc.cpp
│       │   ├── connection.cpp
│       │   ├── connection_pool/
│       │   │   ├── connection_pool_impl.cpp
│       │   │   └── sansio_connection_node.cpp
│       │   ├── connection_pool.cpp
│       │   ├── constant_string_view.cpp
│       │   ├── date.cpp
│       │   ├── datetime.cpp
│       │   ├── detail/
│       │   │   ├── connect_params_helpers.cpp
│       │   │   ├── datetime.cpp
│       │   │   ├── engine_impl.cpp
│       │   │   ├── execution_concepts.cpp
│       │   │   ├── intermediate_handler.cpp
│       │   │   ├── output_string.cpp
│       │   │   ├── row_impl.cpp
│       │   │   ├── rows_iterator.cpp
│       │   │   ├── socket_stream.cpp
│       │   │   ├── typing/
│       │   │   │   ├── meta_check_context.cpp
│       │   │   │   ├── pos_map.cpp
│       │   │   │   ├── readable_field_traits.cpp
│       │   │   │   └── row_traits.cpp
│       │   │   └── writable_field_traits.cpp
│       │   ├── diagnostics.cpp
│       │   ├── escape_string.cpp
│       │   ├── execution_processor/
│       │   │   ├── execution_processor.cpp
│       │   │   ├── execution_processor_helpers.hpp
│       │   │   ├── execution_state_impl.cpp
│       │   │   ├── results_impl.cpp
│       │   │   ├── static_execution_processor_helpers.hpp
│       │   │   ├── static_execution_state_impl.cpp
│       │   │   └── static_results_impl.cpp
│       │   ├── execution_state.cpp
│       │   ├── field.cpp
│       │   ├── field_view.cpp
│       │   ├── format_sql/
│       │   │   ├── api.cpp
│       │   │   ├── basic_format_context.cpp
│       │   │   ├── custom_formatter.cpp
│       │   │   ├── format_common.hpp
│       │   │   ├── format_strings.cpp
│       │   │   ├── formattable.cpp
│       │   │   ├── formattable_ref.cpp
│       │   │   ├── individual_value.cpp
│       │   │   ├── ranges.cpp
│       │   │   └── sequence.cpp
│       │   ├── impl/
│       │   │   ├── dt_to_string.cpp
│       │   │   ├── next_power_of_two.cpp
│       │   │   ├── ssl_context_with_default.cpp
│       │   │   └── variant_stream.cpp
│       │   ├── is_fatal_error.cpp
│       │   ├── mariadb_server_errc.cpp
│       │   ├── metadata.cpp
│       │   ├── mysql_server_errc.cpp
│       │   ├── pfr.cpp
│       │   ├── pipeline.cpp
│       │   ├── pool_params.cpp
│       │   ├── protocol/
│       │   │   ├── binary_protocol.cpp
│       │   │   ├── capabilities.cpp
│       │   │   ├── deserialization.cpp
│       │   │   ├── deserialization_context.cpp
│       │   │   ├── frame_header.cpp
│       │   │   ├── null_bitmap.cpp
│       │   │   ├── operators.hpp
│       │   │   ├── protocol_field_type.cpp
│       │   │   ├── protocol_types.cpp
│       │   │   ├── serialization.cpp
│       │   │   ├── serialization_context.cpp
│       │   │   ├── serialization_test.hpp
│       │   │   ├── static_buffer.cpp
│       │   │   └── text_protocol.cpp
│       │   ├── results.cpp
│       │   ├── resultset.cpp
│       │   ├── resultset_view.cpp
│       │   ├── row.cpp
│       │   ├── row_view.cpp
│       │   ├── rows.cpp
│       │   ├── rows_view.cpp
│       │   ├── sansio/
│       │   │   ├── close_connection.cpp
│       │   │   ├── close_statement.cpp
│       │   │   ├── execute.cpp
│       │   │   ├── handshake/
│       │   │   │   ├── handshake.cpp
│       │   │   │   ├── handshake_capabilities.cpp
│       │   │   │   ├── handshake_common.hpp
│       │   │   │   ├── handshake_connection_state_data.cpp
│       │   │   │   ├── handshake_csha2p.cpp
│       │   │   │   ├── handshake_csha2p_encrypt_password.cpp
│       │   │   │   ├── handshake_csha2p_hash_password.cpp
│       │   │   │   ├── handshake_csha2p_keys.hpp
│       │   │   │   ├── handshake_mnp.cpp
│       │   │   │   └── handshake_mnp_hash_password.cpp
│       │   │   ├── message_reader.cpp
│       │   │   ├── ping.cpp
│       │   │   ├── prepare_statement.cpp
│       │   │   ├── quit_connection.cpp
│       │   │   ├── read_buffer.cpp
│       │   │   ├── read_resultset_head.cpp
│       │   │   ├── read_some_rows.cpp
│       │   │   ├── read_some_rows_dynamic.cpp
│       │   │   ├── reset_connection.cpp
│       │   │   ├── run_pipeline.cpp
│       │   │   ├── set_character_set.cpp
│       │   │   ├── start_execution.cpp
│       │   │   └── top_level_algo.cpp
│       │   ├── spotchecks/
│       │   │   ├── connection_use_after_move.cpp
│       │   │   ├── default_completion_tokens.cpp
│       │   │   ├── execution_requests.cpp
│       │   │   ├── misc.cpp
│       │   │   ├── multifn.cpp
│       │   │   └── read_some_rows_static.cpp
│       │   ├── statement.cpp
│       │   ├── static_execution_state.cpp
│       │   ├── static_results.cpp
│       │   ├── throw_on_error.cpp
│       │   └── with_diagnostics.cpp
│       └── test_csha2p_encrypt_password_errors.cpp
└── tools/
    ├── ci/
    │   ├── ci_util/
    │   │   ├── __init__.py
    │   │   ├── b2.py
    │   │   ├── bench.py
    │   │   ├── cmake.py
    │   │   ├── common.py
    │   │   ├── db_setup.py
    │   │   ├── docs.py
    │   │   ├── fuzz.py
    │   │   ├── install_boost.py
    │   │   ├── main.py
    │   │   └── seed_corpus.py
    │   ├── main.py
    │   ├── run_benchmarks.py
    │   └── seed_corpus.py
    ├── docker/
    │   └── build-msvc.dockerfile
    ├── error_codes.csv
    ├── osx-ci.cnf
    ├── scripts/
    │   ├── build_unix_local.sh
    │   ├── build_windows_local.bat
    │   ├── check_links.py
    │   ├── collations.py
    │   ├── corpus_field_table.py
    │   ├── examples_qbk.py
    │   ├── file_headers.py
    │   └── server_errors.py
    ├── seed_corpus/
    │   ├── field_table.csv
    │   ├── protocol_messages.csv
    │   └── sql_injection_payloads.txt
    ├── setup_db_osx.sh
    ├── ssl/
    │   ├── ca-cert.pem
    │   ├── server-cert.pem
    │   └── server-key.pem
    ├── user-config-osx-gha.jam
    ├── valgrind_suppressions.txt
    └── win-ci.cnf
Download .txt
Showing preview only (762K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (5650 symbols across 482 files)

FILE: bench/connection_pool.cpp
  class coordinator (line 41) | class coordinator
    method coordinator (line 51) | coordinator(mysql::connection_pool* pool = nullptr) : pool_(pool) {}
    method ellapsed (line 52) | std::chrono::milliseconds ellapsed() const
    method record_start (line 56) | void record_start() { tp_start_ = steady_clock::now(); }
    method on_finish (line 57) | void on_finish()
    method on_loop_finish (line 66) | bool on_loop_finish()
    method check_ec (line 73) | bool check_ec(error_code ec, const mysql::diagnostics& diag)
  class task_nopool (line 84) | class task_nopool
    method task_nopool (line 95) | task_nopool(asio::any_io_executor ex, coordinator& coord, const mysql:...
    method resume (line 100) | void resume(error_code ec = {})
  class task_pool (line 142) | class task_pool
    method on_finish (line 152) | void on_finish()
    method task_pool (line 159) | task_pool(mysql::connection_pool& pool, coordinator& coord) : pool_(&p...
    method resume (line 161) | void resume(error_code ec = {})
  function run_nopool (line 205) | void run_nopool(mysql::any_address server_addr, bool use_ssl)
  function run_pool (line 234) | void run_pool(mysql::any_address server_addr, bool use_ssl)
  function usage (line 277) | void usage(const char* progname)
  function main (line 287) | int main(int argc, char** argv)

FILE: bench/db_setup.sql
  type test_data (line 24) | CREATE TABLE test_data(
  type lightweight_data (line 91) | CREATE TABLE lightweight_data(

FILE: bench/many_rows_boost.cpp
  function main (line 25) | int main()

FILE: bench/many_rows_libmariadb.cpp
  function main (line 17) | int main()

FILE: bench/many_rows_libmysqlclient.cpp
  function main (line 19) | int main()

FILE: bench/one_big_row_boost.cpp
  function main (line 27) | int main()

FILE: bench/one_big_row_libmariadb.cpp
  function main (line 17) | int main()

FILE: bench/one_big_row_libmysqlclient.cpp
  function main (line 19) | int main()

FILE: bench/one_small_row_boost.cpp
  function main (line 25) | int main()

FILE: bench/one_small_row_libmariadb.cpp
  function main (line 18) | int main()

FILE: bench/one_small_row_libmysqlclient.cpp
  function main (line 18) | int main()

FILE: bench/stmt_params_boost.cpp
  function main (line 31) | int main()

FILE: bench/stmt_params_libmariadb.cpp
  function main (line 18) | int main()

FILE: bench/stmt_params_libmysqlclient.cpp
  function main (line 19) | int main()

FILE: example/1_tutorial/1_sync.cpp
  function main_impl (line 31) | void main_impl(int argc, char** argv)
  function main (line 82) | int main(int argc, char** argv)

FILE: example/1_tutorial/2_async.cpp
  function coro_main (line 46) | asio::awaitable<void> coro_main(
  function main_impl (line 76) | void main_impl(int argc, char** argv)
  function main (line 120) | int main(int argc, char** argv)
  function main (line 149) | int main()

FILE: example/1_tutorial/3_with_params.cpp
  function coro_main (line 43) | asio::awaitable<void> coro_main(
  function main_impl (line 99) | void main_impl(int argc, char** argv)
  function main (line 133) | int main(int argc, char** argv)
  function main (line 162) | int main()

FILE: example/1_tutorial/4_static_interface.cpp
  function print_employee (line 49) | void print_employee(std::string_view first_name, std::string_view last_n...
  type employee (line 59) | struct employee
  function coro_main (line 66) | asio::awaitable<void> coro_main(
  function main_impl (line 121) | void main_impl(int argc, char** argv)
  function main (line 155) | int main(int argc, char** argv)
  function main (line 184) | int main()

FILE: example/1_tutorial/5_updates_transactions.cpp
  type employee (line 53) | struct employee
  function coro_main (line 60) | asio::awaitable<void> coro_main(
  function main_impl (line 145) | void main_impl(int argc, char** argv)
  function main (line 176) | int main(int argc, char** argv)
  function main (line 205) | int main()

FILE: example/1_tutorial/6_connection_pool.cpp
  type employee (line 71) | struct employee
  function get_employee_details (line 80) | asio::awaitable<std::string> get_employee_details(mysql::connection_pool...
  function handle_session (line 121) | asio::awaitable<void> handle_session(mysql::connection_pool& pool, asio:...
  function listener (line 143) | asio::awaitable<void> listener(mysql::connection_pool& pool, unsigned sh...
  function main_impl (line 199) | void main_impl(int argc, char** argv)
  function main (line 270) | int main(int argc, char** argv)
  function main (line 299) | int main()

FILE: example/1_tutorial/7_error_handling.cpp
  function log_error (line 62) | void log_error(const char* header, boost::system::error_code ec, const m...
  type employee (line 88) | struct employee
  function get_employee_details (line 97) | asio::awaitable<std::string> get_employee_details(mysql::connection_pool...
  function handle_session (line 145) | asio::awaitable<void> handle_session(mysql::connection_pool& pool, asio:...
  function listener (line 209) | asio::awaitable<void> listener(mysql::connection_pool& pool, unsigned sh...
  function main_impl (line 281) | void main_impl(int argc, char** argv)
  function main (line 344) | int main(int argc, char** argv)
  function main (line 363) | int main()

FILE: example/2_simple/batch_inserts.cpp
  type employee (line 65) | struct employee
  function read_file (line 78) | static std::string read_file(const char* file_name)
  function coro_main (line 87) | asio::awaitable<void> coro_main(
  function main_impl (line 144) | void main_impl(int argc, char** argv)
  function main (line 188) | int main(int argc, char** argv)
  function main (line 217) | int main()

FILE: example/2_simple/batch_inserts_generic.cpp
  type employee (line 66) | struct employee
  function get_field_names (line 88) | constexpr std::array<std::string_view, num_public_members<T>> get_field_...
  type insert_struct_format_fn (line 102) | struct insert_struct_format_fn
  function read_file (line 124) | std::string read_file(const char* file_name)
  function coro_main (line 133) | asio::awaitable<void> coro_main(
  function main_impl (line 170) | void main_impl(int argc, char** argv)
  function main (line 214) | int main(int argc, char** argv)
  function main (line 243) | int main()

FILE: example/2_simple/callbacks.cpp
  function print_employee (line 38) | void print_employee(mysql::row_view employee)
  class session (line 48) | class session : public std::enable_shared_from_this<session>
    method session (line 57) | session(
    method error_code (line 73) | error_code get_error() const { return final_error; }
    method start (line 77) | void start()
    method on_connect (line 88) | void on_connect(error_code ec)
    method on_execute (line 112) | void on_execute(error_code ec)
    method finish (line 131) | void finish(error_code err) { final_error = err; }
  function main_impl (line 134) | void main_impl(int argc, char** argv)
  function main (line 165) | int main(int argc, char** argv)

FILE: example/2_simple/coroutines_cpp11.cpp
  function print_employee (line 37) | void print_employee(mysql::row_view employee)
  function coro_main (line 50) | void coro_main(
  function main_impl (line 96) | void main_impl(int argc, char** argv)
  function main (line 130) | int main(int argc, char** argv)

FILE: example/2_simple/deletes.cpp
  function coro_main (line 46) | asio::awaitable<void> coro_main(
  function main_impl (line 90) | void main_impl(int argc, char** argv)
  function main (line 120) | int main(int argc, char** argv)
  function main (line 149) | int main()

FILE: example/2_simple/disable_tls.cpp
  function coro_main (line 41) | asio::awaitable<void> coro_main(
  function main_impl (line 74) | void main_impl(int argc, char** argv)
  function main (line 104) | int main(int argc, char** argv)
  function main (line 133) | int main()

FILE: example/2_simple/dynamic_filters.cpp
  function print_employee (line 51) | void print_employee(mysql::row_view employee)
  type op_type (line 61) | enum class op_type
  function op_type_to_sql (line 71) | std::string_view op_type_to_sql(op_type value)
  type filter (line 87) | struct filter
  type cmdline_args (line 95) | struct cmdline_args
  function cmdline_args (line 114) | static cmdline_args parse_cmdline_args(int argc, char** argv)
  function compose_get_employees_query (line 202) | std::string compose_get_employees_query(
  function coro_main (line 252) | asio::awaitable<void> coro_main(const cmdline_args& args)
  function main_impl (line 291) | void main_impl(int argc, char** argv)
  function main (line 316) | int main(int argc, char** argv)
  function main (line 346) | int main()

FILE: example/2_simple/inserts.cpp
  function coro_main (line 49) | asio::awaitable<void> coro_main(
  function main_impl (line 98) | void main_impl(int argc, char** argv)
  function main (line 145) | int main(int argc, char** argv)
  function main (line 174) | int main()

FILE: example/2_simple/metadata.cpp
  function coro_main (line 40) | asio::awaitable<void> coro_main(
  function main_impl (line 119) | void main_impl(int argc, char** argv)
  function main (line 147) | int main(int argc, char** argv)
  function main (line 176) | int main()

FILE: example/2_simple/multi_function.cpp
  function print_employee (line 38) | void print_employee(mysql::row_view employee)
  function coro_main (line 46) | asio::awaitable<void> coro_main(
  function main_impl (line 87) | void main_impl(int argc, char** argv)
  function main (line 117) | int main(int argc, char** argv)
  function main (line 146) | int main()

FILE: example/2_simple/patch_updates.cpp
  type update_field (line 54) | struct update_field
  type cmdline_args (line 65) | struct cmdline_args
  function cmdline_args (line 84) | static cmdline_args parse_cmdline_args(int argc, char** argv)
  function coro_main (line 155) | asio::awaitable<void> coro_main(const cmdline_args& args)
  function main_impl (line 225) | void main_impl(int argc, char** argv)
  function main (line 250) | int main(int argc, char** argv)
  function main (line 279) | int main()

FILE: example/2_simple/pipeline.cpp
  function batch_prepare (line 49) | asio::awaitable<std::vector<mysql::statement>> batch_prepare(
  function coro_main (line 76) | asio::awaitable<void> coro_main(
  function main_impl (line 142) | void main_impl(int argc, char** argv)
  function main (line 170) | int main(int argc, char** argv)
  function main (line 199) | int main()

FILE: example/2_simple/prepared_statements.cpp
  function print_employee (line 40) | void print_employee(mysql::row_view employee)
  function coro_main (line 48) | asio::awaitable<void> coro_main(
  function main_impl (line 100) | void main_impl(int argc, char** argv)
  function main (line 130) | int main(int argc, char** argv)
  function main (line 159) | int main()

FILE: example/2_simple/source_script.cpp
  function read_file (line 42) | std::string read_file(const char* file_name)
  function print_column_names (line 50) | void print_column_names(boost::mysql::metadata_collection_view meta_coll...
  function print_row (line 68) | void print_row(boost::mysql::row_view row)
  function print_ok (line 83) | void print_ok(const boost::mysql::execution_state& st)
  function main_impl (line 95) | void main_impl(int argc, char** argv)
  function main (line 170) | int main(int argc, char** argv)

FILE: example/2_simple/tls_certificate_verification.cpp
  function coro_main (line 70) | asio::awaitable<void> coro_main(
  function main_impl (line 124) | void main_impl(int argc, char** argv)
  function main (line 154) | int main(int argc, char** argv)
  function main (line 183) | int main()

FILE: example/2_simple/unix_socket.cpp
  function coro_main (line 38) | asio::awaitable<void> coro_main(
  function main_impl (line 72) | void main_impl(int argc, char** argv)
  function main (line 106) | int main(int argc, char** argv)
  function main (line 135) | int main()

FILE: example/3_advanced/http_server_cpp14_coroutines/handle_request.cpp
  function log_mysql_error (line 53) | void log_mysql_error(boost::system::error_code ec, const mysql::diagnost...
  function parse_id (line 79) | boost::optional<std::int64_t> parse_id(const std::string& from)
  function error_response (line 89) | http::response<http::string_body> error_response(http::status code, cons...
  function bad_request (line 98) | http::response<http::string_body> bad_request(const char* body)
  function internal_server_error (line 105) | http::response<http::string_body> internal_server_error()
  function json_response (line 114) | http::response<http::string_body> json_response(const T& body)
  function has_json_content_type (line 131) | bool has_json_content_type(const http::request<http::string_body>& req)
  function parse_json (line 141) | boost::system::result<T> parse_json(boost::mysql::string_view json_string)
  type request_data (line 157) | struct request_data
    method note_repository (line 168) | note_repository repo() const { return note_repository(pool); }
  function handle_get (line 185) | http::response<http::string_body> handle_get(const request_data& input, ...
  function handle_post (line 218) | http::response<http::string_body> handle_post(const request_data& input,...
  function handle_put (line 237) | http::response<http::string_body> handle_put(const request_data& input, ...
  function handle_delete (line 268) | http::response<http::string_body> handle_delete(const request_data& inpu...

FILE: example/3_advanced/http_server_cpp14_coroutines/handle_request.hpp
  type notes (line 22) | namespace notes {

FILE: example/3_advanced/http_server_cpp14_coroutines/main.cpp
  function main (line 59) | int main(int argc, char* argv[])
  function main (line 139) | int main() { std::cout << "Sorry, your compiler doesn't support C++14\n"; }

FILE: example/3_advanced/http_server_cpp14_coroutines/repository.cpp
  function note_t (line 99) | note_t note_repository::create_note(

FILE: example/3_advanced/http_server_cpp14_coroutines/repository.hpp
  type notes (line 26) | namespace notes {
    class note_repository (line 32) | class note_repository
      method note_repository (line 38) | note_repository(boost::mysql::connection_pool& pool) noexcept : pool...

FILE: example/3_advanced/http_server_cpp14_coroutines/server.cpp
  function run_http_session (line 45) | void run_http_session(std::shared_ptr<shared_state> st, asio::ip::tcp::s...

FILE: example/3_advanced/http_server_cpp14_coroutines/server.hpp
  type notes (line 22) | namespace notes {
    type shared_state (line 29) | struct shared_state
      method shared_state (line 33) | shared_state(boost::mysql::connection_pool pool) noexcept : pool(std...

FILE: example/3_advanced/http_server_cpp14_coroutines/types.hpp
  type notes (line 27) | namespace notes {
    type note_t (line 29) | struct note_t
    type note_request_body (line 47) | struct note_request_body
    type multi_notes_response (line 62) | struct multi_notes_response
    type single_note_response (line 70) | struct single_note_response
    type delete_note_response (line 78) | struct delete_note_response

FILE: example/3_advanced/http_server_cpp20/db_setup.sql
  type products (line 23) | CREATE TABLE products (
  type orders (line 31) | CREATE TABLE orders(
  type order_items (line 36) | CREATE TABLE order_items(

FILE: example/3_advanced/http_server_cpp20/error.cpp
  class orders_category (line 36) | class orders_category final : public boost::system::error_category
    method message (line 43) | std::string message(int ev) const final override

FILE: example/3_advanced/http_server_cpp20/error.hpp
  type orders (line 26) | namespace orders {
    type errc (line 29) | enum class errc
    function make_error_code (line 41) | inline boost::system::error_code make_error_code(errc v)
  type boost::system::is_error_code_enum<orders::errc> (line 60) | struct boost::system::is_error_code_enum<orders::errc> : std::true_type

FILE: example/3_advanced/http_server_cpp20/handle_request.cpp
  function log_mysql_error (line 64) | void log_mysql_error(boost::system::error_code ec, const mysql::diagnost...
  function parse_id (line 92) | std::optional<std::int64_t> parse_id(std::string_view from)
  function error_response (line 102) | http::response<http::string_body> error_response(http::status code, std:...
  function bad_request (line 111) | http::response<http::string_body> bad_request(std::string_view body)
  function internal_server_error (line 118) | http::response<http::string_body> internal_server_error()
  function json_response (line 127) | http::response<http::string_body> json_response(const T& body)
  function parse_json (line 147) | result<T> parse_json(std::string_view json_string)
  function response_from_db_error (line 163) | http::response<http::string_body> response_from_db_error(boost::system::...
  type request_data (line 192) | struct request_data
    method repo (line 203) | orders::db_repository repo() const { return orders::db_repository(pool...
  function handle_get_products (line 214) | asio::awaitable<http::response<http::string_body>> handle_get_products(c...
  function handle_get_orders (line 232) | asio::awaitable<http::response<http::string_body>> handle_get_orders(con...
  function handle_create_order (line 267) | asio::awaitable<http::response<http::string_body>> handle_create_order(c...
  function handle_add_order_item (line 278) | asio::awaitable<http::response<http::string_body>> handle_add_order_item...
  function handle_remove_order_item (line 302) | asio::awaitable<http::response<http::string_body>> handle_remove_order_i...
  function handle_checkout_order (line 323) | asio::awaitable<http::response<http::string_body>> handle_checkout_order...
  function handle_complete_order (line 344) | asio::awaitable<http::response<http::string_body>> handle_complete_order...
  type http_endpoint (line 365) | struct http_endpoint

FILE: example/3_advanced/http_server_cpp20/handle_request.hpp
  type orders (line 22) | namespace orders {

FILE: example/3_advanced/http_server_cpp20/main.cpp
  function main_impl (line 73) | int main_impl(int argc, char* argv[])
  function main (line 164) | int main(int argc, char** argv)
  function main (line 183) | int main()

FILE: example/3_advanced/http_server_cpp20/repository.cpp
  function change_order_status (line 297) | static asio::awaitable<boost::system::result<order_with_items>> change_o...

FILE: example/3_advanced/http_server_cpp20/repository.hpp
  type orders (line 27) | namespace orders {
    class db_repository (line 33) | class db_repository
      method db_repository (line 39) | db_repository(boost::mysql::connection_pool& pool) noexcept : pool_(...

FILE: example/3_advanced/http_server_cpp20/server.cpp
  function run_http_session (line 58) | asio::awaitable<void> run_http_session(asio::ip::tcp::socket sock, mysql...

FILE: example/3_advanced/http_server_cpp20/server.hpp
  type orders (line 20) | namespace orders {

FILE: example/3_advanced/http_server_cpp20/types.hpp
  type orders (line 29) | namespace orders {
    type product (line 32) | struct product
    type order (line 50) | struct order
    type order_item (line 67) | struct order_item
    type order_with_items (line 84) | struct order_with_items
    type add_order_item_request (line 98) | struct add_order_item_request

FILE: example/db_setup.sql
  type company (line 17) | CREATE TABLE company(
  type employee (line 22) | CREATE TABLE employee(
  type audit_log (line 30) | CREATE TABLE audit_log(
  type notes (line 35) | CREATE TABLE notes(

FILE: example/private/launch_server.py
  function _parse_server_start_line (line 21) | def _parse_server_start_line(line: str) -> int:
  function launch_server (line 29) | def launch_server(exe: str, host: str, username: str, password: str):

FILE: example/private/run_batch_inserts.py
  class _Runner (line 17) | class _Runner:
    method __init__ (line 18) | def __init__(self, exe: str, host: str) -> None:
    method run (line 22) | def run(self, fname: str) -> None:
  function main (line 29) | def main():

FILE: example/private/run_dynamic_filters.py
  class _Runner (line 15) | class _Runner:
    method __init__ (line 16) | def __init__(self, exe: str, host: str) -> None:
    method run (line 20) | def run(self, opts: List[str]) -> None:
  function main (line 26) | def main():

FILE: example/private/run_notes.py
  function _check_response (line 19) | def _check_response(res: requests.Response):
  function _random_string (line 25) | def _random_string() -> str:
  function _call_endpoints (line 29) | def _call_endpoints(port: int):
  function main (line 85) | def main():

FILE: example/private/run_orders.py
  class TestOrders (line 20) | class TestOrders(unittest.TestCase):
    method _base_url (line 24) | def _base_url(self) -> str:
    method _json_response (line 28) | def _json_response(res: requests.Response):
    method _check_error (line 35) | def _check_error(self, res: requests.Response, expected_status: int) -...
    method _request (line 39) | def _request(self, method: str, url: str, **kwargs) -> requests.Response:
    method _request_as_json (line 43) | def _request_as_json(self, method: str, url: str, **kwargs):
    method _request_error (line 47) | def _request_error(self, method: str, url: str, expected_status: int, ...
    method test_search_products (line 53) | def test_search_products(self) -> None:
    method test_order_lifecycle (line 66) | def test_order_lifecycle(self) -> None:
    method test_remove_items (line 101) | def test_remove_items(self) -> None:
    method test_get_orders (line 133) | def test_get_orders(self) -> None:
    method test_get_single_order (line 138) | def test_get_single_order(self) -> None:
    method test_search_products_missing_param (line 155) | def test_search_products_missing_param(self) -> None:
    method test_get_order_invalid_id (line 162) | def test_get_order_invalid_id(self) -> None:
    method test_get_order_not_found (line 166) | def test_get_order_not_found(self) -> None:
    method test_add_order_item_invalid_content_type (line 173) | def test_add_order_item_invalid_content_type(self) -> None:
    method test_add_order_item_invalid_json (line 185) | def test_add_order_item_invalid_json(self) -> None:
    method test_add_order_item_invalid_json_keys (line 190) | def test_add_order_item_invalid_json_keys(self) -> None:
    method test_add_order_item_order_not_found (line 198) | def test_add_order_item_order_not_found(self) -> None:
    method test_add_order_item_product_not_found (line 206) | def test_add_order_item_product_not_found(self) -> None:
    method test_add_order_item_order_not_editable (line 218) | def test_add_order_item_order_not_editable(self) -> None:
    method test_remove_order_item_missing_id (line 233) | def test_remove_order_item_missing_id(self) -> None:
    method test_remove_order_item_invalid_id (line 237) | def test_remove_order_item_invalid_id(self) -> None:
    method test_remove_order_item_not_found (line 241) | def test_remove_order_item_not_found(self) -> None:
    method test_remove_order_item_order_not_editable (line 245) | def test_remove_order_item_order_not_editable(self) -> None:
    method test_checkout_order_missing_id (line 262) | def test_checkout_order_missing_id(self) -> None:
    method test_checkout_order_invalid_id (line 266) | def test_checkout_order_invalid_id(self) -> None:
    method test_checkout_order_not_found (line 270) | def test_checkout_order_not_found(self) -> None:
    method test_checkout_order_not_editable (line 274) | def test_checkout_order_not_editable(self) -> None:
    method test_complete_order_missing_id (line 286) | def test_complete_order_missing_id(self) -> None:
    method test_complete_order_invalid_id (line 290) | def test_complete_order_invalid_id(self) -> None:
    method test_complete_order_not_found (line 294) | def test_complete_order_not_found(self) -> None:
    method test_complete_order_not_editable (line 298) | def test_complete_order_not_editable(self) -> None:
    method test_endpoint_not_found (line 310) | def test_endpoint_not_found(self) -> None:
    method test_method_not_allowed (line 315) | def test_method_not_allowed(self) -> None:
  function main (line 319) | def main():

FILE: example/private/run_patch_updates.py
  class _Runner (line 15) | class _Runner:
    method __init__ (line 16) | def __init__(self, exe: str, host: str) -> None:
    method run (line 20) | def run(self, updates: List[str]) -> None:
  function main (line 27) | def main():

FILE: example/private/run_tutorial_connection_pool.py
  class _Runner (line 19) | class _Runner:
    method __init__ (line 20) | def __init__(self, port: int) -> None:
    method _connect (line 23) | def _connect(self) -> socket.socket:
    method _query_employee (line 29) | def _query_employee(self, employee_id: int) -> str:
    method _generate_error (line 43) | def _generate_error(self) -> None:
    method run (line 52) | def run(self, test_errors: bool) -> None:
  function main (line 61) | def main():

FILE: example/private/test_script.sql
  type products (line 10) | CREATE TEMPORARY TABLE products (

FILE: include/boost/mysql/any_address.hpp
  type boost (line 18) | namespace boost {
    type mysql (line 19) | namespace mysql {
      type address_type (line 22) | enum class address_type
      type host_and_port (line 36) | struct host_and_port
      type unix_path (line 57) | struct unix_path
      class any_address (line 77) | class any_address
        method any_address (line 87) | any_address(address_type t, std::string&& addr, unsigned short por...
        method any_address (line 103) | any_address() noexcept : any_address(address_type::host_and_port, ...
        method any_address (line 112) | any_address(const any_address& other) = default;
        method any_address (line 120) | any_address(any_address&& other) = default;
        method any_address (line 129) | any_address& operator=(const any_address& other) = default;
        method any_address (line 137) | any_address& operator=(any_address&& other) = default;
        method any_address (line 153) | any_address(host_and_port value) noexcept
        method any_address (line 169) | any_address(unix_path value) noexcept : impl_{address_type::unix_p...
        method address_type (line 176) | address_type type() const noexcept { return impl_.type; }
        method string_view (line 190) | string_view hostname() const noexcept
        method port (line 204) | unsigned short port() const noexcept
        method string_view (line 222) | string_view unix_socket_path() const noexcept
        method emplace_host_and_port (line 245) | void emplace_host_and_port(std::string hostname, unsigned short po...
        method emplace_unix_path (line 267) | void emplace_unix_path(std::string path)

FILE: include/boost/mysql/any_connection.hpp
  type boost (line 47) | namespace boost {
    type mysql (line 48) | namespace mysql {
      class static_execution_state (line 52) | class static_execution_state
      class pipeline_request (line 54) | class pipeline_request
      class stage_response (line 55) | class stage_response
      type any_connection_params (line 60) | struct any_connection_params
      class any_connection (line 151) | class any_connection
        method any_connection (line 163) | any_connection(std::unique_ptr<detail::engine> eng, any_connection...
        method any_connection (line 178) | any_connection(boost::asio::any_io_executor ex, any_connection_par...
        class ExecutionContext (line 196) | class ExecutionContext
        method any_connection (line 204) | any_connection(ExecutionContext& ctx, any_connection_params params...
        method any_connection (line 212) | any_connection(any_connection&& other) = default;
        method any_connection (line 217) | any_connection& operator=(any_connection&& rhs) = default;
        method any_connection (line 220) | any_connection(const any_connection&) = delete;
        method any_connection (line 221) | any_connection& operator=(const any_connection&) = delete;
        method executor_type (line 241) | executor_type get_executor() noexcept { return impl_.get_engine()....
        method uses_ssl (line 256) | bool uses_ssl() const noexcept { return impl_.ssl_active(); }
        method backslash_escapes (line 281) | bool backslash_escapes() const noexcept { return impl_.backslash_e...
        method current_character_set (line 311) | system::result<character_set> current_character_set() const noexcept
        method format_opts (line 328) | system::result<format_options> format_opts() const noexcept
        method metadata_mode (line 344) | metadata_mode meta_mode() const noexcept { return impl_.meta_mode(...
        method set_meta_mode (line 359) | void set_meta_mode(metadata_mode v) noexcept { impl_.set_meta_mode...
        method connection_id (line 394) | boost::optional<std::uint32_t> connection_id() const noexcept { re...
        method connect (line 432) | void connect(const connect_params& params, error_code& ec, diagnos...
        method connect (line 438) | void connect(const connect_params& params)
        method BOOST_MYSQL_RETURN_TYPE (line 470) | BOOST_MYSQL_RETURN_TYPE(detail::async_connect_v2_t<CompletionToken...
        method BOOST_MYSQL_RETURN_TYPE (line 480) | BOOST_MYSQL_RETURN_TYPE(detail::async_connect_v2_t<CompletionToken...
        method execute (line 501) | void execute(ExecutionRequest&& req, ResultsType& result, error_co...
        method execute (line 508) | void execute(ExecutionRequest&& req, ResultsType& result)
        method BOOST_MYSQL_RETURN_TYPE (line 549) | BOOST_MYSQL_RETURN_TYPE(detail::async_execute_t<ExecutionRequest&&...
        method BOOST_MYSQL_RETURN_TYPE (line 570) | BOOST_MYSQL_RETURN_TYPE(detail::async_execute_t<ExecutionRequest&&...
        method start_execution (line 608) | void start_execution(ExecutionRequest&& req, ExecutionStateType& s...
        method start_execution (line 617) | void start_execution(ExecutionRequest&& req, ExecutionStateType& st)
        method BOOST_MYSQL_RETURN_TYPE (line 658) | BOOST_MYSQL_RETURN_TYPE(detail::async_start_execution_t<
        method BOOST_MYSQL_RETURN_TYPE (line 683) | BOOST_MYSQL_RETURN_TYPE(detail::async_start_execution_t<
        method statement (line 703) | statement prepare_statement(string_view stmt, error_code& err, dia...
        method statement (line 709) | statement prepare_statement(string_view stmt)
        method BOOST_MYSQL_RETURN_TYPE (line 743) | BOOST_MYSQL_RETURN_TYPE(detail::async_prepare_statement_t<Completi...
        method BOOST_MYSQL_RETURN_TYPE (line 753) | BOOST_MYSQL_RETURN_TYPE(detail::async_prepare_statement_t<Completi...
        method close_statement (line 770) | void close_statement(const statement& stmt, error_code& err, diagn...
        method close_statement (line 776) | void close_statement(const statement& stmt)
        method BOOST_MYSQL_RETURN_TYPE (line 807) | BOOST_MYSQL_RETURN_TYPE(detail::async_close_statement_t<Completion...
        method BOOST_MYSQL_RETURN_TYPE (line 817) | BOOST_MYSQL_RETURN_TYPE(detail::async_close_statement_t<Completion...
        method rows_view (line 838) | rows_view read_some_rows(execution_state& st, error_code& err, dia...
        method rows_view (line 844) | rows_view read_some_rows(execution_state& st)
        method BOOST_MYSQL_RETURN_TYPE (line 874) | BOOST_MYSQL_RETURN_TYPE(detail::async_read_some_rows_dynamic_t<Com...
        method BOOST_MYSQL_RETURN_TYPE (line 884) | BOOST_MYSQL_RETURN_TYPE(detail::async_read_some_rows_dynamic_t<Com...
        method read_some_rows (line 920) | std::size_t read_some_rows(
        method read_some_rows (line 958) | std::size_t read_some_rows(static_execution_state<StaticRow...>& s...
      function read_resultset_head (line 1110) | void read_resultset_head(ExecutionStateType& st, error_code& err, di...
      function read_resultset_head (line 1117) | void read_resultset_head(ExecutionStateType& st)
      function BOOST_MYSQL_RETURN_TYPE (line 1146) | BOOST_MYSQL_RETURN_TYPE(detail::async_read_resultset_head_t<Completi...
      function BOOST_MYSQL_RETURN_TYPE (line 1157) | BOOST_MYSQL_RETURN_TYPE(detail::async_read_resultset_head_t<Completi...
      function set_character_set (line 1184) | void set_character_set(const character_set& charset, error_code& err...
      function set_character_set (line 1190) | void set_character_set(const character_set& charset)
      function BOOST_MYSQL_RETURN_TYPE (line 1219) | BOOST_MYSQL_RETURN_TYPE(detail::async_set_character_set_t<Completion...
      function BOOST_MYSQL_RETURN_TYPE (line 1232) | BOOST_MYSQL_RETURN_TYPE(detail::async_set_character_set_t<Completion...
      function ping (line 1252) | void ping(error_code& err, diagnostics& diag) { impl_.run(detail::pi...
      function ping (line 1255) | void ping()
      function BOOST_MYSQL_RETURN_TYPE (line 1284) | BOOST_MYSQL_RETURN_TYPE(detail::async_ping_t<CompletionToken&&>)
      function BOOST_MYSQL_RETURN_TYPE (line 1294) | BOOST_MYSQL_RETURN_TYPE(detail::async_ping_t<CompletionToken&&>)
      function reset_connection (line 1334) | void reset_connection(error_code& err, diagnostics& diag)
      function reset_connection (line 1340) | void reset_connection()
      function BOOST_MYSQL_RETURN_TYPE (line 1369) | BOOST_MYSQL_RETURN_TYPE(detail::async_reset_connection_t<CompletionT...
      function BOOST_MYSQL_RETURN_TYPE (line 1379) | BOOST_MYSQL_RETURN_TYPE(detail::async_reset_connection_t<CompletionT...
      function close (line 1404) | void close(error_code& err, diagnostics& diag)
      function close (line 1410) | void close()
      function BOOST_MYSQL_RETURN_TYPE (line 1438) | BOOST_MYSQL_RETURN_TYPE(detail::async_close_connection_t<CompletionT...
      function BOOST_MYSQL_RETURN_TYPE (line 1448) | BOOST_MYSQL_RETURN_TYPE(detail::async_close_connection_t<CompletionT...
      function run_pipeline (line 1475) | void run_pipeline(
      function run_pipeline (line 1486) | void run_pipeline(const pipeline_request& req, std::vector<stage_res...
      function BOOST_MYSQL_RETURN_TYPE (line 1521) | BOOST_MYSQL_RETURN_TYPE(detail::async_run_pipeline_t<CompletionToken...
      function BOOST_MYSQL_RETURN_TYPE (line 1535) | BOOST_MYSQL_RETURN_TYPE(detail::async_run_pipeline_t<CompletionToken...

FILE: include/boost/mysql/bad_field_access.hpp
  type boost (line 13) | namespace boost {
    type mysql (line 14) | namespace mysql {
      class bad_field_access (line 18) | class bad_field_access : public std::exception

FILE: include/boost/mysql/blob.hpp
  type boost (line 13) | namespace boost {
    type mysql (line 14) | namespace mysql {

FILE: include/boost/mysql/blob_view.hpp
  type boost (line 13) | namespace boost {
    type mysql (line 14) | namespace mysql {

FILE: include/boost/mysql/buffer_params.hpp
  type boost (line 17) | namespace boost {
    type mysql (line 18) | namespace mysql {
      class buffer_params (line 28) | class buffer_params
        method buffer_params (line 41) | constexpr explicit buffer_params(std::size_t initial_read_size = d...
        method initial_read_size (line 47) | constexpr std::size_t initial_read_size() const noexcept { return ...
        method set_initial_read_size (line 50) | void set_initial_read_size(std::size_t v) noexcept { initial_read_...

FILE: include/boost/mysql/character_set.hpp
  type boost (line 18) | namespace boost {
    type mysql (line 19) | namespace mysql {
      type character_set (line 28) | struct character_set
      type format_options (line 75) | struct format_options

FILE: include/boost/mysql/client_errc.hpp
  type boost (line 17) | namespace boost {
    type mysql (line 18) | namespace mysql {
      type client_errc (line 24) | enum class client_errc : int
      function error_code (line 184) | inline error_code make_error_code(client_errc error)
    type system (line 192) | namespace system {
      type is_error_code_enum<::boost::mysql::client_errc> (line 195) | struct is_error_code_enum<::boost::mysql::client_errc>

FILE: include/boost/mysql/column_type.hpp
  type boost (line 15) | namespace boost {
    type mysql (line 16) | namespace mysql {
      type column_type (line 28) | enum class column_type

FILE: include/boost/mysql/common_server_errc.hpp
  type boost (line 17) | namespace boost {
    type mysql (line 18) | namespace mysql {
      type common_server_errc (line 28) | enum class common_server_errc : int
      function error_code (line 5107) | inline error_code make_error_code(common_server_errc error)
    type system (line 5115) | namespace system {
      type is_error_code_enum<::boost::mysql::common_server_errc> (line 5118) | struct is_error_code_enum<::boost::mysql::common_server_errc>

FILE: include/boost/mysql/connect_params.hpp
  type boost (line 18) | namespace boost {
    type mysql (line 19) | namespace mysql {
      type connect_params (line 27) | struct connect_params

FILE: include/boost/mysql/connection.hpp
  type boost (line 40) | namespace boost {
    type mysql (line 42) | namespace mysql {
      class static_execution_state (line 46) | class static_execution_state
      class connection (line 74) | class connection
        method connection (line 93) | connection(Args&&... args) : connection(buffer_params(), std::forw...
        method connection (line 112) | connection(const buffer_params& buff_params, Args&&... args)
        method connection (line 124) | connection(connection&& other) = default;
        method connection (line 129) | connection& operator=(connection&& rhs) = default;
        method connection (line 132) | connection(const connection&) = delete;
        method connection (line 133) | connection& operator=(const connection&) = delete;
        method executor_type (line 140) | executor_type get_executor() { return stream().get_executor(); }
        method Stream (line 152) | Stream& stream() noexcept { return detail::stream_from_engine<Stre...
        method Stream (line 161) | const Stream& stream() const noexcept { return detail::stream_from...
        method uses_ssl (line 180) | bool uses_ssl() const noexcept { return impl_.ssl_active(); }
        method metadata_mode (line 183) | metadata_mode meta_mode() const noexcept { return impl_.meta_mode(...
        method set_meta_mode (line 186) | void set_meta_mode(metadata_mode v) noexcept { impl_.set_meta_mode...
        method connect (line 203) | void connect(
        method connect (line 219) | void connect(const EndpointType& endpoint, const handshake_params&...
        method CompletionToken (line 254) | CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_...
        method CompletionToken (line 273) | CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_...
        method handshake (line 303) | void handshake(const handshake_params& params, error_code& ec, dia...
        method handshake (line 309) | void handshake(const handshake_params& params)
        method BOOST_MYSQL_RETURN_TYPE (line 341) | BOOST_MYSQL_RETURN_TYPE(detail::async_handshake_t<CompletionToken&&>)
        method BOOST_MYSQL_RETURN_TYPE (line 353) | BOOST_MYSQL_RETURN_TYPE(detail::async_handshake_t<CompletionToken&&>)
        method execute (line 361) | void execute(ExecutionRequest&& req, ResultsType& result, error_co...
        method execute (line 368) | void execute(ExecutionRequest&& req, ResultsType& result)
        method BOOST_MYSQL_RETURN_TYPE (line 386) | BOOST_MYSQL_RETURN_TYPE(detail::async_execute_t<ExecutionRequest&&...
        method BOOST_MYSQL_RETURN_TYPE (line 407) | BOOST_MYSQL_RETURN_TYPE(detail::async_execute_t<ExecutionRequest&&...
        method start_execution (line 421) | void start_execution(ExecutionRequest&& req, ExecutionStateType& s...
        method start_execution (line 430) | void start_execution(ExecutionRequest&& req, ExecutionStateType& st)
        method BOOST_MYSQL_RETURN_TYPE (line 449) | BOOST_MYSQL_RETURN_TYPE(detail::async_start_execution_t<
        method BOOST_MYSQL_RETURN_TYPE (line 474) | BOOST_MYSQL_RETURN_TYPE(detail::async_start_execution_t<
        method statement (line 488) | statement prepare_statement(string_view stmt, error_code& err, dia...
        method statement (line 494) | statement prepare_statement(string_view stmt)
        method BOOST_MYSQL_RETURN_TYPE (line 509) | BOOST_MYSQL_RETURN_TYPE(detail::async_prepare_statement_t<Completi...
        method BOOST_MYSQL_RETURN_TYPE (line 521) | BOOST_MYSQL_RETURN_TYPE(detail::async_prepare_statement_t<Completi...
        method close_statement (line 531) | void close_statement(const statement& stmt, error_code& err, diagn...
        method close_statement (line 537) | void close_statement(const statement& stmt)
        method BOOST_MYSQL_RETURN_TYPE (line 551) | BOOST_MYSQL_RETURN_TYPE(detail::async_close_statement_t<Completion...
        method BOOST_MYSQL_RETURN_TYPE (line 563) | BOOST_MYSQL_RETURN_TYPE(detail::async_close_statement_t<Completion...
        method rows_view (line 570) | rows_view read_some_rows(execution_state& st, error_code& err, dia...
        method rows_view (line 576) | rows_view read_some_rows(execution_state& st)
        method BOOST_MYSQL_RETURN_TYPE (line 591) | BOOST_MYSQL_RETURN_TYPE(detail::async_read_some_rows_dynamic_t<Com...
        method BOOST_MYSQL_RETURN_TYPE (line 603) | BOOST_MYSQL_RETURN_TYPE(detail::async_read_some_rows_dynamic_t<Com...
        method read_some_rows (line 640) | std::size_t read_some_rows(
        method read_some_rows (line 679) | std::size_t read_some_rows(static_execution_state<StaticRow...>& s...
        method CompletionToken (line 737) | CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_...
        method CompletionToken (line 797) | CompletionToken BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_...
        method read_resultset_head (line 816) | void read_resultset_head(ExecutionStateType& st, error_code& err, ...
        method read_resultset_head (line 823) | void read_resultset_head(ExecutionStateType& st)
        method BOOST_MYSQL_RETURN_TYPE (line 839) | BOOST_MYSQL_RETURN_TYPE(detail::async_read_resultset_head_t<Comple...
        method BOOST_MYSQL_RETURN_TYPE (line 853) | BOOST_MYSQL_RETURN_TYPE(detail::async_read_resultset_head_t<Comple...
        method ping (line 860) | void ping(error_code& err, diagnostics& diag) { impl_.run(detail::...
        method ping (line 863) | void ping()
        method BOOST_MYSQL_RETURN_TYPE (line 875) | BOOST_MYSQL_RETURN_TYPE(detail::async_ping_t<CompletionToken&&>)
        method BOOST_MYSQL_RETURN_TYPE (line 886) | BOOST_MYSQL_RETURN_TYPE(detail::async_ping_t<CompletionToken&&>)
        method reset_connection (line 923) | void reset_connection(error_code& err, diagnostics& diag)
        method reset_connection (line 929) | void reset_connection()
        method BOOST_MYSQL_RETURN_TYPE (line 957) | BOOST_MYSQL_RETURN_TYPE(detail::async_reset_connection_t<Completio...
        method BOOST_MYSQL_RETURN_TYPE (line 968) | BOOST_MYSQL_RETURN_TYPE(detail::async_reset_connection_t<Completio...
        method close (line 983) | void close(error_code& err, diagnostics& diag)
        method close (line 993) | void close()
        method BOOST_MYSQL_RETURN_TYPE (line 1024) | BOOST_MYSQL_RETURN_TYPE(detail::async_close_connection_t<Completio...
        method BOOST_MYSQL_RETURN_TYPE (line 1039) | BOOST_MYSQL_RETURN_TYPE(detail::async_close_connection_t<Completio...
        method quit (line 1059) | void quit(error_code& err, diagnostics& diag)
        method quit (line 1065) | void quit()
        method BOOST_MYSQL_RETURN_TYPE (line 1092) | BOOST_MYSQL_RETURN_TYPE(detail::async_quit_connection_t<Completion...
        method BOOST_MYSQL_RETURN_TYPE (line 1103) | BOOST_MYSQL_RETURN_TYPE(detail::async_quit_connection_t<Completion...
        type rebind_executor (line 1117) | struct rebind_executor

FILE: include/boost/mysql/connection_pool.hpp
  type boost (line 30) | namespace boost {
    type mysql (line 31) | namespace mysql {
      class pooled_connection (line 63) | class pooled_connection
        type impl_t (line 70) | struct impl_t
        method pooled_connection (line 76) | pooled_connection(detail::connection_node& node, std::shared_ptr<d...
        method pooled_connection (line 91) | pooled_connection() noexcept = default;
        method pooled_connection (line 104) | pooled_connection(pooled_connection&& other) noexcept : impl_(std:...
        method pooled_connection (line 124) | pooled_connection& operator=(pooled_connection&& other) noexcept
        method pooled_connection (line 135) | pooled_connection(const pooled_connection&) = delete;
        method pooled_connection (line 136) | pooled_connection& operator=(const pooled_connection&) = delete;
        method valid (line 162) | bool valid() const noexcept { return impl_.pool.get() != nullptr; }
        method any_connection (line 176) | any_connection& get() noexcept { return detail::get_connection(*im...
        method any_connection (line 179) | const any_connection& get() const noexcept { return detail::get_co...
        method any_connection (line 182) | any_connection* operator->() noexcept { return &get(); }
        method any_connection (line 185) | const any_connection* operator->() const noexcept { return &get(); }
        method return_without_reset (line 215) | void return_without_reset() noexcept
      class connection_pool (line 298) | class connection_pool
        type initiate_run (line 306) | struct initiate_run : detail::initiation_base
        type initiate_get_connection (line 324) | struct initiate_get_connection : detail::initiation_base
        method async_get_connection_impl (line 343) | auto async_get_connection_impl(diagnostics* diag, CompletionToken&...
        method connection_pool (line 389) | connection_pool(asio::any_io_executor ex, pool_params params)
        class ExecutionContext (line 408) | class ExecutionContext
        method connection_pool (line 416) | connection_pool(ExecutionContext& ctx, pool_params params)
        method connection_pool (line 422) | connection_pool(const connection_pool&) = delete;
        method connection_pool (line 423) | connection_pool& operator=(const connection_pool&) = delete;
        method connection_pool (line 450) | connection_pool(connection_pool&& other) = default;
        method connection_pool (line 476) | connection_pool& operator=(connection_pool&& other) = default;
        method valid (line 517) | bool valid() const noexcept { return impl_.get() != nullptr; }
        method BOOST_MYSQL_RETURN_TYPE (line 604) | BOOST_MYSQL_RETURN_TYPE(decltype(asio::async_initiate<CompletionTo...
        method BOOST_MYSQL_RETURN_TYPE (line 701) | BOOST_MYSQL_RETURN_TYPE(
        method BOOST_MYSQL_RETURN_TYPE (line 712) | BOOST_MYSQL_RETURN_TYPE(

FILE: include/boost/mysql/constant_string_view.hpp
  type boost (line 19) | namespace boost {
    type mysql (line 20) | namespace mysql {
      class constant_string_view (line 32) | class constant_string_view
        method constant_string_view (line 37) | constexpr constant_string_view(string_view value, int) noexcept : ...
        class T (line 63) | class T
        method BOOST_MYSQL_CONSTEVAL (line 69) | BOOST_MYSQL_CONSTEVAL constant_string_view(const T& value) noexcep...
        method string_view (line 82) | constexpr string_view get() const noexcept { return impl_; }
      function constant_string_view (line 100) | constexpr constant_string_view runtime(string_view value) noexcept {...
        method constant_string_view (line 37) | constexpr constant_string_view(string_view value, int) noexcept : ...
        class T (line 63) | class T
        method BOOST_MYSQL_CONSTEVAL (line 69) | BOOST_MYSQL_CONSTEVAL constant_string_view(const T& value) noexcep...
        method string_view (line 82) | constexpr string_view get() const noexcept { return impl_; }

FILE: include/boost/mysql/date.hpp
  type boost (line 25) | namespace boost {
    type mysql (line 26) | namespace mysql {
      class date (line 52) | class date
        method date (line 72) | constexpr date() noexcept = default;
        method date (line 83) | constexpr date(std::uint16_t year, std::uint8_t month, std::uint8_...
        method BOOST_CXX14_CONSTEXPR (line 98) | BOOST_CXX14_CONSTEXPR explicit date(time_point tp)
        method date (line 119) | constexpr explicit date(std::chrono::local_days tp) : date(time_po...
        method year (line 131) | constexpr std::uint16_t year() const noexcept { return year_; }
        method month (line 142) | constexpr std::uint8_t month() const noexcept { return month_; }
        method day (line 154) | constexpr std::uint8_t day() const noexcept { return day_; }
        method valid (line 165) | constexpr bool valid() const noexcept { return detail::is_valid(ye...
        method BOOST_CXX14_CONSTEXPR (line 179) | BOOST_CXX14_CONSTEXPR time_point get_time_point() const noexcept
        method BOOST_CXX14_CONSTEXPR (line 195) | BOOST_CXX14_CONSTEXPR time_point as_time_point() const
        method get_local_time_point (line 218) | constexpr std::chrono::local_days get_local_time_point() const noe...
        method as_local_time_point (line 237) | constexpr std::chrono::local_days as_local_time_point() const
        method date (line 271) | static date now()
        method BOOST_CXX14_CONSTEXPR (line 282) | BOOST_CXX14_CONSTEXPR days unch_get_days() const

FILE: include/boost/mysql/datetime.hpp
  type boost (line 26) | namespace boost {
    type mysql (line 27) | namespace mysql {
      class datetime (line 53) | class datetime
        method datetime (line 82) | constexpr datetime() noexcept = default;
        method datetime (line 92) | constexpr datetime(
        method datetime (line 134) | constexpr explicit datetime(local_time_point tp) : datetime(time_p...
        method year (line 146) | constexpr std::uint16_t year() const noexcept { return year_; }
        method month (line 157) | constexpr std::uint8_t month() const noexcept { return month_; }
        method day (line 169) | constexpr std::uint8_t day() const noexcept { return day_; }
        method hour (line 177) | constexpr std::uint8_t hour() const noexcept { return hour_; }
        method minute (line 185) | constexpr std::uint8_t minute() const noexcept { return minute_; }
        method second (line 193) | constexpr std::uint8_t second() const noexcept { return second_; }
        method microsecond (line 201) | constexpr std::uint32_t microsecond() const noexcept { return micr...
        method valid (line 213) | constexpr bool valid() const noexcept
        method BOOST_CXX14_CONSTEXPR (line 231) | BOOST_CXX14_CONSTEXPR time_point get_time_point() const noexcept
        method BOOST_CXX14_CONSTEXPR (line 247) | BOOST_CXX14_CONSTEXPR inline time_point as_time_point() const
        method local_time_point (line 270) | constexpr local_time_point get_local_time_point() const noexcept
        method local_time_point (line 289) | constexpr local_time_point as_local_time_point() const
        method datetime (line 323) | static datetime now()
  function BOOST_CXX14_CONSTEXPR (line 366) | BOOST_CXX14_CONSTEXPR boost::mysql::datetime::datetime(time_point tp)

FILE: include/boost/mysql/days.hpp
  type boost (line 13) | namespace boost {
    type mysql (line 14) | namespace mysql {

FILE: include/boost/mysql/defaults.hpp
  type boost (line 15) | namespace boost {
    type mysql (line 16) | namespace mysql {

FILE: include/boost/mysql/detail/access.hpp
  type boost (line 13) | namespace boost {
    type mysql (line 14) | namespace mysql {
      type detail (line 15) | namespace detail {
        type access (line 19) | struct access
          method T (line 34) | static T construct(Args&&... args)

FILE: include/boost/mysql/detail/algo_params.hpp
  type boost (line 24) | namespace boost {
    type mysql (line 25) | namespace mysql {
      class rows_view (line 27) | class rows_view
      class statement (line 28) | class statement
      class stage_response (line 29) | class stage_response
      type detail (line 31) | namespace detail {
        class execution_processor (line 33) | class execution_processor
        class execution_state_impl (line 34) | class execution_state_impl
        type pipeline_request_stage (line 35) | struct pipeline_request_stage
        type connect_algo_params (line 37) | struct connect_algo_params
        type handshake_algo_params (line 47) | struct handshake_algo_params
        type execute_algo_params (line 55) | struct execute_algo_params
        type start_execution_algo_params (line 63) | struct start_execution_algo_params
        type read_resultset_head_algo_params (line 71) | struct read_resultset_head_algo_params
        type read_some_rows_algo_params (line 78) | struct read_some_rows_algo_params
        type read_some_rows_dynamic_algo_params (line 86) | struct read_some_rows_dynamic_algo_params
        type prepare_statement_algo_params (line 93) | struct prepare_statement_algo_params
        type close_statement_algo_params (line 100) | struct close_statement_algo_params
        type ping_algo_params (line 107) | struct ping_algo_params
        type reset_connection_algo_params (line 112) | struct reset_connection_algo_params
        type set_character_set_algo_params (line 117) | struct set_character_set_algo_params
        type quit_connection_algo_params (line 124) | struct quit_connection_algo_params
        type close_connection_algo_params (line 129) | struct close_connection_algo_params
        type run_pipeline_algo_params (line 134) | struct run_pipeline_algo_params

FILE: include/boost/mysql/detail/any_execution_request.hpp
  type boost (line 20) | namespace boost {
    type mysql (line 21) | namespace mysql {
      class field_view (line 23) | class field_view
      class format_arg (line 24) | class format_arg
      type detail (line 26) | namespace detail {
        type any_execution_request (line 28) | struct any_execution_request
          type type_t (line 30) | enum class type_t
          type query_with_params_t (line 40) | struct query_with_params_t
          type stmt_t (line 45) | struct stmt_t
          method data_t (line 52) | data_t(string_view q) noexcept : query(q) {}
          method data_t (line 53) | data_t(query_with_params_t v) noexcept : query_with_params(v) {}
          method data_t (line 54) | data_t(stmt_t v) noexcept : stmt(v) {}
          method any_execution_request (line 60) | any_execution_request(string_view q) noexcept : type(type_t::que...
          method any_execution_request (line 61) | any_execution_request(data_t::query_with_params_t v) noexcept : ...
          method any_execution_request (line 64) | any_execution_request(data_t::stmt_t v) noexcept : type(type_t::...
        type no_execution_request_traits (line 67) | struct no_execution_request_traits
        type execution_request_traits (line 72) | struct execution_request_traits : no_execution_request_traits
        type execution_request_traits<T, typename std::enable_if<std::is_convertible<T, string_view>::value>::type> (line 77) | struct execution_request_traits<T, typename std::enable_if<std::is...
          method any_execution_request (line 79) | static any_execution_request make_request(string_view input, std...

FILE: include/boost/mysql/detail/any_resumable_ref.hpp
  type boost (line 16) | namespace boost {
    type mysql (line 17) | namespace mysql {
      type detail (line 18) | namespace detail {
        class any_resumable_ref (line 20) | class any_resumable_ref
          method any_resumable_ref (line 26) | explicit any_resumable_ref(T& op) noexcept : algo_(&op), fn_(&do...
          method any_resumable_ref (line 31) | any_resumable_ref(void* algo, fn_t fn) noexcept : algo_(algo), f...
          method next_action (line 33) | next_action resume(error_code ec, std::size_t bytes_transferred)
          method next_action (line 40) | static next_action do_resume(void* self, error_code ec, std::siz...

FILE: include/boost/mysql/detail/character_set.hpp
  type boost (line 17) | namespace boost {
    type mysql (line 18) | namespace mysql {
      type detail (line 19) | namespace detail {
        function next_char_ascii (line 21) | inline std::size_t next_char_ascii(span<const unsigned char> input...

FILE: include/boost/mysql/detail/coldef_view.hpp
  type boost (line 16) | namespace boost {
    type mysql (line 17) | namespace mysql {
      type detail (line 18) | namespace detail {
        type coldef_view (line 20) | struct coldef_view

FILE: include/boost/mysql/detail/connect_params_helpers.hpp
  type boost (line 16) | namespace boost {
    type mysql (line 17) | namespace mysql {
      type detail (line 18) | namespace detail {
        function ssl_mode (line 20) | inline ssl_mode adjust_ssl_mode(ssl_mode input, address_type addr_...
        function handshake_params (line 25) | inline handshake_params make_hparams(const connect_params& input)

FILE: include/boost/mysql/detail/connection_impl.hpp
  type boost (line 44) | namespace boost {
    type mysql (line 45) | namespace mysql {
      class static_execution_state (line 49) | class static_execution_state
      type character_set (line 51) | struct character_set
      class pipeline_request (line 52) | class pipeline_request
      type detail (line 54) | namespace detail {
        class connection_state (line 59) | class connection_state
        type connection_state_deleter (line 61) | struct connection_state_deleter
        type completion_signature_impl (line 82) | struct completion_signature_impl
        type completion_signature_impl<AlgoParams, true> (line 85) | struct completion_signature_impl<AlgoParams, true>
        type completion_signature_impl<AlgoParams, false> (line 92) | struct completion_signature_impl<AlgoParams, false>
        type generic_algo_fn (line 105) | struct generic_algo_fn
        class connection_impl (line 122) | class connection_impl
          method get_executor (line 127) | asio::any_io_executor get_executor() const { return engine_->get...
          method make_request (line 131) | static auto make_request(T&& input, connection_state& st)
          method run_impl (line 145) | typename AlgoParams::result_type run_impl(
          method run_impl (line 156) | typename AlgoParams::result_type run_impl(
          method async_run_impl (line 168) | static void async_run_impl(
          method async_run_impl (line 181) | static void async_run_impl(
          method async_run_impl (line 197) | static void async_run_impl(
          type run_algo_initiation (line 208) | struct run_algo_initiation : initiation_base
          method connect_algo_params (line 226) | static connect_algo_params make_params_connect(const void* serve...
          method connect_algo_params (line 231) | static connect_algo_params make_params_connect_v2(const connect_...
          type initiate_connect (line 241) | struct initiate_connect : initiation_base
          type initiate_connect_v2 (line 265) | struct initiate_connect_v2 : initiation_base
          type initiate_execute (line 283) | struct initiate_execute : initiation_base
          type initiate_start_execution (line 308) | struct initiate_start_execution : initiation_base
          method engine (line 347) | engine& get_engine()
          method engine (line 353) | const engine& get_engine() const
          method run (line 361) | typename AlgoParams::result_type run(AlgoParams params, error_co...
          method async_run (line 367) | auto async_run(AlgoParams params, diagnostics& diag, CompletionT...
          method connect (line 389) | void connect(
          method connect_v2 (line 399) | void connect_v2(const connect_params& params, error_code& err, d...
          method async_connect (line 405) | auto async_connect(
          method async_connect_v2 (line 433) | auto async_connect_v2(const connect_params& params, diagnostics&...
          method handshake_algo_params (line 454) | handshake_algo_params make_params_handshake(const handshake_para...
          method execute (line 461) | void execute(ExecutionRequest&& req, ResultsType& result, error_...
          method async_execute (line 474) | auto async_execute(
          method start_execution (line 503) | void start_execution(
          method async_start_execution (line 521) | auto async_start_execution(
          method read_some_rows_dynamic_algo_params (line 549) | read_some_rows_dynamic_algo_params make_params_read_some_rows(ex...
          method read_some_rows_algo_params (line 556) | read_some_rows_algo_params make_params_read_some_rows_static(
          method read_resultset_head_algo_params (line 569) | read_resultset_head_algo_params make_params_read_resultset_head(...
          method close_statement_algo_params (line 575) | close_statement_algo_params make_params_close_statement(statemen...
          method connection_state (line 585) | connection_state& get_state() { return *st_; }

FILE: include/boost/mysql/detail/connection_pool_fwd.hpp
  type boost (line 15) | namespace boost {
    type mysql (line 16) | namespace mysql {
      class pooled_connection (line 18) | class pooled_connection
      class any_connection (line 19) | class any_connection
      type detail (line 21) | namespace detail {
        class basic_connection_node (line 24) | class basic_connection_node
        class basic_pool_impl (line 27) | class basic_pool_impl

FILE: include/boost/mysql/detail/datetime.hpp
  type boost (line 20) | namespace boost {
    type mysql (line 21) | namespace mysql {
      type detail (line 22) | namespace detail {
        function is_leap (line 27) | constexpr bool is_leap(std::uint16_t y) noexcept { return y % 4 ==...
        function last_month_day (line 29) | constexpr inline std::uint8_t last_month_day(std::uint16_t y, std:...
        function is_valid (line 43) | constexpr inline bool is_valid(std::uint16_t years, std::uint8_t m...
        function BOOST_CXX14_CONSTEXPR (line 49) | BOOST_CXX14_CONSTEXPR inline int ymd_to_days(
        function BOOST_CXX14_CONSTEXPR (line 67) | BOOST_CXX14_CONSTEXPR inline bool days_to_ymd(

FILE: include/boost/mysql/detail/engine.hpp
  type boost (line 16) | namespace boost {
    type mysql (line 17) | namespace mysql {
      type detail (line 18) | namespace detail {
        class engine (line 20) | class engine

FILE: include/boost/mysql/detail/engine_impl.hpp
  type boost (line 31) | namespace boost {
    type mysql (line 32) | namespace mysql {
      type detail (line 33) | namespace detail {
        function to_buffer (line 35) | inline asio::mutable_buffer to_buffer(span<std::uint8_t> buff) noe...
        function has_terminal_cancellation (line 40) | inline bool has_terminal_cancellation(asio::cancellation_type_t ca...
        type run_algo_op (line 46) | struct run_algo_op
          method run_algo_op (line 54) | run_algo_op(EngineStream& stream, any_resumable_ref algo) noexce...
        class engine_impl (line 163) | class engine_impl final : public engine
          method engine_impl (line 169) | engine_impl(Args&&... args) : stream_(std::forward<Args>(args)...)
          method EngineStream (line 173) | EngineStream& stream() { return stream_; }
          method EngineStream (line 174) | const EngineStream& stream() const { return stream_; }
          method executor_type (line 177) | executor_type get_executor() override final { return stream_.get...
          method supports_ssl (line 179) | bool supports_ssl() const override final { return stream_.suppor...
          method run (line 181) | void run(any_resumable_ref resumable, error_code& ec) override f...
          method async_run (line 235) | void async_run(any_resumable_ref resumable, asio::any_completion...

FILE: include/boost/mysql/detail/engine_stream_adaptor.hpp
  type boost (line 29) | namespace boost {
    type mysql (line 30) | namespace mysql {
      type detail (line 31) | namespace detail {
        function do_connect_impl (line 36) | void do_connect_impl(Stream&, const void*, error_code&, std::false...
        function do_connect_impl (line 43) | void do_connect_impl(Stream& stream, const void* ep, error_code& e...
        function do_connect (line 52) | void do_connect(Stream& stream, const void* ep, error_code& ec)
        function do_async_connect_impl (line 59) | void do_async_connect_impl(Stream&, const void*, CompletionToken&&...
        function do_async_connect_impl (line 66) | void do_async_connect_impl(Stream& stream, const void* ep, Complet...
        function do_async_connect (line 75) | void do_async_connect(Stream& stream, const void* ep, CompletionTo...
        function do_close_impl (line 82) | void do_close_impl(Stream&, error_code&, std::false_type)
        function do_close_impl (line 89) | void do_close_impl(Stream& stream, error_code& ec, std::true_type)
        function do_close (line 96) | void do_close(Stream& stream, error_code& ec)
        class engine_stream_adaptor (line 102) | class engine_stream_adaptor
          method engine_stream_adaptor (line 108) | engine_stream_adaptor(Args&&... args) : stream_(std::forward<Arg...
          method Stream (line 112) | Stream& stream() { return stream_; }
          method Stream (line 113) | const Stream& stream() const { return stream_; }
          method supports_ssl (line 115) | bool supports_ssl() const { return false; }
          method executor_type (line 118) | executor_type get_executor() { return stream_.get_executor(); }
          method ssl_handshake (line 122) | void ssl_handshake(error_code&) { BOOST_ASSERT(false); }
          method async_ssl_handshake (line 125) | void async_ssl_handshake(CompletinToken&&)
          method ssl_shutdown (line 130) | void ssl_shutdown(error_code&) { BOOST_ASSERT(false); }
          method async_ssl_shutdown (line 133) | void async_ssl_shutdown(CompletionToken&&)
          method read_some (line 140) | std::size_t read_some(boost::asio::mutable_buffer buff, bool use...
          method async_read_some (line 148) | void async_read_some(boost::asio::mutable_buffer buff, bool use_...
          method write_some (line 156) | std::size_t write_some(boost::asio::const_buffer buff, bool use_...
          method async_write_some (line 164) | void async_write_some(boost::asio::const_buffer buff, bool use_s...
          method connect (line 172) | void connect(const void* endpoint, error_code& ec) { do_connect(...
          method async_connect (line 175) | void async_connect(const void* endpoint, CompletionToken&& token)
          method close (line 180) | void close(error_code& ec) { do_close(stream_, ec); }
        class engine_stream_adaptor<asio::ssl::stream<Stream>> (line 184) | class engine_stream_adaptor<asio::ssl::stream<Stream>>
          method engine_stream_adaptor (line 190) | engine_stream_adaptor(Args&&... args) : stream_(std::forward<Arg...
          method supports_ssl (line 197) | bool supports_ssl() const { return true; }
          method executor_type (line 200) | executor_type get_executor() { return stream_.get_executor(); }
          method ssl_handshake (line 203) | void ssl_handshake(error_code& ec) { stream_.handshake(asio::ssl...
          method async_ssl_handshake (line 206) | void async_ssl_handshake(CompletionToken&& token)
          method ssl_shutdown (line 211) | void ssl_shutdown(error_code& ec) { stream_.shutdown(ec); }
          method async_ssl_shutdown (line 214) | void async_ssl_shutdown(CompletionToken&& token)
          method read_some (line 220) | std::size_t read_some(boost::asio::mutable_buffer buff, bool use...
          method async_read_some (line 233) | void async_read_some(boost::asio::mutable_buffer buff, bool use_...
          method write_some (line 246) | std::size_t write_some(boost::asio::const_buffer buff, bool use_...
          method async_write_some (line 259) | void async_write_some(boost::asio::const_buffer buff, bool use_s...
          method connect (line 272) | void connect(const void* endpoint, error_code& ec) { do_connect(...
          method async_connect (line 275) | void async_connect(const void* endpoint, CompletionToken&& token)
          method close (line 280) | void close(error_code& ec) { do_close(stream_, ec); }
        class engine_impl<engine_stream_adaptor<asio::ssl::stream<asio::ip::tcp::socket>>> (line 284) | class engine_impl<engine_stream_adaptor<asio::ssl::stream<asio::ip...
        class engine_impl<engine_stream_adaptor<asio::ip::tcp::socket>> (line 285) | class engine_impl<engine_stream_adaptor<asio::ip::tcp::socket>>
        function make_engine (line 289) | std::unique_ptr<engine> make_engine(Args&&... args)
        function Stream (line 297) | Stream& stream_from_engine(engine& eng)
        function Stream (line 304) | const Stream& stream_from_engine(const engine& eng)

FILE: include/boost/mysql/detail/escape_string.hpp
  type boost (line 19) | namespace boost {
    type mysql (line 20) | namespace mysql {
      type format_options (line 23) | struct format_options
      type detail (line 25) | namespace detail {

FILE: include/boost/mysql/detail/execution_concepts.hpp
  type boost (line 20) | namespace boost {
    type mysql (line 21) | namespace mysql {
      class static_execution_state (line 25) | class static_execution_state
      class static_results (line 28) | class static_results
      class execution_state (line 30) | class execution_state
      class results (line 31) | class results
      type detail (line 33) | namespace detail {
        type is_static_execution_state (line 37) | struct is_static_execution_state : std::false_type
        type is_static_results (line 51) | struct is_static_results : std::false_type
        type is_execution_request (line 65) | struct is_execution_request
  type is_static_execution_state<static_execution_state<T...>> (line 42) | struct is_static_execution_state<static_execution_state<T...>> : std::tr...
  type is_static_results<static_results<T...>> (line 56) | struct is_static_results<static_results<T...>> : std::true_type

FILE: include/boost/mysql/detail/execution_processor/execution_processor.hpp
  type boost (line 31) | namespace boost {
    type mysql (line 32) | namespace mysql {
      type detail (line 33) | namespace detail {
        class output_ref (line 36) | class output_ref
          method output_ref (line 51) | constexpr output_ref() noexcept = default;
          method output_ref (line 54) | constexpr output_ref(boost::span<T> span, std::size_t type_index...
          method max_size (line 59) | std::size_t max_size() const noexcept { return max_size_; }
          method type_index (line 60) | std::size_t type_index() const noexcept { return type_index_; }
          method offset (line 61) | std::size_t offset() const noexcept { return offset_; }
          method set_offset (line 62) | void set_offset(std::size_t v) noexcept { offset_ = v; }
          method T (line 65) | T& span_element() const noexcept
        class execution_processor (line 72) | class execution_processor
          method reset (line 77) | void reset(resultset_encoding enc, metadata_mode mode) noexcept
          method BOOST_ATTRIBUTE_NODISCARD (line 87) | BOOST_ATTRIBUTE_NODISCARD
          method on_num_meta (line 96) | void on_num_meta(std::size_t num_columns)
          method BOOST_ATTRIBUTE_NODISCARD (line 104) | BOOST_ATTRIBUTE_NODISCARD
          method on_row_batch_start (line 115) | void on_row_batch_start()
          method on_row_batch_finish (line 121) | void on_row_batch_finish() { on_row_batch_finish_impl(); }
          method BOOST_ATTRIBUTE_NODISCARD (line 123) | BOOST_ATTRIBUTE_NODISCARD
          method BOOST_ATTRIBUTE_NODISCARD (line 130) | BOOST_ATTRIBUTE_NODISCARD
          method is_reading_first (line 139) | bool is_reading_first() const noexcept { return state_ == state_...
          method is_reading_first_subseq (line 140) | bool is_reading_first_subseq() const noexcept { return state_ ==...
          method is_reading_head (line 141) | bool is_reading_head() const noexcept
          method is_reading_meta (line 145) | bool is_reading_meta() const noexcept { return state_ == state_t...
          method is_reading_rows (line 146) | bool is_reading_rows() const noexcept { return state_ == state_t...
          method is_complete (line 147) | bool is_complete() const noexcept { return state_ == state_t::co...
          method resultset_encoding (line 149) | resultset_encoding encoding() const noexcept { return encoding_; }
          method metadata_mode (line 151) | metadata_mode meta_mode() const noexcept { return mode_; }
          method metadata (line 167) | metadata create_meta(const coldef_view& coldef) const
          type state_t (line 173) | enum class state_t
          method set_state (line 198) | void set_state(state_t v) noexcept { state_ = v; }
          method set_state_for_ok (line 200) | void set_state_for_ok(const ok_view& pack) noexcept

FILE: include/boost/mysql/detail/execution_processor/execution_state_impl.hpp
  type boost (line 25) | namespace boost {
    type mysql (line 26) | namespace mysql {
      type detail (line 27) | namespace detail {
        class execution_state_impl (line 29) | class execution_state_impl final : public execution_processor
          type ok_data (line 31) | struct ok_data
          method on_new_resultset (line 44) | void on_new_resultset() noexcept
          method on_row_batch_start_impl (line 73) | void on_row_batch_start_impl() noexcept override final {}
          method on_row_batch_finish_impl (line 75) | void on_row_batch_finish_impl() noexcept override final {}
          method execution_state_impl (line 78) | execution_state_impl() = default;
          method metadata_collection_view (line 80) | metadata_collection_view meta() const noexcept { return meta_; }
          method get_affected_rows (line 82) | std::uint64_t get_affected_rows() const noexcept
          method get_last_insert_id (line 88) | std::uint64_t get_last_insert_id() const noexcept
          method get_warning_count (line 94) | unsigned get_warning_count() const noexcept
          method string_view (line 100) | string_view get_info() const noexcept
          method get_is_out_params (line 106) | bool get_is_out_params() const noexcept
          method execution_state_impl (line 112) | execution_state_impl& get_interface() noexcept { return *this; }

FILE: include/boost/mysql/detail/execution_processor/results_impl.hpp
  type boost (line 25) | namespace boost {
    type mysql (line 26) | namespace mysql {
      type detail (line 27) | namespace detail {
        type per_resultset_data (line 29) | struct per_resultset_data
        class resultset_container (line 45) | class resultset_container
          method resultset_container (line 52) | resultset_container() = default;
          method size (line 53) | std::size_t size() const noexcept { return !first_has_data_ ? 0 ...
          method empty (line 54) | bool empty() const noexcept { return !first_has_data_; }
          method clear (line 55) | void clear() noexcept
          method per_resultset_data (line 60) | per_resultset_data& operator[](std::size_t i) noexcept
          method per_resultset_data (line 64) | const per_resultset_data& operator[](std::size_t i) const noexcept
          method per_resultset_data (line 69) | per_resultset_data& back() noexcept
          method per_resultset_data (line 73) | const per_resultset_data& back() const noexcept
        class results_impl (line 88) | class results_impl final : public execution_processor
          method results_impl (line 91) | results_impl() = default;
          method num_resultsets (line 96) | std::size_t num_resultsets() const noexcept { return per_result_...
          method rows_view (line 98) | rows_view get_rows(std::size_t index) const noexcept
          method metadata_collection_view (line 108) | metadata_collection_view get_meta(std::size_t index) const noexcept
          method get_affected_rows (line 117) | std::uint64_t get_affected_rows(std::size_t index) const noexcept
          method get_last_insert_id (line 122) | std::uint64_t get_last_insert_id(std::size_t index) const noexcept
          method get_warning_count (line 127) | unsigned get_warning_count(std::size_t index) const noexcept { r...
          method string_view (line 129) | string_view get_info(std::size_t index) const noexcept
          method get_is_out_params (line 135) | bool get_is_out_params(std::size_t index) const noexcept { retur...
          method results_impl (line 137) | results_impl& get_interface() noexcept { return *this; }
          method has_active_batch (line 176) | bool has_active_batch() const noexcept { return num_fields_at_ba...
          method per_resultset_data (line 181) | per_resultset_data& current_resultset() noexcept
          method per_resultset_data (line 187) | const per_resultset_data& current_resultset() const noexcept
          method per_resultset_data (line 199) | const per_resultset_data& get_resultset(std::size_t index) const...
          method metadata_collection_view (line 205) | metadata_collection_view current_resultset_meta() const noexcept

FILE: include/boost/mysql/detail/execution_processor/static_execution_state_impl.hpp
  type boost (line 31) | namespace boost {
    type mysql (line 32) | namespace mysql {
      type detail (line 33) | namespace detail {
        type execst_resultset_descriptor (line 38) | struct execst_resultset_descriptor
        class execst_external_data (line 47) | class execst_external_data
          type ptr_data (line 50) | struct ptr_data
          method execst_external_data (line 55) | execst_external_data(span<const execst_resultset_descriptor> des...
          method num_resultsets (line 60) | std::size_t num_resultsets() const noexcept { return desc_.size(...
          method num_columns (line 61) | std::size_t num_columns(std::size_t idx) const noexcept
          method name_table_t (line 66) | name_table_t name_table(std::size_t idx) const noexcept
          method meta_check_fn_t (line 71) | meta_check_fn_t meta_check_fn(std::size_t idx) const noexcept
          method execst_parse_fn_t (line 76) | execst_parse_fn_t parse_fn(std::size_t idx) const noexcept
          method type_index (line 81) | std::size_t type_index(std::size_t idx) const noexcept
          method pos_map (line 86) | span<std::size_t> pos_map(std::size_t idx) const noexcept
          method set_pointers (line 91) | void set_pointers(ptr_data ptr) noexcept { ptr_ = ptr; }
        class static_execution_state_erased_impl (line 98) | class static_execution_state_erased_impl final : public execution_...
          method static_execution_state_erased_impl (line 101) | static_execution_state_erased_impl(execst_external_data ext) noe...
          method execst_external_data (line 103) | execst_external_data& ext_data() noexcept { return ext_; }
          method metadata_collection_view (line 105) | metadata_collection_view meta() const noexcept { return meta_; }
          method get_affected_rows (line 107) | std::uint64_t get_affected_rows() const noexcept
          method get_last_insert_id (line 113) | std::uint64_t get_last_insert_id() const noexcept
          method get_warning_count (line 119) | unsigned get_warning_count() const noexcept
          method string_view (line 125) | string_view get_info() const noexcept
          method get_is_out_params (line 131) | bool get_is_out_params() const noexcept
          type ok_packet_data (line 139) | struct ok_packet_data
          method on_row_batch_start_impl (line 177) | void on_row_batch_start_impl() noexcept override final {}
          method on_row_batch_finish_impl (line 179) | void on_row_batch_finish_impl() noexcept override final {}
          method name_table_t (line 182) | name_table_t current_name_table() const noexcept { return ext_.n...
          method current_pos_map (line 183) | span<std::size_t> current_pos_map() noexcept { return ext_.pos_m...
          method current_pos_map (line 184) | span<const std::size_t> current_pos_map() const noexcept { retur...
          method error_code (line 186) | error_code meta_check(diagnostics& diag) const
        function error_code (line 199) | static error_code execst_parse_fn(
        function create_execst_resultset_descriptors (line 209) | constexpr std::array<execst_resultset_descriptor, sizeof...(Static...
        class static_execution_state_impl (line 225) | class static_execution_state_impl
          method ptr_data (line 236) | execst_external_data::ptr_data ptr_data() noexcept
          method set_pointers (line 243) | void set_pointers() noexcept { impl_.ext_data().set_pointers(ptr...
          method static_execution_state_impl (line 246) | static_execution_state_impl() noexcept
          method static_execution_state_impl (line 251) | static_execution_state_impl(const static_execution_state_impl& r...
          method static_execution_state_impl (line 256) | static_execution_state_impl(static_execution_state_impl&& rhs) n...
          method static_execution_state_impl (line 262) | static_execution_state_impl& operator=(const static_execution_st...
          method static_execution_state_impl (line 270) | static_execution_state_impl& operator=(static_execution_state_im...
          method output_ref (line 281) | output_ref make_output_ref(span<SpanElementType> output, std::si...
          method static_execution_state_erased_impl (line 291) | const static_execution_state_erased_impl& get_interface() const ...
          method static_execution_state_erased_impl (line 292) | static_execution_state_erased_impl& get_interface() noexcept { r...

FILE: include/boost/mysql/detail/execution_processor/static_results_impl.hpp
  type boost (line 32) | namespace boost {
    type mysql (line 33) | namespace mysql {
      type detail (line 34) | namespace detail {
        type results_resultset_descriptor (line 40) | struct results_resultset_descriptor
        type static_per_resultset_data (line 48) | struct static_per_resultset_data
        class results_external_data (line 61) | class results_external_data
          type ptr_data (line 64) | struct ptr_data
          method results_external_data (line 71) | results_external_data(
          method set_pointers (line 80) | void set_pointers(ptr_data ptr) noexcept { ptr_ = ptr; }
          method num_resultsets (line 82) | std::size_t num_resultsets() const noexcept { return desc_.size(...
          method num_columns (line 83) | std::size_t num_columns(std::size_t idx) const noexcept
          method name_table_t (line 88) | name_table_t name_table(std::size_t idx) const noexcept
          method meta_check_fn_t (line 93) | meta_check_fn_t meta_check_fn(std::size_t idx) const noexcept
          method results_parse_fn_t (line 98) | results_parse_fn_t parse_fn(std::size_t idx) const noexcept
          method results_reset_fn_t (line 103) | results_reset_fn_t reset_fn() const noexcept { return reset_; }
          method pos_map (line 105) | span<std::size_t> pos_map(std::size_t idx) const noexcept
          method static_per_resultset_data (line 109) | static_per_resultset_data& per_result(std::size_t idx) const noe...
        class static_results_erased_impl (line 121) | class static_results_erased_impl final : public execution_processor
          method static_results_erased_impl (line 124) | static_results_erased_impl(results_external_data ext) noexcept :...
          method results_external_data (line 126) | results_external_data& ext_data() noexcept { return ext_; }
          method metadata_collection_view (line 128) | metadata_collection_view get_meta(std::size_t index) const noexcept
          method get_affected_rows (line 134) | std::uint64_t get_affected_rows(std::size_t index) const noexcept
          method get_last_insert_id (line 139) | std::uint64_t get_last_insert_id(std::size_t index) const noexcept
          method get_warning_count (line 144) | unsigned get_warning_count(std::size_t index) const noexcept { r...
          method string_view (line 146) | string_view get_info(std::size_t index) const noexcept
          method get_is_out_params (line 152) | bool get_is_out_params(std::size_t index) const noexcept { retur...
          method on_row_batch_start_impl (line 175) | void on_row_batch_start_impl() override final {}
          method on_row_batch_finish_impl (line 176) | void on_row_batch_finish_impl() override final {}
          method current_pos_map (line 185) | span<std::size_t> current_pos_map() noexcept { return ext_.pos_m...
          method current_pos_map (line 186) | span<const std::size_t> current_pos_map() const noexcept { retur...
          method name_table_t (line 187) | name_table_t current_name_table() const noexcept { return ext_.n...
          method static_per_resultset_data (line 188) | static_per_resultset_data& current_resultset() noexcept { return...
          method metadata_collection_view (line 189) | metadata_collection_view current_resultset_meta() const noexcept
          method error_code (line 200) | error_code meta_check(diagnostics& diag) const
        type results_fns (line 210) | struct results_fns
          type reset_fn (line 214) | struct reset_fn
          method reset (line 225) | static void reset(void* rows_ptr) noexcept
          method error_code (line 232) | static error_code do_parse(span<const std::size_t> pos_map, span...
          method results_resultset_descriptor (line 241) | static constexpr results_resultset_descriptor create_descriptor()
          method create_descriptors (line 253) | static constexpr std::array<results_resultset_descriptor, sizeof...
        class static_results_impl (line 271) | class static_results_impl
          method ptr_data (line 284) | results_external_data::ptr_data ptr_data() noexcept
          method set_pointers (line 293) | void set_pointers() noexcept { impl_.ext_data().set_pointers(ptr...
          method static_results_impl (line 296) | static_results_impl() noexcept
          method static_results_impl (line 305) | static_results_impl(const static_results_impl& rhs) : data_(rhs....
          method static_results_impl (line 310) | static_results_impl(static_results_impl&& rhs) noexcept
          method static_results_impl (line 316) | static_results_impl& operator=(const static_results_impl& rhs)
          method static_results_impl (line 324) | static_results_impl& operator=(static_results_impl&& rhs)
          method get_rows (line 334) | rows_span_t<I, StaticRow...> get_rows() const noexcept
          method static_results_erased_impl (line 339) | const static_results_erased_impl& get_interface() const noexcept...
          method static_results_erased_impl (line 340) | static_results_erased_impl& get_interface() noexcept { return im...

FILE: include/boost/mysql/detail/field_impl.hpp
  type boost (line 25) | namespace boost {
    type mysql (line 26) | namespace mysql {
      type detail (line 27) | namespace detail {
        type field_impl (line 30) | struct field_impl
          method field_impl (line 50) | field_impl() = default;
          method field_impl (line 53) | field_impl(Args&&... args) noexcept(std::is_nothrow_constructibl...
          method field_kind (line 58) | field_kind kind() const noexcept { return static_cast<field_kind...
          method T (line 61) | const T& as() const
          method T (line 70) | T& as()
          method T (line 79) | const T& get() const noexcept
          method T (line 86) | T& get() noexcept

FILE: include/boost/mysql/detail/flags.hpp
  type boost (line 15) | namespace boost {
    type mysql (line 16) | namespace mysql {
      type detail (line 17) | namespace detail {
        type column_flags (line 19) | namespace column_flags {
        type status_flags (line 40) | namespace status_flags {

FILE: include/boost/mysql/detail/format_sql.hpp
  type boost (line 21) | namespace boost {
    type mysql (line 22) | namespace mysql {
      type formatter (line 26) | struct formatter
      class format_context_base (line 28) | class format_context_base
      class formattable_ref (line 29) | class formattable_ref
      class format_arg (line 30) | class format_arg
      type detail (line 32) | namespace detail {
        class format_state (line 34) | class format_state
        type formatter_is_unspecialized (line 36) | struct formatter_is_unspecialized
        function has_specialized_formatter (line 41) | constexpr bool has_specialized_formatter()
        type is_writable_field_ref (line 47) | struct is_writable_field_ref : is_writable_field<typename std::dec...
        type is_formattable_ref (line 52) | struct is_formattable_ref : std::is_same<typename std::decay<T>::t...
        function is_formattable_range_elm_type (line 58) | constexpr bool is_formattable_range_elm_type()
        type is_formattable_range (line 64) | struct is_formattable_range : std::false_type
        function is_formattable_type (line 88) | constexpr bool is_formattable_type()
        type formattable_ref_impl (line 119) | struct formattable_ref_impl
          type type_t (line 121) | enum class type_t
          type fn_and_ptr (line 128) | struct fn_and_ptr
          method data_t (line 139) | data_t(field_view fv) noexcept : fv(fv) {}
          method data_t (line 140) | data_t(fn_and_ptr v) noexcept : custom(v) {}
  type is_formattable_range<
    T,
    typename std::enable_if<
        // std::begin and std::end can be called on it, and we can compare values
        std::is_convertible<decltype(std::begin(std::declval<T&>()) != std::end(std::declval<T&>())), bool>::
            value &&

        // value_type is either a writable field or a type with a specialized formatter.
        // We don't support sequences of sequences out of the box (no known use case)
        is_formattable_range_elm_type<decltype(*std::begin(std::declval<T&>()))>()

        // end of conditions
        >::type> (line 71) | struct is_formattable_range<

FILE: include/boost/mysql/detail/initiation_base.hpp
  type boost (line 19) | namespace boost {
    type mysql (line 20) | namespace mysql {
      type detail (line 21) | namespace detail {
        type executor_with_default (line 23) | struct executor_with_default : asio::any_io_executor
          method executor_with_default (line 30) | executor_with_default(const InnerExecutor1& ex) noexcept : asio:...
        type initiation_base (line 38) | struct initiation_base
          method initiation_base (line 42) | initiation_base(asio::any_io_executor ex) noexcept : ex(std::mov...
          method executor_type (line 45) | const executor_type& get_executor() const noexcept { return ex; }

FILE: include/boost/mysql/detail/intermediate_handler.hpp
  type boost (line 15) | namespace boost {
    type mysql (line 16) | namespace mysql {
      type detail (line 17) | namespace detail {
        type intermediate_handler (line 22) | struct intermediate_handler
        function make_intermediate_handler (line 35) | intermediate_handler<typename std::decay<HandlerFn>::type, typenam...
    type asio (line 46) | namespace asio {
      type associator<Associator, mysql::detail::intermediate_handler<HandlerFn, FinalHandler>, DefaultCandidate> (line 54) | struct associator<Associator, mysql::detail::intermediate_handler<Ha...
        method get (line 57) | static typename Associator<FinalHandler, DefaultCandidate>::type get(
        method get (line 64) | static auto get(

FILE: include/boost/mysql/detail/next_action.hpp
  type boost (line 18) | namespace boost {
    type mysql (line 19) | namespace mysql {
      type detail (line 20) | namespace detail {
        type next_action_type (line 22) | enum class next_action_type
        class next_action (line 33) | class next_action
          type read_args_t (line 36) | struct read_args_t
          type write_args_t (line 42) | struct write_args_t
          method next_action (line 48) | next_action(error_code ec = {}) noexcept : type_(next_action_typ...
          method next_action_type (line 51) | next_action_type type() const noexcept { return type_; }
          method is_done (line 52) | bool is_done() const noexcept { return type_ == next_action_type...
          method success (line 53) | bool success() const noexcept { return is_done() && !data_.ec; }
          method error_code (line 56) | error_code error() const noexcept
          method read_args_t (line 62) | read_args_t read_args() const noexcept
          method write_args_t (line 67) | write_args_t write_args() const noexcept
          method next_action (line 73) | static next_action connect(const void* endpoint) noexcept
          method next_action (line 77) | static next_action read(read_args_t args) noexcept { return next...
          method next_action (line 78) | static next_action write(write_args_t args) noexcept
          method next_action (line 82) | static next_action ssl_handshake() noexcept
          method next_action (line 86) | static next_action ssl_shutdown() noexcept
          method next_action (line 90) | static next_action close() noexcept { return next_action(next_ac...
          method data_t (line 101) | data_t() noexcept : ec(error_code()) {}
          method data_t (line 102) | data_t(const void* endpoint) noexcept : connect_endpoint(endpoin...
          method data_t (line 103) | data_t(error_code ec) noexcept : ec(ec) {}
          method data_t (line 104) | data_t(read_args_t args) noexcept : read_args(args) {}
          method data_t (line 105) | data_t(write_args_t args) noexcept : write_args(args) {}
          method next_action (line 108) | next_action(next_action_type t, data_t data) noexcept : type_(t)...

FILE: include/boost/mysql/detail/ok_view.hpp
  type boost (line 17) | namespace boost {
    type mysql (line 18) | namespace mysql {
      type detail (line 19) | namespace detail {
        type ok_view (line 21) | struct ok_view
          method more_results (line 29) | bool more_results() const noexcept { return status_flags & statu...
          method backslash_escapes (line 30) | bool backslash_escapes() const noexcept { return !(status_flags ...
          method is_out_params (line 31) | bool is_out_params() const noexcept { return status_flags & stat...

FILE: include/boost/mysql/detail/output_string.hpp
  type boost (line 21) | namespace boost {
    type mysql (line 22) | namespace mysql {
      type detail (line 23) | namespace detail {
        class output_string_ref (line 41) | class output_string_ref
          method do_append (line 49) | static void do_append(void* container, const char* data, std::si...
          method output_string_ref (line 55) | output_string_ref(append_fn_t append_fn, void* container) noexcept
          method output_string_ref (line 61) | static output_string_ref create(T& obj) noexcept
          method append (line 66) | void append(string_view data)

FILE: include/boost/mysql/detail/pipeline.hpp
  type boost (line 18) | namespace boost {
    type mysql (line 19) | namespace mysql {
      type detail (line 20) | namespace detail {
        class execution_processor (line 22) | class execution_processor
        type pipeline_stage_kind (line 24) | enum class pipeline_stage_kind
        type pipeline_request_stage (line 34) | struct pipeline_request_stage
          method stage_specific_t (line 44) | stage_specific_t() noexcept : nothing() {}
          method stage_specific_t (line 45) | stage_specific_t(resultset_encoding v) noexcept : enc(v) {}
          method stage_specific_t (line 46) | stage_specific_t(character_set v) noexcept : charset(v) {}

FILE: include/boost/mysql/detail/rebind_executor.hpp
  type boost (line 13) | namespace boost {
    type mysql (line 14) | namespace mysql {
      type detail (line 15) | namespace detail {
        type rebind_executor (line 19) | struct rebind_executor
        type rebind_executor<boost::asio::ssl::stream<Stream>, Executor> (line 25) | struct rebind_executor<boost::asio::ssl::stream<Stream>, Executor>

FILE: include/boost/mysql/detail/results_iterator.hpp
  type boost (line 17) | namespace boost {
    type mysql (line 18) | namespace mysql {
      type detail (line 19) | namespace detail {
        class results_iterator (line 21) | class results_iterator
          method results_iterator (line 33) | results_iterator() = default;
          method results_iterator (line 34) | results_iterator(const results_impl* self, std::size_t index) no...
          method results_iterator (line 36) | results_iterator& operator++() noexcept
          method results_iterator (line 41) | results_iterator operator++(int) noexcept
          method results_iterator (line 47) | results_iterator& operator--() noexcept
          method results_iterator (line 52) | results_iterator operator--(int) noexcept
          method results_iterator (line 58) | results_iterator& operator+=(std::ptrdiff_t n) noexcept
          method results_iterator (line 63) | results_iterator& operator-=(std::ptrdiff_t n) noexcept
          method results_iterator (line 68) | results_iterator operator+(std::ptrdiff_t n) const noexcept
          method results_iterator (line 72) | results_iterator operator-(std::ptrdiff_t n) const noexcept { re...
          method pointer (line 75) | pointer operator->() const noexcept { return **this; }
          method reference (line 76) | reference operator*() const noexcept { return (*this)[0]; }
          method reference (line 77) | reference operator[](std::ptrdiff_t i) const noexcept
          method index (line 89) | std::size_t index() const noexcept { return index_; }
          method results_impl (line 90) | const results_impl* obj() const noexcept { return self_; }
        function results_iterator (line 93) | inline results_iterator operator+(std::ptrdiff_t n, results_iterat...
          method results_iterator (line 33) | results_iterator() = default;
          method results_iterator (line 34) | results_iterator(const results_impl* self, std::size_t index) no...
          method results_iterator (line 36) | results_iterator& operator++() noexcept
          method results_iterator (line 41) | results_iterator operator++(int) noexcept
          method results_iterator (line 47) | results_iterator& operator--() noexcept
          method results_iterator (line 52) | results_iterator operator--(int) noexcept
          method results_iterator (line 58) | results_iterator& operator+=(std::ptrdiff_t n) noexcept
          method results_iterator (line 63) | results_iterator& operator-=(std::ptrdiff_t n) noexcept
          method results_iterator (line 68) | results_iterator operator+(std::ptrdiff_t n) const noexcept
          method results_iterator (line 72) | results_iterator operator-(std::ptrdiff_t n) const noexcept { re...
          method pointer (line 75) | pointer operator->() const noexcept { return **this; }
          method reference (line 76) | reference operator*() const noexcept { return (*this)[0]; }
          method reference (line 77) | reference operator[](std::ptrdiff_t i) const noexcept
          method index (line 89) | std::size_t index() const noexcept { return index_; }
          method results_impl (line 90) | const results_impl* obj() const noexcept { return self_; }

FILE: include/boost/mysql/detail/resultset_encoding.hpp
  type boost (line 11) | namespace boost {
    type mysql (line 12) | namespace mysql {
      type detail (line 13) | namespace detail {
        type resultset_encoding (line 15) | enum class resultset_encoding

FILE: include/boost/mysql/detail/row_impl.hpp
  type boost (line 20) | namespace boost {
    type mysql (line 21) | namespace mysql {
      type detail (line 22) | namespace detail {
        function add_fields (line 26) | inline span<field_view> add_fields(std::vector<field_view>& storag...
        class row_impl (line 35) | class row_impl
          method row_impl (line 38) | row_impl() = default;
          method row_impl (line 43) | row_impl(row_impl&&) = default;
          method row_impl (line 48) | row_impl& operator=(row_impl&&) = default;
          method add_fields (line 61) | span<field_view> add_fields(std::size_t num_fields)
          method clear (line 76) | void clear() noexcept

FILE: include/boost/mysql/detail/rows_iterator.hpp
  type boost (line 21) | namespace boost {
    type mysql (line 22) | namespace mysql {
      type detail (line 23) | namespace detail {
        function row_view (line 25) | inline row_view row_slice(const field_view* fields, std::size_t nu...
        class rows_iterator (line 30) | class rows_iterator
          method rows_iterator (line 43) | rows_iterator() = default;
          method rows_iterator (line 44) | rows_iterator(const field_view* fields, std::size_t num_columns,...
          method rows_iterator (line 49) | rows_iterator& operator++() noexcept
          method rows_iterator (line 54) | rows_iterator operator++(int) noexcept
          method rows_iterator (line 60) | rows_iterator& operator--() noexcept
          method rows_iterator (line 65) | rows_iterator operator--(int) noexcept
          method rows_iterator (line 71) | rows_iterator& operator+=(std::ptrdiff_t n) noexcept
          method rows_iterator (line 76) | rows_iterator& operator-=(std::ptrdiff_t n) noexcept
          method rows_iterator (line 81) | rows_iterator operator+(std::ptrdiff_t n) const noexcept
          method rows_iterator (line 85) | rows_iterator operator-(std::ptrdiff_t n) const noexcept
          method pointer (line 91) | pointer operator->() const noexcept { return **this; }
          method reference (line 92) | reference operator*() const noexcept { return (*this)[0]; }
          method reference (line 93) | reference operator[](std::ptrdiff_t i) const noexcept
        function rows_iterator (line 106) | inline rows_iterator operator+(std::ptrdiff_t n, rows_iterator it)...
          method rows_iterator (line 43) | rows_iterator() = default;
          method rows_iterator (line 44) | rows_iterator(const field_view* fields, std::size_t num_columns,...
          method rows_iterator (line 49) | rows_iterator& operator++() noexcept
          method rows_iterator (line 54) | rows_iterator operator++(int) noexcept
          method rows_iterator (line 60) | rows_iterator& operator--() noexcept
          method rows_iterator (line 65) | rows_iterator operator--(int) noexcept
          method rows_iterator (line 71) | rows_iterator& operator+=(std::ptrdiff_t n) noexcept
          method rows_iterator (line 76) | rows_iterator& operator-=(std::ptrdiff_t n) noexcept
          method rows_iterator (line 81) | rows_iterator operator+(std::ptrdiff_t n) const noexcept
          method rows_iterator (line 85) | rows_iterator operator-(std::ptrdiff_t n) const noexcept
          method pointer (line 91) | pointer operator->() const noexcept { return **this; }
          method reference (line 92) | reference operator*() const noexcept { return (*this)[0]; }
          method reference (line 93) | reference operator[](std::ptrdiff_t i) const noexcept

FILE: include/boost/mysql/detail/sequence.hpp
  type boost (line 26) | namespace boost {
    type mysql (line 27) | namespace mysql {
      type detail (line 28) | namespace detail {
        type sequence_range_impl (line 31) | struct sequence_range_impl
        type sequence_range_impl<std::reference_wrapper<T>> (line 37) | struct sequence_range_impl<std::reference_wrapper<T>>
        type sequence_range_impl<T[N]> (line 43) | struct sequence_range_impl<T[N]>
        function Range (line 52) | Range&& cast_range(Range&& range)
        function cast_range (line 58) | std::array<compat::remove_cv_t<T>, N> cast_range(T (&a)[N])
        function cast_range (line 64) | std::array<compat::remove_cv_t<T>, N> cast_range(T (&&a)[N])
        function do_format_sequence (line 71) | void do_format_sequence(Range& range, const FormatFn& fn, constant...

FILE: include/boost/mysql/detail/socket_stream.hpp
  type boost (line 16) | namespace boost {
    type mysql (line 17) | namespace mysql {
      type detail (line 18) | namespace detail {
        type is_socket (line 21) | struct is_socket : std::false_type
        type is_socket<asio::basic_socket<Protocol, Executor>> (line 28) | struct is_socket<asio::basic_socket<Protocol, Executor>> : std::tr...
        type is_socket<asio::basic_stream_socket<Protocol, Executor>> (line 33) | struct is_socket<asio::basic_stream_socket<Protocol, Executor>> : ...
        type is_socket_stream (line 38) | struct is_socket_stream : std::false_type
        type is_socket_stream<T, typename std::enable_if<is_socket<typename T::lowest_layer_type>::value>::type> (line 43) | struct is_socket_stream<T, typename std::enable_if<is_socket<typen...

FILE: include/boost/mysql/detail/ssl_fwd.hpp
  type boost (line 12) | namespace boost {
    type asio (line 13) | namespace asio {
      type ssl (line 14) | namespace ssl {
        class context (line 16) | class context

FILE: include/boost/mysql/detail/string_view_offset.hpp
  type boost (line 13) | namespace boost {
    type mysql (line 14) | namespace mysql {
      type detail (line 15) | namespace detail {
        type string_view_offset (line 19) | struct string_view_offset

FILE: include/boost/mysql/detail/throw_on_error_loc.hpp
  type boost (line 17) | namespace boost {
    type mysql (line 18) | namespace mysql {
      type detail (line 19) | namespace detail {
        function throw_on_error_loc (line 21) | inline void throw_on_error_loc(error_code err, const diagnostics& ...

FILE: include/boost/mysql/detail/typing/meta_check_context.hpp
  type boost (line 26) | namespace boost {
    type mysql (line 27) | namespace mysql {
      type detail (line 28) | namespace detail {
        class meta_check_context (line 62) | class meta_check_context
          method insert_field_name (line 80) | void insert_field_name(std::ostringstream& os)
          method meta_check_context (line 89) | meta_check_context(
          method metadata (line 99) | const metadata& current_meta() const noexcept { return map_metad...
          method is_current_field_absent (line 100) | bool is_current_field_absent() const noexcept { return pos_map_[...
          method advance (line 103) | void advance() noexcept
          method set_nullability_checked (line 110) | void set_nullability_checked() noexcept { nullability_checked_ =...
          method nullability_checked (line 111) | bool nullability_checked() const noexcept { return nullability_c...

FILE: include/boost/mysql/detail/typing/pos_map.hpp
  type boost (line 22) | namespace boost {
    type mysql (line 23) | namespace mysql {
      type detail (line 24) | namespace detail {
        function has_field_names (line 31) | inline bool has_field_names(name_table_t name_table) noexcept { re...
        function pos_map_reset (line 33) | inline void pos_map_reset(span<std::size_t> self) noexcept
        function pos_map_add_field (line 39) | inline void pos_map_add_field(
        function field_view (line 69) | inline field_view map_field_view(
        function metadata (line 79) | inline const metadata& map_metadata(

FILE: include/boost/mysql/detail/typing/readable_field_traits.hpp
  type boost (line 36) | namespace boost {
    type mysql (line 37) | namespace mysql {
      type detail (line 38) | namespace detail {
        function error_code (line 42) | error_code parse_signed_int(field_view input, SignedInt& output)
        function error_code (line 75) | error_code parse_unsigned_int(field_view input, UnsignedInt& output)
        type int_traits (line 94) | struct int_traits
        type int_traits<T, true, 1> (line 100) | struct int_traits<T, true, 1>
          method meta_check (line 104) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 112) | static error_code parse(field_view input, T& output) { return pa...
        type int_traits<T, false, 1> (line 116) | struct int_traits<T, false, 1>
          method meta_check (line 120) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 128) | static error_code parse(field_view input, T& output) { return pa...
        type int_traits<T, true, 2> (line 132) | struct int_traits<T, true, 2>
          method meta_check (line 136) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 146) | static error_code parse(field_view input, T& output) { return pa...
        type int_traits<T, false, 2> (line 150) | struct int_traits<T, false, 2>
          method meta_check (line 154) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 164) | static error_code parse(field_view input, T& output) { return pa...
        type int_traits<T, true, 4> (line 168) | struct int_traits<T, true, 4>
          method meta_check (line 172) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 184) | static error_code parse(field_view input, T& output) { return pa...
        type int_traits<T, false, 4> (line 188) | struct int_traits<T, false, 4>
          method meta_check (line 192) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 204) | static error_code parse(field_view input, T& output) { return pa...
        type int_traits<T, true, 8> (line 208) | struct int_traits<T, true, 8>
          method meta_check (line 212) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 225) | static error_code parse(field_view input, T& output) { return pa...
        type int_traits<T, false, 8> (line 229) | struct int_traits<T, false, 8>
          method meta_check (line 233) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 247) | static error_code parse(field_view input, std::uint64_t& output)
        type readable_field_traits (line 255) | struct readable_field_traits
        type readable_field_traits<char, void> (line 261) | struct readable_field_traits<char, void> : int_traits<char>
        type readable_field_traits<signed char, void> (line 266) | struct readable_field_traits<signed char, void> : int_traits<signe...
        type readable_field_traits<unsigned char, void> (line 271) | struct readable_field_traits<unsigned char, void> : int_traits<uns...
        type readable_field_traits<short, void> (line 276) | struct readable_field_traits<short, void> : int_traits<short>
        type readable_field_traits<unsigned short, void> (line 281) | struct readable_field_traits<unsigned short, void> : int_traits<un...
        type readable_field_traits<int, void> (line 286) | struct readable_field_traits<int, void> : int_traits<int>
        type readable_field_traits<unsigned int, void> (line 291) | struct readable_field_traits<unsigned int, void> : int_traits<unsi...
        type readable_field_traits<long, void> (line 296) | struct readable_field_traits<long, void> : int_traits<long>
        type readable_field_traits<unsigned long, void> (line 301) | struct readable_field_traits<unsigned long, void> : int_traits<uns...
        type readable_field_traits<long long, void> (line 306) | struct readable_field_traits<long long, void> : int_traits<long long>
        type readable_field_traits<unsigned long long, void> (line 311) | struct readable_field_traits<unsigned long long, void> : int_trait...
        type readable_field_traits<bool, void> (line 316) | struct readable_field_traits<bool, void>
          method meta_check (line 320) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 324) | static error_code parse(field_view input, bool& output)
        type readable_field_traits<float, void> (line 336) | struct readable_field_traits<float, void>
          method meta_check (line 340) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 344) | static error_code parse(field_view input, float& output)
        type readable_field_traits<double, void> (line 356) | struct readable_field_traits<double, void>
          method meta_check (line 360) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 369) | static error_code parse(field_view input, double& output)
        type readable_field_traits<std::basic_string<char, std::char_traits<char>, Allocator>, void> (line 390) | struct readable_field_traits<std::basic_string<char, std::char_tra...
          method meta_check (line 394) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 408) | static error_code parse(
        type readable_field_traits<std::vector<unsigned char, Allocator>, void> (line 423) | struct readable_field_traits<std::vector<unsigned char, Allocator>...
          method meta_check (line 427) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 439) | static error_code parse(field_view input, std::vector<unsigned c...
        type readable_field_traits<date, void> (line 452) | struct readable_field_traits<date, void>
          method meta_check (line 456) | static bool meta_check(meta_check_context& ctx) { return ctx.cur...
          method error_code (line 457) | static error_code parse(field_view input, date& output)
        type readable_field_traits<datetime, void> (line 469) | struct readable_field_traits<datetime, void>
          method meta_check (line 473) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 482) | static error_code parse(field_view input, datetime& output)
        type readable_field_traits<time, void> (line 494) | struct readable_field_traits<time, void>
          method meta_check (line 498) | static bool meta_check(meta_check_context& ctx) { return ctx.cur...
          method error_code (line 499) | static error_code parse(field_view input, time& output)
        type is_readable_optional (line 513) | struct is_readable_optional : std::false_type
        type readable_field_traits<
    T,
    typename std::enable_if<
        is_readable_optional<T>::value && readable_field_traits<typename T::value_type>::is_supported>::type> (line 529) | struct readable_field_traits<
          method meta_check (line 537) | static bool meta_check(meta_check_context& ctx)
          method error_code (line 542) | static error_code parse(field_view input, T& output)
        type is_readable_field (line 558) | struct is_readable_field
        function meta_check_field_impl (line 564) | void meta_check_field_impl(meta_check_context& ctx)
        function meta_check_field (line 590) | void meta_check_field(meta_check_context& ctx)
  type is_readable_optional<
    T,
    void_t<
        typename std::enable_if<
            std::is_same<decltype(std::declval<T&>().value()), typename T::value_type&>::value>::type,
        decltype(std::declval<T&>().emplace()),  // T should be default constructible
        decltype(std::declval<T&>().reset())>> (line 518) | struct is_readable_optional<

FILE: include/boost/mysql/detail/typing/row_traits.hpp
  type boost (line 39) | namespace boost {
    type mysql (line 40) | namespace mysql {
      type detail (line 41) | namespace detail {
        type row_traits_is_unspecialized (line 60) | struct row_traits_is_unspecialized
        class row_traits (line 65) | class row_traits : public row_traits_is_unspecialized
        type array_wrapper (line 74) | struct array_wrapper
          method span (line 78) | constexpr boost::span<const T> span() const noexcept { return bo...
        type array_wrapper<T, 0> (line 82) | struct array_wrapper<T, 0>
          method span (line 88) | constexpr boost::span<const T> span() const noexcept { return bo...
        function get_length (line 93) | constexpr std::size_t get_length(const char* s) noexcept
        function get_describe_names (line 106) | constexpr array_wrapper<string_view, sizeof...(MemberDescriptor)> ...
        class row_traits<DescribeStruct, true> (line 116) | class row_traits<DescribeStruct, true>
          method name_table_t (line 128) | static constexpr name_table_t name_table() noexcept
          method for_each_member (line 134) | static void for_each_member(DescribeStruct& to, F&& function)
        type readable_field_checker (line 165) | struct readable_field_checker
        function check_readable_field (line 179) | static constexpr bool check_readable_field() noexcept
        type row_traits_with_check (line 187) | struct row_traits_with_check : row_traits<StaticRow>
        type meta_check_field_fn (line 193) | struct meta_check_field_fn
        function error_code (line 206) | error_code meta_check_impl(
        class parse_context (line 220) | class parse_context
          method parse_context (line 228) | parse_context(span<const std::size_t> pos_map, span<const field_...
          method parse (line 234) | void parse(ReadableField& output)
          method error_code (line 244) | error_code error() const noexcept { return ec_; }
        type parse_functor (line 248) | struct parse_functor
        function get_row_size (line 285) | constexpr std::size_t get_row_size() noexcept
        function name_table_t (line 291) | constexpr name_table_t get_row_name_table() noexcept
        function error_code (line 297) | error_code meta_check(span<const std::size_t> pos_map, metadata_co...
        function error_code (line 305) | error_code parse(
        function get_type_index (line 328) | constexpr std::size_t get_type_index() noexcept
  class row_traits<std::tuple<ReadableField...>, false> (line 144) | class row_traits<std::tuple<ReadableField...>, false>
    method name_table_t (line 149) | static constexpr name_table_t name_table() noexcept { return name_tabl...
    method for_each_member (line 152) | static void for_each_member(underlying_row_type& to, F&& function)

FILE: include/boost/mysql/detail/void_t.hpp
  type boost (line 11) | namespace boost {
    type mysql (line 12) | namespace mysql {
      type detail (line 13) | namespace detail {

FILE: include/boost/mysql/detail/writable_field_traits.hpp
  type boost (line 17) | namespace boost {
    type mysql (line 18) | namespace mysql {
      type detail (line 19) | namespace detail {
        type writable_field_traits (line 22) | struct writable_field_traits
        type writable_field_traits<bool> (line 28) | struct writable_field_traits<bool>
          method field_view (line 31) | static field_view to_field(bool value) noexcept { return field_v...
        type writable_field_traits<
    T,
    typename std::enable_if<
        std::is_constructible<field_view, const T&>::value && std::is_object<T>::value>::type,
    void> (line 35) | struct writable_field_traits<
          method field_view (line 42) | static field_view to_field(const T& value) noexcept { return fie...
        function field_view (line 65) | field_view to_field(const T& value) noexcept
        type is_writable_field (line 71) | struct is_writable_field : std::integral_constant<bool, writable_f...
        type is_field_view_forward_iterator (line 90) | struct is_field_view_forward_iterator : std::false_type
        type is_field_view_forward_iterator<
    T,
    typename std::enable_if<
        std::is_convertible<
            typename std::iterator_traits<T>::reference,
            field_view
        >::value
        &&
        std::is_base_of<
            std::forward_iterator_tag, 
            typename std::iterator_traits<T>::iterator_category
        >::value
    >::type
> (line 96) | struct is_field_view_forward_iterator<
        type is_writable_field_tuple_impl (line 127) | struct is_writable_field_tuple_impl : std::false_type
        type is_writable_field_tuple (line 138) | struct is_writable_field_tuple : is_writable_field_tuple_impl<type...
  type writable_field_traits<
    T,
    void,
    typename std::enable_if<
        std::is_same<decltype(std::declval<const T&>().has_value()), bool>::value &&
        std::is_same<decltype(std::declval<const T&>().value()), const typename T::value_type&>::value>::type> (line 49) | struct writable_field_traits<
    method field_view (line 58) | static field_view to_field(const T& value) noexcept
  type is_writable_field_tuple_impl<std::tuple<T...>> (line 132) | struct is_writable_field_tuple_impl<std::tuple<T...>>

FILE: include/boost/mysql/diagnostics.hpp
  type boost (line 17) | namespace boost {
    type mysql (line 18) | namespace mysql {
      class diagnostics (line 27) | class diagnostics
        method diagnostics (line 35) | diagnostics() = default;
        method string_view (line 51) | string_view client_message() const noexcept
        method string_view (line 69) | string_view server_message() const noexcept
        method clear (line 79) | void clear() noexcept
        method assign_client (line 92) | void assign_client(std::string from)
        method assign_server (line 98) | void assign_server(std::string from)

FILE: include/boost/mysql/error_categories.hpp
  type boost (line 15) | namespace boost {
    type mysql (line 16) | namespace mysql {

FILE: include/boost/mysql/error_code.hpp
  type boost (line 13) | namespace boost {
    type mysql (line 14) | namespace mysql {

FILE: include/boost/mysql/error_with_diagnostics.hpp
  type boost (line 16) | namespace boost {
    type mysql (line 17) | namespace mysql {
      class error_with_diagnostics (line 25) | class error_with_diagnostics : public system::system_error
        method create_base (line 29) | static system::system_error create_base(const error_code& err, con...
        method error_with_diagnostics (line 37) | error_with_diagnostics(const error_code& err, const diagnostics& d...
        method diagnostics (line 50) | const diagnostics& get_diagnostics() const noexcept { return diag_; }

FILE: include/boost/mysql/escape_string.hpp
  type boost (line 19) | namespace boost {
    type mysql (line 20) | namespace mysql {
      type format_options (line 22) | struct format_options
      type quoting_context (line 27) | enum class quoting_context : char
      function BOOST_ATTRIBUTE_NODISCARD (line 92) | BOOST_ATTRIBUTE_NODISCARD error_code

FILE: include/boost/mysql/execution_state.hpp
  type boost (line 20) | namespace boost {
    type mysql (line 21) | namespace mysql {
      class execution_state (line 35) | class execution_state
        method execution_state (line 46) | execution_state() = default;
        method execution_state (line 56) | execution_state(const execution_state& other) = default;
        method execution_state (line 66) | execution_state(execution_state&& other) = default;
        method execution_state (line 77) | execution_state& operator=(const execution_state& other) = default;
        method execution_state (line 87) | execution_state& operator=(execution_state&& other) = default;
        method should_start_op (line 98) | bool should_start_op() const noexcept { return impl_.is_reading_fi...
        method should_read_head (line 109) | bool should_read_head() const noexcept { return impl_.is_reading_f...
        method should_read_rows (line 120) | bool should_read_rows() const noexcept { return impl_.is_reading_r...
        method complete (line 131) | bool complete() const noexcept { return impl_.is_complete(); }
        method metadata_collection_view (line 147) | metadata_collection_view meta() const noexcept { return impl_.meta...
        method affected_rows (line 160) | std::uint64_t affected_rows() const noexcept { return impl_.get_af...
        method last_insert_id (line 170) | std::uint64_t last_insert_id() const noexcept { return impl_.get_l...
        method warning_count (line 180) | unsigned warning_count() const noexcept { return impl_.get_warning...
        method string_view (line 201) | string_view info() const noexcept { return impl_.get_info(); }
        method is_out_params (line 211) | bool is_out_params() const noexcept { return impl_.get_is_out_para...

FILE: include/boost/mysql/field.hpp
  type boost (line 29) | namespace boost {
    type mysql (line 30) | namespace mysql {
      class field (line 46) | class field
        method field (line 54) | field() = default;
        method field (line 61) | field(const field&) = default;
        method field (line 72) | field(field&& other) = default;
        method field (line 83) | field& operator=(const field&) = default;
        method field (line 96) | field& operator=(field&& other) = default;
        method field (line 110) | explicit field(std::nullptr_t) noexcept {}
        method field (line 117) | explicit field(signed char v) noexcept : repr_(std::int64_t(v)) {}
        method field (line 120) | explicit field(short v) noexcept : repr_(std::int64_t(v)) {}
        method field (line 123) | explicit field(int v) noexcept : repr_(std::int64_t(v)) {}
        method field (line 126) | explicit field(long v) noexcept : repr_(std::int64_t(v)) {}
        method field (line 129) | explicit field(long long v) noexcept : repr_(std::int64_t(v)) {}
        method field (line 136) | explicit field(unsigned char v) noexcept : repr_(std::uint64_t(v)) {}
        method field (line 139) | explicit field(unsigned short v) noexcept : repr_(std::uint64_t(v)...
        method field (line 142) | explicit field(unsigned int v) noexcept : repr_(std::uint64_t(v)) {}
        method field (line 145) | explicit field(unsigned long v) noexcept : repr_(std::uint64_t(v)) {}
        method field (line 148) | explicit field(unsigned long long v) noexcept : repr_(std::uint64_...
        method field (line 154) | explicit field(char) = delete;
        method field (line 157) | explicit field(wchar_t) = delete;
        method field (line 160) | explicit field(char16_t) = delete;
        method field (line 163) | explicit field(char32_t) = delete;
        method field (line 167) | explicit field(char8_t) = delete;
        method field (line 175) | explicit field(const std::string& v) : repr_(v) {}
        method field (line 183) | explicit field(std::string&& v) noexcept : repr_(std::move(v)) {}
        method field (line 186) | explicit field(const char* v) : repr_(boost::variant2::in_place_ty...
        method field (line 189) | explicit field(string_view v) : repr_(boost::variant2::in_place_ty...
        method field (line 193) | explicit field(std::string_view v) : repr_(boost::variant2::in_pla...
        method field (line 202) | explicit field(blob v) noexcept : repr_(std::move(v)) {}
        method field (line 209) | explicit field(float v) noexcept : repr_(v) {}
        method field (line 216) | explicit field(double v) noexcept : repr_(v) {}
        method field (line 223) | explicit field(const date& v) noexcept : repr_(v) {}
        method field (line 230) | explicit field(const datetime& v) noexcept : repr_(v) {}
        method field (line 237) | explicit field(const time& v) noexcept : repr_(v) {}
        method field (line 249) | field(const field_view& v) { from_view(v); }
        method field (line 262) | field& operator=(std::nullptr_t) noexcept
        method field (line 279) | field& operator=(signed char v) noexcept
        method field (line 286) | field& operator=(short v) noexcept
        method field (line 293) | field& operator=(int v) noexcept
        method field (line 300) | field& operator=(long v) noexcept
        method field (line 307) | field& operator=(long long v) noexcept
        method field (line 324) | field& operator=(unsigned char v) noexcept
        method field (line 331) | field& operator=(unsigned short v) noexcept
        method field (line 338) | field& operator=(unsigned int v) noexcept
        method field (line 345) | field& operator=(unsigned long v) noexcept
        method field (line 352) | field& operator=(unsigned long long v) noexcept
        method field (line 362) | field& operator=(char) = delete;
        method field (line 365) | field& operator=(wchar_t) = delete;
        method field (line 368) | field& operator=(char16_t) = delete;
        method field (line 371) | field& operator=(char32_t) = delete;
        method field (line 375) | field& operator=(char8_t) = delete;
        method field (line 389) | field& operator=(const std::string& v)
        method field (line 396) | field& operator=(std::string&& v)
        method field (line 403) | field& operator=(const char* v)
        method field (line 410) | field& operator=(string_view v)
        method field (line 418) | field& operator=(std::string_view v)
        method field (line 436) | field& operator=(blob v)
        method field (line 453) | field& operator=(float v) noexcept
        method field (line 470) | field& operator=(double v) noexcept
        method field (line 487) | field& operator=(const date& v) noexcept
        method field (line 504) | field& operator=(const datetime& v) noexcept
        method field (line 520) | field& operator=(const time& v) noexcept
        method field (line 539) | field& operator=(const field_view& v)
        method field_kind (line 550) | field_kind kind() const noexcept { return repr_.kind(); }
        method is_null (line 557) | bool is_null() const noexcept { return kind() == field_kind::null; }
        method is_int64 (line 564) | bool is_int64() const noexcept { return kind() == field_kind::int6...
        method is_uint64 (line 571) | bool is_uint64() const noexcept { return kind() == field_kind::uin...
        method is_string (line 578) | bool is_string() const noexcept { return kind() == field_kind::str...
        method is_blob (line 585) | bool is_blob() const noexcept { return kind() == field_kind::blob; }
        method is_float (line 592) | bool is_float() const noexcept { return kind() == field_kind::floa...
        method is_double (line 599) | bool is_double() const noexcept { return kind() == field_kind::dou...
        method is_date (line 606) | bool is_date() const noexcept { return kind() == field_kind::date; }
        method is_datetime (line 613) | bool is_datetime() const noexcept { return kind() == field_kind::d...
        method is_time (line 620) | bool is_time() const noexcept { return kind() == field_kind::time; }
        method blob (line 668) | const blob& as_blob() const { return repr_.as<blob>(); }
        method date (line 704) | const date& as_date() const { return repr_.as<date>(); }
        method datetime (line 716) | const datetime& as_datetime() const { return repr_.as<datetime>(); }
        method time (line 728) | const time& as_time() const { return repr_.as<time>(); }
        method blob (line 740) | blob& as_blob() { return repr_.as<blob>(); }
        method date (line 749) | date& as_date() { return repr_.as<date>(); }
        method datetime (line 752) | datetime& as_datetime() { return repr_.as<datetime>(); }
        method time (line 755) | time& as_time() { return repr_.as<time>(); }
        method blob (line 811) | const blob& get_blob() const noexcept { return repr_.get<blob>(); }
        method date (line 853) | const date& get_date() const noexcept { return repr_.get<date>(); }
        method datetime (line 867) | const datetime& get_datetime() const noexcept { return repr_.get<d...
        method time (line 881) | const time& get_time() const noexcept { return repr_.get<time>(); }
        method blob (line 893) | blob& get_blob() noexcept { return repr_.get<blob>(); }
        method date (line 902) | date& get_date() noexcept { return repr_.get<date>(); }
        method datetime (line 905) | datetime& get_datetime() noexcept { return repr_.get<datetime>(); }
        method time (line 908) | time& get_time() noexcept { return repr_.get<time>(); }

FILE: include/boost/mysql/field_kind.hpp
  type boost (line 15) | namespace boost {
    type mysql (line 16) | namespace mysql {
      type field_kind (line 21) | enum class field_kind

FILE: include/boost/mysql/field_view.hpp
  type boost (line 29) | namespace boost {
    type mysql (line 30) | namespace mysql {
      class field_view (line 62) | class field_view
        method BOOST_CXX14_CONSTEXPR (line 73) | BOOST_CXX14_CONSTEXPR field_view() = default;
        method BOOST_CXX14_CONSTEXPR (line 87) | BOOST_CXX14_CONSTEXPR explicit field_view(std::nullptr_t) noexcept {}
        method field_view (line 97) | field_view(signed char v) noexcept : impl_{std::int64_t(v)} {}
        method field_view (line 100) | field_view(short v) noexcept : impl_{std::int64_t(v)} {}
        method field_view (line 103) | field_view(int v) noexcept : impl_{std::int64_t(v)} {}
        method field_view (line 106) | field_view(long v) noexcept : impl_{std::int64_t(v)} {}
        method field_view (line 109) | field_view(long long v) noexcept : impl_{std::int64_t(v)} {}
        method field_view (line 119) | field_view(unsigned char v) noexcept : impl_{std::uint64_t(v)} {}
        method field_view (line 122) | field_view(unsigned short v) noexcept : impl_{std::uint64_t(v)} {}
        method field_view (line 125) | field_view(unsigned int v) noexcept : impl_{std::uint64_t(v)} {}
        method field_view (line 128) | field_view(unsigned long v) noexcept : impl_{std::uint64_t(v)} {}
        method field_view (line 131) | field_view(unsigned long long v) noexcept : impl_{std::uint64_t(v)...
        method field_view (line 137) | explicit field_view(char) = delete;
        method field_view (line 140) | explicit field_view(wchar_t) = delete;
        method field_view (line 143) | explicit field_view(char16_t) = delete;
        method field_view (line 146) | explicit field_view(char32_t) = delete;
        method field_view (line 150) | explicit field_view(char8_t) = delete;
        method field_view (line 162) | field_view(string_view v) noexcept : impl_{v} {}
        method field_view (line 173) | field_view(blob_view v) noexcept : impl_{v} {}
        method field_view (line 183) | field_view(float v) noexcept : impl_{v} {}
        method field_view (line 193) | field_view(double v) noexcept : impl_{v} {}
        method field_view (line 203) | field_view(const date& v) noexcept : impl_{v} {}
        method field_view (line 213) | field_view(const datetime& v) noexcept : impl_{v} {}
        method field_view (line 223) | field_view(const time& v) noexcept : impl_{v} {}
        method BOOST_CXX14_CONSTEXPR (line 237) | BOOST_CXX14_CONSTEXPR bool is_null() const noexcept { return kind(...
        method BOOST_CXX14_CONSTEXPR (line 244) | BOOST_CXX14_CONSTEXPR bool is_int64() const noexcept { return kind...
        method BOOST_CXX14_CONSTEXPR (line 251) | BOOST_CXX14_CONSTEXPR bool is_uint64() const noexcept { return kin...
        method BOOST_CXX14_CONSTEXPR (line 258) | BOOST_CXX14_CONSTEXPR bool is_string() const noexcept { return kin...
        method BOOST_CXX14_CONSTEXPR (line 265) | BOOST_CXX14_CONSTEXPR bool is_blob() const noexcept { return kind(...
        method BOOST_CXX14_CONSTEXPR (line 272) | BOOST_CXX14_CONSTEXPR bool is_float() const noexcept { return kind...
        method BOOST_CXX14_CONSTEXPR (line 279) | BOOST_CXX14_CONSTEXPR bool is_double() const noexcept { return kin...
        method BOOST_CXX14_CONSTEXPR (line 286) | BOOST_CXX14_CONSTEXPR bool is_date() const noexcept { return kind(...
        method BOOST_CXX14_CONSTEXPR (line 293) | BOOST_CXX14_CONSTEXPR bool is_datetime() const noexcept { return k...
        method BOOST_CXX14_CONSTEXPR (line 300) | BOOST_CXX14_CONSTEXPR bool is_time() const noexcept { return kind(...
        method noexcept (line 386) | const noexcept
        method noexcept (line 399) | const noexcept
        method get_string (line 415) | get_string() const noexcept
        method BOOST_CXX14_CONSTEXPR (line 431) | BOOST_CXX14_CONSTEXPR inline blob_view get_blob() const noexcept
        method BOOST_CXX14_CONSTEXPR (line 444) | BOOST_CXX14_CONSTEXPR inline float get_float() const noexcept
        method BOOST_CXX14_CONSTEXPR (line 457) | BOOST_CXX14_CONSTEXPR inline double get_double() const noexcept
        method BOOST_CXX14_CONSTEXPR (line 470) | BOOST_CXX14_CONSTEXPR inline date get_date() const noexcept
        method BOOST_CXX14_CONSTEXPR (line 483) | BOOST_CXX14_CONSTEXPR inline datetime get_datetime() const noexcept
        method BOOST_CXX14_CONSTEXPR (line 496) | BOOST_CXX14_CONSTEXPR inline time get_time() const noexcept
        method BOOST_CXX14_CONSTEXPR (line 519) | BOOST_CXX14_CONSTEXPR bool operator!=(const field_view& rhs) const...
        method field_view (line 522) | field_view(detail::string_view_offset v, bool is_blob) noexcept
        method field_view (line 527) | field_view(const detail::field_impl* v) noexcept : impl_{v} {}
        type internal_kind (line 529) | enum class internal_kind
        method BOOST_CXX14_CONSTEXPR (line 560) | BOOST_CXX14_CONSTEXPR repr_t() noexcept : int64{} {}
        method BOOST_CXX14_CONSTEXPR (line 561) | BOOST_CXX14_CONSTEXPR repr_t(std::int64_t v) noexcept : int64(v) {}
        method BOOST_CXX14_CONSTEXPR (line 562) | BOOST_CXX14_CONSTEXPR repr_t(std::uint64_t v) noexcept : uint64(v) {}
        method BOOST_CXX14_CONSTEXPR (line 563) | BOOST_CXX14_CONSTEXPR repr_t(string_view v) noexcept : string{v} {}
        method BOOST_CXX14_CONSTEXPR (line 564) | BOOST_CXX14_CONSTEXPR repr_t(blob_view v) noexcept : blob{v} {}
        method BOOST_CXX14_CONSTEXPR (line 565) | BOOST_CXX14_CONSTEXPR repr_t(float v) noexcept : float_(v) {}
        method BOOST_CXX14_CONSTEXPR (line 566) | BOOST_CXX14_CONSTEXPR repr_t(double v) noexcept : double_(v) {}
        method BOOST_CXX14_CONSTEXPR (line 567) | BOOST_CXX14_CONSTEXPR repr_t(date v) noexcept : date_(v) {}
        method BOOST_CXX14_CONSTEXPR (line 568) | BOOST_CXX14_CONSTEXPR repr_t(datetime v) noexcept : datetime_(v) {}
        method BOOST_CXX14_CONSTEXPR (line 569) | BOOST_CXX14_CONSTEXPR repr_t(time v) noexcept : time_(v) {}
        method BOOST_CXX14_CONSTEXPR (line 570) | BOOST_CXX14_CONSTEXPR repr_t(detail::string_view_offset v) noexcep...
        method BOOST_CXX14_CONSTEXPR (line 571) | BOOST_CXX14_CONSTEXPR repr_t(const detail::field_impl* v) noexcept...
        type impl_t (line 574) | struct impl_t
          method is_string_offset (line 580) | bool is_string_offset() const noexcept { return ikind == interna...
          method is_blob_offset (line 581) | bool is_blob_offset() const noexcept { return ikind == internal_...
          method BOOST_CXX14_CONSTEXPR (line 583) | BOOST_CXX14_CONSTEXPR impl_t() = default;
          method BOOST_CXX14_CONSTEXPR (line 586) | BOOST_CXX14_CONSTEXPR impl_t(string_view v) noexcept : ikind(int...
          method BOOST_CXX14_CONSTEXPR (line 587) | BOOST_CXX14_CONSTEXPR impl_t(blob_view v) noexcept : ikind(inter...
          method BOOST_CXX14_CONSTEXPR (line 593) | BOOST_CXX14_CONSTEXPR impl_t(detail::string_view_offset v, bool ...
        method BOOST_CXX14_CONSTEXPR (line 603) | BOOST_CXX14_CONSTEXPR bool is_field_ptr() const noexcept

FILE: include/boost/mysql/format_sql.hpp
  type formatter (line 77) | struct formatter
  class formattable_ref (line 96) | class formattable_ref
    method formattable_ref (line 129) | formattable_ref(Formattable&& value) noexcept
  class format_arg (line 145) | class format_arg
    method format_arg (line 169) | format_arg(string_view name, formattable_ref value) noexcept
  class format_context_base (line 193) | class format_context_base
    method format_context_base (line 210) | format_context_base(detail::output_string_ref out, format_options opts...
    method format_context_base (line 215) | format_context_base(detail::output_string_ref out, const format_contex...
    method assign (line 220) | void assign(const format_context_base& rhs) noexcept
    method format_context_base (line 244) | format_context_base& append_raw(constant_string_view sql)
    method format_context_base (line 271) | format_context_base& append_value(
    method add_error (line 294) | void add_error(error_code ec) noexcept
    method error_code (line 306) | error_code error_state() const noexcept { return impl_.ec; }
    method format_options (line 314) | format_options format_opts() const noexcept { return impl_.opts; }
  function ref (line 332) | detail::output_string_ref ref() noexcept { return detail::output_string_...
  function noexcept (line 347) | noexcept(std::is_nothrow_default_constructible<OutputString>::value)
  function noexcept (line 367) | noexcept(std::is_nothrow_move_constructible<OutputString>::value)
  function basic_format_context (line 375) | basic_format_context(const basic_format_context&) = delete;
  function basic_format_context (line 376) | basic_format_context& operator=(const basic_format_context&) = delete;
  function noexcept (line 391) | noexcept(std::is_nothrow_move_constructible<OutputString>::value)
  function noexcept (line 409) | noexcept(std::is_nothrow_move_assignable<OutputString>::value)
  function noexcept (line 434) | noexcept(std::is_nothrow_move_constructible<OutputString>::value)
  function format_sql_to (line 489) | void format_sql_to(format_context_base& ctx, constant_string_view format...
  function format_sql_to (line 504) | inline void format_sql_to(

FILE: include/boost/mysql/handshake_params.hpp
  type boost (line 17) | namespace boost {
    type mysql (line 18) | namespace mysql {
      class handshake_params (line 32) | class handshake_params
        method handshake_params (line 61) | handshake_params(
        method string_view (line 83) | string_view username() const noexcept { return username_; }
        method set_username (line 90) | void set_username(string_view value) noexcept { username_ = value; }
        method string_view (line 97) | string_view password() const noexcept { return password_; }
        method set_password (line 104) | void set_password(string_view value) noexcept { password_ = value; }
        method string_view (line 111) | string_view database() const noexcept { return database_; }
        method set_database (line 118) | void set_database(string_view value) noexcept { database_ = value; }
        method connection_collation (line 125) | std::uint16_t connection_collation() const noexcept { return conne...
        method set_connection_collation (line 132) | void set_connection_collation(std::uint16_t value) noexcept { conn...
        method ssl_mode (line 139) | ssl_mode ssl() const noexcept { return ssl_; }
        method set_ssl (line 146) | void set_ssl(ssl_mode value) noexcept { ssl_ = value; }
        method multi_queries (line 153) | bool multi_queries() const noexcept { return multi_queries_; }
        method set_multi_queries (line 160) | void set_multi_queries(bool v) noexcept { multi_queries_ = v; }

FILE: include/boost/mysql/impl/field_view.hpp
  type boost (line 22) | namespace boost {
    type mysql (line 23) | namespace mysql {
      type detail (line 24) | namespace detail {
        function blobs_equal (line 26) | inline bool blobs_equal(blob_view b1, blob_view b2)
  function BOOST_CXX14_CONSTEXPR (line 37) | BOOST_CXX14_CONSTEXPR inline boost::mysql::field_kind boost::mysql::fiel...
  function BOOST_CXX14_CONSTEXPR (line 57) | BOOST_CXX14_CONSTEXPR std::int64_t boost::mysql::field_view::as_int64() ...
  function BOOST_CXX14_CONSTEXPR (line 65) | BOOST_CXX14_CONSTEXPR std::uint64_t boost::mysql::field_view::as_uint64(...
  function BOOST_CXX14_CONSTEXPR (line 73) | BOOST_CXX14_CONSTEXPR boost::mysql::string_view boost::mysql::field_view...
  function BOOST_CXX14_CONSTEXPR (line 81) | BOOST_CXX14_CONSTEXPR boost::mysql::blob_view boost::mysql::field_view::...
  function BOOST_CXX14_CONSTEXPR (line 89) | BOOST_CXX14_CONSTEXPR float boost::mysql::field_view::as_float() const
  function BOOST_CXX14_CONSTEXPR (line 97) | BOOST_CXX14_CONSTEXPR double boost::mysql::field_view::as_double() const
  function BOOST_CXX14_CONSTEXPR (line 105) | BOOST_CXX14_CONSTEXPR boost::mysql::date boost::mysql::field_view::as_da...
  function BOOST_CXX14_CONSTEXPR (line 113) | BOOST_CXX14_CONSTEXPR boost::mysql::datetime boost::mysql::field_view::a...
  function BOOST_CXX14_CONSTEXPR (line 121) | BOOST_CXX14_CONSTEXPR boost::mysql::time boost::mysql::field_view::as_ti...
  function BOOST_CXX14_CONSTEXPR (line 129) | BOOST_CXX14_CONSTEXPR void boost::mysql::field_view::check_kind(internal...
  function BOOST_CXX14_CONSTEXPR (line 135) | BOOST_CXX14_CONSTEXPR bool boost::mysql::field_view::operator==(const fi...

FILE: include/boost/mysql/impl/format_sql.hpp
  type boost (line 19) | namespace boost {
    type mysql (line 20) | namespace mysql {
      type detail (line 21) | namespace detail {
        function do_format_custom_formatter (line 28) | bool do_format_custom_formatter(
        function do_format_range (line 59) | bool do_format_range(const void* obj, const char* spec_begin, cons...
        function formattable_ref_impl (line 83) | inline formattable_ref_impl make_formattable_ref_custom(
        function formattable_ref_impl (line 93) | formattable_ref_impl make_formattable_ref_custom(
        function formattable_ref_impl (line 117) | formattable_ref_impl make_formattable_ref_range(
        function formattable_ref_impl (line 131) | formattable_ref_impl make_formattable_ref_range(
        function formattable_ref_impl (line 141) | formattable_ref_impl make_formattable_ref_writable(
        function formattable_ref_impl (line 155) | formattable_ref_impl make_formattable_ref_writable(

FILE: include/boost/mysql/impl/internal/byte_to_hex.hpp
  type boost (line 13) | namespace boost {
    type mysql (line 14) | namespace mysql {
      type detail (line 15) | namespace detail {

FILE: include/boost/mysql/impl/internal/call_next_char.hpp
  type boost (line 17) | namespace boost {
    type mysql (line 18) | namespace mysql {
      type detail (line 19) | namespace detail {
        function call_next_char (line 21) | inline std::size_t call_next_char(const character_set& charset, co...

FILE: include/boost/mysql/impl/internal/connection_pool/connection_node.hpp
  type boost (line 37) | namespace boost {
    type mysql (line 38) | namespace mysql {
      type detail (line 39) | namespace detail {
        type conn_shared_state (line 43) | struct conn_shared_state
          method conn_shared_state (line 69) | conn_shared_state(asio::any_io_executor ex)
          method on_connection_start (line 75) | void on_connection_start() { ++num_running_connections; }
          method on_connection_finish (line 77) | void on_connection_finish()
        class basic_connection_node (line 87) | class basic_connection_node : public intrusive::list_base_hook<>,
          method entering_idle (line 109) | void entering_idle()
          method exiting_idle (line 114) | void exiting_idle() { shared_st_->idle_list.erase(shared_st_->id...
          method entering_pending (line 115) | void entering_pending() { ++shared_st_->num_pending_connections; }
          method exiting_pending (line 116) | void exiting_pending() { --shared_st_->num_pending_connections; }
          method propagate_connect_diag (line 119) | void propagate_connect_diag(error_code ec)
          method run_with_timeout (line 125) | void run_with_timeout(Op&& op, std::chrono::steady_clock::durati...
          type connection_task_op (line 137) | struct connection_task_op
            method connection_task_op (line 142) | connection_task_op(this_type& node) noexcept : node_(node) {}
          method basic_connection_node (line 218) | basic_connection_node(
          method cancel (line 235) | void cancel()
          method async_run (line 244) | auto async_run(CompletionToken&& token)
          method notify_collectable (line 251) | void notify_collectable() { collection_timer_.cancel(); }
          method mark_as_collectable (line 254) | void mark_as_collectable(bool should_reset) noexcept
          method ConnectionType (line 262) | ConnectionType& connection() noexcept { return conn_; }
          method collection_state (line 265) | collection_state get_collection_state() const noexcept { return ...

FILE: include/boost/mysql/impl/internal/connection_pool/connection_pool_impl.hpp
  type boost (line 47) | namespace boost {
    type mysql (line 48) | namespace mysql {
      type detail (line 49) | namespace detail {
        function pipeline_request (line 51) | inline pipeline_request make_reset_pipeline()
        class basic_pool_impl (line 61) | class basic_pool_impl
          type state_t (line 69) | enum class state_t
          method shared_from_this_wrapper (line 95) | std::shared_ptr<this_type> shared_from_this_wrapper()
          method create_connection (line 102) | void create_connection()
          method create_connections (line 110) | void create_connections()
          method enter_request_pending (line 128) | void enter_request_pending()
          method exit_request_pending (line 141) | void exit_request_pending()
          method node_type (line 148) | node_type* try_get_connection()
          method enter_strand (line 163) | void enter_strand(OpSelf& self)
          method exit_strand (line 169) | void exit_strand(OpSelf& self)
          method wait_for_connections (line 175) | void wait_for_connections(OpSelf& self)
          type run_op (line 188) | struct run_op
            method run_op (line 194) | run_op(std::shared_ptr<this_type> obj, asio::cancellation_slot...
            type cancel_handler (line 199) | struct cancel_handler
          type get_connection_op (line 265) | struct get_connection_op
            method get_connection_op (line 285) | get_connection_op(
            method thread_safe (line 295) | bool thread_safe() const { return obj->params_.thread_safe; }
            method do_complete (line 298) | void do_complete(Self& self)
          type get_connection_cancel_handler (line 399) | struct get_connection_cancel_handler
            method get_connection_cancel_handler (line 408) | get_connection_cancel_handler(
          method cancel_unsafe (line 443) | void cancel_unsafe() { cancel_timer_.expires_at((std::chrono::st...
          method basic_pool_impl (line 446) | basic_pool_impl(asio::any_io_executor ex, pool_params&& params)
          method strand (line 456) | asio::strand<asio::any_io_executor> strand()
          method executor_type (line 463) | executor_type get_executor() { return original_pool_ex_; }
          method async_run (line 465) | void async_run(asio::any_completion_handler<void(error_code)> ha...
          method async_get_connection (line 480) | void async_get_connection(
          method cancel (line 521) | void cancel()
          method return_connection (line 545) | void return_connection(node_type& node, bool should_reset) noexcept
          method run_supports_cancel_type (line 583) | static bool run_supports_cancel_type(asio::cancellation_type_t v)
          method get_connection_supports_cancel_type (line 589) | static bool get_connection_supports_cancel_type(asio::cancellati...
          method shared_state_type (line 599) | shared_state_type& shared_state() noexcept { return shared_st_; }
          method internal_pool_params (line 600) | internal_pool_params& params() noexcept { return params_; }
          method connection_ex (line 601) | asio::any_io_executor connection_ex() noexcept { return conn_ex_; }
          method pipeline_request (line 602) | const pipeline_request& reset_pipeline_request() const { return ...

FILE: include/boost/mysql/impl/internal/connection_pool/internal_pool_params.hpp
  type boost (line 26) | namespace boost {
    type mysql (line 27) | namespace mysql {
      type detail (line 28) | namespace detail {
        type internal_pool_params (line 31) | struct internal_pool_params
          method any_connection_params (line 44) | any_connection_params make_ctor_params() noexcept
        function check_validity (line 53) | inline void check_validity(const pool_params& params)
        function internal_pool_params (line 75) | inline internal_pool_params make_internal_pool_params(pool_params&...
          method any_connection_params (line 44) | any_connection_params make_ctor_params() noexcept

FILE: include/boost/mysql/impl/internal/connection_pool/sansio_connection_node.hpp
  type boost (line 20) | namespace boost {
    type mysql (line 21) | namespace mysql {
      type detail (line 22) | namespace detail {
        type node_status (line 25) | enum class node_status
        type next_connection_action (line 55) | enum class next_connection_action
        type collection_state (line 78) | enum class collection_state
        class sansio_connection_node (line 93) | class sansio_connection_node
          method is_pending (line 97) | inline bool is_pending(node_status status) noexcept
          method next_connection_action (line 103) | inline static next_connection_action status_to_action(node_statu...
          method next_connection_action (line 118) | next_connection_action set_status(node_status new_status)
          method sansio_connection_node (line 141) | sansio_connection_node(node_status initial_status = node_status:...
          method mark_as_in_use (line 146) | void mark_as_in_use() noexcept
          method cancel (line 152) | void cancel() { set_status(node_status::terminated); }
          method next_connection_action (line 154) | next_connection_action resume(error_code ec, collection_state co...
          method node_status (line 197) | node_status status() const noexcept { return status_; }
        function diagnostics (line 202) | inline diagnostics create_connect_diagnostics(error_code connect_e...
        function num_connections_to_create (line 247) | inline std::size_t num_connections_to_create(

FILE: include/boost/mysql/impl/internal/dt_to_string.hpp
  type boost (line 29) | namespace boost {
    type mysql (line 30) | namespace mysql {
      type detail (line 31) | namespace detail {
        function date_to_string (line 71) | inline std::size_t date_to_string(
        function datetime_to_string (line 99) | inline std::size_t datetime_to_string(
        function time_to_string (line 139) | inline std::size_t time_to_string(::boost::mysql::time value, span...

FILE: include/boost/mysql/impl/internal/error/server_error_to_string.hpp
  type boost (line 13) | namespace boost {
    type mysql (line 14) | namespace mysql {
      type detail (line 15) | namespace detail {

FILE: include/boost/mysql/impl/internal/next_power_of_two.hpp
  type boost (line 16) | namespace boost {
    type mysql (line 17) | namespace mysql {
      type detail (line 18) | namespace detail {
        type recursive_shift_or (line 21) | struct recursive_shift_or
        type recursive_shift_or<Shift, UnsignedInt, true> (line 25) | struct recursive_shift_or<Shift, UnsignedInt, true>
          method apply (line 27) | static void apply(UnsignedInt& n)
        type recursive_shift_or<Shift, UnsignedInt, false> (line 36) | struct recursive_shift_or<Shift, UnsignedInt, false>
          method apply (line 38) | static void apply(UnsignedInt&) {}
        function UnsignedInt (line 52) | UnsignedInt next_power_of_two(UnsignedInt n) noexcept

FILE: include/boost/mysql/impl/internal/protocol/capabilities.hpp
  type boost (line 13) | namespace boost {
    type mysql (line 14) | namespace mysql {
      type detail (line 15) | namespace detail {
        type capabilities (line 17) | enum class capabilities : std::uint32_t
        function capabilities (line 107) | constexpr capabilities operator&(capabilities lhs, capabilities rhs)
        function capabilities (line 112) | constexpr capabilities operator|(capabilities lhs, capabilities rhs)
        function has_capabilities (line 118) | constexpr bool has_capabilities(capabilities caps, capabilities su...

FILE: include/boost/mysql/impl/internal/protocol/db_flavor.hpp
  type boost (line 11) | namespace boost {
    type mysql (line 12) | namespace mysql {
      type detail (line 13) | namespace detail {
        type db_flavor (line 15) | enum class db_flavor

FILE: include/boost/mysql/impl/internal/protocol/deserialization.hpp
  type boost (line 44) | namespace boost {
    type mysql (line 45) | namespace mysql {
      type detail (line 46) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(const ok_view& ok) noexcept : ok(ok) {}
          method data_t (line 216) | data_t(error_code err) noexcept : err(err) {}
          method data_t (line 217) | data_t(auth_switch msg) noexcept : auth_sw(msg) {}
          method data_t (line 218) | data_t(span<const std::uint8_t> more_data) noexcept : more_data(...
          method handshake_server_response (line 221) | handshake_server_response(const ok_view& ok) noexcept : type(typ...
          method handshake_server_response (line 222) | handshake_server_response(error_code err) noexcept : type(type_t...
          method handshake_server_response (line 223) | handshake_server_response(auth_switch auth_switch) noexcept : ty...
          method handshake_server_response (line 226) | handshake_server_response(span<const std::uint8_t> more_data) no...
        function is_next_field_null (line 648) | inline bool is_next_field_null(const deserialization_context& ctx)
        function error_code (line 655) | inline error_code deserialize_text_row(
        function error_code (line 682) | inline error_code deserialize_binary_row(
        function capabilities (line 746) | inline capabilities compose_capabilities(string_fixed<2> low, stri...
        function db_flavor (line 755) | inline db_flavor parse_db_version(string_view version_string)
      type detail (line 247) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(const ok_view& ok) noexcept : ok(ok) {}
          method data_t (line 216) | data_t(error_code err) noexcept : err(err) {}
          method data_t (line 217) | data_t(auth_switch msg) noexcept : auth_sw(msg) {}
          method data_t (line 218) | data_t(span<const std::uint8_t> more_data) noexcept : more_data(...
          method handshake_server_response (line 221) | handshake_server_response(const ok_view& ok) noexcept : type(typ...
          method handshake_server_response (line 222) | handshake_server_response(error_code err) noexcept : type(type_t...
          method handshake_server_response (line 223) | handshake_server_response(auth_switch auth_switch) noexcept : ty...
          method handshake_server_response (line 226) | handshake_server_response(span<const std::uint8_t> more_data) no...
        function is_next_field_null (line 648) | inline bool is_next_field_null(const deserialization_context& ctx)
        function error_code (line 655) | inline error_code deserialize_text_row(
        function error_code (line 682) | inline error_code deserialize_binary_row(
        function capabilities (line 746) | inline capabilities compose_capabilities(string_fixed<2> low, stri...
        function db_flavor (line 755) | inline db_flavor parse_db_version(string_view version_string)
      type detail (line 646) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(const ok_view& ok) noexcept : ok(ok) {}
          method data_t (line 216) | data_t(error_code err) noexcept : err(err) {}
          method data_t (line 217) | data_t(auth_switch msg) noexcept : auth_sw(msg) {}
          method data_t (line 218) | data_t(span<const std::uint8_t> more_data) noexcept : more_data(...
          method handshake_server_response (line 221) | handshake_server_response(const ok_view& ok) noexcept : type(typ...
          method handshake_server_response (line 222) | handshake_server_response(error_code err) noexcept : type(type_t...
          method handshake_server_response (line 223) | handshake_server_response(auth_switch auth_switch) noexcept : ty...
          method handshake_server_response (line 226) | handshake_server_response(span<const std::uint8_t> more_data) no...
        function is_next_field_null (line 648) | inline bool is_next_field_null(const deserialization_context& ctx)
        function error_code (line 655) | inline error_code deserialize_text_row(
        function error_code (line 682) | inline error_code deserialize_binary_row(
        function capabilities (line 746) | inline capabilities compose_capabilities(string_fixed<2> low, stri...
        function db_flavor (line 755) | inline db_flavor parse_db_version(string_view version_string)
      type detail (line 744) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(const ok_view& ok) noexcept : ok(ok) {}
          method data_t (line 216) | data_t(error_code err) noexcept : err(err) {}
          method data_t (line 217) | data_t(auth_switch msg) noexcept : auth_sw(msg) {}
          method data_t (line 218) | data_t(span<const std::uint8_t> more_data) noexcept : more_data(...
          method handshake_server_response (line 221) | handshake_server_response(const ok_view& ok) noexcept : type(typ...
          method handshake_server_response (line 222) | handshake_server_response(error_code err) noexcept : type(type_t...
          method handshake_server_response (line 223) | handshake_server_response(auth_switch auth_switch) noexcept : ty...
          method handshake_server_response (line 226) | handshake_server_response(span<const std::uint8_t> more_data) no...
        function is_next_field_null (line 648) | inline bool is_next_field_null(const deserialization_context& ctx)
        function error_code (line 655) | inline error_code deserialize_text_row(
        function error_code (line 682) | inline error_code deserialize_binary_row(
        function capabilities (line 746) | inline capabilities compose_capabilities(string_fixed<2> low, stri...
        function db_flavor (line 755) | inline db_flavor parse_db_version(string_view version_string)
    type mysql (line 246) | namespace mysql {
      type detail (line 46) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(const ok_view& ok) noexcept : ok(ok) {}
          method data_t (line 216) | data_t(error_code err) noexcept : err(err) {}
          method data_t (line 217) | data_t(auth_switch msg) noexcept : auth_sw(msg) {}
          method data_t (line 218) | data_t(span<const std::uint8_t> more_data) noexcept : more_data(...
          method handshake_server_response (line 221) | handshake_server_response(const ok_view& ok) noexcept : type(typ...
          method handshake_server_response (line 222) | handshake_server_response(error_code err) noexcept : type(type_t...
          method handshake_server_response (line 223) | handshake_server_response(auth_switch auth_switch) noexcept : ty...
          method handshake_server_response (line 226) | handshake_server_response(span<const std::uint8_t> more_data) no...
        function is_next_field_null (line 648) | inline bool is_next_field_null(const deserialization_context& ctx)
        function error_code (line 655) | inline error_code deserialize_text_row(
        function error_code (line 682) | inline error_code deserialize_binary_row(
        function capabilities (line 746) | inline capabilities compose_capabilities(string_fixed<2> low, stri...
        function db_flavor (line 755) | inline db_flavor parse_db_version(string_view version_string)
      type detail (line 247) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(const ok_view& ok) noexcept : ok(ok) {}
          method data_t (line 216) | data_t(error_code err) noexcept : err(err) {}
          method data_t (line 217) | data_t(auth_switch msg) noexcept : auth_sw(msg) {}
          method data_t (line 218) | data_t(span<const std::uint8_t> more_data) noexcept : more_data(...
          method handshake_server_response (line 221) | handshake_server_response(const ok_view& ok) noexcept : type(typ...
          method handshake_server_response (line 222) | handshake_server_response(error_code err) noexcept : type(type_t...
          method handshake_server_response (line 223) | handshake_server_response(auth_switch auth_switch) noexcept : ty...
          method handshake_server_response (line 226) | handshake_server_response(span<const std::uint8_t> more_data) no...
        function is_next_field_null (line 648) | inline bool is_next_field_null(const deserialization_context& ctx)
        function error_code (line 655) | inline error_code deserialize_text_row(
        function error_code (line 682) | inline error_code deserialize_binary_row(
        function capabilities (line 746) | inline capabilities compose_capabilities(string_fixed<2> low, stri...
        function db_flavor (line 755) | inline db_flavor parse_db_version(string_view version_string)
      type detail (line 646) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(const ok_view& ok) noexcept : ok(ok) {}
          method data_t (line 216) | data_t(error_code err) noexcept : err(err) {}
          method data_t (line 217) | data_t(auth_switch msg) noexcept : auth_sw(msg) {}
          method data_t (line 218) | data_t(span<const std::uint8_t> more_data) noexcept : more_data(...
          method handshake_server_response (line 221) | handshake_server_response(const ok_view& ok) noexcept : type(typ...
          method handshake_server_response (line 222) | handshake_server_response(error_code err) noexcept : type(type_t...
          method handshake_server_response (line 223) | handshake_server_response(auth_switch auth_switch) noexcept : ty...
          method handshake_server_response (line 226) | handshake_server_response(span<const std::uint8_t> more_data) no...
        function is_next_field_null (line 648) | inline bool is_next_field_null(const deserialization_context& ctx)
        function error_code (line 655) | inline error_code deserialize_text_row(
        function error_code (line 682) | inline error_code deserialize_binary_row(
        function capabilities (line 746) | inline capabilities compose_capabilities(string_fixed<2> low, stri...
        function db_flavor (line 755) | inline db_flavor parse_db_version(string_view version_string)
      type detail (line 744) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(const ok_view& ok) noexcept : ok(ok) {}
          method data_t (line 216) | data_t(error_code err) noexcept : err(err) {}
          method data_t (line 217) | data_t(auth_switch msg) noexcept : auth_sw(msg) {}
          method data_t (line 218) | data_t(span<const std::uint8_t> more_data) noexcept : more_data(...
          method handshake_server_response (line 221) | handshake_server_response(const ok_view& ok) noexcept : type(typ...
          method handshake_server_response (line 222) | handshake_server_response(error_code err) noexcept : type(type_t...
          method handshake_server_response (line 223) | handshake_server_response(auth_switch auth_switch) noexcept : ty...
          method handshake_server_response (line 226) | handshake_server_response(span<const std::uint8_t> more_data) no...
        function is_next_field_null (line 648) | inline bool is_next_field_null(const deserialization_context& ctx)
        function error_code (line 655) | inline error_code deserialize_text_row(
        function error_code (line 682) | inline error_code deserialize_binary_row(
        function capabilities (line 746) | inline capabilities compose_capabilities(string_fixed<2> low, stri...
        function db_flavor (line 755) | inline db_flavor parse_db_version(string_view version_string)
    type mysql (line 645) | namespace mysql {
      type detail (line 46) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(const ok_view& ok) noexcept : ok(ok) {}
          method data_t (line 216) | data_t(error_code err) noexcept : err(err) {}
          method data_t (line 217) | data_t(auth_switch msg) noexcept : auth_sw(msg) {}
          method data_t (line 218) | data_t(span<const std::uint8_t> more_data) noexcept : more_data(...
          method handshake_server_response (line 221) | handshake_server_response(const ok_view& ok) noexcept : type(typ...
          method handshake_server_response (line 222) | handshake_server_response(error_code err) noexcept : type(type_t...
          method handshake_server_response (line 223) | handshake_server_response(auth_switch auth_switch) noexcept : ty...
          method handshake_server_response (line 226) | handshake_server_response(span<const std::uint8_t> more_data) no...
        function is_next_field_null (line 648) | inline bool is_next_field_null(const deserialization_context& ctx)
        function error_code (line 655) | inline error_code deserialize_text_row(
        function error_code (line 682) | inline error_code deserialize_binary_row(
        function capabilities (line 746) | inline capabilities compose_capabilities(string_fixed<2> low, stri...
        function db_flavor (line 755) | inline db_flavor parse_db_version(string_view version_string)
      type detail (line 247) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(const ok_view& ok) noexcept : ok(ok) {}
          method data_t (line 216) | data_t(error_code err) noexcept : err(err) {}
          method data_t (line 217) | data_t(auth_switch msg) noexcept : auth_sw(msg) {}
          method data_t (line 218) | data_t(span<const std::uint8_t> more_data) noexcept : more_data(...
          method handshake_server_response (line 221) | handshake_server_response(const ok_view& ok) noexcept : type(typ...
          method handshake_server_response (line 222) | handshake_server_response(error_code err) noexcept : type(type_t...
          method handshake_server_response (line 223) | handshake_server_response(auth_switch auth_switch) noexcept : ty...
          method handshake_server_response (line 226) | handshake_server_response(span<const std::uint8_t> more_data) no...
        function is_next_field_null (line 648) | inline bool is_next_field_null(const deserialization_context& ctx)
        function error_code (line 655) | inline error_code deserialize_text_row(
        function error_code (line 682) | inline error_code deserialize_binary_row(
        function capabilities (line 746) | inline capabilities compose_capabilities(string_fixed<2> low, stri...
        function db_flavor (line 755) | inline db_flavor parse_db_version(string_view version_string)
      type detail (line 646) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(const ok_view& ok) noexcept : ok(ok) {}
          method data_t (line 216) | data_t(error_code err) noexcept : err(err) {}
          method data_t (line 217) | data_t(auth_switch msg) noexcept : auth_sw(msg) {}
          method data_t (line 218) | data_t(span<const std::uint8_t> more_data) noexcept : more_data(...
          method handshake_server_response (line 221) | handshake_server_response(const ok_view& ok) noexcept : type(typ...
          method handshake_server_response (line 222) | handshake_server_response(error_code err) noexcept : type(type_t...
          method handshake_server_response (line 223) | handshake_server_response(auth_switch auth_switch) noexcept : ty...
          method handshake_server_response (line 226) | handshake_server_response(span<const std::uint8_t> more_data) no...
        function is_next_field_null (line 648) | inline bool is_next_field_null(const deserialization_context& ctx)
        function error_code (line 655) | inline error_code deserialize_text_row(
        function error_code (line 682) | inline error_code deserialize_binary_row(
        function capabilities (line 746) | inline capabilities compose_capabilities(string_fixed<2> low, stri...
        function db_flavor (line 755) | inline db_flavor parse_db_version(string_view version_string)
      type detail (line 744) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(const ok_view& ok) noexcept : ok(ok) {}
          method data_t (line 216) | data_t(error_code err) noexcept : err(err) {}
          method data_t (line 217) | data_t(auth_switch msg) noexcept : auth_sw(msg) {}
          method data_t (line 218) | data_t(span<const std::uint8_t> more_data) noexcept : more_data(...
          method handshake_server_response (line 221) | handshake_server_response(const ok_view& ok) noexcept : type(typ...
          method handshake_server_response (line 222) | handshake_server_response(error_code err) noexcept : type(type_t...
          method handshake_server_response (line 223) | handshake_server_response(auth_switch auth_switch) noexcept : ty...
          method handshake_server_response (line 226) | handshake_server_response(span<const std::uint8_t> more_data) no...
        function is_next_field_null (line 648) | inline bool is_next_field_null(const deserialization_context& ctx)
        function error_code (line 655) | inline error_code deserialize_text_row(
        function error_code (line 682) | inline error_code deserialize_binary_row(
        function capabilities (line 746) | inline capabilities compose_capabilities(string_fixed<2> low, stri...
        function db_flavor (line 755) | inline db_flavor parse_db_version(string_view version_string)
    type mysql (line 743) | namespace mysql {
      type detail (line 46) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(const ok_view& ok) noexcept : ok(ok) {}
          method data_t (line 216) | data_t(error_code err) noexcept : err(err) {}
          method data_t (line 217) | data_t(auth_switch msg) noexcept : auth_sw(msg) {}
          method data_t (line 218) | data_t(span<const std::uint8_t> more_data) noexcept : more_data(...
          method handshake_server_response (line 221) | handshake_server_response(const ok_view& ok) noexcept : type(typ...
          method handshake_server_response (line 222) | handshake_server_response(error_code err) noexcept : type(type_t...
          method handshake_server_response (line 223) | handshake_server_response(auth_switch auth_switch) noexcept : ty...
          method handshake_server_response (line 226) | handshake_server_response(span<const std::uint8_t> more_data) no...
        function is_next_field_null (line 648) | inline bool is_next_field_null(const deserialization_context& ctx)
        function error_code (line 655) | inline error_code deserialize_text_row(
        function error_code (line 682) | inline error_code deserialize_binary_row(
        function capabilities (line 746) | inline capabilities compose_capabilities(string_fixed<2> low, stri...
        function db_flavor (line 755) | inline db_flavor parse_db_version(string_view version_string)
      type detail (line 247) | namespace detail {
        type err_view (line 52) | struct err_view
        type prepare_stmt_response (line 87) | struct prepare_stmt_response
        type execute_response (line 105) | struct execute_response
          type type_t (line 107) | enum class type_t
          method data_t (line 119) | data_t(size_t v) noexcept : num_fields(v) {}
          method data_t (line 120) | data_t(const ok_view& v) noexcept : ok_pack(v) {}
          method data_t (line 121) | data_t(error_code v) noexcept : err(v) {}
          method execute_response (line 124) | execute_response(std::size_t v) noexcept : type(type_t::num_fiel...
          method execute_response (line 125) | execute_response(const ok_view& v) noexcept : type(type_t::ok_pa...
          method execute_response (line 126) | execute_response(error_code v) noexcept : type(type_t::error), d...
        type row_message (line 134) | struct row_message
          type type_t (line 136) | enum class type_t
          method data_t (line 148) | data_t(span<const std::uint8_t> row) noexcept : row(row) {}
          method data_t (line 149) | data_t(const ok_view& ok_pack) noexcept : ok_pack(ok_pack) {}
          method data_t (line 150) | data_t(error_code err) noexcept : err(err) {}
          method row_message (line 153) | row_message(span<const std::uint8_t> row) noexcept : type(type_t...
          method row_message (line 154) | row_message(const ok_view& ok_pack) noexcept : type(type_t::ok_p...
          method row_message (line 155) | row_message(error_code v) noexcept : type(type_t::error), data(v...
        type server_hello (line 167) | struct server_hello
        type auth_switch (line 187) | struct auth_switch
        type handshake_server_response (line 198) | struct handshake_server_response
          type type_t (line 200) | enum class type_t
          method data_t (line 215) | data_t(con
Condensed preview — 620 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,939K chars).
[
  {
    "path": ".clang-format",
    "chars": 4534,
    "preview": "---\nLanguage: Cpp\nColumnLimit: 110\nIndentWidth: 4\nBreakBeforeBraces: Custom\nBraceWrapping:\n  AfterCaseLabel: true\n  Afte"
  },
  {
    "path": ".clangd",
    "chars": 66,
    "preview": "Diagnostics:\n  ClangTidy:\n    Remove: bugprone-unused-return-value"
  },
  {
    "path": ".codecov.yml",
    "chars": 366,
    "preview": "#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed under the Boost Softwar"
  },
  {
    "path": ".dockerignore",
    "chars": 142,
    "preview": ".cache/\n.cproject\n.project\n.settings/\n.pydevproject\nprivate/\nbuild*/\nout/\n.vs/\n.vscode/\ncompile_commands.json\n.cache/\ndo"
  },
  {
    "path": ".drone.star",
    "chars": 15612,
    "preview": "#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed under the Boost Softwar"
  },
  {
    "path": ".github/workflows/build-code.yml",
    "chars": 910,
    "preview": "#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed under the Boost Softwar"
  },
  {
    "path": ".github/workflows/coverage.yml",
    "chars": 2187,
    "preview": "#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed under the Boost Softwar"
  },
  {
    "path": ".github/workflows/docker-windows.yml",
    "chars": 1446,
    "preview": "#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed under the Boost Softwar"
  },
  {
    "path": ".github/workflows/fuzz.yml",
    "chars": 1564,
    "preview": "#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed under the Boost Softwar"
  },
  {
    "path": ".gitignore",
    "chars": 189,
    "preview": "/__build/\n.cproject\n.project\n.settings/\n.pydevproject\n/private/\nCMakeSettings.json\nout/\n.vs/\ndoc/html/\ndoc/qbk/reference"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 2926,
    "preview": "#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed under the Boost Softwar"
  },
  {
    "path": "LICENSE_1_0.txt",
    "chars": 1338,
    "preview": "Boost Software License - Version 1.0 - August 17th, 2003\n\nPermission is hereby granted, free of charge, to any person or"
  },
  {
    "path": "README.md",
    "chars": 4003,
    "preview": "# Boost.MySQL\n\nBranch | Windows/Linux Build | OSX build | Coverage | Documentation\n-------|---------------------|-------"
  },
  {
    "path": "bench/CMakeLists.txt",
    "chars": 3030,
    "preview": "#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed under the Boost Softwar"
  },
  {
    "path": "bench/bench.ipynb",
    "chars": 2688,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Benchmark data processing\\n\",\n   "
  },
  {
    "path": "bench/connection_pool.cpp",
    "chars": 8720,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "bench/db_setup.sql",
    "chars": 2640,
    "preview": "--\n-- Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n--\n-- Distributed under the Boost Sof"
  },
  {
    "path": "bench/many_rows_boost.cpp",
    "chars": 1843,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "bench/many_rows_libmariadb.cpp",
    "chars": 6614,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "bench/many_rows_libmysqlclient.cpp",
    "chars": 6840,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "bench/one_big_row_boost.cpp",
    "chars": 1962,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "bench/one_big_row_libmariadb.cpp",
    "chars": 6915,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "bench/one_big_row_libmysqlclient.cpp",
    "chars": 7170,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "bench/one_small_row_boost.cpp",
    "chars": 1914,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "bench/one_small_row_libmariadb.cpp",
    "chars": 5482,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "bench/one_small_row_libmysqlclient.cpp",
    "chars": 5717,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "bench/stmt_params_boost.cpp",
    "chars": 3476,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "bench/stmt_params_libmariadb.cpp",
    "chars": 7029,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "bench/stmt_params_libmysqlclient.cpp",
    "chars": 7268,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "build.jam",
    "chars": 1033,
    "preview": "# Copyright René Ferdinand Rivera Morell 2024\n# Distributed under the Boost Software License, Version 1.0.\n# (See accomp"
  },
  {
    "path": "cmake/utils.cmake",
    "chars": 2374,
    "preview": "#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed under the Boost Softwar"
  },
  {
    "path": "doc/Jamfile",
    "chars": 4971,
    "preview": "#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed under the Boost Softwar"
  },
  {
    "path": "doc/config.json",
    "chars": 1246,
    "preview": "{\n    \"include_private\": false,\n    \"legacy_behavior\": false,\n    \"external_marker\": \"!EXTERNAL!\",\n    \"link_prefix\": \"m"
  },
  {
    "path": "doc/doxygen.hpp",
    "chars": 1612,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "doc/qbk/00_main.qbk",
    "chars": 11338,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/01_intro.qbk",
    "chars": 4486,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/02_integrating.qbk",
    "chars": 3547,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/03_1_tutorial_sync.qbk",
    "chars": 3536,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/03_2_tutorial_async.qbk",
    "chars": 3617,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/03_3_tutorial_with_params.qbk",
    "chars": 4438,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/03_4_tutorial_static_interface.qbk",
    "chars": 3626,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/03_5_tutorial_updates_transactions.qbk",
    "chars": 5461,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/03_6_tutorial_connection_pool.qbk",
    "chars": 4707,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/03_7_tutorial_error_handling.qbk",
    "chars": 9266,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/04_overview.qbk",
    "chars": 10430,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/05_connection_establishment.qbk",
    "chars": 10698,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/06_text_queries.qbk",
    "chars": 10916,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/07_prepared_statements.qbk",
    "chars": 7771,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/08_dynamic_interface.qbk",
    "chars": 14955,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/09_static_interface.qbk",
    "chars": 11621,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/10_multi_resultset.qbk",
    "chars": 5497,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/11_multi_function.qbk",
    "chars": 10932,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/12_connection_pool.qbk",
    "chars": 12037,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/13_1_interfacing_sync_async.qbk",
    "chars": 5399,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/13_async.qbk",
    "chars": 5706,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/14_error_handling.qbk",
    "chars": 5888,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/15_sql_formatting_advanced.qbk",
    "chars": 16076,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/16_metadata.qbk",
    "chars": 1602,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/17_charsets.qbk",
    "chars": 12270,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/18_time_types.qbk",
    "chars": 5362,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/19_templated_connection.qbk",
    "chars": 10184,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/20_1_benchmarks.qbk",
    "chars": 5120,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/20_pipeline.qbk",
    "chars": 6468,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/21_examples.qbk",
    "chars": 9254,
    "preview": "[/\n    Copyright (c) 2019-2024 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/helpers/ExecutionRequest.qbk",
    "chars": 1226,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/helpers/ExecutionStateType.qbk",
    "chars": 513,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/helpers/FieldViewFwdIterator.qbk",
    "chars": 516,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/helpers/Formattable.qbk",
    "chars": 1631,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/helpers/OutputString.qbk",
    "chars": 896,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/helpers/ResultsType.qbk",
    "chars": 476,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/helpers/SocketStream.qbk",
    "chars": 858,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/helpers/StaticRow.qbk",
    "chars": 2217,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/helpers/Stream.qbk",
    "chars": 591,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/helpers/WritableFieldTuple.qbk",
    "chars": 904,
    "preview": "[/\n    Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n   \n    Distributed under the Boost "
  },
  {
    "path": "doc/qbk/helpers/quickref.xml",
    "chars": 13247,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE library PUBLIC \"-//Boost//DTD BoostBook XML V1.0//EN\" \"../../../../../t"
  },
  {
    "path": "doc/upgrade_1_82.md",
    "chars": 5541,
    "preview": "# Upgrade instructions to 1.82\n\nThis document describes how to upgrade from 0.2.x to 1.82 (please remember that 1.82 is "
  },
  {
    "path": "example/1_tutorial/1_sync.cpp",
    "chars": 2830,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/1_tutorial/2_async.cpp",
    "chars": 4535,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/1_tutorial/3_with_params.cpp",
    "chars": 5051,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/1_tutorial/4_static_interface.cpp",
    "chars": 5656,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/1_tutorial/5_updates_transactions.cpp",
    "chars": 6791,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/1_tutorial/6_connection_pool.cpp",
    "chars": 10283,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/1_tutorial/7_error_handling.cpp",
    "chars": 12257,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/batch_inserts.cpp",
    "chars": 7082,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/batch_inserts_generic.cpp",
    "chars": 8053,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/callbacks.cpp",
    "chars": 5858,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/coroutines_cpp11.cpp",
    "chars": 5266,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/deletes.cpp",
    "chars": 4481,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/disable_tls.cpp",
    "chars": 4031,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/dynamic_filters.cpp",
    "chars": 12097,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/inserts.cpp",
    "chars": 5619,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/metadata.cpp",
    "chars": 6605,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/multi_function.cpp",
    "chars": 4737,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/patch_updates.cpp",
    "chars": 9674,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/pipeline.cpp",
    "chars": 6955,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/prepared_statements.cpp",
    "chars": 5536,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/source_script.cpp",
    "chars": 6082,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/tls_certificate_verification.cpp",
    "chars": 6909,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/2_simple/unix_socket.cpp",
    "chars": 4253,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp14_coroutines/handle_request.cpp",
    "chars": 11918,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp14_coroutines/handle_request.hpp",
    "chars": 1168,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp14_coroutines/main.cpp",
    "chars": 4657,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp14_coroutines/repository.cpp",
    "chars": 7286,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp14_coroutines/repository.hpp",
    "chars": 2478,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp14_coroutines/server.cpp",
    "chars": 6716,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp14_coroutines/server.hpp",
    "chars": 1428,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp14_coroutines/types.hpp",
    "chars": 2175,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp20/db_setup.sql",
    "chars": 2858,
    "preview": "--\n-- Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n--\n-- Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp20/error.cpp",
    "chars": 2076,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp20/error.hpp",
    "chars": 2213,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp20/handle_request.cpp",
    "chars": 15685,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp20/handle_request.hpp",
    "chars": 1127,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp20/main.cpp",
    "chars": 6062,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp20/repository.cpp",
    "chars": 12277,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp20/repository.hpp",
    "chars": 2937,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp20/server.cpp",
    "chars": 7616,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp20/server.hpp",
    "chars": 914,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/3_advanced/http_server_cpp20/types.hpp",
    "chars": 3483,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "example/CMakeLists.txt",
    "chars": 5340,
    "preview": "#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed under the Boost Softwar"
  },
  {
    "path": "example/Jamfile",
    "chars": 5271,
    "preview": "#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed under the Boost Softwar"
  },
  {
    "path": "example/db_setup.sql",
    "chars": 2594,
    "preview": "--\n-- Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n--\n-- Distributed under the Boost Sof"
  },
  {
    "path": "example/private/employees_multiple.json",
    "chars": 385,
    "preview": "[\n    {\n        \"first_name\": \"Alice\",\n        \"last_name\": \"Davidson\",\n        \"salary\": 40000,\n        \"company_id\": \""
  },
  {
    "path": "example/private/employees_single.json",
    "chars": 134,
    "preview": "[\n    {\n        \"first_name\": \"Lonely\",\n        \"last_name\": \"Developer\",\n        \"salary\": 90000,\n        \"company_id\":"
  },
  {
    "path": "example/private/launch_server.py",
    "chars": 2281,
    "preview": "#!/usr/bin/python3\n#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed unde"
  },
  {
    "path": "example/private/run_batch_inserts.py",
    "chars": 1221,
    "preview": "#!/usr/bin/python3\n#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed unde"
  },
  {
    "path": "example/private/run_dynamic_filters.py",
    "chars": 1331,
    "preview": "#!/usr/bin/python3\n#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed unde"
  },
  {
    "path": "example/private/run_notes.py",
    "chars": 2769,
    "preview": "#!/usr/bin/python3\n#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed unde"
  },
  {
    "path": "example/private/run_orders.py",
    "chars": 11175,
    "preview": "#!/usr/bin/python3\n#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed unde"
  },
  {
    "path": "example/private/run_patch_updates.py",
    "chars": 1286,
    "preview": "#!/usr/bin/python3\n#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed unde"
  },
  {
    "path": "example/private/run_tutorial_connection_pool.py",
    "chars": 2140,
    "preview": "#!/usr/bin/python3\n#\n# Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n#\n# Distributed unde"
  },
  {
    "path": "example/private/test_script.sql",
    "chars": 478,
    "preview": "--\n-- Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n--\n-- Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/any_address.hpp",
    "chars": 9136,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/any_connection.hpp",
    "chars": 68106,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/bad_field_access.hpp",
    "chars": 719,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/blob.hpp",
    "chars": 500,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/blob_view.hpp",
    "chars": 538,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/buffer_params.hpp",
    "chars": 1694,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/character_set.hpp",
    "chars": 2783,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/client_errc.hpp",
    "chars": 6397,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/column_type.hpp",
    "chars": 2268,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/common_server_errc.hpp",
    "chars": 231181,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/connect_params.hpp",
    "chars": 2211,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/connection.hpp",
    "chars": 47699,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/connection_pool.hpp",
    "chars": 30561,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/constant_string_view.hpp",
    "chars": 3353,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/date.hpp",
    "chars": 10439,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/datetime.hpp",
    "chars": 14661,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/days.hpp",
    "chars": 667,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/defaults.hpp",
    "chars": 870,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/access.hpp",
    "chars": 1018,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/algo_params.hpp",
    "chars": 2925,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/any_execution_request.hpp",
    "chars": 2089,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/any_resumable_ref.hpp",
    "chars": 1358,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/character_set.hpp",
    "chars": 746,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/coldef_view.hpp",
    "chars": 1010,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/config.hpp",
    "chars": 1257,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/connect_params_helpers.hpp",
    "chars": 1111,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/connection_impl.hpp",
    "chars": 20225,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/connection_pool_fwd.hpp",
    "chars": 1143,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/datetime.hpp",
    "chars": 3566,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/engine.hpp",
    "chars": 968,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/engine_impl.hpp",
    "chars": 8529,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/engine_stream_adaptor.hpp",
    "chars": 9073,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/escape_string.hpp",
    "chars": 949,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/execution_concepts.hpp",
    "chars": 2141,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/execution_processor/execution_processor.hpp",
    "chars": 6626,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/execution_processor/execution_state_impl.hpp",
    "chars": 3457,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/execution_processor/results_impl.hpp",
    "chars": 7378,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/execution_processor/static_execution_state_impl.hpp",
    "chars": 8957,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/execution_processor/static_results_impl.hpp",
    "chars": 10953,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/field_impl.hpp",
    "chars": 2730,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/flags.hpp",
    "chars": 2227,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/format_sql.hpp",
    "chars": 4162,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/initiation_base.hpp",
    "chars": 1540,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/intermediate_handler.hpp",
    "chars": 2177,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/next_action.hpp",
    "chars": 3095,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/ok_view.hpp",
    "chars": 1019,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/output_string.hpp",
    "chars": 1694,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/pipeline.hpp",
    "chars": 1195,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/rebind_executor.hpp",
    "chars": 942,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/results_iterator.hpp",
    "chars": 3118,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/resultset_encoding.hpp",
    "chars": 596,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/row_impl.hpp",
    "chars": 2591,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/rows_iterator.hpp",
    "chars": 3339,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/sequence.hpp",
    "chars": 2235,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/socket_stream.hpp",
    "chars": 1246,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/ssl_fwd.hpp",
    "chars": 492,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/string_view_offset.hpp",
    "chars": 933,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/throw_on_error_loc.hpp",
    "chars": 852,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/typing/meta_check_context.hpp",
    "chars": 4246,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/typing/pos_map.hpp",
    "chars": 2464,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/typing/readable_field_traits.hpp",
    "chars": 17229,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/typing/row_traits.hpp",
    "chars": 10190,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/void_t.hpp",
    "chars": 541,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/detail/writable_field_traits.hpp",
    "chars": 4177,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/diagnostics.hpp",
    "chars": 3695,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/error_categories.hpp",
    "chars": 2107,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/error_code.hpp",
    "chars": 534,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/error_with_diagnostics.hpp",
    "chars": 1625,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  },
  {
    "path": "include/boost/mysql/escape_string.hpp",
    "chars": 4099,
    "preview": "//\n// Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)\n//\n// Distributed under the Boost Sof"
  }
]

// ... and 420 more files (download for full content)

About this extraction

This page contains the full source code of the boostorg/mysql GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 620 files (4.5 MB), approximately 1.2M tokens, and a symbol index with 5650 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!