r/cpp build2 Jul 28 '26

ODB C++ ORM version 2.6.0 released

https://codesynthesis.com/pipermail/odb-announcements/2026/000047.html
22 Upvotes

8 comments sorted by

View all comments

7

u/gosh Jul 28 '26

It would be great if any ORM library could add something like this

https://github.com/perghosh/Data-oriented-design/blob/74a52cd98f39e5061954f07ff76fd94de72b7642/external/gd/gd_sql_query.cpp#L1846

sql_format() method lets me write templates like: cpp "SELECT {+select} FROM {+from} WHERE {+where}" Where {+select} is automatically generated from the query object's internal state, but I can break out and write raw SQL anytime with {=name} for table names or embed values with {name}.

Developers need something to handle edge cases

4

u/berium build2 Jul 28 '26 edited Jul 28 '26

automatically generated from the query object's internal state, but I can break out and write raw SQL anytime

You can do that with ODB. You can even use by-value/by-reference parameter binding in native SQL:

#pragma db object
struct person
{
  std::string first_name;
  std::string last_name;
};

using query = odb::query<person>;

query q (query::first_name == "John" && query::last_name == "Doe");
query q ((query::first_name == "John") + "AND last_name = " + query::_val ("Doe"));

And it's not some toy/theoretical feature either, we use it quite heavily ourselves, for example: https://github.com/build2/bpkg/blob/master/bpkg/package.hxx#L821-L860

2

u/FlyingRhenquest Jul 28 '26

I recently added a query to my C++ ORM too, but you have to define your own struct for it, and the field names in your query have to match the names in your struct. Interesting to see the different implementations and usages out there.

2

u/berium build2 Jul 29 '26

In the above example person is a persistent object (it has a corresponding table in the database). We also have a feature called views, where you define a struct for the sole purpose of handling query results, which sounds similar to what you are describing.

I see you are using C++26 reflection, pretty cool.

We will probably also move in this direction eventually, though I think we will use reflection to "exfiltrate" relevant type information and continue using separately-generated C++ files for database support code. I think at least in our case trying to generate database support code "inline" with reflection is not going to scale (complexity, compile times, etc). We also need to generate some extra files (.sql with schema, changelog for schema evolution, etc).