We now only define our targets if they don't exist yet to avoid errors
due to redefining them if find_package(SOCI) is done more than once.
Note that multiple calls to find_package(SOCI) that specify different
components will cause all call-sides to use the superset of all
requested components as targets are global (and hence also their link
dependencies).
Fixes#1344.
See #1346.
Using header-only library for static build and building shared library
for shared build was inconsistent and the rationale given for avoiding
creating a separate library for the static build also applies in the
latter case too, so just always use header-only fmt variant to avoid
imposing extra linking requirements on SOCI users.
Originally, the indicator passed by the user was copied into a stored-for-later
variable. This value could have been overwritten during conversion of the bound
parameter to its base type.
Signed-off-by: Innokentiy Alaytsev <alaitsev@gmail.com>
The tests are expected to fail, because the value of an indicator, passed to the
soci::values::set() function is replaced with the value returned from the
type_conversion::to_base() function. Since it is possible that a valid value was
passed alongside the i_null indicator, e.g., for setting an integer field to
NULL, the type_conversion::to_base() function might return i_ok, as the default
implementation of the function does.
The problematic behaviour is not detected by the existing tests.
Signed-off-by: Innokentiy Alaytsev <alaitsev@gmail.com>
Provide soci_error constructors taking a format string and an argument
instead.
This is still unsafe, because we lose the compile-time check of the
format string, but is slightly less ugly than defining format() in our
own namespace.
Non literal strings can't be used with fmt::format() when using C++20,
so use fmt::vformat() instead.
This is ugly and unsafe, upcoming commits will provide a better fix, but
for now at least make the library compile in C++20 again.
This can happen when the library is used as a sub-project by a
super-project also using fmt and we don't need to do anything in this
case (and doing anything would be actively harmful as we could either
not find fmt at all or find a wrong version of it).
Previously an overload of the soci::use function accepted a value of
type T and a vector of indicators. This function worked when T was
std::vector<U>, but would fail if T was any other type. Judging by the
comment, the original intent was to have an overload for std::vector<T>.
Closes#1334.
Closes#1336.
Signed-off-by: Innokentiy Alaytsev <alaitsev@gmail.com>
This was supposed to allow reading into char[N] but either was never
implemented or got broken a long time ago and doesn't seem really useful
compared to using std::string with into(), so simply remove this
overload.
Closes#1332.
See #1333.
It may be more convenient to work with this type than with "long long",
so provide an overload allowing to retrieve the ID as it too.
Closes#1232.
Closes#1325.
This is useful when the library is used as a sub-project by a
super-project which has already defined targets for various dependencies
(e.g. typically because it bundles them together with SOCI too).
This is more than just an optimization as searching for the dependency
could (and typically would, when they're bundled as mentioned above)
fail, while skipping it allows the configuration and build to succeed.
This change is done mostly not for run-time optimizations purposes but
to show that we don't need to continue iterating after missing at least
one missing target dependency.
Remove ugly get_error_details() function taking multiple output
parameters and just create oracle_soci_error objects directly.
As error.h has now become useless, remove it too.
Instead of calling throw_oracle_soci_error(), add oracle_soci_error ctor
taking the parameters that were passed to this function and just throw
the object created using this ctor.
This is more explicit and simpler.
No real changes.
If execute() didn't bring any data from the server, all statement member
variables remained uninitialized, resulting in problems (UB, infinite
loops, ...) if fetch() is called later.
Fix this by initializing numberOfRows_ and checking for it in fetch()
and simply not doing anything there if it is 0.
Closes#1328.
This also fixes compilation error due to not including <sstream> any
more after the changes of a7b02446 (Merge branch 'use-fmt', 2026-01-15).
See #1321.
While using ints is safe from the point of view of SQL injection, it's
still not a great example, so use parameters instead of building the SQL
query by simple string concatenation.
It was used in a couple of places, but not everywhere. Removing it would
make the example using std::copy less clear, so add the missing
occurrences of "std::".
Use bundled fmt as fallback by default, but also add SOCI_FMT_BUILTIN
option to force or, on the contrary, forbid using it.
Note that we need to use header-only version of the library when
building SOCI statically because otherwise we'd have to install fmt
library too and we don't want to do this. It's fine to link with the
static fmt when using shared SOCI, however.
Replace existing use of std::cout and std::cerr with fmt::print[ln]():
this is simpler and more convenient and also faster to compile.
Also configure all CI jobs to clone submodules, as fmt submodule is
required now.
Run clang-tidy modernize-use-nullptr check on all files and manually
change the remaining NULLs skipped by it to nullptr.
Also use nullptr in the documentation.
The recent 335b8e53 (Give context in error message when
define_and_bind() fails, 2026-01-14) accidentally used "context" string
instead of context variable, as intended.
If session_backend dtor threw an exception, backEnd_ remained pointing
at an already destroyed object. Fix this by resetting it first in any
case and deleting the object pointed to by it later.
This notably affected session's own reconnect() function which could
crash if the connection to the server was broken -- which is precisely
when it's likely to be called.
It was not obvious that this member variable couldn't be used without
being initialized, so do initialize it to ensure that it always has a
valid value.
Also fix a typo in a related comment.