// -*- C++ -*-
//
// This file was generated by ODB, object-relational mapping (ORM)
// compiler for C++.
//

#include <odb/pre.hxx>

#include <bpkg/package-common-odb.hxx>

#include <cassert>
#include <cstring>  // std::memcpy


#include <odb/sqlite/traits.hxx>
#include <odb/sqlite/database.hxx>
#include <odb/sqlite/transaction.hxx>
#include <odb/sqlite/connection.hxx>
#include <odb/sqlite/statement.hxx>
#include <odb/sqlite/statement-cache.hxx>
#include <odb/sqlite/container-statements.hxx>
#include <odb/sqlite/exceptions.hxx>

namespace odb
{
  // _version
  //

  bool access::composite_value_traits< ::bpkg::_version, id_sqlite >::
  grow (image_type& i,
        bool* t)
  {
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (t);

    bool grew (false);

    // epoch
    //
    t[0UL] = false;

    // canonical_upstream
    //
    if (t[1UL])
    {
      i.canonical_upstream_value.capacity (i.canonical_upstream_size);
      grew = true;
    }

    // canonical_release
    //
    if (t[2UL])
    {
      i.canonical_release_value.capacity (i.canonical_release_size);
      grew = true;
    }

    // revision
    //
    t[3UL] = false;

    // iteration
    //
    t[4UL] = false;

    // upstream
    //
    if (t[5UL])
    {
      i.upstream_value.capacity (i.upstream_size);
      grew = true;
    }

    // release
    //
    if (t[6UL])
    {
      i.release_value.capacity (i.release_size);
      grew = true;
    }

    return grew;
  }

  void access::composite_value_traits< ::bpkg::_version, id_sqlite >::
  bind (sqlite::bind* b,
        image_type& i,
        sqlite::statement_kind sk)
  {
    ODB_POTENTIALLY_UNUSED (b);
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (sk);

    using namespace sqlite;

    std::size_t n (0);
    ODB_POTENTIALLY_UNUSED (n);

    // epoch
    //
    b[n].type = sqlite::bind::integer;
    b[n].buffer = &i.epoch_value;
    b[n].is_null = &i.epoch_null;
    n++;

    // canonical_upstream
    //
    b[n].type = sqlite::image_traits<
      ::std::string,
      sqlite::id_text>::bind_value;
    b[n].buffer = i.canonical_upstream_value.data ();
    b[n].size = &i.canonical_upstream_size;
    b[n].capacity = i.canonical_upstream_value.capacity ();
    b[n].is_null = &i.canonical_upstream_null;
    n++;

    // canonical_release
    //
    b[n].type = sqlite::image_traits<
      ::std::string,
      sqlite::id_text>::bind_value;
    b[n].buffer = i.canonical_release_value.data ();
    b[n].size = &i.canonical_release_size;
    b[n].capacity = i.canonical_release_value.capacity ();
    b[n].is_null = &i.canonical_release_null;
    n++;

    // revision
    //
    b[n].type = sqlite::bind::integer;
    b[n].buffer = &i.revision_value;
    b[n].is_null = &i.revision_null;
    n++;

    // iteration
    //
    b[n].type = sqlite::bind::integer;
    b[n].buffer = &i.iteration_value;
    b[n].is_null = &i.iteration_null;
    n++;

    // upstream
    //
    b[n].type = sqlite::image_traits<
      ::std::string,
      sqlite::id_text>::bind_value;
    b[n].buffer = i.upstream_value.data ();
    b[n].size = &i.upstream_size;
    b[n].capacity = i.upstream_value.capacity ();
    b[n].is_null = &i.upstream_null;
    n++;

    // release
    //
    b[n].type = sqlite::image_traits<
      ::butl::optional< ::std::basic_string< char > >,
      sqlite::id_text>::bind_value;
    b[n].buffer = i.release_value.data ();
    b[n].size = &i.release_size;
    b[n].capacity = i.release_value.capacity ();
    b[n].is_null = &i.release_null;
    n++;
  }

  bool access::composite_value_traits< ::bpkg::_version, id_sqlite >::
  init (image_type& i,
        const value_type& o,
        sqlite::statement_kind sk)
  {
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (o);
    ODB_POTENTIALLY_UNUSED (sk);

    using namespace sqlite;

    bool grew (false);

    // epoch
    //
    {
      ::uint16_t const& v =
        o.epoch;

      bool is_null (false);
      sqlite::value_traits<
          ::uint16_t,
          sqlite::id_integer >::set_image (
        i.epoch_value,
        is_null,
        v);
      i.epoch_null = is_null;
    }

    // canonical_upstream
    //
    {
      ::std::string const& v =
        o.canonical_upstream;

      bool is_null (false);
      std::size_t cap (i.canonical_upstream_value.capacity ());
      sqlite::value_traits<
          ::std::string,
          sqlite::id_text >::set_image (
        i.canonical_upstream_value,
        i.canonical_upstream_size,
        is_null,
        v);
      i.canonical_upstream_null = is_null;
      grew = grew || (cap != i.canonical_upstream_value.capacity ());
    }

    // canonical_release
    //
    {
      ::std::string const& v =
        o.canonical_release;

      bool is_null (false);
      std::size_t cap (i.canonical_release_value.capacity ());
      sqlite::value_traits<
          ::std::string,
          sqlite::id_text >::set_image (
        i.canonical_release_value,
        i.canonical_release_size,
        is_null,
        v);
      i.canonical_release_null = is_null;
      grew = grew || (cap != i.canonical_release_value.capacity ());
    }

    // revision
    //
    {
      ::butl::optional< short unsigned int > const& v =
        o.revision;

      bool is_null (true);
      sqlite::value_traits<
          ::butl::optional< short unsigned int >,
          sqlite::id_integer >::set_image (
        i.revision_value,
        is_null,
        v);
      i.revision_null = is_null;
    }

    // iteration
    //
    {
      ::uint32_t const& v =
        o.iteration;

      bool is_null (false);
      sqlite::value_traits<
          ::uint32_t,
          sqlite::id_integer >::set_image (
        i.iteration_value,
        is_null,
        v);
      i.iteration_null = is_null;
    }

    // upstream
    //
    {
      ::std::string const& v =
        o.upstream;

      bool is_null (false);
      std::size_t cap (i.upstream_value.capacity ());
      sqlite::value_traits<
          ::std::string,
          sqlite::id_text >::set_image (
        i.upstream_value,
        i.upstream_size,
        is_null,
        v);
      i.upstream_null = is_null;
      grew = grew || (cap != i.upstream_value.capacity ());
    }

    // release
    //
    {
      ::butl::optional< ::std::basic_string< char > > const& v =
        o.release;

      bool is_null (true);
      std::size_t cap (i.release_value.capacity ());
      sqlite::value_traits<
          ::butl::optional< ::std::basic_string< char > >,
          sqlite::id_text >::set_image (
        i.release_value,
        i.release_size,
        is_null,
        v);
      i.release_null = is_null;
      grew = grew || (cap != i.release_value.capacity ());
    }

    return grew;
  }

  void access::composite_value_traits< ::bpkg::_version, id_sqlite >::
  init (value_type& o,
        const image_type&  i,
        database* db)
  {
    ODB_POTENTIALLY_UNUSED (o);
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (db);

    // epoch
    //
    {
      ::uint16_t& v =
        o.epoch;

      sqlite::value_traits<
          ::uint16_t,
          sqlite::id_integer >::set_value (
        v,
        i.epoch_value,
        i.epoch_null);
    }

    // canonical_upstream
    //
    {
      ::std::string& v =
        o.canonical_upstream;

      sqlite::value_traits<
          ::std::string,
          sqlite::id_text >::set_value (
        v,
        i.canonical_upstream_value,
        i.canonical_upstream_size,
        i.canonical_upstream_null);
    }

    // canonical_release
    //
    {
      ::std::string& v =
        o.canonical_release;

      sqlite::value_traits<
          ::std::string,
          sqlite::id_text >::set_value (
        v,
        i.canonical_release_value,
        i.canonical_release_size,
        i.canonical_release_null);
    }

    // revision
    //
    {
      ::butl::optional< short unsigned int >& v =
        o.revision;

      sqlite::value_traits<
          ::butl::optional< short unsigned int >,
          sqlite::id_integer >::set_value (
        v,
        i.revision_value,
        i.revision_null);
    }

    // iteration
    //
    {
      ::uint32_t& v =
        o.iteration;

      sqlite::value_traits<
          ::uint32_t,
          sqlite::id_integer >::set_value (
        v,
        i.iteration_value,
        i.iteration_null);
    }

    // upstream
    //
    {
      ::std::string& v =
        o.upstream;

      sqlite::value_traits<
          ::std::string,
          sqlite::id_text >::set_value (
        v,
        i.upstream_value,
        i.upstream_size,
        i.upstream_null);
    }

    // release
    //
    {
      ::butl::optional< ::std::basic_string< char > >& v =
        o.release;

      sqlite::value_traits<
          ::butl::optional< ::std::basic_string< char > >,
          sqlite::id_text >::set_value (
        v,
        i.release_value,
        i.release_size,
        i.release_null);
    }
  }

  // canonical_version
  //

  bool access::composite_value_traits< ::bpkg::canonical_version, id_sqlite >::
  grow (image_type& i,
        bool* t)
  {
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (t);

    bool grew (false);

    // epoch
    //
    t[0UL] = false;

    // canonical_upstream
    //
    if (t[1UL])
    {
      i.canonical_upstream_value.capacity (i.canonical_upstream_size);
      grew = true;
    }

    // canonical_release
    //
    if (t[2UL])
    {
      i.canonical_release_value.capacity (i.canonical_release_size);
      grew = true;
    }

    // revision
    //
    t[3UL] = false;

    // iteration
    //
    t[4UL] = false;

    return grew;
  }

  void access::composite_value_traits< ::bpkg::canonical_version, id_sqlite >::
  bind (sqlite::bind* b,
        image_type& i,
        sqlite::statement_kind sk)
  {
    ODB_POTENTIALLY_UNUSED (b);
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (sk);

    using namespace sqlite;

    std::size_t n (0);
    ODB_POTENTIALLY_UNUSED (n);

    // epoch
    //
    b[n].type = sqlite::bind::integer;
    b[n].buffer = &i.epoch_value;
    b[n].is_null = &i.epoch_null;
    n++;

    // canonical_upstream
    //
    b[n].type = sqlite::image_traits<
      ::std::string,
      sqlite::id_text>::bind_value;
    b[n].buffer = i.canonical_upstream_value.data ();
    b[n].size = &i.canonical_upstream_size;
    b[n].capacity = i.canonical_upstream_value.capacity ();
    b[n].is_null = &i.canonical_upstream_null;
    n++;

    // canonical_release
    //
    b[n].type = sqlite::image_traits<
      ::std::string,
      sqlite::id_text>::bind_value;
    b[n].buffer = i.canonical_release_value.data ();
    b[n].size = &i.canonical_release_size;
    b[n].capacity = i.canonical_release_value.capacity ();
    b[n].is_null = &i.canonical_release_null;
    n++;

    // revision
    //
    b[n].type = sqlite::bind::integer;
    b[n].buffer = &i.revision_value;
    b[n].is_null = &i.revision_null;
    n++;

    // iteration
    //
    b[n].type = sqlite::bind::integer;
    b[n].buffer = &i.iteration_value;
    b[n].is_null = &i.iteration_null;
    n++;
  }

  bool access::composite_value_traits< ::bpkg::canonical_version, id_sqlite >::
  init (image_type& i,
        const value_type& o,
        sqlite::statement_kind sk)
  {
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (o);
    ODB_POTENTIALLY_UNUSED (sk);

    using namespace sqlite;

    bool grew (false);

    // epoch
    //
    {
      ::uint16_t const& v =
        o.epoch;

      bool is_null (false);
      sqlite::value_traits<
          ::uint16_t,
          sqlite::id_integer >::set_image (
        i.epoch_value,
        is_null,
        v);
      i.epoch_null = is_null;
    }

    // canonical_upstream
    //
    {
      ::std::string const& v =
        o.canonical_upstream;

      bool is_null (false);
      std::size_t cap (i.canonical_upstream_value.capacity ());
      sqlite::value_traits<
          ::std::string,
          sqlite::id_text >::set_image (
        i.canonical_upstream_value,
        i.canonical_upstream_size,
        is_null,
        v);
      i.canonical_upstream_null = is_null;
      grew = grew || (cap != i.canonical_upstream_value.capacity ());
    }

    // canonical_release
    //
    {
      ::std::string const& v =
        o.canonical_release;

      bool is_null (false);
      std::size_t cap (i.canonical_release_value.capacity ());
      sqlite::value_traits<
          ::std::string,
          sqlite::id_text >::set_image (
        i.canonical_release_value,
        i.canonical_release_size,
        is_null,
        v);
      i.canonical_release_null = is_null;
      grew = grew || (cap != i.canonical_release_value.capacity ());
    }

    // revision
    //
    {
      ::uint16_t const& v =
        o.revision;

      bool is_null (false);
      sqlite::value_traits<
          ::uint16_t,
          sqlite::id_integer >::set_image (
        i.revision_value,
        is_null,
        v);
      i.revision_null = is_null;
    }

    // iteration
    //
    {
      ::uint32_t const& v =
        o.iteration;

      bool is_null (false);
      sqlite::value_traits<
          ::uint32_t,
          sqlite::id_integer >::set_image (
        i.iteration_value,
        is_null,
        v);
      i.iteration_null = is_null;
    }

    return grew;
  }

  void access::composite_value_traits< ::bpkg::canonical_version, id_sqlite >::
  init (value_type& o,
        const image_type&  i,
        database* db)
  {
    ODB_POTENTIALLY_UNUSED (o);
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (db);

    // epoch
    //
    {
      ::uint16_t& v =
        o.epoch;

      sqlite::value_traits<
          ::uint16_t,
          sqlite::id_integer >::set_value (
        v,
        i.epoch_value,
        i.epoch_null);
    }

    // canonical_upstream
    //
    {
      ::std::string& v =
        o.canonical_upstream;

      sqlite::value_traits<
          ::std::string,
          sqlite::id_text >::set_value (
        v,
        i.canonical_upstream_value,
        i.canonical_upstream_size,
        i.canonical_upstream_null);
    }

    // canonical_release
    //
    {
      ::std::string& v =
        o.canonical_release;

      sqlite::value_traits<
          ::std::string,
          sqlite::id_text >::set_value (
        v,
        i.canonical_release_value,
        i.canonical_release_size,
        i.canonical_release_null);
    }

    // revision
    //
    {
      ::uint16_t& v =
        o.revision;

      sqlite::value_traits<
          ::uint16_t,
          sqlite::id_integer >::set_value (
        v,
        i.revision_value,
        i.revision_null);
    }

    // iteration
    //
    {
      ::uint32_t& v =
        o.iteration;

      sqlite::value_traits<
          ::uint32_t,
          sqlite::id_integer >::set_value (
        v,
        i.iteration_value,
        i.iteration_null);
    }
  }

  // original_version
  //

  bool access::composite_value_traits< ::bpkg::original_version, id_sqlite >::
  grow (image_type& i,
        bool* t)
  {
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (t);

    bool grew (false);

    // upstream_
    //
    if (t[0UL])
    {
      i.upstream_value.capacity (i.upstream_size);
      grew = true;
    }

    // release_
    //
    if (t[1UL])
    {
      i.release_value.capacity (i.release_size);
      grew = true;
    }

    return grew;
  }

  void access::composite_value_traits< ::bpkg::original_version, id_sqlite >::
  bind (sqlite::bind* b,
        image_type& i,
        sqlite::statement_kind sk)
  {
    ODB_POTENTIALLY_UNUSED (b);
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (sk);

    using namespace sqlite;

    std::size_t n (0);
    ODB_POTENTIALLY_UNUSED (n);

    // upstream_
    //
    b[n].type = sqlite::image_traits<
      ::std::string,
      sqlite::id_text>::bind_value;
    b[n].buffer = i.upstream_value.data ();
    b[n].size = &i.upstream_size;
    b[n].capacity = i.upstream_value.capacity ();
    b[n].is_null = &i.upstream_null;
    n++;

    // release_
    //
    b[n].type = sqlite::image_traits<
      ::bpkg::optional_string,
      sqlite::id_text>::bind_value;
    b[n].buffer = i.release_value.data ();
    b[n].size = &i.release_size;
    b[n].capacity = i.release_value.capacity ();
    b[n].is_null = &i.release_null;
    n++;
  }

  bool access::composite_value_traits< ::bpkg::original_version, id_sqlite >::
  init (image_type& i,
        const value_type& o,
        sqlite::statement_kind sk)
  {
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (o);
    ODB_POTENTIALLY_UNUSED (sk);

    using namespace sqlite;

    bool grew (false);

    // upstream_
    //
    {
      // From package-common.hxx:181:7
      ::std::string const& v =
        o.upstream;

      bool is_null (false);
      std::size_t cap (i.upstream_value.capacity ());
      sqlite::value_traits<
          ::std::string,
          sqlite::id_text >::set_image (
        i.upstream_value,
        i.upstream_size,
        is_null,
        v);
      i.upstream_null = is_null;
      grew = grew || (cap != i.upstream_value.capacity ());
    }

    // release_
    //
    {
      // From package-common.hxx:186:7
      ::bpkg::optional_string const& v =
        o.release;

      bool is_null (true);
      std::size_t cap (i.release_value.capacity ());
      sqlite::value_traits<
          ::bpkg::optional_string,
          sqlite::id_text >::set_image (
        i.release_value,
        i.release_size,
        is_null,
        v);
      i.release_null = is_null;
      grew = grew || (cap != i.release_value.capacity ());
    }

    return grew;
  }

  void access::composite_value_traits< ::bpkg::original_version, id_sqlite >::
  init (value_type& o,
        const image_type&  i,
        database* db)
  {
    ODB_POTENTIALLY_UNUSED (o);
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (db);

    // upstream_
    //
    {
      // From package-common.hxx:182:7
      ::std::string v;

      sqlite::value_traits<
          ::std::string,
          sqlite::id_text >::set_value (
        v,
        i.upstream_value,
        i.upstream_size,
        i.upstream_null);

      // From package-common.hxx:182:7
      o = bpkg::version (0, std::move (v), std::string (), bpkg::nullopt, 0);
    }

    // release_
    //
    {
      // From package-common.hxx:187:7
      ::bpkg::optional_string v;

      sqlite::value_traits<
          ::bpkg::optional_string,
          sqlite::id_text >::set_value (
        v,
        i.release_value,
        i.release_size,
        i.release_null);

      // From package-common.hxx:187:7
      o = bpkg::version (0, std::move (o.upstream), std::move (v), bpkg::nullopt, 0);
    }
  }

  // package_id
  //

  bool access::composite_value_traits< ::bpkg::package_id, id_sqlite >::
  grow (image_type& i,
        bool* t)
  {
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (t);

    bool grew (false);

    // name
    //
    if (t[0UL])
    {
      i.name_value.capacity (i.name_size);
      grew = true;
    }

    // version
    //
    if (composite_value_traits< ::bpkg::canonical_version, id_sqlite >::grow (
          i.version_value, t + 1UL))
      grew = true;

    return grew;
  }

  void access::composite_value_traits< ::bpkg::package_id, id_sqlite >::
  bind (sqlite::bind* b,
        image_type& i,
        sqlite::statement_kind sk)
  {
    ODB_POTENTIALLY_UNUSED (b);
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (sk);

    using namespace sqlite;

    std::size_t n (0);
    ODB_POTENTIALLY_UNUSED (n);

    // name
    //
    b[n].type = sqlite::image_traits<
      ::bpkg::package_name,
      sqlite::id_text>::bind_value;
    b[n].buffer = i.name_value.data ();
    b[n].size = &i.name_size;
    b[n].capacity = i.name_value.capacity ();
    b[n].is_null = &i.name_null;
    n++;

    // version
    //
    composite_value_traits< ::bpkg::canonical_version, id_sqlite >::bind (
      b + n, i.version_value, sk);
    n += 5UL;
  }

  bool access::composite_value_traits< ::bpkg::package_id, id_sqlite >::
  init (image_type& i,
        const value_type& o,
        sqlite::statement_kind sk)
  {
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (o);
    ODB_POTENTIALLY_UNUSED (sk);

    using namespace sqlite;

    bool grew (false);

    // name
    //
    {
      ::bpkg::package_name const& v =
        o.name;

      bool is_null (false);
      std::size_t cap (i.name_value.capacity ());
      sqlite::value_traits<
          ::bpkg::package_name,
          sqlite::id_text >::set_image (
        i.name_value,
        i.name_size,
        is_null,
        v);
      i.name_null = is_null;
      grew = grew || (cap != i.name_value.capacity ());
    }

    // version
    //
    {
      ::bpkg::canonical_version const& v =
        o.version;

      if (composite_value_traits< ::bpkg::canonical_version, id_sqlite >::init (
            i.version_value,
            v,
            sk))
        grew = true;
    }

    return grew;
  }

  void access::composite_value_traits< ::bpkg::package_id, id_sqlite >::
  init (value_type& o,
        const image_type&  i,
        database* db)
  {
    ODB_POTENTIALLY_UNUSED (o);
    ODB_POTENTIALLY_UNUSED (i);
    ODB_POTENTIALLY_UNUSED (db);

    // name
    //
    {
      ::bpkg::package_name& v =
        o.name;

      sqlite::value_traits<
          ::bpkg::package_name,
          sqlite::id_text >::set_value (
        v,
        i.name_value,
        i.name_size,
        i.name_null);
    }

    // version
    //
    {
      ::bpkg::canonical_version& v =
        o.version;

      composite_value_traits< ::bpkg::canonical_version, id_sqlite >::init (
        v,
        i.version_value,
        db);
    }
  }
}

#include <odb/post.hxx>
