-
-
Notifications
You must be signed in to change notification settings - Fork 339
Description
This is an issue regarding 2 different items that both fall under the same category: returning named objects rather than tuples to provide an easier API to work with.
Item 1
I would like to perform a select * query with a left join (and return all data from both tables) and instead of returning tuples, I would return the objects of both tables (as it’s a select *).
After digging around in your examples and code I see you have sqlite_orm::object
, which is defined underneath sqlite_orm::asterisk
. To my confusion, the following code compiles (but returns tuples, which I don’t want in this scenario):
return dbStorage->select(
sqlite_orm::columns(
sqlite_orm::asterisk<X>(), sqlite_orm::asterisk <Y>()
),
sqlite_orm::left_join<Y>(sqlite_orm::on(
sqlite_orm::c(&Y:: Key) == &X::Key
)), orderBySql, sqlite_orm::limit(limitCount.value_or(-1))
);
But the same code using sqlite_orm::object
, does not:
return dbStorage->select(
sqlite_orm::columns(
sqlite_orm::object<X>(), sqlite_orm::object<Y>()
),
sqlite_orm::left_join<Y>(sqlite_orm::on(
sqlite_orm::c(&Y:: Key) == &X::Key
)), orderBySql, sqlite_orm::limit(limitCount.value_or(-1))
);
The reasoning why I want to return the objects instead of tuples is that X
and Y
each have 5-10 properties which would result in a large return tuple in the first example, all with unnamed return types. It’s easier for the developer to use the API that example 2 provides.
The error is as follows: sqlite_orm.h(8754,61): error C2280: 'V sqlite_orm::row_extractor<V,void>::extract(sqlite3_stmt *,int) const': attempting to reference a deleted function
To mitigate this issue, my current strategy is to make a new struct Z
that contains the all of the properties of X
and Y
and use std::make_from_tuple
, like so:
template <typename T, typename... Args>
std::vector<T> ConvertTuplesToStructs(std::vector<std::tuple<Args...>>&& tuples)
{
std::vector<T> results;
results.reserve(tuples.size());
for (auto& tuple : tuples)
{
results.push_back(std::make_from_tuple<T>(std::move(tuple)));
}
return results;
}
This leads into item 2.
Item 2
It would be nice if there was an API that allowed us to return new named structs that contain all of the return type members from a query. For example, I run this query:
dbStorage->select(
sqlite_orm::columns(
&X::col1,
&X::col2,
&X::col3,
&Y::col1
),
sqlite_orm::join<Y>(
sqlite_orm::on(sqlite_orm::c(&Y::Key) == &X::Key)
)
);
This will return a vector of tuples of 4 unnamed values, however, if in the future I update it to retrieve 5 values and the new value is in before &X::col1
, all of the callers retrieving the 0th to 4th value will have to change their code. Once again, I can mitigate this using my approach above with the method ConvertTuplesToStructs
and some other struct Z
containing duplicates of the members X::col1, X::col2, X::col3, Y::col1
. It would be nice however, if something like this was built into the API, where the developer could specify the return type struct.
Thanks!