[/
    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]