Skip to content

Unable to use db map pragma for types used for object ids #16

@karen-arutyunov

Description

@karen-arutyunov

When, for example, we try to use the following mapping for repository_url type

#pragma db map type(repository_url) as(string)   \
    to((?).string ())   \
    from((?).empty () ? bpkg::repository_url () : bpkg::repository_url (?))

and use this type as an id for the pkg_repository_metadata type (url member) in bpkg project, we end up with ODB-generated files which cannot be compiled. The compilation fails for the following reasons:

fetch-cache-data-odb.ixx:

  inline
  access::object_traits< ::bpkg::pkg_repository_metadata >::id_type
  access::object_traits< ::bpkg::pkg_repository_metadata >::
  id (const object_type& o)
  {
    return o.url; // Error: can't convert from repository_url to string.
  }

fetch-cache-data-odb.cxx:

  access::object_traits_impl< ::bpkg::pkg_repository_metadata, id_sqlite >::id_type
  access::object_traits_impl< ::bpkg::pkg_repository_metadata, id_sqlite >::
  id (const image_type& i)
  {
    sqlite::database* db (0);
    ODB_POTENTIALLY_UNUSED (db);

    id_type id;
    {
      ::std::string vt;

      sqlite::value_traits<
          ::std::string,
          sqlite::id_text >::set_value (
        vt,
        i.url_value,
        i.url_size,
        i.url_null);

      // From fetch-cache-data.hxx:68:14
      id = (vt).empty () ? bpkg::repository_url () : bpkg::repository_url (vt); // Error: can't convert from repository_url to string.
    }
  ...

  void access::object_traits_impl< ::bpkg::pkg_repository_metadata, id_sqlite >::
  init (id_image_type& i, const id_type& id)
  {
    bool grew (false);
    {
      // From fetch-cache-data.hxx:68:14
      ::std::string const& vt =
        (id).string (); // Error: std::string has no string() member.
   ...

Note that while the id_type is defined as std::string for the pkg_repository_metadata class, the ODB-generated implementation erroneously treats it as repository_url in a number of places.

Another surprising thing is that comparison of query<pkg_repository_metadata>::url member in query expressions for such a mapping expects the value of std::string type rather than of repository_url type:

db.query<pkg_repository_metadata> (query<pkg_repository_metadata>::url == string (...))         // OK.
db.query<pkg_repository_metadata> (query<pkg_repository_metadata>::url == repository_url (...)) // Error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions