[/ 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:dynamic_interface The dynamic interface] [nochunk] To use the dynamic interface, use the [reflink results] class. `results` is an in-memory representation of a resultset. We can depict it like this (this is actually a simplified representation, since [link mysql.multi_resultset some statements may return more than one resultset]). [$mysql/images/results.svg [align center] [scale 125]] We can see that [refmem results rows] returns a matrix-like object, containing the retrieved rows. This section is dedicated on diving deeper on how to use these objects. [heading Rows and fields] This matrix-like structure is composed of variant-like objects called ['fields]. Field objects are capable of representing any value retrieved from MySQL. This library defines the following classes to work with rows and fields: [variablelist [ [[reflink field]] [The smallest unit of data. A single "cell" in a MySQL table. This is an owning, variant-like type.] ] [ [[reflink field_view]] [Like `field`, but non-owning.] ] [ [[reflink row]] [An owning, `vector`-like collection of fields.] ] [ [[reflink row_view]] [Like `row`, but non-owning.] ] [ [[reflink rows]] [An owning, matrix-like collection of fields. Represents several rows of the same size in an optimized way.] ] [ [[reflink rows_view]] [Like `rows`, but non-owning.] ] ] [refmem results rows] returns a [reflink rows_view] object. The memory for the rows is owned by the `results` object. Indexing the returned view also returns view objects: [dynamic_views] Views behave similarly to `std::string_view`. You must make sure that you don't use a view after the storage it points to has gone out of scope. In this case, you must not use any of the views after the `results` object has gone out of scope. As it happens with `std::string_view`, you can take ownership of a view using its owning counterpart: [dynamic_taking_ownership] [heading Using fields] [reflink field] and [reflink field_view] are specialized variant-like types that can hold any type you may find in a MySQL table. Once you obtain a field, you can access its contents using the following functions: * You can query a field's type by using [refmemunq field_view kind], which returns a [reflink field_kind] enum. * You can query whether a field contains a certain type with `field::is_xxx`. * You can get the underlying value with `field::as_xxx` and `field::get_xxx`. The `as_xxx` functions are checked (they will throw an exception if the actual type doesn't match), while the `get_xxx` are unchecked (they result in undefined behavior on type mismatch). * You can stream fields and compare them for equality. For example: [dynamic_using_fields] `NULL` values are represented as field objects having `kind() == field_kind::null`. You can check whether a value is `NULL` or not using [refmemunq field_view is_null]. This is how `NULL`s are typically handled: [dynamic_handling_nulls] [heading MySQL to C++ type mappings] Every MySQL type is mapped to a single C++ type. The following table shows these mappings: [table:accessors [ [`field_kind`] [C++ type] [MySQL types] [`is` accessor] [`as` accessor] [`get` accessor] ] [ [`int64`] [`std::int64_t`] [__TINYINT__, __SMALLINT__, __MEDIUMINT__, __INT__, __BIGINT__] [[refmemunq field_view is_int64]] [[refmemunq field_view as_int64]] [[refmemunq field_view get_int64]] ] [ [`uint64`] [`std::uint64_t`] [Unsigned __TINYINT__, __SMALLINT__, __MEDIUMINT__, __INT__, __BIGINT__, __YEAR__, __BIT__] [[refmemunq field_view is_uint64]] [[refmemunq field_view as_uint64]] [[refmemunq field_view get_uint64]] ] [ [`string`] [ [reflink string_view] for `field_view` `std::string` for `field` ] [ __CHAR__, __VARCHAR__, __TEXT__ (all sizes), __ENUM__, __SET__, __DECIMAL__, __NUMERIC__, __JSON__ ] [[refmemunq field_view is_string]] [[refmemunq field_view as_string]] [[refmemunq field_view get_string]] ] [ [`blob`] [ [reflink blob_view] for `field_view` [reflink blob] for `field` ] [__BINARY__, __VARBINARY__, __BLOB__ (all sizes), __GEOMETRY__] [[refmemunq field_view is_blob]] [[refmemunq field_view as_blob]] [[refmemunq field_view get_blob]] ] [ [`float_`] [`float`] [__FLOAT__] [[refmemunq field_view is_float]] [[refmemunq field_view as_float]] [[refmemunq field_view get_float]] ] [ [`double_`] [`double`] [__DOUBLE__] [[refmemunq field_view is_double]] [[refmemunq field_view as_double]] [[refmemunq field_view get_double]] ] [ [`date`] [[reflink date]] [__DATE__] [[refmemunq field_view is_date]] [[refmemunq field_view as_date]] [[refmemunq field_view get_date]] ] [ [`datetime`] [[reflink datetime]] [__DATETIME__, __TIMESTAMP__] [[refmemunq field_view is_datetime]] [[refmemunq field_view as_datetime]] [[refmemunq field_view get_datetime]] ] [ [`time`] [[reflink time]] [__TIME__] [[refmemunq field_view is_time]] [[refmemunq field_view as_time]] [[refmemunq field_view get_time]] ] [ [`null`] [] [Any of the above, when they're `NULL`] [[refmemunq field_view is_null]] [] [] ] ] No character set conversion is applied on strings. They are provided as the server sends them. If you've run [refmemunq any_connection async_set_character_set], strings will be encoded according to the passed character set. For details, see [link mysql.charsets this section]. [heading The field class] [reflink field_view] is to [reflink field] what `std::string_view` is to `std::string`. `field_view`s are cheap to create and to copy, as they are small objects and don't perform any memory allocations. They are also immutable. On the other hand, `field`s may be more expensive to create and copy, as they may perform memory allocations. `field`s are mutable. `field` and `field_view` use the same underlying types for scalars. For strings and blobs, `field` uses the owning types `std::string` and [reflink blob], while `field_view` uses the reference types [reflink string_view] and [reflink blob_view]. `field` accessors return references, which allow you to mutate the underlying object: [dynamic_field_accessor_references] You can also mutate a `field` using the assignment operator. This allows you to also change the underlying type of a `field`: [dynamic_field_assignment] [heading Multi-resultset and multi-function operations] You can use both with the dynamic interface. Please refer to the sections on [link mysql.multi_resultset multi-resultset operations] and [link mysql.multi_function multi-function operations] for more information. [heading MySQL to C++ type mapping reference] The following table reflects mapping from database types to C++ types. The range column shows the range of values that MySQL admits for that type. This library guarantees that any field retrieved from the database honors that range. The `column_type` column shows what [refmem metadata type] would return for a column of that type. [table:dynamic_field_mappings [ [MySQL type] [`field_kind`] [C++ type] [Range] [`column_type`] [Considerations] ] [ [__TINYINT__] [`int64`] [`std::int64_t`] [`-0x80` to `0x7f`] [`tinyint`] [1 byte integer] ] [ [__TINYINT__ `UNSIGNED`] [`uint64`] [`std::uint64_t`] [`0` to `0xff`] [`tinyint`] [1 byte integer] ] [ [__SMALLINT__] [`int64`] [`std::int64_t`] [`-0x8000` to `0x7fff`] [`smallint`] [2 byte integer] ] [ [__SMALLINT__ `UNSIGNED`] [`uint64`] [`std::uint64_t`] [`0` to `0xffff`] [`smallint`] [2 byte integer] ] [ [__MEDIUMINT__] [`int64`] [`std::int64_t`] [`-0x800000` to `0x7fffff`] [`mediumint`] [3 byte integer] ] [ [__MEDIUMINT__ `UNSIGNED`] [`uint64`] [`std::uint64_t`] [`0` to `0xffffff`] [`mediumint`] [3 byte integer] ] [ [__INT__] [`int64`] [`std::int64_t`] [`-0x80000000` to `0x7fffffff`] [`int_`] [4 byte integer] ] [ [__INT__ `UNSIGNED`] [`uint64`] [`std::uint64_t`] [`0` to `0xffffffff`] [`int_`] [4 byte integer] ] [ [__BIGINT__] [`int64`] [`std::int64_t`] [`-0x8000000000000000` to `0x7fffffffffffffff`] [`bigint`] [8 byte integer] ] [ [__BIGINT__ `UNSIGNED`] [`uint64`] [`std::uint64_t`] [`0` and `0xffffffffffffffff`] [`bigint`] [8 byte integer] ] [ [__YEAR__] [`uint64`] [`std::uint64_t`] [\[`1901`, `2155`\], plus zero] [`year`] [ 1 byte integer type used to represent years Zero is often employed to represent invalid year values. We represent zero year as a numeric 0. ] ] [ [__BIT__] [`uint64`] [`std::uint64_t`] [Depends on the bitset width. Max `0` to `0xffffffffffffffff`.] [`bit`] [ A bitset between 1 and 64 bits wide. ] ] [ [__FLOAT__] [`float_`] [`float`] [IEEE 754 `float` range] [`float_`] [ 4 byte floating point type ] ] [ [__DOUBLE__] [`double_`] [`double`] [IEEE 754 `double` range] [`double_`] [ 8 byte floating point type ] ] [ [__DATE__] [`date`] [[reflink date]] [ \[[reflink min_date], [reflink max_date]\] (some MySQL implementations may allow a narrower range), plus invalid and zero dates (see __allow_invalid_dates__ and __strict_sql__). ] [`date`] [] ] [ [__DATETIME__] [`datetime`] [[reflink datetime]] [ \[[reflink min_datetime], [reflink max_datetime]\] (some MySQL implementations may allow a narrower range), plus invalid and zero datetimes (see __allow_invalid_dates__ and __strict_sql__). ] [`datetime`] [ Time point type without time zone, with a resolution of one microsecond. ] ] [ [__TIMESTAMP__] [`datetime`] [[reflink datetime]] [ \[[reflink min_datetime], [reflink max_datetime]\] (the actual MySQL supported range is usually narrower, but we don't enforce it in the client), plus zero timestamps (see __strict_sql__). ] [`timestamp`] [ Time point type with a resolution of one microsecond. ] ] [ [__TIME__] [`time`] [[reflink time]] [ \[[reflink min_time], [reflink max_time]\] ] [`time`] [ Signed time duration, with a resolution of one microsecond. ] ] [ [__CHAR__] [`string`] [[reflink string_view] or `std::string`] [] [`char_`] [ Fixed-size character string. ] ] [ [__VARCHAR__] [`string`] [[reflink string_view] or `std::string`] [] [`varchar`] [ Variable size character string with a maximum size. ] ] [ [__TEXT__ (all sizes)] [`string`] [[reflink string_view] or `std::string`] [] [`text`] [ Variable size character string. ] ] [ [__ENUM__] [`string`] [[reflink string_view] or `std::string`] [] [`enum_`] [ Character string with a fixed set of possible values (only one possible). ] ] [ [__SET__] [`string`] [[reflink string_view] or `std::string`] [] [`set`] [ Character string with a fixed set of possible values (many possible). ] ] [ [__JSON__] [`string`] [[reflink string_view] or `std::string`] [] [`json` (MySQL) or `text` (MariaDB)] [ A serialized JSON value of any type. Note that [refmem metadata type] is different depending on the DB system. MySQL has a dedicated `JSON` type, while in MariaDB `JSON` is an alias for `LONGTEXT`. JSON values are represented as strings by this library in both cases. ] ] [ [__DECIMAL__/__NUMERIC__] [`string`] [[reflink string_view] or `std::string`] [Depends on the column definition] [`decimal`] [ A fixed precision numeric value. In this case, the string will contain the textual representation of the number (e.g. the string `"20.52"` for `20.52`). This type is mapped to a string to avoid losing precision. ] ] [ [__BINARY__] [`blob`] [[reflink blob_view] or [reflink blob]] [] [`binary`] [ Fixed-size blob. ] ] [ [__VARBINARY__] [`blob`] [[reflink blob_view] or [reflink blob]] [] [`varbinary`] [ Variable size blob with a maximum size. ] ] [ [__BLOB__ (all sizes)] [`blob`] [[reflink blob_view] or [reflink blob]] [] [`blob`] [ Variable size blob. ] ] [ [__GEOMETRY__] [`blob`] [[reflink blob_view] or [reflink blob]] [] [`geometry`] [ Any of the spatial data types. The string contains the binary representation of the geometry type. ] ] ] [endsect]