-
-
Notifications
You must be signed in to change notification settings - Fork 322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compilation fail with sync_schema and inheritance #854
Comments
try adding explicit type to auto storage = sqlite_orm::make_storage("test.db"
, sqlite_orm::make_table<Base>("entries"
, sqlite_orm::make_column("id", &A::id, sqlite_orm::autoincrement(), sqlite_orm::primary_key())
, sqlite_orm::make_column("name", &A::name)
, sqlite_orm::make_column("timestamp", &A::timestamp)
, sqlite_orm::unique(&A::name, &A::timestamp)
)); |
Perfect. Thank you. |
Follow up, with
How would you achieve that? Or is it best to avoid inheritance with sqlite_orm? |
try |
Thanks you for the suggestion but this leads to complete code for reference: struct Base {
std::string name;
int64_t timestamp;
int64_t value;
};
struct A : public Base {
int64_t id;
};
auto storage = sqlite_orm::make_storage("test.db"
, sqlite_orm::make_table<Base>("entries"
, sqlite_orm::make_column("id", &A::id, sqlite_orm::autoincrement(), sqlite_orm::primary_key())
, sqlite_orm::make_column("name", &A::name)
, sqlite_orm::make_column("timestamp", &A::timestamp)
, sqlite_orm::unique(&A::name, &A::timestamp)
));
for (const auto& res : storage.sync_schema()) {
(void)res;
// check sync results here..
}
A a;
storage.insert(a); |
I need to think here. Probably the first advice was wrong. I'll answer soon |
Alright thank you For this use case where you might want to reuse existing classes and structs and for storing I got the following workaround now: As described earlier I have a Base class struct Base {
std::string name;
int64_t timestamp;
int64_t value;
}; I want to store Base objects while adding an additional field, an auto-increment id, without The table should look like this: auto storage = sqlite_orm::make_storage("test.db"
, sqlite_orm::make_table("entries"
, sqlite_orm::make_column("id", &A::id, sqlite_orm::autoincrement(), sqlite_orm::primary_key())
, sqlite_orm::make_column("name", &A::name)
, sqlite_orm::make_column("timestamp", &A::timestamp)
, sqlite_orm::unique(&A::name, &A::timestamp)
)); With the following you will run into all kinds of problems: struct A : public Base {
int64_t id = -1;
}; With an additional boilerplate and custom reference_value_wrapper it works: struct A : public Base {
int64_t id = -1;
db::ref_val_wrapper<std::string> name = Base::name;
db::ref_val_wrapper<int64_t> timestamp = Base::timestamp;
}; The custom namespace db
{
template<typename T>
struct ref_val_wrapper
{
ref_val_wrapper(T& t) : refval(static_cast<T*>(&t)) {}
ref_val_wrapper(T&& t) : refval(std::move(t)) {}
inline ref_val_wrapper& operator=(T&& t)
{
if (std::holds_alternative<T*>(refval)) {
*std::get<T*>(refval) = std::move(t);
}
else {
std::get<T>(refval) = std::move(t);
}
return *this;
}
operator const T&() const
{
if (std::holds_alternative<T*>(refval))
return *std::get<T*>(refval);
else
return std::get<T>(refval);
}
[[nodiscard]]
inline const T& get() const
{
if (std::holds_alternative<T*>(refval))
return *std::get<T*>(refval);
else
return std::get<T>(refval);
}
[[nodiscard]]
inline T& get()
{
if (std::holds_alternative<T*>(refval))
return *std::get<T*>(refval);
else
return std::get<T>(refval);
}
[[nodiscard]]
inline bool is_value() const {
return std::holds_alternative<T>(refval);
}
[[nodiscard]]
inline bool is_reference() const {
return std::holds_alternative<T*>(refval);
}
private:
std::variant<T*, T> refval;
};
} // end namespace db
namespace sqlite_orm {
template<typename T>
struct type_printer<::db::ref_val_wrapper<T>> : public type_printer<T> {};
template<typename T>
struct statement_binder<::db::ref_val_wrapper<T>> {
int bind(sqlite3_stmt *stmt, int index, const ::db::ref_val_wrapper<T> &valueRef) {
return statement_binder<T>().bind(stmt, index, valueRef.get());
}
};
template<typename T>
struct row_extractor<::db::ref_val_wrapper<T>> : public row_extractor<T> {};
} // end namespace sqlite_orm |
Nice thank you, hopefully I get time tonight to check it out. |
👍 works for what I tested - inserting, iterating, iterating with where clauses. |
@jahnf so you need to use |
Hey,
I think I found an Issue with inheritance and sync_schema:
With the following code, I get a compilation error:
Error output:
The text was updated successfully, but these errors were encountered: