Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Boost 1.87: new discussion and examples #378

Merged
merged 83 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
e803582
Tutorials
anarthal Sep 30, 2024
3559cd6
tutorial updates
anarthal Sep 30, 2024
53be729
Revamp the callbacks example
anarthal Sep 30, 2024
f249091
Namespace aliases for tutorials
anarthal Sep 30, 2024
e4f059e
Revamp the coroutines c++11 example
anarthal Sep 30, 2024
350ae88
Remove obsolete examples
anarthal Sep 30, 2024
aa34c7c
Merge branch 'develop' into feature/new-discussion
anarthal Oct 3, 2024
44e0fae
batch inserts
anarthal Oct 3, 2024
cc6b887
batch_inserts_generic
anarthal Oct 9, 2024
75a1026
Patch updates example
anarthal Oct 11, 2024
af48fbd
Revamp dynamic_filters example
anarthal Oct 11, 2024
bdf746d
Revamp unix sockets
anarthal Oct 11, 2024
f98d1e8
cmake initial revamp
anarthal Oct 11, 2024
1924b70
New disable_tls example
anarthal Oct 11, 2024
6dc4741
Revamp SSL example
anarthal Oct 11, 2024
b00fa54
Fix problem with args in cmake
anarthal Oct 11, 2024
618d0a6
Metadata example
anarthal Oct 11, 2024
86ac37f
Prepared statements example
anarthal Oct 11, 2024
90e99ba
Move examples
anarthal Oct 11, 2024
073d54e
with_params tutorial
anarthal Oct 11, 2024
f8f25a5
Example on timeouts
anarthal Oct 11, 2024
316f5d6
timeouts includes
anarthal Oct 11, 2024
b75df04
Pipeline example
anarthal Oct 11, 2024
d09efe3
multi_function example
anarthal Oct 11, 2024
ec4c2be
Merge branch 'develop' into feature/366-example-update
anarthal Oct 12, 2024
e0e617f
Unused include
anarthal Oct 12, 2024
2a04a29
example on transactions
anarthal Oct 12, 2024
0bad6ab
Merge branch 'develop' into feature/366-example-update
anarthal Oct 28, 2024
465942f
Merge branch 'develop' into feature/366-example-update
anarthal Oct 29, 2024
9cc45df
Relink examples
anarthal Oct 29, 2024
30aab13
Update example comments
anarthal Oct 29, 2024
f99a19d
Redo and automate example page
anarthal Oct 29, 2024
5793277
Redo tutorial section
anarthal Oct 29, 2024
4bf2efa
tutorial async to discussion
anarthal Oct 30, 2024
d8aae22
Tutorial 3 outline
anarthal Oct 30, 2024
3b379da
Tutorial 3 final writing
anarthal Oct 30, 2024
6336f55
Clarify affected_rows
anarthal Oct 30, 2024
59c2433
Static iface tutorial
anarthal Nov 2, 2024
7d901d6
snippets_fixture
anarthal Nov 2, 2024
f3be3c0
Add examples_qbk to file_header
anarthal Nov 2, 2024
507e18f
Tutorial 4 discussion
anarthal Nov 2, 2024
bf07836
Add tutorial 4 to examples section
anarthal Nov 2, 2024
cd3bfbc
WIP connection establishment
anarthal Nov 3, 2024
e3d9f42
Merge branch 'develop' into feature/366-example-update
anarthal Nov 3, 2024
4d61102
Change import autogeneration
anarthal Nov 4, 2024
8fa9371
New example on multi_queries
anarthal Nov 4, 2024
1c64f57
Closing connections
anarthal Nov 4, 2024
8cc748c
Finished connection establishment
anarthal Nov 4, 2024
381d5dc
Remove reconnection
anarthal Nov 4, 2024
ba75289
Merge branch 'develop' into feature/366-example-update
anarthal Nov 4, 2024
d2c442d
Reorder
anarthal Nov 4, 2024
1bdb676
Rework text queries
anarthal Nov 4, 2024
29c9ffe
Final qbk reorder
anarthal Nov 4, 2024
0657634
Overview rework
anarthal Nov 4, 2024
a32272b
Comment templated connection
anarthal Nov 4, 2024
1be7286
Remove SET NAMES recommendatins
anarthal Nov 4, 2024
fdba7b0
Further SET NAMES references
anarthal Nov 4, 2024
a0dbb5e
TODO cleanup
anarthal Nov 4, 2024
fe70e9d
PFR guard
anarthal Nov 4, 2024
a52606a
Move source_script
anarthal Nov 4, 2024
523c3bf
Remove old orders examples
anarthal Nov 4, 2024
8b4541f
Final example cmake
anarthal Nov 4, 2024
10332ff
charsets fix
anarthal Nov 4, 2024
615b7ec
Fix patch_updates
anarthal Nov 4, 2024
2847ce6
Fix callbacks
anarthal Nov 4, 2024
8db4d08
Fix callbacks
anarthal Nov 4, 2024
423ce91
workaround certificate verification
anarthal Nov 4, 2024
c4357ac
Fix connection_pool
anarthal Nov 4, 2024
932e488
Fix snippets
anarthal Nov 4, 2024
1433955
Fix missing include
anarthal Nov 4, 2024
4d0a9b6
Example jamfile
anarthal Nov 4, 2024
50480bb
Removed order_management db_setup
anarthal Nov 4, 2024
d409ac9
Remove named initializers
anarthal Nov 4, 2024
ef5fee4
Workaround for context not running out of work
anarthal Nov 4, 2024
a3ff255
Use PFR with named entities
anarthal Nov 4, 2024
b0d74e6
Update source_sql location
anarthal Nov 4, 2024
03580d7
Uncomment reference
anarthal Nov 4, 2024
0f9211a
Link fixes
anarthal Nov 4, 2024
a0d2623
Remove Boost.Context dependency
anarthal Nov 4, 2024
8771982
inline namespaces to prevent ODR violations
anarthal Nov 4, 2024
1b1f9bf
Missing with_diagnostics in coro example
anarthal Nov 4, 2024
acccd57
Fix MSVC warning
anarthal Nov 4, 2024
b780376
Workaround old libc++ problem
anarthal Nov 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 69 additions & 36 deletions doc/qbk/00_main.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

[library Boost.MySQL
[quickbook 1.7]
[copyright 2019 - 2023 Ruben Perez]
[copyright 2019 - 2024 Ruben Perez]
[id mysql]
[purpose MySQL client library]
[license
Expand Down Expand Up @@ -56,16 +56,16 @@
[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 __see_error_handling__ See [link mysql.error_handling this section] for more info on error handling.]
[def __assume_setup__ This example assumes you have gone through the [link mysql.examples.setup setup].]
[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 __SET_NAMES__ [mysqllink set-names.html `SET NAMES`]]
[def __TINYINT__ [mysqllink integer-types.html `TINYINT`]]
[def __SMALLINT__ [mysqllink integer-types.html `SMALLINT`]]
[def __MEDIUMINT__ [mysqllink integer-types.html `MEDIUMINT`]]
Expand Down Expand Up @@ -124,47 +124,80 @@ BEGIN
END
```]

[import ../../test/integration/include/test_integration/snippets/describe.hpp]
[import ../../test/integration/test/snippets/overview.cpp]
[import ../../test/integration/test/snippets/dynamic.cpp]
[import ../../test/integration/test/snippets/static.cpp]
[/ 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/2_simple/prepared_statements.cpp]
[import ../../example/2_simple/timeouts.cpp]
[import ../../example/2_simple/multi_queries_transactions.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/connection_pool/main.cpp]
[import ../../example/3_advanced/connection_pool/types.hpp]
[import ../../example/3_advanced/connection_pool/repository.hpp]
[import ../../example/3_advanced/connection_pool/repository.cpp]
[import ../../example/3_advanced/connection_pool/handle_request.hpp]
[import ../../example/3_advanced/connection_pool/handle_request.cpp]
[import ../../example/3_advanced/connection_pool/server.hpp]
[import ../../example/3_advanced/connection_pool/server.cpp]
[import ../../example/3_advanced/connection_pool/log_error.hpp]
[import ../../test/integration/test/snippets/prepared_statements.cpp]
[import ../../test/integration/test/snippets/multi_resultset.cpp]
[import ../../test/integration/test/snippets/connection_establishment.cpp]
[import ../../test/integration/test/snippets/charsets.cpp]
[import ../../test/integration/test/snippets/sql_formatting_custom.cpp]
[import ../../test/integration/test/snippets/multi_function.cpp]
[import ../../test/integration/test/snippets/tutorials.cpp]
[import ../../test/integration/test/snippets/metadata.cpp]
[import ../../test/integration/test/snippets/charsets.cpp]
[import ../../test/integration/test/snippets/time_types.cpp]
[import ../../test/integration/test/snippets/any_connection.cpp]
[import ../../test/integration/test/snippets/connection_pool.cpp]
[import ../../test/integration/test/snippets/sql_formatting.cpp]
[import ../../test/integration/test/snippets/sql_formatting_custom.cpp]
[import ../../test/integration/test/snippets/time_types.cpp]
[import ../../test/integration/test/snippets/pipeline.cpp]
[import ../../test/integration/test/snippets/sql_formatting.cpp]
[import ../../test/integration/test/snippets/overview.cpp]
[import ../../test/integration/test/snippets/dynamic.cpp]
[import ../../test/integration/test/snippets/multi_resultset.cpp]
[import ../../test/integration/test/snippets/static.cpp]
[/ AUTOGENERATED IMPORTS END ]
[import ../../test/integration/include/test_integration/snippets/describe.hpp]

[include 01_intro.qbk]
[include 02_integrating.qbk]
[include 03_tutorial.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 04_overview.qbk]
[include 05_dynamic_interface.qbk]
[include 06_static_interface.qbk]
[include 07_queries.qbk]
[include 08_prepared_statements.qbk]
[include 09_multi_resultset.qbk]
[include 10_multi_function.qbk]
[include 11_metadata.qbk]
[include 12_async.qbk]
[include 13_ssl.qbk]
[include 14_other_streams.qbk]
[include 15_error_handling.qbk]
[include 16_connparams.qbk]
[include 17_reconnecting.qbk]
[include 18_charsets.qbk]
[include 19_time_types.qbk]
[include 20_any_connection.qbk]
[include 21_connection_pool.qbk]
[include 22_sql_formatting.qbk]
[include 23_sql_formatting_advanced.qbk]
[include 24_pipeline.qbk]
[include 24_examples.qbk]
[include 05_connection_establishment.qbk]
[include 06_sql_formatting.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 14_error_handling.qbk]
[include 15_sql_formatting_advanced.qbk]
[include 16_metadata.qbk]
[include 17_charsets.qbk]
[include 18_time_types.qbk]
[/ TODO: re-enable this
[include 19_templated_connection.qbk] ]
[include 20_pipeline.qbk]
[include 21_examples.qbk]



[section:ref Reference]
Expand Down
2 changes: 1 addition & 1 deletion doc/qbk/02_integrating.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ target_link_libraries(main PRIVATE Boost::charconv Threads::Threads OpenSSL::Cry
an older version, use the `Boost::headers` target, instead.
]

If you're happy with header-only mode, have a look at [link mysql.tutorial the tutorial]
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]
Expand Down
119 changes: 119 additions & 0 deletions doc/qbk/03_1_tutorial_sync.qbk
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
[/
Copyright (c) 2019-2024 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]
105 changes: 105 additions & 0 deletions doc/qbk/03_2_tutorial_async.qbk
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
[/
Copyright (c) 2019-2024 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]
Loading