sqlite_orm icon indicating copy to clipboard operation
sqlite_orm copied to clipboard

struct inheritance error when using unique

Open crabiner opened this issue 2 years ago • 17 comments

Hi,

The code below which uses inheritance doesn't compile when I add the unique line it compiles without it. is there a way to fix it?

struct TbBase {
    int id;
    bool deleted;
}; 

struct XUser : public TbBase {
    std::string firstName;
    std::string lastName;
};

auto storage = sqlite_orm::make_storage("",
                                            make_table("tb_xuser",
                                                    make_column("id", &XUser::id, autoincrement(), primary_key()),
                                                    make_column("deleted", &XUser::deleted),
                                                    make_column("first_name", &XUser::firstName),
                                                    make_column("last_name", &XUser::lastName),
                                                    unique(&XUser::firstName, &XUser::lastName)
                                                    ));

The error is:

/usr/include/c++/10/bits/stl_algo.h:949:9: error: no pre-increment operator for type
  949 |       ++__first;
      |         ^~~~~~~
/usr/include/c++/10/bits/stl_algo.h:950:16: error: no pre-increment operator for type
  950 |       while (++__first != __last)
      |                ^~~~~~~
/usr/include/c++/10/bits/stl_algo.h:952:7: error: no pre-increment operator for type
  952 |    *++__dest = _GLIBCXX_MOVE(*__first);

crabiner avatar Jul 11 '22 08:07 crabiner

I also found fix #863 mentioned in #854 does not compile with error

error: no matching function for call to ‘sqlite_orm::internal::serializator_context<sqlite_orm::internal::storage_impl<sqlite_orm::internal::table_t<A, sqlite_orm::internal::column_t<A, int, const int& (A::*)() const, void (A::*)(int), sqlite_orm::internal::autoincrement_t, sqlite_orm::internal::primary_key_t<> >, sqlite_orm::internal::column_t<Base, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >& (Base::*)() const, void (Base::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)>, sqlite_orm::internal::column_t<Base, int, const int& (Base::*)() const, void (Base::*)(int)>, sqlite_orm::internal::unique_t<sqlite_orm::internal::column_pointer<A, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > Base::*>, sqlite_orm::internal::column_pointer<A, int Base::*> > > > >::column_name(const sqlite_orm::internal::column_pointer<A, int Base::*>&) const’
13839 |                         if(auto columnNamePointer = context.column_name(column)) {

crabiner avatar Jul 11 '22 10:07 crabiner

You need to qualify the call to sqlite_orm::unique().

trueqbit avatar Jul 12 '22 09:07 trueqbit

@crabiner try make_table<XUser> instead of make_table

fnc12 avatar Jul 12 '22 10:07 fnc12

Correct! if you do not qualify unique it will not take sqlite_orm::unique!! The compiler seems to think std::unique is a better match than sqlite_orm::unique! It thinks the pointer to member variables are iterators

The solution is:

auto storage = sqlite_orm::make_storage("",
    make_table<XUser>("tb_xuser",
        make_column("id", &XUser::id, autoincrement(), primary_key()),
        make_column("deleted", &XUser::deleted),
        make_column("first_name", &XUser::firstName),
        make_column("last_name", &XUser::lastName),
        sqlite_orm::unique(&XUser::firstName, &XUser::lastName)
    ));

juandent avatar Jul 12 '22 12:07 juandent

and the explicit table template argument is necessary because of the inheritance... (in make_table)

juandent avatar Jul 12 '22 12:07 juandent

Amazing! it works Thank you @juandent @fnc12 and @trueqbit !

crabiner avatar Jul 13 '22 10:07 crabiner

Hey guys, one last follow up to really nail this

In my case the unique is on members from the base class and it doesn't compile when my code also invokes storage.sync_schema()

So the code snippet below has compile error of

 error: ‘struct sqlite_orm::internal::storage_impl<>’ has no member named ‘column_name’
 9071 |                 return this->super::column_name(m);
struct TbBase {
    int id;
    bool deleted;
    std::string firstName;
    std::string lastName;
}; 

struct XUser : public TbBase {

};

auto storage = sqlite_orm::make_storage("",
    make_table<XUser>("tb_xuser",
        make_column("id", &XUser::id, autoincrement(), primary_key()),
        make_column("deleted", &XUser::deleted),
        make_column("first_name", &XUser::firstName),
        make_column("last_name", &XUser::lastName),
        sqlite_orm::unique(&XUser::firstName, &XUser::lastName)
    ));


int main()
{
    for (const auto& res :storage.sync_schema()) {
        (void)res;
    // check sync results here..
    }
}

crabiner avatar Jul 13 '22 12:07 crabiner

Hi!

Do this:

auto storage = sqlite_orm::make_storage("",
    make_table<XUser>("tb_xuser",
        make_column("id", &XUser::id, autoincrement(), primary_key()),
        make_column("deleted", &XUser::deleted),
        make_column("first_name", &XUser::firstName),
        make_column("last_name", &XUser::lastName),
        sqlite_orm::unique(column<XUser>(&XUser::firstName), column<XUser>(&XUser::lastName))
    ));

it should work

juandent avatar Jul 13 '22 15:07 juandent

Still getting error

error: no matching function for call to ‘sqlite_orm::internal::serializator_context<sqlite_orm::internal::storage_impl<sqlite_orm::internal::table_t<XUser, sqlite_orm::internal::column_t<TbBase, int, const int& (TbBase::*)() const, void (TbBase::*)(int), sqlite_orm::internal::autoincrement_t, sqlite_orm::internal::primary_key_t<> >, sqlite_orm::internal::column_t<TbBase, bool, const bool& (TbBase::*)() const, void (TbBase::*)(bool)>, sqlite_orm::internal::column_t<TbBase, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >& (TbBase::*)() const, void (TbBase::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)>, sqlite_orm::internal::column_t<TbBase, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >& (TbBase::*)() const, void (TbBase::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)>, sqlite_orm::internal::unique_t<sqlite_orm::internal::column_pointer<XUser, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > TbBase::*>, sqlite_orm::internal::column_pointer<XUser, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > TbBase::*> > > > >::column_name(const sqlite_orm::internal::column_pointer<XUser, std::__cxx11::basic_string<char> TbBase::*>&) const’
13839 |                         if(auto columnNamePointer = context.column_name(column)) {
      |                                 ^~~~~~~~~~~~~~~~~

crabiner avatar Jul 15 '22 04:07 crabiner

@crabiner Are you able to use the latest dev branch? My guess is that you are hitting #933, or a variant of it.

trueqbit avatar Jul 15 '22 13:07 trueqbit

@crabiner yeah looks like you have outdated sqlite_orm version. Everything compiles well with the current sqlite_orm

fnc12 avatar Jul 15 '22 21:07 fnc12

@trueqbit @fnc12 you are correct, I'm using master branch latest commit No luck confirming the issue is solved on dev because when I tried switching to dev I have compilation errors with sqlite_orm build

crabiner avatar Jul 17 '22 06:07 crabiner

@crabiner share compilation errors please

fnc12 avatar Jul 17 '22 06:07 fnc12

@fnc12

/sqlite_orm_git/build/tests && /usr/bin/g++  -I/sqlite_orm_git/include -I/sqlite_orm_git/build/_deps/catch2-src/single_include -std=c++14 -Winvalid-pch -x c++-header -include /sqlite_orm_git/build/tests/CMakeFiles/unit_tests.dir/cmake_pch.hxx -MD -MT tests/CMakeFiles/unit_tests.dir/cmake_pch.hxx.gch -MF CMakeFiles/unit_tests.dir/cmake_pch.hxx.gch.d -o CMakeFiles/unit_tests.dir/cmake_pch.hxx.gch -c /sqlite_orm_git/build/tests/CMakeFiles/unit_tests.dir/cmake_pch.hxx.cxx
In file included from /sqlite_orm_git/build/tests/CMakeFiles/unit_tests.dir/cmake_pch.hxx:5,
                 from <command-line>:
/sqlite_orm_git/include/sqlite_orm/sqlite_orm.h:11040:13: error: ‘connection_ref’ does not name a type
11040 |             connection_ref con;
      |             ^~~~~~~~~~~~~~
/sqlite_orm_git/include/sqlite_orm/sqlite_orm.h:11094:70: error: ‘connection_ref’ has not been declared
11094 |             prepared_statement_t(T expression_, sqlite3_stmt* stmt_, connection_ref con_) :
      |                                                                      ^~~~~~~~~~~~~~
/sqlite_orm_git/include/sqlite_orm/sqlite_orm.h:11150:29: error: ‘set_t’ was not declared in this scope; did you mean ‘sqlite_orm::internal::set_t’?
11150 |         struct update_all_t<set_t<Args...>, Wargs...> {
      |                             ^~~~~
      |                             sqlite_orm::internal::set_t

crabiner avatar Jul 17 '22 06:07 crabiner

Are you sure that you are using the latest dev? It looks like a very old error which was fixed a long ago

fnc12 avatar Jul 17 '22 06:07 fnc12

git log gives the following

commit d40a2b09604f83175912b0fb410492f8c6d4e520 (HEAD -> dev, origin/dev)
Merge: 31c3beb 5704f9b
Author: Yevgeniy Zakharov <[email protected]>
Date:   Mon Jul 11 13:57:06 2022 +0200

    Merge pull request #1064 from fnc12/feature/on-conflict-primary-key
    
    added on conflict for primary key

crabiner avatar Jul 17 '22 06:07 crabiner

I am sure you have 1.7 not 1.7.1 cause this error message looks like the one existed in 1.7. Please check shasum of real file which is compiled and compare it with the one from sqlite_orm repo

fnc12 avatar Jul 25 '22 20:07 fnc12

@crabiner how are you? does it work?

fnc12 avatar Oct 08 '23 13:10 fnc12

closing due to inactivity

fnc12 avatar Oct 13 '23 12:10 fnc12