SOCI / soci

Official repository of the SOCI - The C++ Database Access Library
http://soci.sourceforge.net/
Boost Software License 1.0
1.42k stars 478 forks source link

Can't bind into bool variable #944

Open Krzmbrzl opened 2 years ago

Krzmbrzl commented 2 years ago

I am using a query of the form

bool flag = false;
sql << "SELECT ...", soci::into(flag);

which results in a compilation error like this:

In file included from /home/user/Documents/Git/mumble/3rdparty/soci/src/core/../../include/soci/into-type.h:13,
                 from /home/user/Documents/Git/mumble/3rdparty/soci/src/core/../../include/soci/blob-exchange.h:12,
                 from /home/user/Documents/Git/mumble/3rdparty/soci/src/core/../../include/soci/soci.h:15,
                 from /home/user/Documents/Git/mumble/src/database/Database.h:17,
                 from /home/user/Documents/Git/mumble/src/database/Database.cpp:7:
/home/user/Documents/Git/mumble/3rdparty/soci/src/core/../../include/soci/exchange-traits.h: In instantiation of ‘struct soci::details::exchange_traits<bool>’:
/home/user/Documents/Git/mumble/3rdparty/soci/src/core/../../include/soci/bind-values.h:211:68:   required from ‘void soci::details::into_type_vector::exchange_(const soci::details::into_container<T, void>&, ...) [with T = bool]’
/home/user/Documents/Git/mumble/3rdparty/soci/src/core/../../include/soci/bind-values.h:143:9:   required from ‘void soci::details::into_type_vector::exchange(const soci::details::into_container<T, Indicator>&) [with T = bool; Indicator = void]’
/home/user/Documents/Git/mumble/3rdparty/soci/src/core/../../include/soci/statement.h:50:7:   required from ‘void soci::details::statement_impl::exchange(const soci::details::into_container<T, Indicator>&) [with T = bool; Indicator = void]’
/home/user/Documents/Git/mumble/3rdparty/soci/src/core/../../include/soci/statement.h:199:71:   required from ‘void soci::statement::exchange(const soci::details::into_container<T, Indicator>&) [with T = bool; Indicator = void]’
/home/user/Documents/Git/mumble/3rdparty/soci/src/core/../../include/soci/ref-counted-statement.h:92:27:   required from ‘void soci::details::ref_counted_statement::exchange(T&) [with T = const soci::details::into_container<bool, void>]’
/home/user/Documents/Git/mumble/3rdparty/soci/src/core/../../include/soci/once-temp-type.h:49:9:   required from ‘soci::details::once_temp_type& soci::details::once_temp_type::operator,(const soci::details::into_container<T, Indicator>&) [with T = bool; Indicator = void]’
/home/user/Documents/Git/mumble/src/database/Database.cpp:221:54:   required from here
/home/user/Documents/Git/mumble/3rdparty/soci/src/core/../../include/soci/exchange-traits.h:36:5: error: incomplete type ‘soci::details::exchange_traits<bool>’ used in nested name specifier

Inspecting exchange_traits.h it seems there are explicit template specializations for most common types (int, double, string, etc.) but not for bool.

Changing the type of flag in my example above fixes the issue, so this appears as if the culprit is that there is no specialization for bool available. Was this a deliberate choice? If so: why?

If not, I think it would be quite handy to add a specialization for bool as I would expect this to be a somewhat common datatype for people to use and thus being able to bind into it, would be great.

vadz commented 2 years ago

I'm more or less certain that it was a deliberate choice and while I am not sure about why exactly it was done (that would be the question for @msobczak), I'd hazard a guess and say that this is due to the fact that there was historically no obviously appropriate corresponding SQL type for bool: people stored it as 0/1 number of Y/N chars and probably in other ways too. I'm not even sure if BOOLEAN type is widely available now, 15 years later -- apparently SQL Server still doesn't have it and you're supposed to use BIT with it.

Anyhow, we could add support for bool but it wouldn't as simple as just adding a specialization for it because support for actually reading/writing it from/to the database would need to be added too.

Krzmbrzl commented 2 years ago

Indeed, a BOOLEAN data type does not exist in most databases. However, I think the mapping to and from a numeric value that is then used in the SQL should be easy enough.

I might give a shot at implementing this, if you don't mind. Any pitfalls that I should be aware of?

vadz commented 2 years ago

I think this should be relatively straightforward if we decide on using a fixed type for each database (rather than providing some way to choose between the different mappings). But I could be missing something, often problems only become apparent when you start actually implementing things...

Good luck!

Krzmbrzl commented 2 years ago

Okay, turns out that this seems to be a lot more complicated that I expected it to be. And since I can't find any documentation on the internal workings (am I missing something?), I don't feel like navigating this template jungle :sweat_smile: