aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2020-07-03 20:07:59 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2020-07-03 20:07:59 +0300
commit148f7741733e2db19d2af84ebbed20b75734971f (patch)
treeb7fdf50c79720d69d9716dc7987e6c2bc12e62ff
parent30b37545ea821bd5a73bdc0a41d5b37c1c002a37 (diff)
Make changes required for CIci
-rw-r--r--bpkg/argument-grouping.cxx81
-rw-r--r--bpkg/argument-grouping.hxx31
-rw-r--r--bpkg/bpkg-options.cxx1491
-rw-r--r--bpkg/bpkg-options.hxx375
-rw-r--r--bpkg/bpkg-options.ixx207
-rw-r--r--bpkg/cfg-create-options.cxx636
-rw-r--r--bpkg/cfg-create-options.hxx125
-rw-r--r--bpkg/cfg-create-options.ixx45
-rw-r--r--bpkg/common-options.cxx1706
-rw-r--r--bpkg/common-options.hxx822
-rw-r--r--bpkg/common-options.ixx698
-rw-r--r--bpkg/configuration-options.cxx545
-rw-r--r--bpkg/configuration-options.hxx117
-rw-r--r--bpkg/configuration-options.ixx33
-rw-r--r--bpkg/default-options-files.cxx92
-rw-r--r--bpkg/default-options-files.hxx31
-rw-r--r--bpkg/help-options.cxx549
-rw-r--r--bpkg/help-options.hxx109
-rw-r--r--bpkg/help-options.ixx21
-rw-r--r--bpkg/package-odb.cxx12353
-rw-r--r--bpkg/package-odb.hxx4411
-rw-r--r--bpkg/package-odb.ixx767
-rw-r--r--bpkg/pkg-build-options.cxx1257
-rw-r--r--bpkg/pkg-build-options.hxx397
-rw-r--r--bpkg/pkg-build-options.ixx408
-rw-r--r--bpkg/pkg-checkout-options.cxx581
-rw-r--r--bpkg/pkg-checkout-options.hxx113
-rw-r--r--bpkg/pkg-checkout-options.ixx27
-rw-r--r--bpkg/pkg-clean-options.cxx584
-rw-r--r--bpkg/pkg-clean-options.hxx113
-rw-r--r--bpkg/pkg-clean-options.ixx27
-rw-r--r--bpkg/pkg-configure-options.cxx571
-rw-r--r--bpkg/pkg-configure-options.hxx109
-rw-r--r--bpkg/pkg-configure-options.ixx21
-rw-r--r--bpkg/pkg-disfigure-options.cxx579
-rw-r--r--bpkg/pkg-disfigure-options.hxx113
-rw-r--r--bpkg/pkg-disfigure-options.ixx27
-rw-r--r--bpkg/pkg-drop-options.cxx685
-rw-r--r--bpkg/pkg-drop-options.hxx145
-rw-r--r--bpkg/pkg-drop-options.ixx75
-rw-r--r--bpkg/pkg-fetch-options.cxx619
-rw-r--r--bpkg/pkg-fetch-options.hxx121
-rw-r--r--bpkg/pkg-fetch-options.ixx39
-rw-r--r--bpkg/pkg-install-options.cxx622
-rw-r--r--bpkg/pkg-install-options.hxx121
-rw-r--r--bpkg/pkg-install-options.ixx39
-rw-r--r--bpkg/pkg-purge-options.cxx598
-rw-r--r--bpkg/pkg-purge-options.hxx117
-rw-r--r--bpkg/pkg-purge-options.ixx33
-rw-r--r--bpkg/pkg-status-options.cxx757
-rw-r--r--bpkg/pkg-status-options.hxx141
-rw-r--r--bpkg/pkg-status-options.ixx69
-rw-r--r--bpkg/pkg-test-options.cxx630
-rw-r--r--bpkg/pkg-test-options.hxx125
-rw-r--r--bpkg/pkg-test-options.ixx45
-rw-r--r--bpkg/pkg-uninstall-options.cxx615
-rw-r--r--bpkg/pkg-uninstall-options.hxx121
-rw-r--r--bpkg/pkg-uninstall-options.ixx39
-rw-r--r--bpkg/pkg-unpack-options.cxx633
-rw-r--r--bpkg/pkg-unpack-options.hxx121
-rw-r--r--bpkg/pkg-unpack-options.ixx39
-rw-r--r--bpkg/pkg-update-options.cxx604
-rw-r--r--bpkg/pkg-update-options.hxx121
-rw-r--r--bpkg/pkg-update-options.ixx39
-rw-r--r--bpkg/pkg-verify-options.cxx615
-rw-r--r--bpkg/pkg-verify-options.hxx125
-rw-r--r--bpkg/pkg-verify-options.ixx45
-rw-r--r--bpkg/rep-add-options.cxx595
-rw-r--r--bpkg/rep-add-options.hxx119
-rw-r--r--bpkg/rep-add-options.ixx33
-rw-r--r--bpkg/rep-create-options.cxx595
-rw-r--r--bpkg/rep-create-options.hxx121
-rw-r--r--bpkg/rep-create-options.ixx39
-rw-r--r--bpkg/rep-fetch-options.cxx586
-rw-r--r--bpkg/rep-fetch-options.hxx113
-rw-r--r--bpkg/rep-fetch-options.ixx27
-rw-r--r--bpkg/rep-info-options.cxx774
-rw-r--r--bpkg/rep-info-options.hxx179
-rw-r--r--bpkg/rep-info-options.ixx123
-rw-r--r--bpkg/rep-list-options.cxx593
-rw-r--r--bpkg/rep-list-options.hxx119
-rw-r--r--bpkg/rep-list-options.ixx33
-rw-r--r--bpkg/rep-remove-options.cxx596
-rw-r--r--bpkg/rep-remove-options.hxx119
-rw-r--r--bpkg/rep-remove-options.ixx33
-rw-r--r--bpkg/repository-signing.cxx201
-rw-r--r--bpkg/repository-signing.hxx31
-rw-r--r--bpkg/repository-types.cxx205
-rw-r--r--bpkg/repository-types.hxx31
-rw-r--r--buildfile2
-rw-r--r--repositories.manifest15
91 files changed, 43538 insertions, 14 deletions
diff --git a/bpkg/argument-grouping.cxx b/bpkg/argument-grouping.cxx
new file mode 100644
index 0000000..0d0417e
--- /dev/null
+++ b/bpkg/argument-grouping.cxx
@@ -0,0 +1,81 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/argument-grouping.hxx>
+
+#include <map>
+#include <cstring>
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_argument_grouping_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg\033[0m \033[1m{\033[0m \033[4moptions\033[0m \033[1m}+\033[0m \033[4margument\033[0m \033[1m+{\033[0m \033[4moptions\033[0m \033[1m}\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "For certain commands certain options and command line variables can be grouped" << ::std::endl
+ << "to only apply to specific arguments. This help topic describes the argument" << ::std::endl
+ << "grouping facility used for this purpose." << ::std::endl
+ << ::std::endl
+ << "Groups can be specified before (leading) and/or after (trailing) the argument" << ::std::endl
+ << "they apply to. A leading group starts with '\033[1m{\033[0m' and ends with '\033[1m}+\033[0m' while a" << ::std::endl
+ << "trailing group starts with '\033[1m+{\033[0m' and ends with '\033[1m}\033[0m'. For example:" << ::std::endl
+ << ::std::endl
+ << "{ --foo --bar }+ arg # 'arg' with '--foo' '--bar'" << ::std::endl
+ << "arg +{ fox=1 baz=2 } # 'arg' with 'fox=1' 'baz=2'" << ::std::endl
+ << ::std::endl
+ << "Multiple leading and/or trailing groups can be specified for the same argument." << ::std::endl
+ << "For example:" << ::std::endl
+ << ::std::endl
+ << "{ -f }+ { -b }+ arg +{ f=1 } +{ b=2 } # 'arg' with '-f' 'b' 'f=1' 'b=2'" << ::std::endl
+ << ::std::endl
+ << "Note that the group applies to a single argument only. For example:" << ::std::endl
+ << ::std::endl
+ << "{ --foo }+ arg1 arg2 +{ --bar } # 'arg1' with '--foo' and" << ::std::endl
+ << " # 'arg2' with '--bar'" << ::std::endl
+ << ::std::endl
+ << "The group separators ('\033[1m{\033[0m', '\033[1m}+'\033[0m, etc) must be separate command line arguments." << ::std::endl
+ << "In particular, they must not be adjacent either to the arguments inside the" << ::std::endl
+ << "group nor to the argument they apply to. All such cases will be treated as" << ::std::endl
+ << "ordinary arguments. For example:" << ::std::endl
+ << ::std::endl
+ << "{--foo}+ arg # '{--foo}+' ..." << ::std::endl
+ << "arg+{ --foo } # 'arg+{' ..." << ::std::endl
+ << ::std::endl
+ << "If one of the group separators needs to be specified as an argument verbatim," << ::std::endl
+ << "then it must be escaped with '\033[1m\\\033[0m'. For example:" << ::std::endl
+ << ::std::endl
+ << "} # error: unexpected group separator" << ::std::endl
+ << "}x # '}x'" << ::std::endl
+ << "\\} # '}'" << ::std::endl
+ << "{ \\}+ }+ arg # 'arg' with '}+'" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/argument-grouping.hxx b/bpkg/argument-grouping.hxx
new file mode 100644
index 0000000..64019de
--- /dev/null
+++ b/bpkg/argument-grouping.hxx
@@ -0,0 +1,31 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_ARGUMENT_GROUPING_HXX
+#define BPKG_ARGUMENT_GROUPING_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_argument_grouping_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_ARGUMENT_GROUPING_HXX
diff --git a/bpkg/bpkg-options.cxx b/bpkg/bpkg-options.cxx
new file mode 100644
index 0000000..0baf798
--- /dev/null
+++ b/bpkg/bpkg-options.cxx
@@ -0,0 +1,1491 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/bpkg-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <ostream>
+#include <sstream>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ template <typename X>
+ struct parser
+ {
+ static void
+ parse (X& x, bool& xs, scanner& s)
+ {
+ using namespace std;
+
+ const char* o (s.next ());
+ if (s.more ())
+ {
+ string v (s.next ());
+ istringstream is (v);
+ if (!(is >> x && is.peek () == istringstream::traits_type::eof ()))
+ throw invalid_value (o, v);
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (X& b, const X& a)
+ {
+ b = a;
+ }
+ };
+
+ template <>
+ struct parser<bool>
+ {
+ static void
+ parse (bool& x, scanner& s)
+ {
+ s.next ();
+ x = true;
+ }
+
+ static void
+ merge (bool& b, const bool&)
+ {
+ b = true;
+ }
+ };
+
+ template <>
+ struct parser<std::string>
+ {
+ static void
+ parse (std::string& x, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ x = s.next ();
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (std::string& b, const std::string& a)
+ {
+ b = a;
+ }
+ };
+
+ template <typename X>
+ struct parser<std::vector<X> >
+ {
+ static void
+ parse (std::vector<X>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.push_back (x);
+ xs = true;
+ }
+
+ static void
+ merge (std::vector<X>& b, const std::vector<X>& a)
+ {
+ b.insert (b.end (), a.begin (), a.end ());
+ }
+ };
+
+ template <typename X>
+ struct parser<std::set<X> >
+ {
+ static void
+ parse (std::set<X>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.insert (x);
+ xs = true;
+ }
+
+ static void
+ merge (std::set<X>& b, const std::set<X>& a)
+ {
+ b.insert (a.begin (), a.end ());
+ }
+ };
+
+ template <typename K, typename V>
+ struct parser<std::map<K, V> >
+ {
+ static void
+ parse (std::map<K, V>& m, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ std::string ov (s.next ());
+ std::string::size_type p = ov.find ('=');
+
+ K k = K ();
+ V v = V ();
+ std::string kstr (ov, 0, p);
+ std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (o),
+ 0
+ };
+
+ bool dummy;
+ if (!kstr.empty ())
+ {
+ av[1] = const_cast<char*> (kstr.c_str ());
+ argv_scanner s (0, ac, av);
+ parser<K>::parse (k, dummy, s);
+ }
+
+ if (!vstr.empty ())
+ {
+ av[1] = const_cast<char*> (vstr.c_str ());
+ argv_scanner s (0, ac, av);
+ parser<V>::parse (v, dummy, s);
+ }
+
+ m[k] = v;
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (std::map<K, V>& b, const std::map<K, V>& a)
+ {
+ for (typename std::map<K, V>::const_iterator i (a.begin ());
+ i != a.end ();
+ ++i)
+ b[i->first] = i->second;
+ }
+ };
+
+ template <typename X, typename T, T X::*M>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, s);
+ }
+
+ template <typename X, typename T, T X::*M, bool X::*S>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, x.*S, s);
+ }
+ }
+}
+
+#include <map>
+#include <cstring>
+
+namespace bpkg
+{
+ // commands
+ //
+
+ commands::
+ commands ()
+ : help_ (),
+ cfg_create_ (),
+ rep_info_ (),
+ rep_add_ (),
+ rep_remove_ (),
+ rep_list_ (),
+ rep_fetch_ (),
+ rep_create_ (),
+ pkg_status_ (),
+ pkg_build_ (),
+ pkg_drop_ (),
+ pkg_install_ (),
+ pkg_uninstall_ (),
+ pkg_update_ (),
+ pkg_test_ (),
+ pkg_clean_ (),
+ pkg_verify_ (),
+ pkg_fetch_ (),
+ pkg_unpack_ (),
+ pkg_checkout_ (),
+ pkg_configure_ (),
+ pkg_disfigure_ (),
+ pkg_purge_ ()
+ {
+ }
+
+ bool commands::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool commands::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool commands::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool commands::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool commands::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void commands::
+ merge (const commands& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ if (a.help_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->help_, a.help_);
+ }
+
+ if (a.cfg_create_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->cfg_create_, a.cfg_create_);
+ }
+
+ if (a.rep_info_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->rep_info_, a.rep_info_);
+ }
+
+ if (a.rep_add_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->rep_add_, a.rep_add_);
+ }
+
+ if (a.rep_remove_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->rep_remove_, a.rep_remove_);
+ }
+
+ if (a.rep_list_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->rep_list_, a.rep_list_);
+ }
+
+ if (a.rep_fetch_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->rep_fetch_, a.rep_fetch_);
+ }
+
+ if (a.rep_create_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->rep_create_, a.rep_create_);
+ }
+
+ if (a.pkg_status_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_status_, a.pkg_status_);
+ }
+
+ if (a.pkg_build_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_build_, a.pkg_build_);
+ }
+
+ if (a.pkg_drop_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_drop_, a.pkg_drop_);
+ }
+
+ if (a.pkg_install_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_install_, a.pkg_install_);
+ }
+
+ if (a.pkg_uninstall_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_uninstall_, a.pkg_uninstall_);
+ }
+
+ if (a.pkg_update_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_update_, a.pkg_update_);
+ }
+
+ if (a.pkg_test_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_test_, a.pkg_test_);
+ }
+
+ if (a.pkg_clean_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_clean_, a.pkg_clean_);
+ }
+
+ if (a.pkg_verify_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_verify_, a.pkg_verify_);
+ }
+
+ if (a.pkg_fetch_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_fetch_, a.pkg_fetch_);
+ }
+
+ if (a.pkg_unpack_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_unpack_, a.pkg_unpack_);
+ }
+
+ if (a.pkg_checkout_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_checkout_, a.pkg_checkout_);
+ }
+
+ if (a.pkg_configure_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_configure_, a.pkg_configure_);
+ }
+
+ if (a.pkg_disfigure_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_disfigure_, a.pkg_disfigure_);
+ }
+
+ if (a.pkg_purge_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->pkg_purge_, a.pkg_purge_);
+ }
+ }
+
+ ::bpkg::cli::usage_para commands::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mCOMMANDS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1mhelp\033[0m [\033[4mtopic\033[0m] \033[1mbpkg-help(1)\033[0m -- show help for a command or help topic" << ::std::endl;
+
+ os << "\033[1mcfg-create\033[0m|\033[1mcreate\033[0m \033[1mbpkg-cfg-create(1)\033[0m -- create configuration" << ::std::endl;
+
+ os << "\033[1mrep-info\033[0m \033[1mbpkg-rep-info(1)\033[0m -- print repository information" << ::std::endl;
+
+ os << "\033[1mrep-add\033[0m|\033[1madd\033[0m \033[1mbpkg-rep-add(1)\033[0m -- add repository to configuration" << ::std::endl;
+
+ os << "\033[1mrep-remove\033[0m|\033[1mremove\033[0m \033[1mbpkg-rep-remove(1)\033[0m -- remove repository from" << ::std::endl
+ << " configuration" << ::std::endl;
+
+ os << "\033[1mrep-list\033[0m|\033[1mlist\033[0m \033[1mbpkg-rep-list(1)\033[0m -- list repositories in configuration" << ::std::endl;
+
+ os << "\033[1mrep-fetch\033[0m|\033[1mfetch\033[0m \033[1mbpkg-rep-fetch(1)\033[0m -- fetch list of available packages" << ::std::endl;
+
+ os << "\033[1mrep-create\033[0m \033[1mbpkg-rep-create(1)\033[0m -- create repository" << ::std::endl;
+
+ os << "\033[1mpkg-status\033[0m|\033[1mstatus\033[0m \033[1mbpkg-pkg-status(1)\033[0m -- print package status" << ::std::endl;
+
+ os << "\033[1mpkg-build\033[0m|\033[1mbuild\033[0m \033[1mbpkg-pkg-build(1)\033[0m -- build package" << ::std::endl;
+
+ os << "\033[1mpkg-drop\033[0m|\033[1mdrop\033[0m \033[1mbpkg-pkg-drop(1)\033[0m -- drop package" << ::std::endl;
+
+ os << "\033[1mpkg-install\033[0m|\033[1minstall\033[0m \033[1mbpkg-pkg-install(1)\033[0m -- install package" << ::std::endl;
+
+ os << "\033[1mpkg-uninstall\033[0m|\033[1muninstall\033[0m \033[1mbpkg-pkg-uninstall(1)\033[0m -- uninstall package" << ::std::endl;
+
+ os << "\033[1mpkg-update\033[0m|\033[1mupdate\033[0m \033[1mbpkg-pkg-update(1)\033[0m -- update package" << ::std::endl;
+
+ os << "\033[1mpkg-test\033[0m|\033[1mtest\033[0m \033[1mbpkg-pkg-test(1)\033[0m -- test package" << ::std::endl;
+
+ os << "\033[1mpkg-clean\033[0m|\033[1mclean\033[0m \033[1mbpkg-pkg-clean(1)\033[0m -- clean package" << ::std::endl;
+
+ os << "\033[1mpkg-verify\033[0m \033[1mbpkg-pkg-verify(1)\033[0m -- verify package archive" << ::std::endl;
+
+ os << "\033[1mpkg-fetch\033[0m \033[1mbpkg-pkg-fetch(1)\033[0m -- fetch package archive" << ::std::endl;
+
+ os << "\033[1mpkg-unpack\033[0m \033[1mbpkg-pkg-unpack(1)\033[0m -- unpack package archive" << ::std::endl;
+
+ os << "\033[1mpkg-checkout\033[0m \033[1mbpkg-pkg-checkout(1)\033[0m -- check out package version" << ::std::endl;
+
+ os << "\033[1mpkg-configure\033[0m \033[1mbpkg-pkg-configure(1)\033[0m -- configure package" << ::std::endl;
+
+ os << "\033[1mpkg-disfigure\033[0m \033[1mbpkg-pkg-disfigure(1)\033[0m -- disfigure package" << ::std::endl;
+
+ os << "\033[1mpkg-purge\033[0m \033[1mbpkg-pkg-purge(1)\033[0m -- purge package" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (commands&, ::bpkg::cli::scanner&)>
+ _cli_commands_map;
+
+ static _cli_commands_map _cli_commands_map_;
+
+ struct _cli_commands_map_init
+ {
+ _cli_commands_map_init ()
+ {
+ _cli_commands_map_["help"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::help_ >;
+ _cli_commands_map_["cfg-create"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::cfg_create_ >;
+ _cli_commands_map_["create"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::cfg_create_ >;
+ _cli_commands_map_["rep-info"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::rep_info_ >;
+ _cli_commands_map_["rep-add"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::rep_add_ >;
+ _cli_commands_map_["add"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::rep_add_ >;
+ _cli_commands_map_["rep-remove"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::rep_remove_ >;
+ _cli_commands_map_["remove"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::rep_remove_ >;
+ _cli_commands_map_["rep-list"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::rep_list_ >;
+ _cli_commands_map_["list"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::rep_list_ >;
+ _cli_commands_map_["rep-fetch"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::rep_fetch_ >;
+ _cli_commands_map_["fetch"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::rep_fetch_ >;
+ _cli_commands_map_["rep-create"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::rep_create_ >;
+ _cli_commands_map_["pkg-status"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_status_ >;
+ _cli_commands_map_["status"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_status_ >;
+ _cli_commands_map_["pkg-build"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_build_ >;
+ _cli_commands_map_["build"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_build_ >;
+ _cli_commands_map_["pkg-drop"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_drop_ >;
+ _cli_commands_map_["drop"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_drop_ >;
+ _cli_commands_map_["pkg-install"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_install_ >;
+ _cli_commands_map_["install"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_install_ >;
+ _cli_commands_map_["pkg-uninstall"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_uninstall_ >;
+ _cli_commands_map_["uninstall"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_uninstall_ >;
+ _cli_commands_map_["pkg-update"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_update_ >;
+ _cli_commands_map_["update"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_update_ >;
+ _cli_commands_map_["pkg-test"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_test_ >;
+ _cli_commands_map_["test"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_test_ >;
+ _cli_commands_map_["pkg-clean"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_clean_ >;
+ _cli_commands_map_["clean"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_clean_ >;
+ _cli_commands_map_["pkg-verify"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_verify_ >;
+ _cli_commands_map_["pkg-fetch"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_fetch_ >;
+ _cli_commands_map_["pkg-unpack"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_unpack_ >;
+ _cli_commands_map_["pkg-checkout"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_checkout_ >;
+ _cli_commands_map_["pkg-configure"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_configure_ >;
+ _cli_commands_map_["pkg-disfigure"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_disfigure_ >;
+ _cli_commands_map_["pkg-purge"] =
+ &::bpkg::cli::thunk< commands, bool, &commands::pkg_purge_ >;
+ }
+ };
+
+ static _cli_commands_map_init _cli_commands_map_init_;
+
+ bool commands::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_commands_map::const_iterator i (_cli_commands_map_.find (o));
+
+ if (i != _cli_commands_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool commands::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (_parse (co.c_str (), ns))
+ {
+ // Parsed the option but not its value?
+ //
+ if (ns.end () != 2)
+ throw ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+
+ // topics
+ //
+
+ topics::
+ topics ()
+ : common_options_ (),
+ default_options_files_ (),
+ repository_types_ (),
+ repository_signing_ (),
+ argument_grouping_ ()
+ {
+ }
+
+ bool topics::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool topics::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool topics::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool topics::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool topics::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void topics::
+ merge (const topics& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ if (a.common_options_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->common_options_, a.common_options_);
+ }
+
+ if (a.default_options_files_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->default_options_files_, a.default_options_files_);
+ }
+
+ if (a.repository_types_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->repository_types_, a.repository_types_);
+ }
+
+ if (a.repository_signing_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->repository_signing_, a.repository_signing_);
+ }
+
+ if (a.argument_grouping_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->argument_grouping_, a.argument_grouping_);
+ }
+ }
+
+ ::bpkg::cli::usage_para topics::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mHELP TOPICS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1mcommon-options\033[0m \033[1mbpkg-common-options(1)\033[0m -- details on common options" << ::std::endl;
+
+ os << "\033[1mdefault-options-files\033[0m \033[1mbpkg-default-options-files(1)\033[0m -- specifying default" << ::std::endl
+ << " options" << ::std::endl;
+
+ os << "\033[1mrepository-types\033[0m \033[1mbpkg-repository-types(1)\033[0m -- repository types," << ::std::endl
+ << " structure, and URLs" << ::std::endl;
+
+ os << "\033[1mrepository-signing\033[0m \033[1mbpkg-repository-signing(1)\033[0m -- how to sign repository" << ::std::endl;
+
+ os << "\033[1margument-grouping\033[0m \033[1mbpkg-argument-grouping(1)\033[0m -- argument grouping" << ::std::endl
+ << " facility" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (topics&, ::bpkg::cli::scanner&)>
+ _cli_topics_map;
+
+ static _cli_topics_map _cli_topics_map_;
+
+ struct _cli_topics_map_init
+ {
+ _cli_topics_map_init ()
+ {
+ _cli_topics_map_["common-options"] =
+ &::bpkg::cli::thunk< topics, bool, &topics::common_options_ >;
+ _cli_topics_map_["default-options-files"] =
+ &::bpkg::cli::thunk< topics, bool, &topics::default_options_files_ >;
+ _cli_topics_map_["repository-types"] =
+ &::bpkg::cli::thunk< topics, bool, &topics::repository_types_ >;
+ _cli_topics_map_["repository-signing"] =
+ &::bpkg::cli::thunk< topics, bool, &topics::repository_signing_ >;
+ _cli_topics_map_["argument-grouping"] =
+ &::bpkg::cli::thunk< topics, bool, &topics::argument_grouping_ >;
+ }
+ };
+
+ static _cli_topics_map_init _cli_topics_map_init_;
+
+ bool topics::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_topics_map::const_iterator i (_cli_topics_map_.find (o));
+
+ if (i != _cli_topics_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool topics::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (_parse (co.c_str (), ns))
+ {
+ // Parsed the option but not its value?
+ //
+ if (ns.end () != 2)
+ throw ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+
+ // options
+ //
+
+ options::
+ options ()
+ : help_ (),
+ version_ ()
+ {
+ }
+
+ bool options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void options::
+ merge (const options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // common_options base
+ //
+ ::bpkg::common_options::merge (a);
+
+ if (a.help_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->help_, a.help_);
+ }
+
+ if (a.version_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->version_, a.version_);
+ }
+ }
+
+ ::bpkg::cli::usage_para options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ // common_options base
+ //
+ p = ::bpkg::common_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (options&, ::bpkg::cli::scanner&)>
+ _cli_options_map;
+
+ static _cli_options_map _cli_options_map_;
+
+ struct _cli_options_map_init
+ {
+ _cli_options_map_init ()
+ {
+ _cli_options_map_["--help"] =
+ &::bpkg::cli::thunk< options, bool, &options::help_ >;
+ _cli_options_map_["--version"] =
+ &::bpkg::cli::thunk< options, bool, &options::version_ >;
+ }
+ };
+
+ static _cli_options_map_init _cli_options_map_init_;
+
+ bool options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_options_map::const_iterator i (_cli_options_map_.find (o));
+
+ if (i != _cli_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // common_options base
+ //
+ if (::bpkg::common_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (_parse (co.c_str (), ns))
+ {
+ // Parsed the option but not its value?
+ //
+ if (ns.end () != 2)
+ throw ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg --help\033[0m" << ::std::endl
+ << "\033[1mbpkg --version\033[0m" << ::std::endl
+ << "\033[1mbpkg help\033[0m [\033[4mcommand\033[0m | \033[4mtopic\033[0m]" << ::std::endl
+ << "\033[1mbpkg\033[0m [\033[4mcommon-options\033[0m] \033[4mcommand\033[0m [\033[4mcommand-options\033[0m] \033[4mcommand-args\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mbuild2\033[0m package dependency manager is used to manipulate build" << ::std::endl
+ << "configurations, packages, and repositories using a set of commands that are" << ::std::endl
+ << "summarized below." << ::std::endl
+ << ::std::endl
+ << "For a detailed description of any command or help topic, use the \033[1mhelp\033[0m command" << ::std::endl
+ << "or see the corresponding man page (the man pages have the \033[1mbpkg-\033[0m prefix, for" << ::std::endl
+ << "example \033[1mbpkg-help(1)\033[0m). Note also that \033[4mcommand-options\033[0m and \033[4mcommand-args\033[0m can be" << ::std::endl
+ << "specified in any order and \033[4mcommon-options\033[0m can be specified as part of" << ::std::endl
+ << "\033[4mcommand-options\033[0m." << ::std::endl;
+
+ p = ::bpkg::commands::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ p = ::bpkg::topics::print_usage (os, p);
+
+ p = ::bpkg::options::print_usage (os, p);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mENVIRONMENT\033[0m" << ::std::endl
+ << ::std::endl
+ << "Commands executed by \033[1mbpkg\033[0m while the build configuration database is open will" << ::std::endl
+ << "have the \033[1mBPKG_OPEN_CONFIG\033[0m environment variable set to the absolute and" << ::std::endl
+ << "normalized configuration directory path. This can be used by build system hooks" << ::std::endl
+ << "and/or programs that they execute." << ::std::endl;
+
+ os << std::endl
+ << "\033[1mEXIT STATUS\033[0m" << ::std::endl
+ << ::std::endl
+ << "Non-zero exit status is returned in case of an error." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/bpkg-options.hxx b/bpkg/bpkg-options.hxx
new file mode 100644
index 0000000..ecfadb0
--- /dev/null
+++ b/bpkg/bpkg-options.hxx
@@ -0,0 +1,375 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_BPKG_OPTIONS_HXX
+#define BPKG_BPKG_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+namespace bpkg
+{
+ class commands
+ {
+ public:
+ commands ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const commands&);
+
+ // Option accessors.
+ //
+ const bool&
+ help () const;
+
+ const bool&
+ cfg_create () const;
+
+ const bool&
+ rep_info () const;
+
+ const bool&
+ rep_add () const;
+
+ const bool&
+ rep_remove () const;
+
+ const bool&
+ rep_list () const;
+
+ const bool&
+ rep_fetch () const;
+
+ const bool&
+ rep_create () const;
+
+ const bool&
+ pkg_status () const;
+
+ const bool&
+ pkg_build () const;
+
+ const bool&
+ pkg_drop () const;
+
+ const bool&
+ pkg_install () const;
+
+ const bool&
+ pkg_uninstall () const;
+
+ const bool&
+ pkg_update () const;
+
+ const bool&
+ pkg_test () const;
+
+ const bool&
+ pkg_clean () const;
+
+ const bool&
+ pkg_verify () const;
+
+ const bool&
+ pkg_fetch () const;
+
+ const bool&
+ pkg_unpack () const;
+
+ const bool&
+ pkg_checkout () const;
+
+ const bool&
+ pkg_configure () const;
+
+ const bool&
+ pkg_disfigure () const;
+
+ const bool&
+ pkg_purge () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool help_;
+ bool cfg_create_;
+ bool rep_info_;
+ bool rep_add_;
+ bool rep_remove_;
+ bool rep_list_;
+ bool rep_fetch_;
+ bool rep_create_;
+ bool pkg_status_;
+ bool pkg_build_;
+ bool pkg_drop_;
+ bool pkg_install_;
+ bool pkg_uninstall_;
+ bool pkg_update_;
+ bool pkg_test_;
+ bool pkg_clean_;
+ bool pkg_verify_;
+ bool pkg_fetch_;
+ bool pkg_unpack_;
+ bool pkg_checkout_;
+ bool pkg_configure_;
+ bool pkg_disfigure_;
+ bool pkg_purge_;
+ };
+
+ class topics
+ {
+ public:
+ topics ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const topics&);
+
+ // Option accessors.
+ //
+ const bool&
+ common_options () const;
+
+ const bool&
+ default_options_files () const;
+
+ const bool&
+ repository_types () const;
+
+ const bool&
+ repository_signing () const;
+
+ const bool&
+ argument_grouping () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool common_options_;
+ bool default_options_files_;
+ bool repository_types_;
+ bool repository_signing_;
+ bool argument_grouping_;
+ };
+
+ class options: public ::bpkg::common_options
+ {
+ public:
+ options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const options&);
+
+ // Option accessors.
+ //
+ const bool&
+ help () const;
+
+ const bool&
+ version () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ bool help_;
+ bool version_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/bpkg-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_BPKG_OPTIONS_HXX
diff --git a/bpkg/bpkg-options.ixx b/bpkg/bpkg-options.ixx
new file mode 100644
index 0000000..bcf8c7f
--- /dev/null
+++ b/bpkg/bpkg-options.ixx
@@ -0,0 +1,207 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // commands
+ //
+
+ inline const bool& commands::
+ help () const
+ {
+ return this->help_;
+ }
+
+ inline const bool& commands::
+ cfg_create () const
+ {
+ return this->cfg_create_;
+ }
+
+ inline const bool& commands::
+ rep_info () const
+ {
+ return this->rep_info_;
+ }
+
+ inline const bool& commands::
+ rep_add () const
+ {
+ return this->rep_add_;
+ }
+
+ inline const bool& commands::
+ rep_remove () const
+ {
+ return this->rep_remove_;
+ }
+
+ inline const bool& commands::
+ rep_list () const
+ {
+ return this->rep_list_;
+ }
+
+ inline const bool& commands::
+ rep_fetch () const
+ {
+ return this->rep_fetch_;
+ }
+
+ inline const bool& commands::
+ rep_create () const
+ {
+ return this->rep_create_;
+ }
+
+ inline const bool& commands::
+ pkg_status () const
+ {
+ return this->pkg_status_;
+ }
+
+ inline const bool& commands::
+ pkg_build () const
+ {
+ return this->pkg_build_;
+ }
+
+ inline const bool& commands::
+ pkg_drop () const
+ {
+ return this->pkg_drop_;
+ }
+
+ inline const bool& commands::
+ pkg_install () const
+ {
+ return this->pkg_install_;
+ }
+
+ inline const bool& commands::
+ pkg_uninstall () const
+ {
+ return this->pkg_uninstall_;
+ }
+
+ inline const bool& commands::
+ pkg_update () const
+ {
+ return this->pkg_update_;
+ }
+
+ inline const bool& commands::
+ pkg_test () const
+ {
+ return this->pkg_test_;
+ }
+
+ inline const bool& commands::
+ pkg_clean () const
+ {
+ return this->pkg_clean_;
+ }
+
+ inline const bool& commands::
+ pkg_verify () const
+ {
+ return this->pkg_verify_;
+ }
+
+ inline const bool& commands::
+ pkg_fetch () const
+ {
+ return this->pkg_fetch_;
+ }
+
+ inline const bool& commands::
+ pkg_unpack () const
+ {
+ return this->pkg_unpack_;
+ }
+
+ inline const bool& commands::
+ pkg_checkout () const
+ {
+ return this->pkg_checkout_;
+ }
+
+ inline const bool& commands::
+ pkg_configure () const
+ {
+ return this->pkg_configure_;
+ }
+
+ inline const bool& commands::
+ pkg_disfigure () const
+ {
+ return this->pkg_disfigure_;
+ }
+
+ inline const bool& commands::
+ pkg_purge () const
+ {
+ return this->pkg_purge_;
+ }
+
+ // topics
+ //
+
+ inline const bool& topics::
+ common_options () const
+ {
+ return this->common_options_;
+ }
+
+ inline const bool& topics::
+ default_options_files () const
+ {
+ return this->default_options_files_;
+ }
+
+ inline const bool& topics::
+ repository_types () const
+ {
+ return this->repository_types_;
+ }
+
+ inline const bool& topics::
+ repository_signing () const
+ {
+ return this->repository_signing_;
+ }
+
+ inline const bool& topics::
+ argument_grouping () const
+ {
+ return this->argument_grouping_;
+ }
+
+ // options
+ //
+
+ inline const bool& options::
+ help () const
+ {
+ return this->help_;
+ }
+
+ inline const bool& options::
+ version () const
+ {
+ return this->version_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/cfg-create-options.cxx b/bpkg/cfg-create-options.cxx
new file mode 100644
index 0000000..4e69658
--- /dev/null
+++ b/bpkg/cfg-create-options.cxx
@@ -0,0 +1,636 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/cfg-create-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <ostream>
+#include <sstream>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ template <typename X>
+ struct parser
+ {
+ static void
+ parse (X& x, bool& xs, scanner& s)
+ {
+ using namespace std;
+
+ const char* o (s.next ());
+ if (s.more ())
+ {
+ string v (s.next ());
+ istringstream is (v);
+ if (!(is >> x && is.peek () == istringstream::traits_type::eof ()))
+ throw invalid_value (o, v);
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (X& b, const X& a)
+ {
+ b = a;
+ }
+ };
+
+ template <>
+ struct parser<bool>
+ {
+ static void
+ parse (bool& x, scanner& s)
+ {
+ s.next ();
+ x = true;
+ }
+
+ static void
+ merge (bool& b, const bool&)
+ {
+ b = true;
+ }
+ };
+
+ template <>
+ struct parser<std::string>
+ {
+ static void
+ parse (std::string& x, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ x = s.next ();
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (std::string& b, const std::string& a)
+ {
+ b = a;
+ }
+ };
+
+ template <typename X>
+ struct parser<std::vector<X> >
+ {
+ static void
+ parse (std::vector<X>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.push_back (x);
+ xs = true;
+ }
+
+ static void
+ merge (std::vector<X>& b, const std::vector<X>& a)
+ {
+ b.insert (b.end (), a.begin (), a.end ());
+ }
+ };
+
+ template <typename X>
+ struct parser<std::set<X> >
+ {
+ static void
+ parse (std::set<X>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.insert (x);
+ xs = true;
+ }
+
+ static void
+ merge (std::set<X>& b, const std::set<X>& a)
+ {
+ b.insert (a.begin (), a.end ());
+ }
+ };
+
+ template <typename K, typename V>
+ struct parser<std::map<K, V> >
+ {
+ static void
+ parse (std::map<K, V>& m, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ std::string ov (s.next ());
+ std::string::size_type p = ov.find ('=');
+
+ K k = K ();
+ V v = V ();
+ std::string kstr (ov, 0, p);
+ std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (o),
+ 0
+ };
+
+ bool dummy;
+ if (!kstr.empty ())
+ {
+ av[1] = const_cast<char*> (kstr.c_str ());
+ argv_scanner s (0, ac, av);
+ parser<K>::parse (k, dummy, s);
+ }
+
+ if (!vstr.empty ())
+ {
+ av[1] = const_cast<char*> (vstr.c_str ());
+ argv_scanner s (0, ac, av);
+ parser<V>::parse (v, dummy, s);
+ }
+
+ m[k] = v;
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (std::map<K, V>& b, const std::map<K, V>& a)
+ {
+ for (typename std::map<K, V>::const_iterator i (a.begin ());
+ i != a.end ();
+ ++i)
+ b[i->first] = i->second;
+ }
+ };
+
+ template <typename X, typename T, T X::*M>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, s);
+ }
+
+ template <typename X, typename T, T X::*M, bool X::*S>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, x.*S, s);
+ }
+ }
+}
+
+#include <map>
+#include <cstring>
+
+namespace bpkg
+{
+ // cfg_create_options
+ //
+
+ cfg_create_options::
+ cfg_create_options ()
+ : directory_ ("."),
+ directory_specified_ (false),
+ existing_ (),
+ wipe_ ()
+ {
+ }
+
+ bool cfg_create_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool cfg_create_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool cfg_create_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool cfg_create_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool cfg_create_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void cfg_create_options::
+ merge (const cfg_create_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // common_options base
+ //
+ ::bpkg::common_options::merge (a);
+
+ if (a.directory_specified_)
+ {
+ ::bpkg::cli::parser< dir_path>::merge (
+ this->directory_, a.directory_);
+ this->directory_specified_ = true;
+ }
+
+ if (a.existing_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->existing_, a.existing_);
+ }
+
+ if (a.wipe_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->wipe_, a.wipe_);
+ }
+ }
+
+ ::bpkg::cli::usage_para cfg_create_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mCFG-CREATE OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--directory\033[0m|\033[1m-d\033[0m \033[4mdir\033[0m Create the configuration in \033[4mdir\033[0m rather than in the" << ::std::endl
+ << " current working directory." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--existing\033[0m|\033[1m-e\033[0m Initialize a \033[1mbpkg\033[0m configuration based on an existing" << ::std::endl
+ << " build system configuration." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--wipe\033[0m Wipe the configuration directory clean before creating" << ::std::endl
+ << " the new configuration. For safety, this option" << ::std::endl
+ << " requires that you specify the configuration directory" << ::std::endl
+ << " explicitly with \033[1m--directory|-d\033[0m." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // common_options base
+ //
+ p = ::bpkg::common_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (cfg_create_options&, ::bpkg::cli::scanner&)>
+ _cli_cfg_create_options_map;
+
+ static _cli_cfg_create_options_map _cli_cfg_create_options_map_;
+
+ struct _cli_cfg_create_options_map_init
+ {
+ _cli_cfg_create_options_map_init ()
+ {
+ _cli_cfg_create_options_map_["--directory"] =
+ &::bpkg::cli::thunk< cfg_create_options, dir_path, &cfg_create_options::directory_,
+ &cfg_create_options::directory_specified_ >;
+ _cli_cfg_create_options_map_["-d"] =
+ &::bpkg::cli::thunk< cfg_create_options, dir_path, &cfg_create_options::directory_,
+ &cfg_create_options::directory_specified_ >;
+ _cli_cfg_create_options_map_["--existing"] =
+ &::bpkg::cli::thunk< cfg_create_options, bool, &cfg_create_options::existing_ >;
+ _cli_cfg_create_options_map_["-e"] =
+ &::bpkg::cli::thunk< cfg_create_options, bool, &cfg_create_options::existing_ >;
+ _cli_cfg_create_options_map_["--wipe"] =
+ &::bpkg::cli::thunk< cfg_create_options, bool, &cfg_create_options::wipe_ >;
+ }
+ };
+
+ static _cli_cfg_create_options_map_init _cli_cfg_create_options_map_init_;
+
+ bool cfg_create_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_cfg_create_options_map::const_iterator i (_cli_cfg_create_options_map_.find (o));
+
+ if (i != _cli_cfg_create_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // common_options base
+ //
+ if (::bpkg::common_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool cfg_create_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (_parse (co.c_str (), ns))
+ {
+ // Parsed the option but not its value?
+ //
+ if (ns.end () != 2)
+ throw ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_cfg_create_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg cfg-create\033[0m|\033[1mcreate\033[0m [\033[4moptions\033[0m] [\033[4mcfg-args\033[0m]" << ::std::endl
+ << "\033[1mbpkg cfg-create\033[0m|\033[1mcreate\033[0m [\033[4moptions\033[0m] \033[1m--existing|-e\033[0m\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[4mcfg-args\033[0m = (\033[4mmodule\033[0m | \033[4mcfg-var\033[0m)...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The \033[1mcfg-create\033[0m command creates a new \033[1mbpkg\033[0m configuration with the specified" << ::std::endl
+ << "\033[1mbuild2\033[0m modules and configuration variables (the first form) or initializes one" << ::std::endl
+ << "based on an existing build system configuration (the second form). The \033[1mbpkg\033[0m" << ::std::endl
+ << "configuration itself is a build system configuration; see build system driver" << ::std::endl
+ << "(\033[1mb(1)\033[0m) \033[1mcreate\033[0m meta-operation for details." << ::std::endl
+ << ::std::endl
+ << "Unless the \033[1m--existing|-e\033[0m or \033[1m--wipe\033[0m option is specified, \033[1mcfg-create\033[0m expects the" << ::std::endl
+ << "configuration directory to be empty or to not exist (in which case it will be" << ::std::endl
+ << "created)." << ::std::endl
+ << ::std::endl
+ << "By default, the configuration created with the first form loads the \033[1mconfig\033[0m," << ::std::endl
+ << "\033[1mtest\033[0m, \033[1mdist\033[0m, and \033[1minstall\033[0m modules. However, additional modules and, if required," << ::std::endl
+ << "their configuration variables can be specified as the \033[1mcfg-create\033[0m arguments. For" << ::std::endl
+ << "example:" << ::std::endl
+ << ::std::endl
+ << "bpkg create cxx config.cxx=clang++ config.install.root=/usr/local" << ::std::endl
+ << ::std::endl
+ << "By default, \033[1mbpkg\033[0m appends \033[1m.config\033[0m to the names of the modules that you specify" << ::std::endl
+ << "so that only their configurations are loaded. You can override this behavior by" << ::std::endl
+ << "specifying the period (\033[1m.\033[0m) after the module name. You can also instruct \033[1mbpkg\033[0m to" << ::std::endl
+ << "use the optional module load by prefixing the module name with the question" << ::std::endl
+ << "mark (\033[1m?\033[0m). For example:" << ::std::endl
+ << ::std::endl
+ << "bpkg create cxx. \"?cli\"" << ::std::endl;
+
+ p = ::bpkg::cfg_create_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mcfg-create\033[0m command the search start directory is the parent directory" << ::std::endl
+ << "of the new configuration. The following options files are searched for in each" << ::std::endl
+ << "directory and, if found, loaded in the order listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-cfg-create.options" << ::std::endl
+ << ::std::endl
+ << "The following \033[1mcfg-create\033[0m command options cannot be specified in the default" << ::std::endl
+ << "options files:" << ::std::endl
+ << ::std::endl
+ << "--directory|-d" << ::std::endl
+ << "--wipe" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/cfg-create-options.hxx b/bpkg/cfg-create-options.hxx
new file mode 100644
index 0000000..28db622
--- /dev/null
+++ b/bpkg/cfg-create-options.hxx
@@ -0,0 +1,125 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_CFG_CREATE_OPTIONS_HXX
+#define BPKG_CFG_CREATE_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+namespace bpkg
+{
+ class cfg_create_options: public ::bpkg::common_options
+ {
+ public:
+ cfg_create_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const cfg_create_options&);
+
+ // Option accessors.
+ //
+ const dir_path&
+ directory () const;
+
+ bool
+ directory_specified () const;
+
+ const bool&
+ existing () const;
+
+ const bool&
+ wipe () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ dir_path directory_;
+ bool directory_specified_;
+ bool existing_;
+ bool wipe_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_cfg_create_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/cfg-create-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_CFG_CREATE_OPTIONS_HXX
diff --git a/bpkg/cfg-create-options.ixx b/bpkg/cfg-create-options.ixx
new file mode 100644
index 0000000..22caddc
--- /dev/null
+++ b/bpkg/cfg-create-options.ixx
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // cfg_create_options
+ //
+
+ inline const dir_path& cfg_create_options::
+ directory () const
+ {
+ return this->directory_;
+ }
+
+ inline bool cfg_create_options::
+ directory_specified () const
+ {
+ return this->directory_specified_;
+ }
+
+ inline const bool& cfg_create_options::
+ existing () const
+ {
+ return this->existing_;
+ }
+
+ inline const bool& cfg_create_options::
+ wipe () const
+ {
+ return this->wipe_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/common-options.cxx b/bpkg/common-options.cxx
new file mode 100644
index 0000000..0d74702
--- /dev/null
+++ b/bpkg/common-options.cxx
@@ -0,0 +1,1706 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <ostream>
+#include <sstream>
+#include <cstring>
+#include <fstream>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ // unknown_option
+ //
+ unknown_option::
+ ~unknown_option () throw ()
+ {
+ }
+
+ void unknown_option::
+ print (::std::ostream& os) const
+ {
+ os << "unknown option '" << option ().c_str () << "'";
+ }
+
+ const char* unknown_option::
+ what () const throw ()
+ {
+ return "unknown option";
+ }
+
+ // unknown_argument
+ //
+ unknown_argument::
+ ~unknown_argument () throw ()
+ {
+ }
+
+ void unknown_argument::
+ print (::std::ostream& os) const
+ {
+ os << "unknown argument '" << argument ().c_str () << "'";
+ }
+
+ const char* unknown_argument::
+ what () const throw ()
+ {
+ return "unknown argument";
+ }
+
+ // missing_value
+ //
+ missing_value::
+ ~missing_value () throw ()
+ {
+ }
+
+ void missing_value::
+ print (::std::ostream& os) const
+ {
+ os << "missing value for option '" << option ().c_str () << "'";
+ }
+
+ const char* missing_value::
+ what () const throw ()
+ {
+ return "missing option value";
+ }
+
+ // invalid_value
+ //
+ invalid_value::
+ ~invalid_value () throw ()
+ {
+ }
+
+ void invalid_value::
+ print (::std::ostream& os) const
+ {
+ os << "invalid value '" << value ().c_str () << "' for option '"
+ << option ().c_str () << "'";
+
+ if (!message ().empty ())
+ os << ": " << message ().c_str ();
+ }
+
+ const char* invalid_value::
+ what () const throw ()
+ {
+ return "invalid option value";
+ }
+
+ // eos_reached
+ //
+ void eos_reached::
+ print (::std::ostream& os) const
+ {
+ os << what ();
+ }
+
+ const char* eos_reached::
+ what () const throw ()
+ {
+ return "end of argument stream reached";
+ }
+
+ // file_io_failure
+ //
+ file_io_failure::
+ ~file_io_failure () throw ()
+ {
+ }
+
+ void file_io_failure::
+ print (::std::ostream& os) const
+ {
+ os << "unable to open file '" << file ().c_str () << "' or read failure";
+ }
+
+ const char* file_io_failure::
+ what () const throw ()
+ {
+ return "unable to open file or read failure";
+ }
+
+ // unmatched_quote
+ //
+ unmatched_quote::
+ ~unmatched_quote () throw ()
+ {
+ }
+
+ void unmatched_quote::
+ print (::std::ostream& os) const
+ {
+ os << "unmatched quote in argument '" << argument ().c_str () << "'";
+ }
+
+ const char* unmatched_quote::
+ what () const throw ()
+ {
+ return "unmatched quote";
+ }
+
+ // unexpected_group
+ //
+ unexpected_group::
+ ~unexpected_group () throw ()
+ {
+ }
+
+ void unexpected_group::
+ print (::std::ostream& os) const
+ {
+ os << "unexpected grouped argument '" << group_ << "' "
+ << "for argument '" << argument_ << "'";
+ }
+
+ const char* unexpected_group::
+ what () const throw ()
+ {
+ return "unexpected grouped argument";
+ }
+
+ // group_separator
+ //
+ group_separator::
+ ~group_separator () throw ()
+ {
+ }
+
+ void group_separator::
+ print (::std::ostream& os) const
+ {
+ bool ex (!expected_.empty ());
+ bool en (!encountered_.empty ());
+
+ if (ex)
+ {
+ os << "expected group separator '" << expected_ << "'";
+ if (en)
+ os << " instead of '" << encountered_ << "'";
+ }
+ else
+ os << "unexpected group separator '" << encountered_ << "'";
+
+ if (en)
+ os << ", use '\\" << encountered_ << "' to escape";
+ }
+
+ const char* group_separator::
+ what () const throw ()
+ {
+ bool ex (!expected_.empty ());
+ bool en (!encountered_.empty ());
+
+ return en
+ ? ex ? "wrong group separator" : "unexpected group separator"
+ : ex ? "expected group separator" : "";
+ }
+
+ // scanner
+ //
+ scanner::
+ ~scanner ()
+ {
+ }
+
+ // argv_scanner
+ //
+ bool argv_scanner::
+ more ()
+ {
+ return i_ < argc_;
+ }
+
+ const char* argv_scanner::
+ peek ()
+ {
+ if (i_ < argc_)
+ return argv_[i_];
+ else
+ throw eos_reached ();
+ }
+
+ const char* argv_scanner::
+ next ()
+ {
+ if (i_ < argc_)
+ {
+ const char* r (argv_[i_]);
+
+ if (erase_)
+ {
+ for (int i (i_ + 1); i < argc_; ++i)
+ argv_[i - 1] = argv_[i];
+
+ --argc_;
+ argv_[argc_] = 0;
+ }
+ else
+ ++i_;
+
+ return r;
+ }
+ else
+ throw eos_reached ();
+ }
+
+ void argv_scanner::
+ skip ()
+ {
+ if (i_ < argc_)
+ ++i_;
+ else
+ throw eos_reached ();
+ }
+
+ // vector_scanner
+ //
+ bool vector_scanner::
+ more ()
+ {
+ return i_ < v_.size ();
+ }
+
+ const char* vector_scanner::
+ peek ()
+ {
+ if (i_ < v_.size ())
+ return v_[i_].c_str ();
+ else
+ throw eos_reached ();
+ }
+
+ const char* vector_scanner::
+ next ()
+ {
+ if (i_ < v_.size ())
+ return v_[i_++].c_str ();
+ else
+ throw eos_reached ();
+ }
+
+ void vector_scanner::
+ skip ()
+ {
+ if (i_ < v_.size ())
+ ++i_;
+ else
+ throw eos_reached ();
+ }
+
+ // argv_file_scanner
+ //
+ int argv_file_scanner::zero_argc_ = 0;
+ std::string argv_file_scanner::empty_string_;
+
+ bool argv_file_scanner::
+ more ()
+ {
+ if (!args_.empty ())
+ return true;
+
+ while (base::more ())
+ {
+ // See if the next argument is the file option.
+ //
+ const char* a (base::peek ());
+ const option_info* oi = 0;
+ const char* ov = 0;
+
+ if (!skip_)
+ {
+ if ((oi = find (a)) != 0)
+ {
+ base::next ();
+
+ if (!base::more ())
+ throw missing_value (a);
+
+ ov = base::next ();
+ }
+ else if (std::strncmp (a, "-", 1) == 0)
+ {
+ if ((ov = std::strchr (a, '=')) != 0)
+ {
+ std::string o (a, 0, ov - a);
+ if ((oi = find (o.c_str ())) != 0)
+ {
+ base::next ();
+ ++ov;
+ }
+ }
+ }
+ }
+
+ if (oi != 0)
+ {
+ if (oi->search_func != 0)
+ {
+ std::string f (oi->search_func (ov, oi->arg));
+
+ if (!f.empty ())
+ load (f);
+ }
+ else
+ load (ov);
+
+ if (!args_.empty ())
+ return true;
+ }
+ else
+ {
+ if (!skip_)
+ skip_ = (std::strcmp (a, "--") == 0);
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ const char* argv_file_scanner::
+ peek ()
+ {
+ if (!more ())
+ throw eos_reached ();
+
+ return args_.empty () ? base::peek () : args_.front ().value.c_str ();
+ }
+
+ const std::string& argv_file_scanner::
+ peek_file ()
+ {
+ if (!more ())
+ throw eos_reached ();
+
+ return args_.empty () ? empty_string_ : *args_.front ().file;
+ }
+
+ std::size_t argv_file_scanner::
+ peek_line ()
+ {
+ if (!more ())
+ throw eos_reached ();
+
+ return args_.empty () ? 0 : args_.front ().line;
+ }
+
+ const char* argv_file_scanner::
+ next ()
+ {
+ if (!more ())
+ throw eos_reached ();
+
+ if (args_.empty ())
+ return base::next ();
+ else
+ {
+ hold_[i_ == 0 ? ++i_ : --i_].swap (args_.front ().value);
+ args_.pop_front ();
+ return hold_[i_].c_str ();
+ }
+ }
+
+ void argv_file_scanner::
+ skip ()
+ {
+ if (!more ())
+ throw eos_reached ();
+
+ if (args_.empty ())
+ return base::skip ();
+ else
+ args_.pop_front ();
+ }
+
+ const argv_file_scanner::option_info* argv_file_scanner::
+ find (const char* a) const
+ {
+ for (std::size_t i (0); i < options_count_; ++i)
+ if (std::strcmp (a, options_[i].option) == 0)
+ return &options_[i];
+
+ return 0;
+ }
+
+ void argv_file_scanner::
+ load (const std::string& file)
+ {
+ using namespace std;
+
+ ifstream is (file.c_str ());
+
+ if (!is.is_open ())
+ throw file_io_failure (file);
+
+ files_.push_back (file);
+
+ arg a;
+ a.file = &*files_.rbegin ();
+
+ for (a.line = 1; !is.eof (); ++a.line)
+ {
+ string line;
+ getline (is, line);
+
+ if (is.fail () && !is.eof ())
+ throw file_io_failure (file);
+
+ string::size_type n (line.size ());
+
+ // Trim the line from leading and trailing whitespaces.
+ //
+ if (n != 0)
+ {
+ const char* f (line.c_str ());
+ const char* l (f + n);
+
+ const char* of (f);
+ while (f < l && (*f == ' ' || *f == '\t' || *f == '\r'))
+ ++f;
+
+ --l;
+
+ const char* ol (l);
+ while (l > f && (*l == ' ' || *l == '\t' || *l == '\r'))
+ --l;
+
+ if (f != of || l != ol)
+ line = f <= l ? string (f, l - f + 1) : string ();
+ }
+
+ // Ignore empty lines, those that start with #.
+ //
+ if (line.empty () || line[0] == '#')
+ continue;
+
+ string::size_type p (string::npos);
+ if (line.compare (0, 1, "-") == 0)
+ {
+ p = line.find (' ');
+
+ string::size_type q (line.find ('='));
+ if (q != string::npos && q < p)
+ p = q;
+ }
+
+ string s1;
+ if (p != string::npos)
+ {
+ s1.assign (line, 0, p);
+
+ // Skip leading whitespaces in the argument.
+ //
+ if (line[p] == '=')
+ ++p;
+ else
+ {
+ n = line.size ();
+ for (++p; p < n; ++p)
+ {
+ char c (line[p]);
+ if (c != ' ' && c != '\t' && c != '\r')
+ break;
+ }
+ }
+ }
+ else if (!skip_)
+ skip_ = (line == "--");
+
+ string s2 (line, p != string::npos ? p : 0);
+
+ // If the string (which is an option value or argument) is
+ // wrapped in quotes, remove them.
+ //
+ n = s2.size ();
+ char cf (s2[0]), cl (s2[n - 1]);
+
+ if (cf == '"' || cf == '\'' || cl == '"' || cl == '\'')
+ {
+ if (n == 1 || cf != cl)
+ throw unmatched_quote (s2);
+
+ s2 = string (s2, 1, n - 2);
+ }
+
+ if (!s1.empty ())
+ {
+ // See if this is another file option.
+ //
+ const option_info* oi;
+ if (!skip_ && (oi = find (s1.c_str ())))
+ {
+ if (s2.empty ())
+ throw missing_value (oi->option);
+
+ if (oi->search_func != 0)
+ {
+ std::string f (oi->search_func (s2.c_str (), oi->arg));
+ if (!f.empty ())
+ load (f);
+ }
+ else
+ load (s2);
+
+ continue;
+ }
+
+ a.value = s1;
+ args_.push_back (a);
+ }
+
+ a.value = s2;
+ args_.push_back (a);
+ }
+ }
+
+ // group_scanner
+ //
+ bool group_scanner::
+ more ()
+ {
+ // We don't want to call scan_group() here since that
+ // would invalidate references to previous arguments.
+ // But we do need to check that the previous group was
+ // handled.
+ //
+ if (state_ == scanned)
+ {
+ if (group_scan_.end () != group_.size ())
+ throw unexpected_group (arg_[i_], group_scan_.next ());
+ }
+
+ return scan_.more ();
+ }
+
+ const char* group_scanner::
+ peek ()
+ {
+ if (state_ != peeked)
+ scan_group (peeked);
+ scan_.peek ();
+ // Return unescaped.
+ return arg_[i_].c_str ();
+ }
+
+ const char* group_scanner::
+ next ()
+ {
+ if (state_ != peeked)
+ scan_group (peeked);
+ scan_.next ();
+ scan_group (scanned);
+ // Return unescaped.
+ return arg_[i_].c_str ();
+ }
+
+ void group_scanner::
+ skip ()
+ {
+ if (state_ != peeked)
+ scan_group (peeked);
+ scan_.skip ();
+ scan_group (skipped);
+ }
+
+ void group_scanner::
+ scan_group (state st)
+ {
+ // If the previous argument has been scanned, then make
+ // sure the group has been scanned (handled) as well.
+ //
+ if (state_ == scanned)
+ {
+ if (group_scan_.end () != group_.size ())
+ throw unexpected_group (arg_[i_], group_scan_.next ());
+ }
+
+ if (state_ != peeked)
+ {
+ arg_[i_ == 0 ? ++i_ : --i_].clear ();
+ group_.clear ();
+ group_scan_.reset ();
+ }
+
+ // We recognize all group sequences both before and
+ // after the argument and diagnose any misuse. We may
+ // also have multiple groups:
+ //
+ // { -x }+ { -y }+ arg
+ //
+
+ // Using group_ won't cover empty groups.
+ //
+ bool g (false);
+
+ while (scan_.more ())
+ {
+ const char* a (scan_.peek ());
+ size_t i (*a == '\\' ? 1 : 0);
+ separator s (sense (a + i));
+
+ if (s == none || i != 0)
+ {
+ if (state_ != peeked)
+ arg_[i_] = a + (s != none ? i : 0);
+ break;
+ }
+
+ // Start of a leading group for the next argument.
+ //
+ if (s == open && state_ == peeked)
+ break;
+
+ if (s != (state_ == peeked ? open_plus : open))
+ throw group_separator (a, "");
+
+ g = true;
+
+ // Scan the group until the closing separator.
+ //
+ scan_.next ();
+ s = none;
+ while (s == none && scan_.more ())
+ {
+ a = scan_.next ();
+ i = (*a == '\\' ? 1 : 0);
+ s = sense (a + i);
+
+ if (s == none || i != 0)
+ {
+ group_.push_back (a + (s != none ? i : 0));
+ s = none;
+ }
+ }
+
+ if (s != (state_ == peeked ? close : close_plus))
+ {
+ throw group_separator ((s != none ? a : ""),
+ (state_ == peeked ? "}" : "}+"));
+ }
+ }
+
+ // Handle the case where we have seen the leading group
+ // but there are no more arguments.
+ //
+ if (g && state_ != peeked && !scan_.more ())
+ throw group_separator ("{", "");
+
+ state_ = st;
+ }
+
+ template <typename X>
+ struct parser
+ {
+ static void
+ parse (X& x, bool& xs, scanner& s)
+ {
+ using namespace std;
+
+ const char* o (s.next ());
+ if (s.more ())
+ {
+ string v (s.next ());
+ istringstream is (v);
+ if (!(is >> x && is.peek () == istringstream::traits_type::eof ()))
+ throw invalid_value (o, v);
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (X& b, const X& a)
+ {
+ b = a;
+ }
+ };
+
+ template <>
+ struct parser<bool>
+ {
+ static void
+ parse (bool& x, scanner& s)
+ {
+ s.next ();
+ x = true;
+ }
+
+ static void
+ merge (bool& b, const bool&)
+ {
+ b = true;
+ }
+ };
+
+ template <>
+ struct parser<std::string>
+ {
+ static void
+ parse (std::string& x, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ x = s.next ();
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (std::string& b, const std::string& a)
+ {
+ b = a;
+ }
+ };
+
+ template <typename X>
+ struct parser<std::vector<X> >
+ {
+ static void
+ parse (std::vector<X>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.push_back (x);
+ xs = true;
+ }
+
+ static void
+ merge (std::vector<X>& b, const std::vector<X>& a)
+ {
+ b.insert (b.end (), a.begin (), a.end ());
+ }
+ };
+
+ template <typename X>
+ struct parser<std::set<X> >
+ {
+ static void
+ parse (std::set<X>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.insert (x);
+ xs = true;
+ }
+
+ static void
+ merge (std::set<X>& b, const std::set<X>& a)
+ {
+ b.insert (a.begin (), a.end ());
+ }
+ };
+
+ template <typename K, typename V>
+ struct parser<std::map<K, V> >
+ {
+ static void
+ parse (std::map<K, V>& m, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ std::string ov (s.next ());
+ std::string::size_type p = ov.find ('=');
+
+ K k = K ();
+ V v = V ();
+ std::string kstr (ov, 0, p);
+ std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (o),
+ 0
+ };
+
+ bool dummy;
+ if (!kstr.empty ())
+ {
+ av[1] = const_cast<char*> (kstr.c_str ());
+ argv_scanner s (0, ac, av);
+ parser<K>::parse (k, dummy, s);
+ }
+
+ if (!vstr.empty ())
+ {
+ av[1] = const_cast<char*> (vstr.c_str ());
+ argv_scanner s (0, ac, av);
+ parser<V>::parse (v, dummy, s);
+ }
+
+ m[k] = v;
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (std::map<K, V>& b, const std::map<K, V>& a)
+ {
+ for (typename std::map<K, V>::const_iterator i (a.begin ());
+ i != a.end ();
+ ++i)
+ b[i->first] = i->second;
+ }
+ };
+
+ template <typename X, typename T, T X::*M>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, s);
+ }
+
+ template <typename X, typename T, T X::*M, bool X::*S>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, x.*S, s);
+ }
+ }
+}
+
+#include <map>
+#include <cstring>
+
+namespace bpkg
+{
+ // common_options
+ //
+
+ common_options::
+ common_options ()
+ : v_ (),
+ V_ (),
+ quiet_ (),
+ verbose_ (1),
+ verbose_specified_ (false),
+ jobs_ (),
+ jobs_specified_ (false),
+ no_result_ (),
+ no_progress_ (),
+ build_ (),
+ build_specified_ (false),
+ build_option_ (),
+ build_option_specified_ (false),
+ fetch_ (),
+ fetch_specified_ (false),
+ fetch_option_ (),
+ fetch_option_specified_ (false),
+ fetch_timeout_ (),
+ fetch_timeout_specified_ (false),
+ pkg_proxy_ (),
+ pkg_proxy_specified_ (false),
+ git_ ("git"),
+ git_specified_ (false),
+ git_option_ (),
+ git_option_specified_ (false),
+ sha256_ (),
+ sha256_specified_ (false),
+ sha256_option_ (),
+ sha256_option_specified_ (false),
+ tar_ (),
+ tar_specified_ (false),
+ tar_option_ (),
+ tar_option_specified_ (false),
+ openssl_ ("openssl"),
+ openssl_specified_ (false),
+ openssl_option_ (),
+ openssl_option_specified_ (false),
+ auth_ (bpkg::auth::remote),
+ auth_specified_ (false),
+ trust_ (),
+ trust_specified_ (false),
+ trust_yes_ (),
+ trust_no_ (),
+ pager_ (),
+ pager_specified_ (false),
+ pager_option_ (),
+ pager_option_specified_ (false),
+ options_file_ (),
+ options_file_specified_ (false),
+ default_options_ (),
+ default_options_specified_ (false),
+ no_default_options_ ()
+ {
+ }
+
+ void common_options::
+ merge (const common_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ if (a.v_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->v_, a.v_);
+ }
+
+ if (a.V_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->V_, a.V_);
+ }
+
+ if (a.quiet_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->quiet_, a.quiet_);
+ }
+
+ if (a.verbose_specified_)
+ {
+ ::bpkg::cli::parser< uint16_t>::merge (
+ this->verbose_, a.verbose_);
+ this->verbose_specified_ = true;
+ }
+
+ if (a.jobs_specified_)
+ {
+ ::bpkg::cli::parser< size_t>::merge (
+ this->jobs_, a.jobs_);
+ this->jobs_specified_ = true;
+ }
+
+ if (a.no_result_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_result_, a.no_result_);
+ }
+
+ if (a.no_progress_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_progress_, a.no_progress_);
+ }
+
+ if (a.build_specified_)
+ {
+ ::bpkg::cli::parser< path>::merge (
+ this->build_, a.build_);
+ this->build_specified_ = true;
+ }
+
+ if (a.build_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->build_option_, a.build_option_);
+ this->build_option_specified_ = true;
+ }
+
+ if (a.fetch_specified_)
+ {
+ ::bpkg::cli::parser< path>::merge (
+ this->fetch_, a.fetch_);
+ this->fetch_specified_ = true;
+ }
+
+ if (a.fetch_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->fetch_option_, a.fetch_option_);
+ this->fetch_option_specified_ = true;
+ }
+
+ if (a.fetch_timeout_specified_)
+ {
+ ::bpkg::cli::parser< size_t>::merge (
+ this->fetch_timeout_, a.fetch_timeout_);
+ this->fetch_timeout_specified_ = true;
+ }
+
+ if (a.pkg_proxy_specified_)
+ {
+ ::bpkg::cli::parser< butl::url>::merge (
+ this->pkg_proxy_, a.pkg_proxy_);
+ this->pkg_proxy_specified_ = true;
+ }
+
+ if (a.git_specified_)
+ {
+ ::bpkg::cli::parser< path>::merge (
+ this->git_, a.git_);
+ this->git_specified_ = true;
+ }
+
+ if (a.git_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->git_option_, a.git_option_);
+ this->git_option_specified_ = true;
+ }
+
+ if (a.sha256_specified_)
+ {
+ ::bpkg::cli::parser< path>::merge (
+ this->sha256_, a.sha256_);
+ this->sha256_specified_ = true;
+ }
+
+ if (a.sha256_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->sha256_option_, a.sha256_option_);
+ this->sha256_option_specified_ = true;
+ }
+
+ if (a.tar_specified_)
+ {
+ ::bpkg::cli::parser< path>::merge (
+ this->tar_, a.tar_);
+ this->tar_specified_ = true;
+ }
+
+ if (a.tar_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->tar_option_, a.tar_option_);
+ this->tar_option_specified_ = true;
+ }
+
+ if (a.openssl_specified_)
+ {
+ ::bpkg::cli::parser< qualified_option<openssl_commands, path>>::merge (
+ this->openssl_, a.openssl_);
+ this->openssl_specified_ = true;
+ }
+
+ if (a.openssl_option_specified_)
+ {
+ ::bpkg::cli::parser< qualified_option<openssl_commands, strings>>::merge (
+ this->openssl_option_, a.openssl_option_);
+ this->openssl_option_specified_ = true;
+ }
+
+ if (a.auth_specified_)
+ {
+ ::bpkg::cli::parser< bpkg::auth>::merge (
+ this->auth_, a.auth_);
+ this->auth_specified_ = true;
+ }
+
+ if (a.trust_specified_)
+ {
+ ::bpkg::cli::parser< std::set<string>>::merge (
+ this->trust_, a.trust_);
+ this->trust_specified_ = true;
+ }
+
+ if (a.trust_yes_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->trust_yes_, a.trust_yes_);
+ }
+
+ if (a.trust_no_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->trust_no_, a.trust_no_);
+ }
+
+ if (a.pager_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->pager_, a.pager_);
+ this->pager_specified_ = true;
+ }
+
+ if (a.pager_option_specified_)
+ {
+ ::bpkg::cli::parser< strings>::merge (
+ this->pager_option_, a.pager_option_);
+ this->pager_option_specified_ = true;
+ }
+
+ if (a.options_file_specified_)
+ {
+ ::bpkg::cli::parser< string>::merge (
+ this->options_file_, a.options_file_);
+ this->options_file_specified_ = true;
+ }
+
+ if (a.default_options_specified_)
+ {
+ ::bpkg::cli::parser< dir_path>::merge (
+ this->default_options_, a.default_options_);
+ this->default_options_specified_ = true;
+ }
+
+ if (a.no_default_options_)
+ {
+ ::bpkg::cli::parser< bool>::merge (
+ this->no_default_options_, a.no_default_options_);
+ }
+ }
+
+ ::bpkg::cli::usage_para common_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mCOMMON OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "The common options are summarized below with a more detailed description" << ::std::endl
+ << "available in \033[1mbpkg-common-options(1)\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m-v\033[0m Print essential underlying commands being executed." << ::std::endl;
+
+ os << "\033[1m-V\033[0m Print all underlying commands being executed." << ::std::endl;
+
+ os << "\033[1m--quiet\033[0m|\033[1m-q\033[0m Run quietly, only printing error messages." << ::std::endl;
+
+ os << "\033[1m--verbose\033[0m \033[4mlevel\033[0m Set the diagnostics verbosity to \033[4mlevel\033[0m between 0 and" << ::std::endl
+ << " 6." << ::std::endl;
+
+ os << "\033[1m--jobs\033[0m|\033[1m-j\033[0m \033[4mnum\033[0m Number of jobs to perform in parallel." << ::std::endl;
+
+ os << "\033[1m--no-result\033[0m Don't print informational messages about the outcome" << ::std::endl
+ << " of performing a command." << ::std::endl;
+
+ os << "\033[1m--no-progress\033[0m Suppress progress indicators for long-lasting" << ::std::endl
+ << " operations, such as network transfers, building, etc." << ::std::endl;
+
+ os << "\033[1m--build\033[0m \033[4mpath\033[0m The build program to be used to build packages." << ::std::endl;
+
+ os << "\033[1m--build-option\033[0m \033[4mopt\033[0m Additional option to be passed to the build program." << ::std::endl;
+
+ os << "\033[1m--fetch\033[0m \033[4mpath\033[0m The fetch program to be used to download resources." << ::std::endl;
+
+ os << "\033[1m--fetch-option\033[0m \033[4mopt\033[0m Additional option to be passed to the fetch program." << ::std::endl;
+
+ os << "\033[1m--fetch-timeout\033[0m \033[4msec\033[0m The fetch and fetch-like (for example, \033[1mgit\033[0m) program" << ::std::endl
+ << " timeout." << ::std::endl;
+
+ os << "\033[1m--pkg-proxy\033[0m \033[4murl\033[0m HTTP proxy server to use when fetching package" << ::std::endl
+ << " manifests and archives from remote \033[1mpkg\033[0m repositories." << ::std::endl;
+
+ os << "\033[1m--git\033[0m \033[4mpath\033[0m The git program to be used to fetch git repositories." << ::std::endl;
+
+ os << "\033[1m--git-option\033[0m \033[4mopt\033[0m Additional common option to be passed to the git" << ::std::endl
+ << " program." << ::std::endl;
+
+ os << "\033[1m--sha256\033[0m \033[4mpath\033[0m The sha256 program to be used to calculate SHA256" << ::std::endl
+ << " sums." << ::std::endl;
+
+ os << "\033[1m--sha256-option\033[0m \033[4mopt\033[0m Additional option to be passed to the sha256 program." << ::std::endl;
+
+ os << "\033[1m--tar\033[0m \033[4mpath\033[0m The tar program to be used to extract package" << ::std::endl
+ << " archives." << ::std::endl;
+
+ os << "\033[1m--tar-option\033[0m \033[4mopt\033[0m Additional option to be passed to the tar program." << ::std::endl;
+
+ os << "\033[1m--openssl\033[0m \033[4mpath\033[0m The openssl program to be used for crypto operations." << ::std::endl;
+
+ os << "\033[1m--openssl-option\033[0m \033[4mopt\033[0m Additional option to be passed to the openssl program." << ::std::endl;
+
+ os << "\033[1m--auth\033[0m \033[4mtype\033[0m Types of repositories to authenticate." << ::std::endl;
+
+ os << "\033[1m--trust\033[0m \033[4mfingerprint\033[0m Trust repository certificate with a SHA256" << ::std::endl
+ << " \033[4mfingerprint\033[0m." << ::std::endl;
+
+ os << "\033[1m--trust-yes\033[0m Assume the answer to all authentication prompts is" << ::std::endl
+ << " \033[1myes\033[0m." << ::std::endl;
+
+ os << "\033[1m--trust-no\033[0m Assume the answer to all authentication prompts is \033[1mno\033[0m." << ::std::endl;
+
+ os << "\033[1m--pager\033[0m \033[4mpath\033[0m The pager program to be used to show long text." << ::std::endl;
+
+ os << "\033[1m--pager-option\033[0m \033[4mopt\033[0m Additional option to be passed to the pager program." << ::std::endl;
+
+ os << "\033[1m--options-file\033[0m \033[4mfile\033[0m Read additional options from \033[4mfile\033[0m." << ::std::endl;
+
+ os << "\033[1m--default-options\033[0m \033[4mdir\033[0m The directory to load additional default options files" << ::std::endl
+ << " from." << ::std::endl;
+
+ os << "\033[1m--no-default-options\033[0m Don't load default options files." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ return p;
+ }
+
+ ::bpkg::cli::usage_para common_options::
+ print_long_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mCOMMON OPTIONS\033[0m" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m-v\033[0m Print essential underlying commands being executed." << ::std::endl
+ << " This is equivalent to \033[1m--verbose 2\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m-V\033[0m Print all underlying commands being executed. This is" << ::std::endl
+ << " equivalent to \033[1m--verbose 3\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--quiet\033[0m|\033[1m-q\033[0m Run quietly, only printing error messages. This is" << ::std::endl
+ << " equivalent to \033[1m--verbose 0\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--verbose\033[0m \033[4mlevel\033[0m Set the diagnostics verbosity to \033[4mlevel\033[0m between 0 and" << ::std::endl
+ << " 6. Level 0 disables any non-error messages while level" << ::std::endl
+ << " 6 produces lots of information, with level 1 being the" << ::std::endl
+ << " default. The following additional types of diagnostics" << ::std::endl
+ << " are produced at each level:" << ::std::endl
+ << ::std::endl
+ << " 1. High-level information messages." << ::std::endl
+ << " 2. Essential underlying commands being executed." << ::std::endl
+ << " 3. All underlying commands being executed." << ::std::endl
+ << " 4. Information that could be helpful to the user." << ::std::endl
+ << " 5. Information that could be helpful to the developer." << ::std::endl
+ << " 6. Even more detailed information." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--jobs\033[0m|\033[1m-j\033[0m \033[4mnum\033[0m Number of jobs to perform in parallel. If this option" << ::std::endl
+ << " is not specified or specified with the 0\033[0m value, then" << ::std::endl
+ << " the number of available hardware threads is used. This" << ::std::endl
+ << " option is also propagated when performing build system" << ::std::endl
+ << " operations such as \033[1mupdate\033[0m, \033[1mtest\033[0m, etc." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-result\033[0m Don't print informational messages about the outcome" << ::std::endl
+ << " of performing a command." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-progress\033[0m Suppress progress indicators for long-lasting" << ::std::endl
+ << " operations, such as network transfers, building, etc." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--build\033[0m \033[4mpath\033[0m The build program to be used to build packages. This" << ::std::endl
+ << " should be the path to the build2 \033[1mb\033[0m executable. You can" << ::std::endl
+ << " also specify additional options that should be passed" << ::std::endl
+ << " to the build program with \033[1m--build-option\033[0m." << ::std::endl
+ << ::std::endl
+ << " If the build program is not explicitly specified, then" << ::std::endl
+ << " \033[1mbpkg\033[0m will by default use \033[1mb\033[0m plus an executable suffix" << ::std::endl
+ << " if one was specified when building \033[1mbpkg\033[0m. So, for" << ::std::endl
+ << " example, if \033[1mbpkg\033[0m name was set to \033[1mbpkg-1.0\033[0m, then it" << ::std::endl
+ << " will look for \033[1mb-1.0\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--build-option\033[0m \033[4mopt\033[0m Additional option to be passed to the build program." << ::std::endl
+ << " See \033[1m--build\033[0m for more information on the build program." << ::std::endl
+ << " Repeat this option to specify multiple build options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fetch\033[0m \033[4mpath\033[0m The fetch program to be used to download resources." << ::std::endl
+ << " Currently, \033[1mbpkg\033[0m recognizes \033[1mcurl\033[0m, \033[1mwget\033[0m, and \033[1mfetch\033[0m. Note" << ::std::endl
+ << " that the last component of \033[4mpath\033[0m must contain one of" << ::std::endl
+ << " these names as a substring in order for \033[1mbpkg\033[0m to" << ::std::endl
+ << " recognize which program is being used. You can also" << ::std::endl
+ << " specify additional options that should be passed to" << ::std::endl
+ << " the fetch program with \033[1m--fetch-option\033[0m." << ::std::endl
+ << ::std::endl
+ << " If the fetch program is not specified, then \033[1mbpkg\033[0m will" << ::std::endl
+ << " try to discover if one of the above programs is" << ::std::endl
+ << " available and use that. Currently, \033[1mbpkg\033[0m has the" << ::std::endl
+ << " following preference order: \033[1mwget\033[0m 1.16 or higher" << ::std::endl
+ << " (supports \033[1m--show-progress\033[0m), \033[1mcurl\033[0m, \033[1mwget\033[0m, and \033[1mfetch\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fetch-option\033[0m \033[4mopt\033[0m Additional option to be passed to the fetch program." << ::std::endl
+ << " See \033[1m--fetch\033[0m for more information on the fetch program." << ::std::endl
+ << " Repeat this option to specify multiple fetch options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--fetch-timeout\033[0m \033[4msec\033[0m The fetch and fetch-like (for example, \033[1mgit\033[0m) program" << ::std::endl
+ << " timeout. While the exact semantics of the value" << ::std::endl
+ << " depends on the program used, at a minimum it specifies" << ::std::endl
+ << " in seconds the maximum time that can be spent without" << ::std::endl
+ << " any network activity." << ::std::endl
+ << ::std::endl
+ << " Specifically, it is translated to the \033[1m--max-time\033[0m" << ::std::endl
+ << " option for \033[1mcurl\033[0m and to the \033[1m--timeout\033[0m option for \033[1mwget\033[0m" << ::std::endl
+ << " and \033[1mfetch\033[0m. For \033[1mgit\033[0m over HTTP/HTTPS this semantics is" << ::std::endl
+ << " achieved using the \033[1mhttp.lowSpeedLimit\033[0m=\033[4m1\033[0m" << ::std::endl
+ << " \033[1mhttp.lowSpeedTime\033[0m=\033[4msec\033[0m configuration values (the" << ::std::endl
+ << " \033[1mgit://\033[0m and \033[1mssh://\033[0m protocols currently do not support" << ::std::endl
+ << " timeouts)." << ::std::endl
+ << ::std::endl
+ << " See \033[1m--fetch\033[0m and \033[1m--git\033[0m for more information on the" << ::std::endl
+ << " fetch programs." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--pkg-proxy\033[0m \033[4murl\033[0m HTTP proxy server to use when fetching package" << ::std::endl
+ << " manifests and archives from remote \033[1mpkg\033[0m repositories." << ::std::endl
+ << " If specified, the proxy \033[4murl\033[0m must be in the" << ::std::endl
+ << " \033[1mhttp://\033[0m\033[4mhost\033[0m[\033[1m:\033[0m\033[4mport\033[0m]\033[0m form. If \033[4mport\033[0m is omitted, 80 is" << ::std::endl
+ << " used by default." << ::std::endl
+ << ::std::endl
+ << " Note that to allow caching, the proxied \033[1mhttps://\033[0m URLs" << ::std::endl
+ << " are converted to \033[1mhttp://\033[0m in order to prevent the fetch" << ::std::endl
+ << " program from tunneling (which is the standard approach" << ::std::endl
+ << " for proxying HTTPS). If both HTTP and HTTPS" << ::std::endl
+ << " repositories are used, it is assumed that the proxy" << ::std::endl
+ << " server can figure out which URLs need to be converted" << ::std::endl
+ << " back to \033[1mhttps://\033[0m based on the request information (for" << ::std::endl
+ << " example, host name). For security, this mechanism" << ::std::endl
+ << " should only be used with signed repositories or when" << ::std::endl
+ << " the proxy is located inside a trusted network." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--git\033[0m \033[4mpath\033[0m The git program to be used to fetch git repositories." << ::std::endl
+ << " You can also specify additional options that should be" << ::std::endl
+ << " passed to the git program with \033[1m--git-option\033[0m." << ::std::endl
+ << ::std::endl
+ << " If the git program is not explicitly specified, then" << ::std::endl
+ << " \033[1mbpkg\033[0m will use \033[1mgit\033[0m by default." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--git-option\033[0m \033[4mopt\033[0m Additional common option to be passed to the git" << ::std::endl
+ << " program. Note that the common options are the ones" << ::std::endl
+ << " that precede the \033[1mgit\033[0m command. See \033[1m--git\033[0m for more" << ::std::endl
+ << " information on the git program. Repeat this option to" << ::std::endl
+ << " specify multiple git options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--sha256\033[0m \033[4mpath\033[0m The sha256 program to be used to calculate SHA256" << ::std::endl
+ << " sums. Currently, \033[1mbpkg\033[0m recognizes \033[1msha256\033[0m, \033[1msha256sum\033[0m," << ::std::endl
+ << " and \033[1mshasum\033[0m. Note that the last component of \033[4mpath\033[0m must" << ::std::endl
+ << " contain one of these names as a substring in order for" << ::std::endl
+ << " \033[1mbpkg\033[0m to recognize which program is being used. You can" << ::std::endl
+ << " also specify additional options that should be passed" << ::std::endl
+ << " to the sha256 program with \033[1m--sha256-option\033[0m." << ::std::endl
+ << ::std::endl
+ << " If the sha256 program is not specified, then \033[1mbpkg\033[0m will" << ::std::endl
+ << " try to discover if one of the above programs is" << ::std::endl
+ << " available and use that. Currently, \033[1mbpkg\033[0m has the" << ::std::endl
+ << " following preference order: \033[1msha256\033[0m, \033[1msha256sum\033[0m, and" << ::std::endl
+ << " \033[1mshasum\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--sha256-option\033[0m \033[4mopt\033[0m Additional option to be passed to the sha256 program." << ::std::endl
+ << " See \033[1m--sha256\033[0m for more information on the sha256" << ::std::endl
+ << " program. Repeat this option to specify multiple sha256" << ::std::endl
+ << " options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--tar\033[0m \033[4mpath\033[0m The tar program to be used to extract package" << ::std::endl
+ << " archives. For example, \033[1mgtar\033[0m or \033[1mbsdtar\033[0m. You can also" << ::std::endl
+ << " specify additional options that should be passed to" << ::std::endl
+ << " the tar program with \033[1m--tar-option\033[0m. If the tar program" << ::std::endl
+ << " is not explicitly specified, then \033[1mbpkg\033[0m will use \033[1mtar\033[0m by" << ::std::endl
+ << " default." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--tar-option\033[0m \033[4mopt\033[0m Additional option to be passed to the tar program. See" << ::std::endl
+ << " \033[1m--tar\033[0m for more information on the tar program. Repeat" << ::std::endl
+ << " this option to specify multiple tar options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--openssl\033[0m \033[4mpath\033[0m The openssl program to be used for crypto operations." << ::std::endl
+ << " You can also specify additional options that should be" << ::std::endl
+ << " passed to the openssl program with \033[1m--openssl-option\033[0m." << ::std::endl
+ << " If the openssl program is not explicitly specified," << ::std::endl
+ << " then \033[1mbpkg\033[0m will use \033[1mopenssl\033[0m by default." << ::std::endl
+ << ::std::endl
+ << " The \033[1m--openssl*\033[0m values can be optionally qualified with" << ::std::endl
+ << " the openssl command in the \033[4mcommand\033[0m\033[1m:\033[0m\033[4mvalue\033[0m\033[0m form. This" << ::std::endl
+ << " makes the value only applicable to the specific" << ::std::endl
+ << " command, for example:" << ::std::endl
+ << ::std::endl
+ << " bpkg rep-create \\" << ::std::endl
+ << " --openssl rsautl:/path/to/openssl \\" << ::std::endl
+ << " --openssl-option rsautl:-engine \\" << ::std::endl
+ << " --openssl-option rsautl:pkcs11 \\" << ::std::endl
+ << " ..." << ::std::endl
+ << ::std::endl
+ << " An unqualified value that contains a colon can be" << ::std::endl
+ << " specified as qualified with an empty command, for" << ::std::endl
+ << " example, \033[1m--openssl :C:\\bin\\openssl\033[0m. To see openssl" << ::std::endl
+ << " commands executed by \033[1mbpkg\033[0m, use the verbose mode (\033[1m-v\033[0m" << ::std::endl
+ << " option)." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--openssl-option\033[0m \033[4mopt\033[0m Additional option to be passed to the openssl program." << ::std::endl
+ << " See \033[1m--openssl\033[0m for more information on the openssl" << ::std::endl
+ << " program. The values can be optionally qualified with" << ::std::endl
+ << " the openssl command, as discussed in \033[1m--openssl\033[0m. Repeat" << ::std::endl
+ << " this option to specify multiple openssl options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--auth\033[0m \033[4mtype\033[0m Types of repositories to authenticate. Valid values" << ::std::endl
+ << " for this option are \033[1mnone\033[0m, \033[1mremote\033[0m, \033[1mall\033[0m. By default only" << ::std::endl
+ << " remote repositories are authenticated. You can request" << ::std::endl
+ << " authentication of local repositories by passing \033[1mall\033[0m or" << ::std::endl
+ << " disable authentication completely by passing \033[1mnone\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--trust\033[0m \033[4mfingerprint\033[0m Trust repository certificate with a SHA256" << ::std::endl
+ << " \033[4mfingerprint\033[0m. Such a certificate is trusted" << ::std::endl
+ << " automatically, without prompting the user for a" << ::std::endl
+ << " confirmation. Repeat this option to trust multiple" << ::std::endl
+ << " certificates." << ::std::endl
+ << ::std::endl
+ << " Note that by default \033[1mopenssl\033[0m prints a SHA1 fingerprint" << ::std::endl
+ << " and to obtain a SHA256 one you will need to pass the" << ::std::endl
+ << " \033[1m-sha256\033[0m option, for example:" << ::std::endl
+ << ::std::endl
+ << " openssl x509 -sha256 -fingerprint -noout -in cert.pem" << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--trust-yes\033[0m Assume the answer to all authentication prompts is" << ::std::endl
+ << " \033[1myes\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--trust-no\033[0m Assume the answer to all authentication prompts is \033[1mno\033[0m." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--pager\033[0m \033[4mpath\033[0m The pager program to be used to show long text." << ::std::endl
+ << " Commonly used pager programs are \033[1mless\033[0m and \033[1mmore\033[0m. You" << ::std::endl
+ << " can also specify additional options that should be" << ::std::endl
+ << " passed to the pager program with \033[1m--pager-option\033[0m. If an" << ::std::endl
+ << " empty string is specified as the pager program, then" << ::std::endl
+ << " no pager will be used. If the pager program is not" << ::std::endl
+ << " explicitly specified, then \033[1mbpkg\033[0m will try to use \033[1mless\033[0m." << ::std::endl
+ << " If it is not available, then no pager will be used." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--pager-option\033[0m \033[4mopt\033[0m Additional option to be passed to the pager program." << ::std::endl
+ << " See \033[1m--pager\033[0m for more information on the pager program." << ::std::endl
+ << " Repeat this option to specify multiple pager options." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--options-file\033[0m \033[4mfile\033[0m Read additional options from \033[4mfile\033[0m. Each option should" << ::std::endl
+ << " appear on a separate line optionally followed by space" << ::std::endl
+ << " or equal sign (\033[1m=\033[0m) and an option value. Empty lines and" << ::std::endl
+ << " lines starting with \033[1m#\033[0m are ignored. Option values can" << ::std::endl
+ << " be enclosed in double (\033[1m\"\033[0m) or single (\033[1m'\033[0m) quotes to" << ::std::endl
+ << " preserve leading and trailing whitespaces as well as" << ::std::endl
+ << " to specify empty values. If the value itself contains" << ::std::endl
+ << " trailing or leading quotes, enclose it with an extra" << ::std::endl
+ << " pair of quotes, for example \033[1m'\"x\"'\033[0m. Non-leading and" << ::std::endl
+ << " non-trailing quotes are interpreted as being part of" << ::std::endl
+ << " the option value." << ::std::endl
+ << ::std::endl
+ << " The semantics of providing options in a file is" << ::std::endl
+ << " equivalent to providing the same set of options in the" << ::std::endl
+ << " same order on the command line at the point where the" << ::std::endl
+ << " \033[1m--options-file\033[0m option is specified except that the" << ::std::endl
+ << " shell escaping and quoting is not required. Repeat" << ::std::endl
+ << " this option to specify more than one options file." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--default-options\033[0m \033[4mdir\033[0m The directory to load additional default options files" << ::std::endl
+ << " from." << ::std::endl;
+
+ os << std::endl
+ << "\033[1m--no-default-options\033[0m Don't load default options files." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (common_options&, ::bpkg::cli::scanner&)>
+ _cli_common_options_map;
+
+ static _cli_common_options_map _cli_common_options_map_;
+
+ struct _cli_common_options_map_init
+ {
+ _cli_common_options_map_init ()
+ {
+ _cli_common_options_map_["-v"] =
+ &::bpkg::cli::thunk< common_options, bool, &common_options::v_ >;
+ _cli_common_options_map_["-V"] =
+ &::bpkg::cli::thunk< common_options, bool, &common_options::V_ >;
+ _cli_common_options_map_["--quiet"] =
+ &::bpkg::cli::thunk< common_options, bool, &common_options::quiet_ >;
+ _cli_common_options_map_["-q"] =
+ &::bpkg::cli::thunk< common_options, bool, &common_options::quiet_ >;
+ _cli_common_options_map_["--verbose"] =
+ &::bpkg::cli::thunk< common_options, uint16_t, &common_options::verbose_,
+ &common_options::verbose_specified_ >;
+ _cli_common_options_map_["--jobs"] =
+ &::bpkg::cli::thunk< common_options, size_t, &common_options::jobs_,
+ &common_options::jobs_specified_ >;
+ _cli_common_options_map_["-j"] =
+ &::bpkg::cli::thunk< common_options, size_t, &common_options::jobs_,
+ &common_options::jobs_specified_ >;
+ _cli_common_options_map_["--no-result"] =
+ &::bpkg::cli::thunk< common_options, bool, &common_options::no_result_ >;
+ _cli_common_options_map_["--no-progress"] =
+ &::bpkg::cli::thunk< common_options, bool, &common_options::no_progress_ >;
+ _cli_common_options_map_["--build"] =
+ &::bpkg::cli::thunk< common_options, path, &common_options::build_,
+ &common_options::build_specified_ >;
+ _cli_common_options_map_["--build-option"] =
+ &::bpkg::cli::thunk< common_options, strings, &common_options::build_option_,
+ &common_options::build_option_specified_ >;
+ _cli_common_options_map_["--fetch"] =
+ &::bpkg::cli::thunk< common_options, path, &common_options::fetch_,
+ &common_options::fetch_specified_ >;
+ _cli_common_options_map_["--fetch-option"] =
+ &::bpkg::cli::thunk< common_options, strings, &common_options::fetch_option_,
+ &common_options::fetch_option_specified_ >;
+ _cli_common_options_map_["--fetch-timeout"] =
+ &::bpkg::cli::thunk< common_options, size_t, &common_options::fetch_timeout_,
+ &common_options::fetch_timeout_specified_ >;
+ _cli_common_options_map_["--pkg-proxy"] =
+ &::bpkg::cli::thunk< common_options, butl::url, &common_options::pkg_proxy_,
+ &common_options::pkg_proxy_specified_ >;
+ _cli_common_options_map_["--git"] =
+ &::bpkg::cli::thunk< common_options, path, &common_options::git_,
+ &common_options::git_specified_ >;
+ _cli_common_options_map_["--git-option"] =
+ &::bpkg::cli::thunk< common_options, strings, &common_options::git_option_,
+ &common_options::git_option_specified_ >;
+ _cli_common_options_map_["--sha256"] =
+ &::bpkg::cli::thunk< common_options, path, &common_options::sha256_,
+ &common_options::sha256_specified_ >;
+ _cli_common_options_map_["--sha256-option"] =
+ &::bpkg::cli::thunk< common_options, strings, &common_options::sha256_option_,
+ &common_options::sha256_option_specified_ >;
+ _cli_common_options_map_["--tar"] =
+ &::bpkg::cli::thunk< common_options, path, &common_options::tar_,
+ &common_options::tar_specified_ >;
+ _cli_common_options_map_["--tar-option"] =
+ &::bpkg::cli::thunk< common_options, strings, &common_options::tar_option_,
+ &common_options::tar_option_specified_ >;
+ _cli_common_options_map_["--openssl"] =
+ &::bpkg::cli::thunk< common_options, qualified_option<openssl_commands, path>, &common_options::openssl_,
+ &common_options::openssl_specified_ >;
+ _cli_common_options_map_["--openssl-option"] =
+ &::bpkg::cli::thunk< common_options, qualified_option<openssl_commands, strings>, &common_options::openssl_option_,
+ &common_options::openssl_option_specified_ >;
+ _cli_common_options_map_["--auth"] =
+ &::bpkg::cli::thunk< common_options, bpkg::auth, &common_options::auth_,
+ &common_options::auth_specified_ >;
+ _cli_common_options_map_["--trust"] =
+ &::bpkg::cli::thunk< common_options, std::set<string>, &common_options::trust_,
+ &common_options::trust_specified_ >;
+ _cli_common_options_map_["--trust-yes"] =
+ &::bpkg::cli::thunk< common_options, bool, &common_options::trust_yes_ >;
+ _cli_common_options_map_["--trust-no"] =
+ &::bpkg::cli::thunk< common_options, bool, &common_options::trust_no_ >;
+ _cli_common_options_map_["--pager"] =
+ &::bpkg::cli::thunk< common_options, string, &common_options::pager_,
+ &common_options::pager_specified_ >;
+ _cli_common_options_map_["--pager-option"] =
+ &::bpkg::cli::thunk< common_options, strings, &common_options::pager_option_,
+ &common_options::pager_option_specified_ >;
+ _cli_common_options_map_["--options-file"] =
+ &::bpkg::cli::thunk< common_options, string, &common_options::options_file_,
+ &common_options::options_file_specified_ >;
+ _cli_common_options_map_["--default-options"] =
+ &::bpkg::cli::thunk< common_options, dir_path, &common_options::default_options_,
+ &common_options::default_options_specified_ >;
+ _cli_common_options_map_["--no-default-options"] =
+ &::bpkg::cli::thunk< common_options, bool, &common_options::no_default_options_ >;
+ }
+ };
+
+ static _cli_common_options_map_init _cli_common_options_map_init_;
+
+ bool common_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_common_options_map::const_iterator i (_cli_common_options_map_.find (o));
+
+ if (i != _cli_common_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ return false;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_common_options_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg\033[0m [\033[4mcommon-options\033[0m] ...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The common options control behavior that is common to all or most of the \033[1mbpkg\033[0m" << ::std::endl
+ << "commands. They can be specified either before the command or after, together" << ::std::endl
+ << "with the command-specific options." << ::std::endl;
+
+ p = ::bpkg::common_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ return p;
+ }
+
+ ::bpkg::cli::usage_para
+ print_bpkg_common_options_long_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg\033[0m [\033[4mcommon-options\033[0m] ...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "The common options control behavior that is common to all or most of the \033[1mbpkg\033[0m" << ::std::endl
+ << "commands. They can be specified either before the command or after, together" << ::std::endl
+ << "with the command-specific options." << ::std::endl;
+
+ p = ::bpkg::common_options::print_long_usage (os, ::bpkg::cli::usage_para::text);
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/common-options.hxx b/bpkg/common-options.hxx
new file mode 100644
index 0000000..afdd9b4
--- /dev/null
+++ b/bpkg/common-options.hxx
@@ -0,0 +1,822 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_COMMON_OPTIONS_HXX
+#define BPKG_COMMON_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <list>
+#include <deque>
+#include <vector>
+#include <iosfwd>
+#include <string>
+#include <cstddef>
+#include <exception>
+
+#ifndef CLI_POTENTIALLY_UNUSED
+# if defined(_MSC_VER) || defined(__xlC__)
+# define CLI_POTENTIALLY_UNUSED(x) (void*)&x
+# else
+# define CLI_POTENTIALLY_UNUSED(x) (void)x
+# endif
+#endif
+
+namespace bpkg
+{
+ namespace cli
+ {
+ class usage_para
+ {
+ public:
+ enum value
+ {
+ none,
+ text,
+ option
+ };
+
+ usage_para (value);
+
+ operator value () const
+ {
+ return v_;
+ }
+
+ private:
+ value v_;
+ };
+
+ class unknown_mode
+ {
+ public:
+ enum value
+ {
+ skip,
+ stop,
+ fail
+ };
+
+ unknown_mode (value);
+
+ operator value () const
+ {
+ return v_;
+ }
+
+ private:
+ value v_;
+ };
+
+ // Exceptions.
+ //
+
+ class exception: public std::exception
+ {
+ public:
+ virtual void
+ print (::std::ostream&) const = 0;
+ };
+
+ ::std::ostream&
+ operator<< (::std::ostream&, const exception&);
+
+ class unknown_option: public exception
+ {
+ public:
+ virtual
+ ~unknown_option () throw ();
+
+ unknown_option (const std::string& option);
+
+ const std::string&
+ option () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string option_;
+ };
+
+ class unknown_argument: public exception
+ {
+ public:
+ virtual
+ ~unknown_argument () throw ();
+
+ unknown_argument (const std::string& argument);
+
+ const std::string&
+ argument () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string argument_;
+ };
+
+ class missing_value: public exception
+ {
+ public:
+ virtual
+ ~missing_value () throw ();
+
+ missing_value (const std::string& option);
+
+ const std::string&
+ option () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string option_;
+ };
+
+ class invalid_value: public exception
+ {
+ public:
+ virtual
+ ~invalid_value () throw ();
+
+ invalid_value (const std::string& option,
+ const std::string& value,
+ const std::string& message = std::string ());
+
+ const std::string&
+ option () const;
+
+ const std::string&
+ value () const;
+
+ const std::string&
+ message () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string option_;
+ std::string value_;
+ std::string message_;
+ };
+
+ class eos_reached: public exception
+ {
+ public:
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+ };
+
+ class file_io_failure: public exception
+ {
+ public:
+ virtual
+ ~file_io_failure () throw ();
+
+ file_io_failure (const std::string& file);
+
+ const std::string&
+ file () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string file_;
+ };
+
+ class unmatched_quote: public exception
+ {
+ public:
+ virtual
+ ~unmatched_quote () throw ();
+
+ unmatched_quote (const std::string& argument);
+
+ const std::string&
+ argument () const;
+
+ virtual void
+ print (::std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string argument_;
+ };
+
+ class unexpected_group: public exception
+ {
+ public:
+ virtual
+ ~unexpected_group () throw ();
+
+ unexpected_group (const std::string& argument,
+ const std::string& group);
+
+ const std::string&
+ argument () const;
+
+ const std::string&
+ group () const;
+
+ virtual void
+ print (std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string argument_;
+ std::string group_;
+ };
+
+ class group_separator: public exception
+ {
+ public:
+ virtual
+ ~group_separator () throw ();
+
+ // Note: either (but not both) can be empty.
+ //
+ group_separator (const std::string& encountered,
+ const std::string& expected);
+
+ const std::string&
+ encountered () const;
+
+ const std::string&
+ expected () const;
+
+ virtual void
+ print (std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string encountered_;
+ std::string expected_;
+ };
+
+ // Command line argument scanner interface.
+ //
+ // The values returned by next() are guaranteed to be valid
+ // for the two previous arguments up until a call to a third
+ // peek() or next().
+ //
+ class scanner
+ {
+ public:
+ virtual
+ ~scanner ();
+
+ virtual bool
+ more () = 0;
+
+ virtual const char*
+ peek () = 0;
+
+ virtual const char*
+ next () = 0;
+
+ virtual void
+ skip () = 0;
+ };
+
+ class argv_scanner: public scanner
+ {
+ public:
+ argv_scanner (int& argc, char** argv, bool erase = false);
+ argv_scanner (int start, int& argc, char** argv, bool erase = false);
+
+ int
+ end () const;
+
+ virtual bool
+ more ();
+
+ virtual const char*
+ peek ();
+
+ virtual const char*
+ next ();
+
+ virtual void
+ skip ();
+
+ private:
+ int i_;
+ int& argc_;
+ char** argv_;
+ bool erase_;
+ };
+
+ class vector_scanner: public scanner
+ {
+ public:
+ vector_scanner (const std::vector<std::string>&, std::size_t start = 0);
+
+ std::size_t
+ end () const;
+
+ void
+ reset (std::size_t start = 0);
+
+ virtual bool
+ more ();
+
+ virtual const char*
+ peek ();
+
+ virtual const char*
+ next ();
+
+ virtual void
+ skip ();
+
+ private:
+ const std::vector<std::string>& v_;
+ std::size_t i_;
+ };
+
+ class argv_file_scanner: public argv_scanner
+ {
+ public:
+ argv_file_scanner (int& argc,
+ char** argv,
+ const std::string& option,
+ bool erase = false);
+
+ argv_file_scanner (int start,
+ int& argc,
+ char** argv,
+ const std::string& option,
+ bool erase = false);
+
+ argv_file_scanner (const std::string& file,
+ const std::string& option);
+
+ struct option_info
+ {
+ // If search_func is not NULL, it is called, with the arg
+ // value as the second argument, to locate the options file.
+ // If it returns an empty string, then the file is ignored.
+ //
+ const char* option;
+ std::string (*search_func) (const char*, void* arg);
+ void* arg;
+ };
+
+ argv_file_scanner (int& argc,
+ char** argv,
+ const option_info* options,
+ std::size_t options_count,
+ bool erase = false);
+
+ argv_file_scanner (int start,
+ int& argc,
+ char** argv,
+ const option_info* options,
+ std::size_t options_count,
+ bool erase = false);
+
+ argv_file_scanner (const std::string& file,
+ const option_info* options = 0,
+ std::size_t options_count = 0);
+
+ virtual bool
+ more ();
+
+ virtual const char*
+ peek ();
+
+ virtual const char*
+ next ();
+
+ virtual void
+ skip ();
+
+ // Return the file path if the peeked at argument came from a file and
+ // the empty string otherwise. The reference is guaranteed to be valid
+ // till the end of the scanner lifetime.
+ //
+ const std::string&
+ peek_file ();
+
+ // Return the 1-based line number if the peeked at argument came from
+ // a file and zero otherwise.
+ //
+ std::size_t
+ peek_line ();
+
+ private:
+ const option_info*
+ find (const char*) const;
+
+ void
+ load (const std::string& file);
+
+ typedef argv_scanner base;
+
+ const std::string option_;
+ option_info option_info_;
+ const option_info* options_;
+ std::size_t options_count_;
+
+ struct arg
+ {
+ std::string value;
+ const std::string* file;
+ std::size_t line;
+ };
+
+ std::deque<arg> args_;
+ std::list<std::string> files_;
+
+ // Circular buffer of two arguments.
+ //
+ std::string hold_[2];
+ std::size_t i_;
+
+ bool skip_;
+
+ static int zero_argc_;
+ static std::string empty_string_;
+ };
+
+ class group_scanner: public scanner
+ {
+ public:
+ group_scanner (scanner&);
+
+ virtual bool
+ more ();
+
+ virtual const char*
+ peek ();
+
+ virtual const char*
+ next ();
+
+ virtual void
+ skip ();
+
+ // The group is only available after the call to next()
+ // (and skip() -- in case one needs to make sure the group
+ // was empty, or some such) and is only valid (and must be
+ // handled) until the next call to any of the scanner
+ // functions (including more()).
+ //
+ scanner&
+ group ();
+
+ // Escape an argument that is a group separator. Return the
+ // passed string if no escaping is required.
+ //
+ static const char*
+ escape (const char*);
+
+ private:
+ enum state
+ {
+ peeked, // Argument peeked at with peek().
+ scanned, // Argument scanned with next().
+ skipped, // Argument skipped with skip()/initial.
+ };
+
+ enum separator
+ {
+ none,
+ open, // {
+ close, // }
+ open_plus, // +{
+ close_plus // }+
+ };
+
+ static separator
+ sense (const char*);
+
+ // If the state is scanned or skipped, then scan the
+ // leading groups and save the next (unescaped) argument in
+ // arg_. If the state is peeked, then scan the trailing
+ // groups. In both cases set the new state.
+ //
+ void
+ scan_group (state);
+
+ scanner& scan_;
+ state state_;
+
+ // Circular buffer of two arguments.
+ //
+ std::string arg_[2];
+ std::size_t i_;
+
+ std::vector<std::string> group_;
+ vector_scanner group_scan_;
+ };
+
+ template <typename X>
+ struct parser;
+ }
+}
+
+#include <set>
+
+#include <bpkg/types.hxx>
+
+#include <bpkg/options-types.hxx>
+
+namespace bpkg
+{
+ class common_options
+ {
+ public:
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const common_options&);
+
+ // Option accessors.
+ //
+ const bool&
+ v () const;
+
+ const bool&
+ V () const;
+
+ const bool&
+ quiet () const;
+
+ const uint16_t&
+ verbose () const;
+
+ bool
+ verbose_specified () const;
+
+ const size_t&
+ jobs () const;
+
+ bool
+ jobs_specified () const;
+
+ const bool&
+ no_result () const;
+
+ const bool&
+ no_progress () const;
+
+ const path&
+ build () const;
+
+ bool
+ build_specified () const;
+
+ const strings&
+ build_option () const;
+
+ bool
+ build_option_specified () const;
+
+ const path&
+ fetch () const;
+
+ bool
+ fetch_specified () const;
+
+ const strings&
+ fetch_option () const;
+
+ bool
+ fetch_option_specified () const;
+
+ const size_t&
+ fetch_timeout () const;
+
+ bool
+ fetch_timeout_specified () const;
+
+ const butl::url&
+ pkg_proxy () const;
+
+ bool
+ pkg_proxy_specified () const;
+
+ const path&
+ git () const;
+
+ bool
+ git_specified () const;
+
+ const strings&
+ git_option () const;
+
+ bool
+ git_option_specified () const;
+
+ const path&
+ sha256 () const;
+
+ bool
+ sha256_specified () const;
+
+ const strings&
+ sha256_option () const;
+
+ bool
+ sha256_option_specified () const;
+
+ const path&
+ tar () const;
+
+ bool
+ tar_specified () const;
+
+ const strings&
+ tar_option () const;
+
+ bool
+ tar_option_specified () const;
+
+ const qualified_option<openssl_commands, path>&
+ openssl () const;
+
+ bool
+ openssl_specified () const;
+
+ const qualified_option<openssl_commands, strings>&
+ openssl_option () const;
+
+ bool
+ openssl_option_specified () const;
+
+ const bpkg::auth&
+ auth () const;
+
+ bool
+ auth_specified () const;
+
+ const std::set<string>&
+ trust () const;
+
+ bool
+ trust_specified () const;
+
+ const bool&
+ trust_yes () const;
+
+ const bool&
+ trust_no () const;
+
+ const string&
+ pager () const;
+
+ bool
+ pager_specified () const;
+
+ const strings&
+ pager_option () const;
+
+ bool
+ pager_option_specified () const;
+
+ const string&
+ options_file () const;
+
+ bool
+ options_file_specified () const;
+
+ const dir_path&
+ default_options () const;
+
+ bool
+ default_options_specified () const;
+
+ const bool&
+ no_default_options () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ static ::bpkg::cli::usage_para
+ print_long_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ common_options ();
+
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ public:
+ bool v_;
+ bool V_;
+ bool quiet_;
+ uint16_t verbose_;
+ bool verbose_specified_;
+ size_t jobs_;
+ bool jobs_specified_;
+ bool no_result_;
+ bool no_progress_;
+ path build_;
+ bool build_specified_;
+ strings build_option_;
+ bool build_option_specified_;
+ path fetch_;
+ bool fetch_specified_;
+ strings fetch_option_;
+ bool fetch_option_specified_;
+ size_t fetch_timeout_;
+ bool fetch_timeout_specified_;
+ butl::url pkg_proxy_;
+ bool pkg_proxy_specified_;
+ path git_;
+ bool git_specified_;
+ strings git_option_;
+ bool git_option_specified_;
+ path sha256_;
+ bool sha256_specified_;
+ strings sha256_option_;
+ bool sha256_option_specified_;
+ path tar_;
+ bool tar_specified_;
+ strings tar_option_;
+ bool tar_option_specified_;
+ qualified_option<openssl_commands, path> openssl_;
+ bool openssl_specified_;
+ qualified_option<openssl_commands, strings> openssl_option_;
+ bool openssl_option_specified_;
+ bpkg::auth auth_;
+ bool auth_specified_;
+ std::set<string> trust_;
+ bool trust_specified_;
+ bool trust_yes_;
+ bool trust_no_;
+ string pager_;
+ bool pager_specified_;
+ strings pager_option_;
+ bool pager_option_specified_;
+ string options_file_;
+ bool options_file_specified_;
+ dir_path default_options_;
+ bool default_options_specified_;
+ bool no_default_options_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_common_options_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ ::bpkg::cli::usage_para
+ print_bpkg_common_options_long_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/common-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_COMMON_OPTIONS_HXX
diff --git a/bpkg/common-options.ixx b/bpkg/common-options.ixx
new file mode 100644
index 0000000..1d299d2
--- /dev/null
+++ b/bpkg/common-options.ixx
@@ -0,0 +1,698 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <cassert>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ // usage_para
+ //
+ inline usage_para::
+ usage_para (value v)
+ : v_ (v)
+ {
+ }
+
+ // unknown_mode
+ //
+ inline unknown_mode::
+ unknown_mode (value v)
+ : v_ (v)
+ {
+ }
+
+ // exception
+ //
+ inline ::std::ostream&
+ operator<< (::std::ostream& os, const exception& e)
+ {
+ e.print (os);
+ return os;
+ }
+
+ // unknown_option
+ //
+ inline unknown_option::
+ unknown_option (const std::string& option)
+ : option_ (option)
+ {
+ }
+
+ inline const std::string& unknown_option::
+ option () const
+ {
+ return option_;
+ }
+
+ // unknown_argument
+ //
+ inline unknown_argument::
+ unknown_argument (const std::string& argument)
+ : argument_ (argument)
+ {
+ }
+
+ inline const std::string& unknown_argument::
+ argument () const
+ {
+ return argument_;
+ }
+
+ // missing_value
+ //
+ inline missing_value::
+ missing_value (const std::string& option)
+ : option_ (option)
+ {
+ }
+
+ inline const std::string& missing_value::
+ option () const
+ {
+ return option_;
+ }
+
+ // invalid_value
+ //
+ inline invalid_value::
+ invalid_value (const std::string& option,
+ const std::string& value,
+ const std::string& message)
+ : option_ (option),
+ value_ (value),
+ message_ (message)
+ {
+ }
+
+ inline const std::string& invalid_value::
+ option () const
+ {
+ return option_;
+ }
+
+ inline const std::string& invalid_value::
+ value () const
+ {
+ return value_;
+ }
+
+ inline const std::string& invalid_value::
+ message () const
+ {
+ return message_;
+ }
+
+ // file_io_failure
+ //
+ inline file_io_failure::
+ file_io_failure (const std::string& file)
+ : file_ (file)
+ {
+ }
+
+ inline const std::string& file_io_failure::
+ file () const
+ {
+ return file_;
+ }
+
+ // unmatched_quote
+ //
+ inline unmatched_quote::
+ unmatched_quote (const std::string& argument)
+ : argument_ (argument)
+ {
+ }
+
+ inline const std::string& unmatched_quote::
+ argument () const
+ {
+ return argument_;
+ }
+
+ // unexpected_group
+ //
+ inline unexpected_group::
+ unexpected_group (const std::string& argument,
+ const std::string& group)
+ : argument_ (argument), group_ (group)
+ {
+ }
+
+ inline const std::string& unexpected_group::
+ argument () const
+ {
+ return argument_;
+ }
+
+ inline const std::string& unexpected_group::
+ group () const
+ {
+ return group_;
+ }
+
+ // group_separator
+ //
+ inline group_separator::
+ group_separator (const std::string& encountered,
+ const std::string& expected)
+ : encountered_ (encountered), expected_ (expected)
+ {
+ }
+
+ inline const std::string& group_separator::
+ encountered () const
+ {
+ return encountered_;
+ }
+
+ inline const std::string& group_separator::
+ expected () const
+ {
+ return expected_;
+ }
+
+ // argv_scanner
+ //
+ inline argv_scanner::
+ argv_scanner (int& argc, char** argv, bool erase)
+ : i_ (1), argc_ (argc), argv_ (argv), erase_ (erase)
+ {
+ }
+
+ inline argv_scanner::
+ argv_scanner (int start, int& argc, char** argv, bool erase)
+ : i_ (start), argc_ (argc), argv_ (argv), erase_ (erase)
+ {
+ }
+
+ inline int argv_scanner::
+ end () const
+ {
+ return i_;
+ }
+
+ // vector_scanner
+ //
+ inline vector_scanner::
+ vector_scanner (const std::vector<std::string>& v, std::size_t i)
+ : v_ (v), i_ (i)
+ {
+ }
+
+ inline std::size_t vector_scanner::
+ end () const
+ {
+ return i_;
+ }
+
+ inline void vector_scanner::
+ reset (std::size_t i)
+ {
+ i_ = i;
+ }
+
+ // argv_file_scanner
+ //
+ inline argv_file_scanner::
+ argv_file_scanner (int& argc,
+ char** argv,
+ const std::string& option,
+ bool erase)
+ : argv_scanner (argc, argv, erase),
+ option_ (option),
+ options_ (&option_info_),
+ options_count_ (1),
+ i_ (1),
+ skip_ (false)
+ {
+ option_info_.option = option_.c_str ();
+ option_info_.search_func = 0;
+ }
+
+ inline argv_file_scanner::
+ argv_file_scanner (int start,
+ int& argc,
+ char** argv,
+ const std::string& option,
+ bool erase)
+ : argv_scanner (start, argc, argv, erase),
+ option_ (option),
+ options_ (&option_info_),
+ options_count_ (1),
+ i_ (1),
+ skip_ (false)
+ {
+ option_info_.option = option_.c_str ();
+ option_info_.search_func = 0;
+ }
+
+ inline argv_file_scanner::
+ argv_file_scanner (const std::string& file,
+ const std::string& option)
+ : argv_scanner (0, zero_argc_, 0),
+ option_ (option),
+ options_ (&option_info_),
+ options_count_ (1),
+ i_ (1),
+ skip_ (false)
+ {
+ option_info_.option = option_.c_str ();
+ option_info_.search_func = 0;
+
+ load (file);
+ }
+
+ inline argv_file_scanner::
+ argv_file_scanner (int& argc,
+ char** argv,
+ const option_info* options,
+ std::size_t options_count,
+ bool erase)
+ : argv_scanner (argc, argv, erase),
+ options_ (options),
+ options_count_ (options_count),
+ i_ (1),
+ skip_ (false)
+ {
+ }
+
+ inline argv_file_scanner::
+ argv_file_scanner (int start,
+ int& argc,
+ char** argv,
+ const option_info* options,
+ std::size_t options_count,
+ bool erase)
+ : argv_scanner (start, argc, argv, erase),
+ options_ (options),
+ options_count_ (options_count),
+ i_ (1),
+ skip_ (false)
+ {
+ }
+
+ inline argv_file_scanner::
+ argv_file_scanner (const std::string& file,
+ const option_info* options,
+ std::size_t options_count)
+ : argv_scanner (0, zero_argc_, 0),
+ options_ (options),
+ options_count_ (options_count),
+ i_ (1),
+ skip_ (false)
+ {
+ load (file);
+ }
+
+ // group_scanner
+ //
+ inline group_scanner::
+ group_scanner (scanner& s)
+ : scan_ (s), state_ (skipped), i_ (1), group_scan_ (group_)
+ {
+ }
+
+ inline scanner& group_scanner::
+ group ()
+ {
+ assert (state_ == scanned || state_ == skipped);
+ return group_scan_;
+ }
+
+ inline const char* group_scanner::
+ escape (const char* a)
+ {
+ switch (sense (a))
+ {
+ case separator::none: break;
+ case separator::open: return "\\{";
+ case separator::close: return "\\}";
+ case separator::open_plus: return "\\+{";
+ case separator::close_plus: return "\\}+";
+ }
+
+ return a;
+ }
+
+ inline group_scanner::separator group_scanner::
+ sense (const char* s)
+ {
+ switch (s[0])
+ {
+ case '{': return s[1] == '\0' ? open : none;
+ case '}':
+ {
+ switch (s[1])
+ {
+ case '+': return s[2] == '\0' ? close_plus : none;
+ default: return s[1] == '\0' ? close : none;
+ }
+ }
+ case '+':
+ {
+ switch (s[1])
+ {
+ case '{': return s[2] == '\0' ? open_plus : none;
+ default: return none;
+ }
+ }
+ }
+
+ return none;
+ }
+ }
+}
+
+namespace bpkg
+{
+ // common_options
+ //
+
+ inline const bool& common_options::
+ v () const
+ {
+ return this->v_;
+ }
+
+ inline const bool& common_options::
+ V () const
+ {
+ return this->V_;
+ }
+
+ inline const bool& common_options::
+ quiet () const
+ {
+ return this->quiet_;
+ }
+
+ inline const uint16_t& common_options::
+ verbose () const
+ {
+ return this->verbose_;
+ }
+
+ inline bool common_options::
+ verbose_specified () const
+ {
+ return this->verbose_specified_;
+ }
+
+ inline const size_t& common_options::
+ jobs () const
+ {
+ return this->jobs_;
+ }
+
+ inline bool common_options::
+ jobs_specified () const
+ {
+ return this->jobs_specified_;
+ }
+
+ inline const bool& common_options::
+ no_result () const
+ {
+ return this->no_result_;
+ }
+
+ inline const bool& common_options::
+ no_progress () const
+ {
+ return this->no_progress_;
+ }
+
+ inline const path& common_options::
+ build () const
+ {
+ return this->build_;
+ }
+
+ inline bool common_options::
+ build_specified () const
+ {
+ return this->build_specified_;
+ }
+
+ inline const strings& common_options::
+ build_option () const
+ {
+ return this->build_option_;
+ }
+
+ inline bool common_options::
+ build_option_specified () const
+ {
+ return this->build_option_specified_;
+ }
+
+ inline const path& common_options::
+ fetch () const
+ {
+ return this->fetch_;
+ }
+
+ inline bool common_options::
+ fetch_specified () const
+ {
+ return this->fetch_specified_;
+ }
+
+ inline const strings& common_options::
+ fetch_option () const
+ {
+ return this->fetch_option_;
+ }
+
+ inline bool common_options::
+ fetch_option_specified () const
+ {
+ return this->fetch_option_specified_;
+ }
+
+ inline const size_t& common_options::
+ fetch_timeout () const
+ {
+ return this->fetch_timeout_;
+ }
+
+ inline bool common_options::
+ fetch_timeout_specified () const
+ {
+ return this->fetch_timeout_specified_;
+ }
+
+ inline const butl::url& common_options::
+ pkg_proxy () const
+ {
+ return this->pkg_proxy_;
+ }
+
+ inline bool common_options::
+ pkg_proxy_specified () const
+ {
+ return this->pkg_proxy_specified_;
+ }
+
+ inline const path& common_options::
+ git () const
+ {
+ return this->git_;
+ }
+
+ inline bool common_options::
+ git_specified () const
+ {
+ return this->git_specified_;
+ }
+
+ inline const strings& common_options::
+ git_option () const
+ {
+ return this->git_option_;
+ }
+
+ inline bool common_options::
+ git_option_specified () const
+ {
+ return this->git_option_specified_;
+ }
+
+ inline const path& common_options::
+ sha256 () const
+ {
+ return this->sha256_;
+ }
+
+ inline bool common_options::
+ sha256_specified () const
+ {
+ return this->sha256_specified_;
+ }
+
+ inline const strings& common_options::
+ sha256_option () const
+ {
+ return this->sha256_option_;
+ }
+
+ inline bool common_options::
+ sha256_option_specified () const
+ {
+ return this->sha256_option_specified_;
+ }
+
+ inline const path& common_options::
+ tar () const
+ {
+ return this->tar_;
+ }
+
+ inline bool common_options::
+ tar_specified () const
+ {
+ return this->tar_specified_;
+ }
+
+ inline const strings& common_options::
+ tar_option () const
+ {
+ return this->tar_option_;
+ }
+
+ inline bool common_options::
+ tar_option_specified () const
+ {
+ return this->tar_option_specified_;
+ }
+
+ inline const qualified_option<openssl_commands, path>& common_options::
+ openssl () const
+ {
+ return this->openssl_;
+ }
+
+ inline bool common_options::
+ openssl_specified () const
+ {
+ return this->openssl_specified_;
+ }
+
+ inline const qualified_option<openssl_commands, strings>& common_options::
+ openssl_option () const
+ {
+ return this->openssl_option_;
+ }
+
+ inline bool common_options::
+ openssl_option_specified () const
+ {
+ return this->openssl_option_specified_;
+ }
+
+ inline const bpkg::auth& common_options::
+ auth () const
+ {
+ return this->auth_;
+ }
+
+ inline bool common_options::
+ auth_specified () const
+ {
+ return this->auth_specified_;
+ }
+
+ inline const std::set<string>& common_options::
+ trust () const
+ {
+ return this->trust_;
+ }
+
+ inline bool common_options::
+ trust_specified () const
+ {
+ return this->trust_specified_;
+ }
+
+ inline const bool& common_options::
+ trust_yes () const
+ {
+ return this->trust_yes_;
+ }
+
+ inline const bool& common_options::
+ trust_no () const
+ {
+ return this->trust_no_;
+ }
+
+ inline const string& common_options::
+ pager () const
+ {
+ return this->pager_;
+ }
+
+ inline bool common_options::
+ pager_specified () const
+ {
+ return this->pager_specified_;
+ }
+
+ inline const strings& common_options::
+ pager_option () const
+ {
+ return this->pager_option_;
+ }
+
+ inline bool common_options::
+ pager_option_specified () const
+ {
+ return this->pager_option_specified_;
+ }
+
+ inline const string& common_options::
+ options_file () const
+ {
+ return this->options_file_;
+ }
+
+ inline bool common_options::
+ options_file_specified () const
+ {
+ return this->options_file_specified_;
+ }
+
+ inline const dir_path& common_options::
+ default_options () const
+ {
+ return this->default_options_;
+ }
+
+ inline bool common_options::
+ default_options_specified () const
+ {
+ return this->default_options_specified_;
+ }
+
+ inline const bool& common_options::
+ no_default_options () const
+ {
+ return this->no_default_options_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/configuration-options.cxx b/bpkg/configuration-options.cxx
new file mode 100644
index 0000000..8a33ece
--- /dev/null
+++ b/bpkg/configuration-options.cxx
@@ -0,0 +1,545 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/configuration-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <ostream>
+#include <sstream>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ template <typename X>
+ struct parser
+ {
+ static void
+ parse (X& x, bool& xs, scanner& s)
+ {
+ using namespace std;
+
+ const char* o (s.next ());
+ if (s.more ())
+ {
+ string v (s.next ());
+ istringstream is (v);
+ if (!(is >> x && is.peek () == istringstream::traits_type::eof ()))
+ throw invalid_value (o, v);
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (X& b, const X& a)
+ {
+ b = a;
+ }
+ };
+
+ template <>
+ struct parser<bool>
+ {
+ static void
+ parse (bool& x, scanner& s)
+ {
+ s.next ();
+ x = true;
+ }
+
+ static void
+ merge (bool& b, const bool&)
+ {
+ b = true;
+ }
+ };
+
+ template <>
+ struct parser<std::string>
+ {
+ static void
+ parse (std::string& x, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ x = s.next ();
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (std::string& b, const std::string& a)
+ {
+ b = a;
+ }
+ };
+
+ template <typename X>
+ struct parser<std::vector<X> >
+ {
+ static void
+ parse (std::vector<X>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.push_back (x);
+ xs = true;
+ }
+
+ static void
+ merge (std::vector<X>& b, const std::vector<X>& a)
+ {
+ b.insert (b.end (), a.begin (), a.end ());
+ }
+ };
+
+ template <typename X>
+ struct parser<std::set<X> >
+ {
+ static void
+ parse (std::set<X>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.insert (x);
+ xs = true;
+ }
+
+ static void
+ merge (std::set<X>& b, const std::set<X>& a)
+ {
+ b.insert (a.begin (), a.end ());
+ }
+ };
+
+ template <typename K, typename V>
+ struct parser<std::map<K, V> >
+ {
+ static void
+ parse (std::map<K, V>& m, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ std::string ov (s.next ());
+ std::string::size_type p = ov.find ('=');
+
+ K k = K ();
+ V v = V ();
+ std::string kstr (ov, 0, p);
+ std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (o),
+ 0
+ };
+
+ bool dummy;
+ if (!kstr.empty ())
+ {
+ av[1] = const_cast<char*> (kstr.c_str ());
+ argv_scanner s (0, ac, av);
+ parser<K>::parse (k, dummy, s);
+ }
+
+ if (!vstr.empty ())
+ {
+ av[1] = const_cast<char*> (vstr.c_str ());
+ argv_scanner s (0, ac, av);
+ parser<V>::parse (v, dummy, s);
+ }
+
+ m[k] = v;
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (std::map<K, V>& b, const std::map<K, V>& a)
+ {
+ for (typename std::map<K, V>::const_iterator i (a.begin ());
+ i != a.end ();
+ ++i)
+ b[i->first] = i->second;
+ }
+ };
+
+ template <typename X, typename T, T X::*M>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, s);
+ }
+
+ template <typename X, typename T, T X::*M, bool X::*S>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, x.*S, s);
+ }
+ }
+}
+
+#include <map>
+#include <cstring>
+
+namespace bpkg
+{
+ // configuration_options
+ //
+
+ configuration_options::
+ configuration_options ()
+ : directory_ ("."),
+ directory_specified_ (false)
+ {
+ }
+
+ bool configuration_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool configuration_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool configuration_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool configuration_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool configuration_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void configuration_options::
+ merge (const configuration_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // common_options base
+ //
+ ::bpkg::common_options::merge (a);
+
+ if (a.directory_specified_)
+ {
+ ::bpkg::cli::parser< dir_path>::merge (
+ this->directory_, a.directory_);
+ this->directory_specified_ = true;
+ }
+ }
+
+ ::bpkg::cli::usage_para configuration_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1m--directory\033[0m|\033[1m-d\033[0m \033[4mdir\033[0m Assume configuration is in \033[4mdir\033[0m rather than in the" << ::std::endl
+ << " current working directory." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::option;
+
+ // common_options base
+ //
+ p = ::bpkg::common_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (configuration_options&, ::bpkg::cli::scanner&)>
+ _cli_configuration_options_map;
+
+ static _cli_configuration_options_map _cli_configuration_options_map_;
+
+ struct _cli_configuration_options_map_init
+ {
+ _cli_configuration_options_map_init ()
+ {
+ _cli_configuration_options_map_["--directory"] =
+ &::bpkg::cli::thunk< configuration_options, dir_path, &configuration_options::directory_,
+ &configuration_options::directory_specified_ >;
+ _cli_configuration_options_map_["-d"] =
+ &::bpkg::cli::thunk< configuration_options, dir_path, &configuration_options::directory_,
+ &configuration_options::directory_specified_ >;
+ }
+ };
+
+ static _cli_configuration_options_map_init _cli_configuration_options_map_init_;
+
+ bool configuration_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_configuration_options_map::const_iterator i (_cli_configuration_options_map_.find (o));
+
+ if (i != _cli_configuration_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // common_options base
+ //
+ if (::bpkg::common_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool configuration_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (_parse (co.c_str (), ns))
+ {
+ // Parsed the option but not its value?
+ //
+ if (ns.end () != 2)
+ throw ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_configuration_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ p = ::bpkg::configuration_options::print_usage (os, p);
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/configuration-options.hxx b/bpkg/configuration-options.hxx
new file mode 100644
index 0000000..d7a61db
--- /dev/null
+++ b/bpkg/configuration-options.hxx
@@ -0,0 +1,117 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_CONFIGURATION_OPTIONS_HXX
+#define BPKG_CONFIGURATION_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+namespace bpkg
+{
+ class configuration_options: public ::bpkg::common_options
+ {
+ public:
+ configuration_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const configuration_options&);
+
+ // Option accessors.
+ //
+ const dir_path&
+ directory () const;
+
+ bool
+ directory_specified () const;
+
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ dir_path directory_;
+ bool directory_specified_;
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_configuration_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/configuration-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_CONFIGURATION_OPTIONS_HXX
diff --git a/bpkg/configuration-options.ixx b/bpkg/configuration-options.ixx
new file mode 100644
index 0000000..294a431
--- /dev/null
+++ b/bpkg/configuration-options.ixx
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // configuration_options
+ //
+
+ inline const dir_path& configuration_options::
+ directory () const
+ {
+ return this->directory_;
+ }
+
+ inline bool configuration_options::
+ directory_specified () const
+ {
+ return this->directory_specified_;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/default-options-files.cxx b/bpkg/default-options-files.cxx
new file mode 100644
index 0000000..ccdc161
--- /dev/null
+++ b/bpkg/default-options-files.cxx
@@ -0,0 +1,92 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/default-options-files.hxx>
+
+#include <map>
+#include <cstring>
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_default_options_files_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg\033[0m \033[4mcommand\033[0m [\033[4mmode-options\033[0m] ...\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "Instead of having a separate config file format for tool configuration, the" << ::std::endl
+ << "\033[1mbuild2\033[0m toolchain uses \033[4mdefault options files\033[0m which contain the same options as" << ::std::endl
+ << "what can be specified on the command line. The default options files are like" << ::std::endl
+ << "options files that one can specify with \033[1m--options-file\033[0m (\033[1mbpkg-common-options(1)\033[0m)" << ::std::endl
+ << "except that they are loaded by default." << ::std::endl
+ << ::std::endl
+ << "The default options files are searched for in the \033[1m.build2/\033[0m and \033[1m.build2/local/\033[0m" << ::std::endl
+ << "subdirectories of each outer directory beginning from the \033[4mstart directory\033[0m and" << ::std::endl
+ << "until reaching either the home directory or the filesystem root directory (both" << ::std::endl
+ << "excluding). Then in the \033[1m.build2/\033[0m subdirectory of the home directory and finally" << ::std::endl
+ << "in the system directory (for example, \033[1m/etc/build2/\033[0m) if configured." << ::std::endl
+ << ::std::endl
+ << "Once the search is complete, the files are loaded in the reverse order, that" << ::std::endl
+ << "is, beginning from the system directory (if any), followed by the home" << ::std::endl
+ << "directory, ending with the start directory, and finishing off with the options" << ::std::endl
+ << "specified on the command line. In other words, the files are loaded from the" << ::std::endl
+ << "more generic to the more specific with the command line options having the" << ::std::endl
+ << "ability to override any values specified in the default options files." << ::std::endl
+ << ::std::endl
+ << "The start directory, the names of the default options files, and in which order" << ::std::endl
+ << "they are loaded within each directory are determined by the \033[4mcommand\033[0m and" << ::std::endl
+ << "potentially its \033[4mmode-options\033[0m. See each command's DEFAULT OPTIONS FILES section" << ::std::endl
+ << "for details." << ::std::endl
+ << ::std::endl
+ << "If a default options file contains \033[1m--no-default-options\033[0m, then the search is" << ::std::endl
+ << "stopped at the directory containing this file and no outer files are loaded. If" << ::std::endl
+ << "this option is specified on the command line, then none of the default options" << ::std::endl
+ << "files are searched for or loaded." << ::std::endl
+ << ::std::endl
+ << "An additional directory containing default options files can be specified with" << ::std::endl
+ << "\033[1m--default-options\033[0m. If such a directory is a subdirectory of the start directory" << ::std::endl
+ << "or is between the start directory and the end of the outer search, then its" << ::std::endl
+ << "configuration files are loaded at the corresponding point in the directory" << ::std::endl
+ << "hierarchy. Otherwise, they are loaded after the home directory." << ::std::endl
+ << ::std::endl
+ << "The presence of the \033[1m.git\033[0m filesystem entry causes the default options files in" << ::std::endl
+ << "this directory and any of its subdirectories to be considered remote. Depending" << ::std::endl
+ << "on the command, some security-sensitive options may be disallowed or trigger a" << ::std::endl
+ << "prompt when specified in remote options files (in the current implementation" << ::std::endl
+ << "this is the case even for files from the \033[1m.build2/local/\033[0m subdirectory since the" << ::std::endl
+ << "mere location is not a sufficient ground to definitively conclude that the file" << ::std::endl
+ << "is not remote; to be sure we would need to query the version control system)." << ::std::endl
+ << "Note that additional default options files specified with \033[1m--default-options\033[0m are" << ::std::endl
+ << "never considered remote." << ::std::endl
+ << ::std::endl
+ << "The order in which default options files are loaded is traced at the verbosity" << ::std::endl
+ << "level 3 (\033[1m-V\033[0m option) or higher." << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/default-options-files.hxx b/bpkg/default-options-files.hxx
new file mode 100644
index 0000000..a26c600
--- /dev/null
+++ b/bpkg/default-options-files.hxx
@@ -0,0 +1,31 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_DEFAULT_OPTIONS_FILES_HXX
+#define BPKG_DEFAULT_OPTIONS_FILES_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_default_options_files_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_DEFAULT_OPTIONS_FILES_HXX
diff --git a/bpkg/help-options.cxx b/bpkg/help-options.cxx
new file mode 100644
index 0000000..7b9eeef
--- /dev/null
+++ b/bpkg/help-options.cxx
@@ -0,0 +1,549 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+#include <bpkg/types-parsers.hxx>
+//
+// End prologue.
+
+#include <bpkg/help-options.hxx>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <ostream>
+#include <sstream>
+
+namespace bpkg
+{
+ namespace cli
+ {
+ template <typename X>
+ struct parser
+ {
+ static void
+ parse (X& x, bool& xs, scanner& s)
+ {
+ using namespace std;
+
+ const char* o (s.next ());
+ if (s.more ())
+ {
+ string v (s.next ());
+ istringstream is (v);
+ if (!(is >> x && is.peek () == istringstream::traits_type::eof ()))
+ throw invalid_value (o, v);
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (X& b, const X& a)
+ {
+ b = a;
+ }
+ };
+
+ template <>
+ struct parser<bool>
+ {
+ static void
+ parse (bool& x, scanner& s)
+ {
+ s.next ();
+ x = true;
+ }
+
+ static void
+ merge (bool& b, const bool&)
+ {
+ b = true;
+ }
+ };
+
+ template <>
+ struct parser<std::string>
+ {
+ static void
+ parse (std::string& x, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ x = s.next ();
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (std::string& b, const std::string& a)
+ {
+ b = a;
+ }
+ };
+
+ template <typename X>
+ struct parser<std::vector<X> >
+ {
+ static void
+ parse (std::vector<X>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.push_back (x);
+ xs = true;
+ }
+
+ static void
+ merge (std::vector<X>& b, const std::vector<X>& a)
+ {
+ b.insert (b.end (), a.begin (), a.end ());
+ }
+ };
+
+ template <typename X>
+ struct parser<std::set<X> >
+ {
+ static void
+ parse (std::set<X>& c, bool& xs, scanner& s)
+ {
+ X x;
+ bool dummy;
+ parser<X>::parse (x, dummy, s);
+ c.insert (x);
+ xs = true;
+ }
+
+ static void
+ merge (std::set<X>& b, const std::set<X>& a)
+ {
+ b.insert (a.begin (), a.end ());
+ }
+ };
+
+ template <typename K, typename V>
+ struct parser<std::map<K, V> >
+ {
+ static void
+ parse (std::map<K, V>& m, bool& xs, scanner& s)
+ {
+ const char* o (s.next ());
+
+ if (s.more ())
+ {
+ std::string ov (s.next ());
+ std::string::size_type p = ov.find ('=');
+
+ K k = K ();
+ V v = V ();
+ std::string kstr (ov, 0, p);
+ std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ()));
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (o),
+ 0
+ };
+
+ bool dummy;
+ if (!kstr.empty ())
+ {
+ av[1] = const_cast<char*> (kstr.c_str ());
+ argv_scanner s (0, ac, av);
+ parser<K>::parse (k, dummy, s);
+ }
+
+ if (!vstr.empty ())
+ {
+ av[1] = const_cast<char*> (vstr.c_str ());
+ argv_scanner s (0, ac, av);
+ parser<V>::parse (v, dummy, s);
+ }
+
+ m[k] = v;
+ }
+ else
+ throw missing_value (o);
+
+ xs = true;
+ }
+
+ static void
+ merge (std::map<K, V>& b, const std::map<K, V>& a)
+ {
+ for (typename std::map<K, V>::const_iterator i (a.begin ());
+ i != a.end ();
+ ++i)
+ b[i->first] = i->second;
+ }
+ };
+
+ template <typename X, typename T, T X::*M>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, s);
+ }
+
+ template <typename X, typename T, T X::*M, bool X::*S>
+ void
+ thunk (X& x, scanner& s)
+ {
+ parser<T>::parse (x.*M, x.*S, s);
+ }
+ }
+}
+
+#include <map>
+#include <cstring>
+
+namespace bpkg
+{
+ // help_options
+ //
+
+ help_options::
+ help_options ()
+ {
+ }
+
+ bool help_options::
+ parse (int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool help_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ bool help_options::
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool help_options::
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ ::bpkg::cli::argv_scanner s (start, argc, argv, erase);
+ bool r = _parse (s, opt, arg);
+ end = s.end ();
+ return r;
+ }
+
+ bool help_options::
+ parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt,
+ ::bpkg::cli::unknown_mode arg)
+ {
+ bool r = _parse (s, opt, arg);
+ return r;
+ }
+
+ void help_options::
+ merge (const help_options& a)
+ {
+ CLI_POTENTIALLY_UNUSED (a);
+
+ // common_options base
+ //
+ ::bpkg::common_options::merge (a);
+ }
+
+ ::bpkg::cli::usage_para help_options::
+ print_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ // common_options base
+ //
+ p = ::bpkg::common_options::print_usage (os, p);
+
+ return p;
+ }
+
+ typedef
+ std::map<std::string, void (*) (help_options&, ::bpkg::cli::scanner&)>
+ _cli_help_options_map;
+
+ static _cli_help_options_map _cli_help_options_map_;
+
+ struct _cli_help_options_map_init
+ {
+ _cli_help_options_map_init ()
+ {
+ }
+ };
+
+ static _cli_help_options_map_init _cli_help_options_map_init_;
+
+ bool help_options::
+ _parse (const char* o, ::bpkg::cli::scanner& s)
+ {
+ _cli_help_options_map::const_iterator i (_cli_help_options_map_.find (o));
+
+ if (i != _cli_help_options_map_.end ())
+ {
+ (*(i->second)) (*this, s);
+ return true;
+ }
+
+ // common_options base
+ //
+ if (::bpkg::common_options::_parse (o, s))
+ return true;
+
+ return false;
+ }
+
+ bool help_options::
+ _parse (::bpkg::cli::scanner& s,
+ ::bpkg::cli::unknown_mode opt_mode,
+ ::bpkg::cli::unknown_mode arg_mode)
+ {
+ // Can't skip combined flags (--no-combined-flags).
+ //
+ assert (opt_mode != ::bpkg::cli::unknown_mode::skip);
+
+ bool r = false;
+ bool opt = true;
+
+ while (s.more ())
+ {
+ const char* o = s.peek ();
+
+ if (std::strcmp (o, "--") == 0)
+ {
+ opt = false;
+ }
+
+ if (opt)
+ {
+ if (_parse (o, s))
+ {
+ r = true;
+ continue;
+ }
+
+ if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0')
+ {
+ // Handle combined option values.
+ //
+ std::string co;
+ if (const char* v = std::strchr (o, '='))
+ {
+ co.assign (o, 0, v - o);
+ ++v;
+
+ int ac (2);
+ char* av[] =
+ {
+ const_cast<char*> (co.c_str ()),
+ const_cast<char*> (v)
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (_parse (co.c_str (), ns))
+ {
+ // Parsed the option but not its value?
+ //
+ if (ns.end () != 2)
+ throw ::bpkg::cli::invalid_value (co, v);
+
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = co.c_str ();
+ }
+ }
+
+ // Handle combined flags.
+ //
+ char cf[3];
+ {
+ const char* p = o + 1;
+ for (; *p != '\0'; ++p)
+ {
+ if (!((*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9')))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ for (p = o + 1; *p != '\0'; ++p)
+ {
+ std::strcpy (cf, "-");
+ cf[1] = *p;
+ cf[2] = '\0';
+
+ int ac (1);
+ char* av[] =
+ {
+ cf
+ };
+
+ ::bpkg::cli::argv_scanner ns (0, ac, av);
+
+ if (!_parse (cf, ns))
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ // All handled.
+ //
+ s.next ();
+ r = true;
+ continue;
+ }
+ else
+ {
+ // Set the unknown option and fall through.
+ //
+ o = cf;
+ }
+ }
+ }
+
+ switch (opt_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_option (o);
+ }
+ }
+
+ break;
+ }
+ }
+
+ switch (arg_mode)
+ {
+ case ::bpkg::cli::unknown_mode::skip:
+ {
+ s.skip ();
+ r = true;
+ continue;
+ }
+ case ::bpkg::cli::unknown_mode::stop:
+ {
+ break;
+ }
+ case ::bpkg::cli::unknown_mode::fail:
+ {
+ throw ::bpkg::cli::unknown_argument (o);
+ }
+ }
+
+ break;
+ }
+
+ return r;
+ }
+}
+
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_help_usage (::std::ostream& os, ::bpkg::cli::usage_para p)
+ {
+ CLI_POTENTIALLY_UNUSED (os);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mSYNOPSIS\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mbpkg help\033[0m [\033[4mcommand\033[0m | \033[4mtopic\033[0m]\033[0m" << ::std::endl
+ << ::std::endl
+ << "\033[1mDESCRIPTION\033[0m" << ::std::endl
+ << ::std::endl
+ << "Show the detailed help for \033[4mcommand\033[0m or help \033[4mtopic\033[0m or a summary of available" << ::std::endl
+ << "commands and topics if none was specified." << ::std::endl;
+
+ p = ::bpkg::help_options::print_usage (os, ::bpkg::cli::usage_para::text);
+
+ if (p != ::bpkg::cli::usage_para::none)
+ os << ::std::endl;
+
+ os << "\033[1mDEFAULT OPTIONS FILES\033[0m" << ::std::endl
+ << ::std::endl
+ << "See \033[1mbpkg-default-options-files(1)\033[0m for an overview of the default options files." << ::std::endl
+ << "For the \033[1mhelp\033[0m command the following options files are searched for only in the" << ::std::endl
+ << "predefined directories (home, system, etc) and, if found, loaded in the order" << ::std::endl
+ << "listed:" << ::std::endl
+ << ::std::endl
+ << "bpkg.options" << ::std::endl
+ << "bpkg-help.options" << ::std::endl;
+
+ p = ::bpkg::cli::usage_para::text;
+
+ return p;
+ }
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
diff --git a/bpkg/help-options.hxx b/bpkg/help-options.hxx
new file mode 100644
index 0000000..9c67dee
--- /dev/null
+++ b/bpkg/help-options.hxx
@@ -0,0 +1,109 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+#ifndef BPKG_HELP_OPTIONS_HXX
+#define BPKG_HELP_OPTIONS_HXX
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+#include <bpkg/common-options.hxx>
+
+namespace bpkg
+{
+ class help_options: public ::bpkg::common_options
+ {
+ public:
+ help_options ();
+
+ // Return true if anything has been parsed.
+ //
+ bool
+ parse (int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (int start,
+ int& argc,
+ char** argv,
+ int& end,
+ bool erase = false,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ bool
+ parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option = ::bpkg::cli::unknown_mode::fail,
+ ::bpkg::cli::unknown_mode argument = ::bpkg::cli::unknown_mode::stop);
+
+ // Merge options from the specified instance appending/overriding
+ // them as if they appeared after options in this instance.
+ //
+ void
+ merge (const help_options&);
+
+ // Option accessors.
+ //
+ // Print usage information.
+ //
+ static ::bpkg::cli::usage_para
+ print_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+
+ // Implementation details.
+ //
+ protected:
+ bool
+ _parse (const char*, ::bpkg::cli::scanner&);
+
+ private:
+ bool
+ _parse (::bpkg::cli::scanner&,
+ ::bpkg::cli::unknown_mode option,
+ ::bpkg::cli::unknown_mode argument);
+
+ public:
+ };
+}
+
+// Print page usage information.
+//
+namespace bpkg
+{
+ ::bpkg::cli::usage_para
+ print_bpkg_help_usage (::std::ostream&,
+ ::bpkg::cli::usage_para = ::bpkg::cli::usage_para::none);
+}
+
+#include <bpkg/help-options.ixx>
+
+// Begin epilogue.
+//
+//
+// End epilogue.
+
+#endif // BPKG_HELP_OPTIONS_HXX
diff --git a/bpkg/help-options.ixx b/bpkg/help-options.ixx
new file mode 100644
index 0000000..91f5bfd
--- /dev/null
+++ b/bpkg/help-options.ixx
@@ -0,0 +1,21 @@
+// -*- C++ -*-
+//
+// This file was generated by CLI, a command line interface
+// compiler for C++.
+//
+
+// Begin prologue.
+//
+//
+// End prologue.
+
+namespace bpkg
+{
+ // help_options
+ //
+}
+
+// Begin epilogue.
+//
+//
+// End epilogue.
diff --git a/bpkg/package-odb.cxx b/bpkg/package-odb.cxx
new file mode 100644
index 0000000..f21bec9
--- /dev/null
+++ b/bpkg/package-odb.cxx
@@ -0,0 +1,12353 @@
+// -*- C++ -*-
+//
+// This file was generated by ODB, object-relational mapping (ORM)
+// compiler for C++.
+//
+
+#include <odb/pre.hxx>
+
+#include <bpkg/package-odb.hxx>
+
+#include <cassert>
+#include <cstring> // std::memcpy
+
+#include <odb/schema-catalog-impl.hxx>
+
+#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/simple-object-statements.hxx>
+#include <odb/sqlite/view-statements.hxx>
+#include <odb/sqlite/container-statements.hxx>
+#include <odb/sqlite/exceptions.hxx>
+#include <odb/sqlite/simple-object-result.hxx>
+#include <odb/sqlite/view-result.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);
+ }
+ }
+
+ // version_constraint
+ //
+
+ bool access::composite_value_traits< ::bpkg::version_constraint, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // min_version
+ //
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::grow (
+ i.min_version_value, t + 0UL))
+ grew = true;
+
+ // max_version
+ //
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::grow (
+ i.max_version_value, t + 7UL))
+ grew = true;
+
+ // min_open
+ //
+ t[14UL] = false;
+
+ // max_open
+ //
+ t[15UL] = false;
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::version_constraint, 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);
+
+ // min_version
+ //
+ composite_value_traits< ::bpkg::_version, id_sqlite >::bind (
+ b + n, i.min_version_value, sk);
+ n += 7UL;
+
+ // max_version
+ //
+ composite_value_traits< ::bpkg::_version, id_sqlite >::bind (
+ b + n, i.max_version_value, sk);
+ n += 7UL;
+
+ // min_open
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.min_open_value;
+ b[n].is_null = &i.min_open_null;
+ n++;
+
+ // max_open
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.max_open_value;
+ b[n].is_null = &i.max_open_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::version_constraint, 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);
+
+ // min_version
+ //
+ {
+ ::butl::optional< ::bpkg::version > const& v =
+ o.min_version;
+
+ // From package.hxx:238:14
+ ::bpkg::_optional_version const& vt =
+ (v) ? bpkg::_version
+ {
+ (v)->epoch, (v)->canonical_upstream, (v)->canonical_release, (v)->revision, (v)->iteration, (v)->upstream, (v)->release
+ } : bpkg::_optional_version ();
+
+ if (wrapper_traits< ::bpkg::_optional_version >::get_null (vt))
+ composite_value_traits< ::bpkg::_version, id_sqlite >::set_null (
+ i.min_version_value, sk);
+ else
+ {
+ const::bpkg::_version& vw =
+ wrapper_traits< ::bpkg::_optional_version >::get_ref (vt);
+
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::init (
+ i.min_version_value,
+ vw,
+ sk))
+ grew = true;
+ }
+ }
+
+ // max_version
+ //
+ {
+ ::butl::optional< ::bpkg::version > const& v =
+ o.max_version;
+
+ // From package.hxx:238:14
+ ::bpkg::_optional_version const& vt =
+ (v) ? bpkg::_version
+ {
+ (v)->epoch, (v)->canonical_upstream, (v)->canonical_release, (v)->revision, (v)->iteration, (v)->upstream, (v)->release
+ } : bpkg::_optional_version ();
+
+ if (wrapper_traits< ::bpkg::_optional_version >::get_null (vt))
+ composite_value_traits< ::bpkg::_version, id_sqlite >::set_null (
+ i.max_version_value, sk);
+ else
+ {
+ const::bpkg::_version& vw =
+ wrapper_traits< ::bpkg::_optional_version >::get_ref (vt);
+
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::init (
+ i.max_version_value,
+ vw,
+ sk))
+ grew = true;
+ }
+ }
+
+ // min_open
+ //
+ {
+ bool const& v =
+ o.min_open;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.min_open_value,
+ is_null,
+ v);
+ i.min_open_null = is_null;
+ }
+
+ // max_open
+ //
+ {
+ bool const& v =
+ o.max_open;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.max_open_value,
+ is_null,
+ v);
+ i.max_open_null = is_null;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::version_constraint, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // min_version
+ //
+ {
+ ::butl::optional< ::bpkg::version >& v =
+ o.min_version;
+
+ ::bpkg::_optional_version vt;
+
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::get_null (
+ i.min_version_value))
+ wrapper_traits< ::bpkg::_optional_version >::set_null (vt);
+ else
+ {
+ ::bpkg::_version& vw =
+ wrapper_traits< ::bpkg::_optional_version >::set_ref (vt);
+
+ composite_value_traits< ::bpkg::_version, id_sqlite >::init (
+ vw,
+ i.min_version_value,
+ db);
+ }
+
+ // From package.hxx:238:14
+ v = (vt) ? bpkg::version ((vt)->epoch, std::move ((vt)->upstream), std::move ((vt)->release), (vt)->revision, (vt)->iteration) : bpkg::optional_version ();
+ }
+
+ // max_version
+ //
+ {
+ ::butl::optional< ::bpkg::version >& v =
+ o.max_version;
+
+ ::bpkg::_optional_version vt;
+
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::get_null (
+ i.max_version_value))
+ wrapper_traits< ::bpkg::_optional_version >::set_null (vt);
+ else
+ {
+ ::bpkg::_version& vw =
+ wrapper_traits< ::bpkg::_optional_version >::set_ref (vt);
+
+ composite_value_traits< ::bpkg::_version, id_sqlite >::init (
+ vw,
+ i.max_version_value,
+ db);
+ }
+
+ // From package.hxx:238:14
+ v = (vt) ? bpkg::version ((vt)->epoch, std::move ((vt)->upstream), std::move ((vt)->release), (vt)->revision, (vt)->iteration) : bpkg::optional_version ();
+ }
+
+ // min_open
+ //
+ {
+ bool& v =
+ o.min_open;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.min_open_value,
+ i.min_open_null);
+ }
+
+ // max_open
+ //
+ {
+ bool& v =
+ o.max_open;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.max_open_value,
+ i.max_open_null);
+ }
+ }
+
+ // dependency
+ //
+
+ bool access::composite_value_traits< ::bpkg::dependency, 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;
+ }
+
+ // constraint
+ //
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::grow (
+ i.constraint_value, t + 1UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency, 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++;
+
+ // constraint
+ //
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::bind (
+ b + n, i.constraint_value, sk);
+ n += 16UL;
+ }
+
+ bool access::composite_value_traits< ::bpkg::dependency, 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 ());
+ }
+
+ // constraint
+ //
+ {
+ ::butl::optional< ::bpkg::version_constraint > const& v =
+ o.constraint;
+
+ if (wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::get_null (v))
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::set_null (
+ i.constraint_value, sk);
+ else
+ {
+ const::bpkg::version_constraint& vw =
+ wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::get_ref (v);
+
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::init (
+ i.constraint_value,
+ vw,
+ sk))
+ grew = true;
+ }
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency, 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);
+ }
+
+ // constraint
+ //
+ {
+ ::butl::optional< ::bpkg::version_constraint >& v =
+ o.constraint;
+
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::get_null (
+ i.constraint_value))
+ wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::set_null (v);
+ else
+ {
+ ::bpkg::version_constraint& vw =
+ wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::set_ref (v);
+
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::init (
+ vw,
+ i.constraint_value,
+ db);
+ }
+ }
+ }
+
+ // dependency_alternatives
+ //
+
+ bool access::composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // conditional
+ //
+ t[0UL] = false;
+
+ // buildtime
+ //
+ t[1UL] = false;
+
+ // comment
+ //
+ if (t[2UL])
+ {
+ i.comment_value.capacity (i.comment_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency_alternatives, 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);
+
+ // conditional
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.conditional_value;
+ b[n].is_null = &i.conditional_null;
+ n++;
+
+ // buildtime
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.buildtime_value;
+ b[n].is_null = &i.buildtime_null;
+ n++;
+
+ // comment
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.comment_value.data ();
+ b[n].size = &i.comment_size;
+ b[n].capacity = i.comment_value.capacity ();
+ b[n].is_null = &i.comment_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::dependency_alternatives, 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);
+
+ // conditional
+ //
+ {
+ bool const& v =
+ o.conditional;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.conditional_value,
+ is_null,
+ v);
+ i.conditional_null = is_null;
+ }
+
+ // buildtime
+ //
+ {
+ bool const& v =
+ o.buildtime;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.buildtime_value,
+ is_null,
+ v);
+ i.buildtime_null = is_null;
+ }
+
+ // comment
+ //
+ {
+ ::std::string const& v =
+ o.comment;
+
+ bool is_null (false);
+ std::size_t cap (i.comment_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.comment_value,
+ i.comment_size,
+ is_null,
+ v);
+ i.comment_null = is_null;
+ grew = grew || (cap != i.comment_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // conditional
+ //
+ {
+ bool& v =
+ o.conditional;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.conditional_value,
+ i.conditional_null);
+ }
+
+ // buildtime
+ //
+ {
+ bool& v =
+ o.buildtime;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.buildtime_value,
+ i.buildtime_null);
+ }
+
+ // comment
+ //
+ {
+ ::std::string& v =
+ o.comment;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.comment_value,
+ i.comment_size,
+ i.comment_null);
+ }
+ }
+
+ // test_dependency
+ //
+
+ bool access::composite_value_traits< ::bpkg::test_dependency, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // dependency base
+ //
+ if (composite_value_traits< ::bpkg::dependency, id_sqlite >::grow (
+ i, t + 0UL))
+ grew = true;
+
+ // type
+ //
+ if (t[17UL])
+ {
+ i.type_value.capacity (i.type_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::test_dependency, 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);
+
+ // dependency base
+ //
+ composite_value_traits< ::bpkg::dependency, id_sqlite >::bind (b + n, i, sk);
+ n += 17UL;
+
+ // type
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.type_value.data ();
+ b[n].size = &i.type_size;
+ b[n].capacity = i.type_value.capacity ();
+ b[n].is_null = &i.type_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::test_dependency, 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);
+
+ // dependency base
+ //
+ if (composite_value_traits< ::bpkg::dependency, id_sqlite >::init (i, o, sk))
+ grew = true;
+
+ // type
+ //
+ {
+ ::bpkg::test_dependency_type const& v =
+ o.type;
+
+ // From package.hxx:494:14
+ ::std::string const& vt =
+ to_string (v);
+
+ bool is_null (false);
+ std::size_t cap (i.type_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.type_value,
+ i.type_size,
+ is_null,
+ vt);
+ i.type_null = is_null;
+ grew = grew || (cap != i.type_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::test_dependency, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // dependency base
+ //
+ composite_value_traits< ::bpkg::dependency, id_sqlite >::init (o, i, db);
+
+ // type
+ //
+ {
+ ::bpkg::test_dependency_type& v =
+ o.type;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.type_value,
+ i.type_size,
+ i.type_null);
+
+ // From package.hxx:494:14
+ v = bpkg::to_test_dependency_type (vt);
+ }
+ }
+
+ // 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);
+ }
+ }
+
+ // upstream_version
+ //
+
+ bool access::composite_value_traits< ::bpkg::upstream_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::upstream_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::upstream_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.hxx:189: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.hxx:194: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::upstream_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.hxx:190: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.hxx:190:7
+ o = bpkg::version (0, std::move (v), std::string (), bpkg::nullopt, 0);
+ }
+
+ // release_
+ //
+ {
+ // From package.hxx:195: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.hxx:195:7
+ o = bpkg::version (0, std::move (o.upstream), std::move (v), bpkg::nullopt, 0);
+ }
+ }
+
+ // _repository_location
+ //
+
+ bool access::composite_value_traits< ::bpkg::_repository_location, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // url
+ //
+ if (t[0UL])
+ {
+ i.url_value.capacity (i.url_size);
+ grew = true;
+ }
+
+ // type
+ //
+ if (t[1UL])
+ {
+ i.type_value.capacity (i.type_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::_repository_location, 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);
+
+ // url
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.url_value.data ();
+ b[n].size = &i.url_size;
+ b[n].capacity = i.url_value.capacity ();
+ b[n].is_null = &i.url_null;
+ n++;
+
+ // type
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.type_value.data ();
+ b[n].size = &i.type_size;
+ b[n].capacity = i.type_value.capacity ();
+ b[n].is_null = &i.type_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::_repository_location, 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);
+
+ // url
+ //
+ {
+ ::bpkg::repository_url const& v =
+ o.url;
+
+ // From package.hxx:271:14
+ ::std::string const& vt =
+ (v).string ();
+
+ bool is_null (false);
+ std::size_t cap (i.url_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.url_value,
+ i.url_size,
+ is_null,
+ vt);
+ i.url_null = is_null;
+ grew = grew || (cap != i.url_value.capacity ());
+ }
+
+ // type
+ //
+ {
+ ::bpkg::repository_type const& v =
+ o.type;
+
+ // From package.hxx:275:14
+ ::std::string const& vt =
+ to_string (v);
+
+ bool is_null (false);
+ std::size_t cap (i.type_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.type_value,
+ i.type_size,
+ is_null,
+ vt);
+ i.type_null = is_null;
+ grew = grew || (cap != i.type_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::_repository_location, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // url
+ //
+ {
+ ::bpkg::repository_url& v =
+ o.url;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.url_value,
+ i.url_size,
+ i.url_null);
+
+ // From package.hxx:271:14
+ v = (vt).empty () ? bpkg::repository_url () : bpkg::repository_url (vt);
+ }
+
+ // type
+ //
+ {
+ ::bpkg::repository_type& v =
+ o.type;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.type_value,
+ i.type_size,
+ i.type_null);
+
+ // From package.hxx:275:14
+ v = bpkg::to_repository_type (vt);
+ }
+ }
+
+ // repository_fragment
+ //
+
+ struct access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::extra_statement_cache_type
+ {
+ sqlite::container_statements_impl< complements_traits > complements;
+ sqlite::container_statements_impl< prerequisites_traits > prerequisites;
+
+ extra_statement_cache_type (
+ sqlite::connection& c,
+ image_type&,
+ id_image_type&,
+ sqlite::binding& id,
+ sqlite::binding&)
+ : complements (c, id),
+ prerequisites (c, id)
+ {
+ }
+ };
+
+ // complements
+ //
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ select_statement[] =
+ "SELECT "
+ "\"repository_fragment_complements\".\"complement\" "
+ "FROM \"repository_fragment_complements\" "
+ "WHERE \"repository_fragment_complements\".\"repository_fragment\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ insert_statement[] =
+ "INSERT INTO \"repository_fragment_complements\" "
+ "(\"repository_fragment\", "
+ "\"complement\") "
+ "VALUES "
+ "(?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ delete_statement[] =
+ "DELETE FROM \"repository_fragment_complements\" "
+ "WHERE \"repository_fragment\"=?";
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // value
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = d.value_value.data ();
+ b[n].size = &d.value_size;
+ b[n].capacity = d.value_value.capacity ();
+ b[n].is_null = &d.value_null;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // value
+ //
+ if (t[0UL])
+ {
+ i.value_value.capacity (i.value_size);
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ init (data_image_type& i,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // value
+ //
+ {
+ typedef object_traits< ::bpkg::repository > obj_traits;
+ typedef odb::pointer_traits< value_type > wptr_traits;
+ typedef odb::pointer_traits< wptr_traits::strong_pointer_type > ptr_traits;
+
+ wptr_traits::strong_pointer_type sp (wptr_traits::lock (v));
+ bool is_null (ptr_traits::null_ptr (sp));
+ if (!is_null)
+ {
+ const obj_traits::id_type& ptr_id (
+ ptr_traits::object_id< ptr_traits::element_type > (sp));
+
+ std::size_t cap (i.value_value.capacity ());
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_image (
+ i.value_value,
+ i.value_size,
+ is_null,
+ ptr_id);
+ i.value_null = is_null;
+ grew = grew || (cap != i.value_value.capacity ());
+ }
+ else
+ throw null_pointer ();
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ init (value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // value
+ //
+ {
+ typedef object_traits< ::bpkg::repository > obj_traits;
+ typedef odb::pointer_traits< value_type > ptr_traits;
+
+ if (i.value_null)
+ v = ptr_traits::pointer_type ();
+ else
+ {
+ obj_traits::id_type ptr_id;
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_value (
+ ptr_id,
+ i.value_value,
+ i.value_size,
+ i.value_null);
+
+ v = ptr_traits::pointer_type (
+ *static_cast<sqlite::database*> (db), ptr_id);
+ }
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ insert (const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ select (value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::complements_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::erase (fs);
+ }
+
+ // prerequisites
+ //
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ select_statement[] =
+ "SELECT "
+ "\"repository_fragment_prerequisites\".\"prerequisite\" "
+ "FROM \"repository_fragment_prerequisites\" "
+ "WHERE \"repository_fragment_prerequisites\".\"repository_fragment\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ insert_statement[] =
+ "INSERT INTO \"repository_fragment_prerequisites\" "
+ "(\"repository_fragment\", "
+ "\"prerequisite\") "
+ "VALUES "
+ "(?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ delete_statement[] =
+ "DELETE FROM \"repository_fragment_prerequisites\" "
+ "WHERE \"repository_fragment\"=?";
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // value
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = d.value_value.data ();
+ b[n].size = &d.value_size;
+ b[n].capacity = d.value_value.capacity ();
+ b[n].is_null = &d.value_null;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // value
+ //
+ if (t[0UL])
+ {
+ i.value_value.capacity (i.value_size);
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ init (data_image_type& i,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // value
+ //
+ {
+ typedef object_traits< ::bpkg::repository > obj_traits;
+ typedef odb::pointer_traits< value_type > wptr_traits;
+ typedef odb::pointer_traits< wptr_traits::strong_pointer_type > ptr_traits;
+
+ wptr_traits::strong_pointer_type sp (wptr_traits::lock (v));
+ bool is_null (ptr_traits::null_ptr (sp));
+ if (!is_null)
+ {
+ const obj_traits::id_type& ptr_id (
+ ptr_traits::object_id< ptr_traits::element_type > (sp));
+
+ std::size_t cap (i.value_value.capacity ());
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_image (
+ i.value_value,
+ i.value_size,
+ is_null,
+ ptr_id);
+ i.value_null = is_null;
+ grew = grew || (cap != i.value_value.capacity ());
+ }
+ else
+ throw null_pointer ();
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ init (value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // value
+ //
+ {
+ typedef object_traits< ::bpkg::repository > obj_traits;
+ typedef odb::pointer_traits< value_type > ptr_traits;
+
+ if (i.value_null)
+ v = ptr_traits::pointer_type ();
+ else
+ {
+ obj_traits::id_type ptr_id;
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_value (
+ ptr_id,
+ i.value_value,
+ i.value_size,
+ i.value_null);
+
+ v = ptr_traits::pointer_type (
+ *static_cast<sqlite::database*> (db), ptr_id);
+ }
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ insert (const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ select (value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::prerequisites_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::erase (fs);
+ }
+
+ access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::id_type
+ access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ id (const image_type& i)
+ {
+ sqlite::database* db (0);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ id_type id;
+ {
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ id,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ return id;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, 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;
+ }
+
+ // location
+ //
+ if (composite_value_traits< ::bpkg::_repository_location, id_sqlite >::grow (
+ i.location_value, t + 1UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+
+ // name
+ //
+ if (sk != statement_update)
+ {
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ 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++;
+ }
+
+ // location
+ //
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::bind (
+ b + n, i.location_value, sk);
+ n += 2UL;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ bind (sqlite::bind* b, id_image_type& i)
+ {
+ std::size_t n (0);
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.id_value.data ();
+ b[n].size = &i.id_size;
+ b[n].capacity = i.id_value.capacity ();
+ b[n].is_null = &i.id_null;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ init (image_type& i,
+ const object_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
+ //
+ if (sk == statement_insert)
+ {
+ ::std::string const& v =
+ o.name;
+
+ bool is_null (false);
+ std::size_t cap (i.name_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ 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 ());
+ }
+
+ // location
+ //
+ {
+ ::bpkg::repository_location const& v =
+ o.location;
+
+ // From package.hxx:281:14
+ ::bpkg::_repository_location const& vt =
+ bpkg::_repository_location
+ {
+ (v).url (), (v).empty () ? bpkg::repository_type::pkg : (v).type ()
+ };
+
+
+ if (composite_value_traits< ::bpkg::_repository_location, id_sqlite >::init (
+ i.location_value,
+ vt,
+ sk))
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ init (object_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // name
+ //
+ {
+ ::std::string& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // location
+ //
+ {
+ // From package.hxx:349:7
+ ::bpkg::repository_location v;
+
+ ::bpkg::_repository_location vt;
+
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::init (
+ vt,
+ i.location_value,
+ db);
+
+ // From package.hxx:281:14
+ v = bpkg::repository_location (std::move ((vt).url), (vt).type);
+ // From package.hxx:349:7
+ o.location = std::move (v);
+ assert (o.name == o.location.canonical_name ());
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ init (id_image_type& i, const id_type& id)
+ {
+ bool grew (false);
+ {
+ bool is_null (false);
+ std::size_t cap (i.id_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.id_value,
+ i.id_size,
+ is_null,
+ id);
+ i.id_null = is_null;
+ grew = grew || (cap != i.id_value.capacity ());
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::persist_statement[] =
+ "INSERT INTO \"repository_fragment\" "
+ "(\"name\", "
+ "\"url\", "
+ "\"type\") "
+ "VALUES "
+ "(?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::find_statement[] =
+ "SELECT "
+ "\"repository_fragment\".\"name\", "
+ "\"repository_fragment\".\"url\", "
+ "\"repository_fragment\".\"type\" "
+ "FROM \"repository_fragment\" "
+ "WHERE \"repository_fragment\".\"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::update_statement[] =
+ "UPDATE \"repository_fragment\" "
+ "SET "
+ "\"url\"=?, "
+ "\"type\"=? "
+ "WHERE \"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::erase_statement[] =
+ "DELETE FROM \"repository_fragment\" "
+ "WHERE \"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::query_statement[] =
+ "SELECT "
+ "\"repository_fragment\".\"name\", "
+ "\"repository_fragment\".\"url\", "
+ "\"repository_fragment\".\"type\" "
+ "FROM \"repository_fragment\"";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::erase_query_statement[] =
+ "DELETE FROM \"repository_fragment\"";
+
+ const char access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::table_name[] =
+ "\"repository_fragment\"";
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ persist (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ callback (db,
+ obj,
+ callback_event::pre_persist);
+
+ image_type& im (sts.image ());
+ binding& imb (sts.insert_image_binding ());
+
+ if (init (im, obj, statement_insert))
+ im.version++;
+
+ if (im.version != sts.insert_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_insert);
+ sts.insert_image_version (im.version);
+ imb.version++;
+ }
+
+ insert_statement& st (sts.persist_statement ());
+ if (!st.execute ())
+ throw object_already_persistent ();
+
+ id_image_type& i (sts.id_image ());
+ init (i, id (obj));
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // complements
+ //
+ {
+ ::bpkg::repository_fragment::dependencies const& v =
+ obj.complements;
+
+ complements_traits::persist (
+ v,
+ esc.complements);
+ }
+
+ // prerequisites
+ //
+ {
+ ::bpkg::repository_fragment::dependencies const& v =
+ obj.prerequisites;
+
+ prerequisites_traits::persist (
+ v,
+ esc.prerequisites);
+ }
+
+ callback (db,
+ obj,
+ callback_event::post_persist);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ update (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+ using sqlite::update_statement;
+
+ callback (db, obj, callback_event::pre_update);
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ sqlite::connection& conn (tr.connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& idi (sts.id_image ());
+ init (idi, id (obj));
+
+ image_type& im (sts.image ());
+ if (init (im, obj, statement_update))
+ im.version++;
+
+ bool u (false);
+ binding& imb (sts.update_image_binding ());
+ if (im.version != sts.update_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_update);
+ sts.update_image_version (im.version);
+ imb.version++;
+ u = true;
+ }
+
+ binding& idb (sts.id_image_binding ());
+ if (idi.version != sts.update_id_image_version () ||
+ idb.version == 0)
+ {
+ if (idi.version != sts.id_image_version () ||
+ idb.version == 0)
+ {
+ bind (idb.bind, idi);
+ sts.id_image_version (idi.version);
+ idb.version++;
+ }
+
+ sts.update_id_image_version (idi.version);
+
+ if (!u)
+ imb.version++;
+ }
+
+ update_statement& st (sts.update_statement ());
+ if (st.execute () == 0)
+ throw object_not_persistent ();
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // complements
+ //
+ {
+ ::bpkg::repository_fragment::dependencies const& v =
+ obj.complements;
+
+ complements_traits::update (
+ v,
+ esc.complements);
+ }
+
+ // prerequisites
+ //
+ {
+ ::bpkg::repository_fragment::dependencies const& v =
+ obj.prerequisites;
+
+ prerequisites_traits::update (
+ v,
+ esc.prerequisites);
+ }
+
+ callback (db, obj, callback_event::post_update);
+ pointer_cache_traits::update (db, obj);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ erase (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& i (sts.id_image ());
+ init (i, id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // complements
+ //
+ {
+ complements_traits::erase (
+ esc.complements);
+ }
+
+ // prerequisites
+ //
+ {
+ prerequisites_traits::erase (
+ esc.prerequisites);
+ }
+
+ if (sts.erase_statement ().execute () != 1)
+ throw object_not_persistent ();
+
+ pointer_cache_traits::erase (db, id);
+ }
+
+ access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::pointer_type
+ access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ find (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ {
+ pointer_type p (pointer_cache_traits::find (db, id));
+
+ if (!pointer_traits::null_ptr (p))
+ return p;
+ }
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+
+ if (l.locked ())
+ {
+ if (!find_ (sts, &id))
+ return pointer_type ();
+ }
+
+ pointer_type p (
+ access::object_factory<object_type, pointer_type>::create ());
+ pointer_traits::guard pg (p);
+
+ pointer_cache_traits::insert_guard ig (
+ pointer_cache_traits::insert (db, id, p));
+
+ object_type& obj (pointer_traits::get_ref (p));
+
+ if (l.locked ())
+ {
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ pointer_cache_traits::load (ig.position ());
+ }
+ else
+ sts.delay_load (id, obj, ig.position ());
+
+ ig.release ();
+ pg.release ();
+ return p;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ find (database& db, const id_type& id, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ reference_cache_traits::position_type pos (
+ reference_cache_traits::insert (db, id, obj));
+ reference_cache_traits::insert_guard ig (pos);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ reference_cache_traits::load (pos);
+ ig.release ();
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ reload (database& db, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ const id_type& id (object_traits_impl::id (obj));
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, true);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ find_ (statements_type& sts,
+ const id_type* id)
+ {
+ using namespace sqlite;
+
+ id_image_type& i (sts.id_image ());
+ init (i, *id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ select_statement& st (sts.find_statement ());
+
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ if (grow (im, sts.select_image_truncated ()))
+ im.version++;
+
+ if (im.version != sts.select_image_version ())
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ load_ (statements_type& sts,
+ object_type& obj,
+ bool reload)
+ {
+ ODB_POTENTIALLY_UNUSED (reload);
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // complements
+ //
+ {
+ ::bpkg::repository_fragment::dependencies& v =
+ obj.complements;
+
+ complements_traits::load (
+ v,
+ esc.complements);
+ }
+
+ // prerequisites
+ //
+ {
+ ::bpkg::repository_fragment::dependencies& v =
+ obj.prerequisites;
+
+ prerequisites_traits::load (
+ v,
+ esc.prerequisites);
+ }
+ }
+
+ result< access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::object_type >
+ access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ q.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::object_result_impl<object_type> > r (
+ new (shared) sqlite::object_result_impl<object_type> (
+ q, st, sts, 0));
+
+ return result<object_type> (r);
+ }
+
+ unsigned long long access::object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::
+ erase_query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ std::string text (erase_query_statement);
+ if (!q.empty ())
+ {
+ text += ' ';
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ delete_statement st (
+ conn,
+ text,
+ q.parameters_binding ());
+
+ return st.execute ();
+ }
+
+ // repository_fragment_count
+ //
+
+ bool access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // result
+ //
+ t[0UL] = false;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // result
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.result_value;
+ b[n].is_null = &i.result_null;
+ n++;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // result
+ //
+ {
+ ::std::size_t& v =
+ o.result;
+
+ sqlite::value_traits<
+ ::std::size_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.result_value,
+ i.result_null);
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "count(*) ");
+
+ r += "FROM \"repository_fragment\"";
+
+ query_base_type c (
+ // From package.hxx:364:5
+ query_columns::name != "" && (q.empty () ? query_base_type::true_expr : q));
+
+ c.optimize ();
+
+ if (!c.empty ())
+ {
+ r += " ";
+ r += c.clause_prefix ();
+ r += c;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::repository_fragment_count, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ // fragment_type
+ //
+
+ bool access::composite_value_traits< ::bpkg::repository::fragment_type, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // friendly_name
+ //
+ if (t[0UL])
+ {
+ i.friendly_name_value.capacity (i.friendly_name_size);
+ grew = true;
+ }
+
+ // fragment
+ //
+ if (t[1UL])
+ {
+ i.fragment_value.capacity (i.fragment_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::repository::fragment_type, 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);
+
+ // friendly_name
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.friendly_name_value.data ();
+ b[n].size = &i.friendly_name_size;
+ b[n].capacity = i.friendly_name_value.capacity ();
+ b[n].is_null = &i.friendly_name_null;
+ n++;
+
+ // fragment
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.fragment_value.data ();
+ b[n].size = &i.fragment_size;
+ b[n].capacity = i.fragment_value.capacity ();
+ b[n].is_null = &i.fragment_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::repository::fragment_type, 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);
+
+ // friendly_name
+ //
+ {
+ ::std::string const& v =
+ o.friendly_name;
+
+ bool is_null (false);
+ std::size_t cap (i.friendly_name_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.friendly_name_value,
+ i.friendly_name_size,
+ is_null,
+ v);
+ i.friendly_name_null = is_null;
+ grew = grew || (cap != i.friendly_name_value.capacity ());
+ }
+
+ // fragment
+ //
+ {
+ ::odb::lazy_shared_ptr< ::bpkg::repository_fragment > const& v =
+ o.fragment;
+
+ typedef object_traits< ::bpkg::repository_fragment > obj_traits;
+ typedef odb::pointer_traits< ::odb::lazy_shared_ptr< ::bpkg::repository_fragment > > ptr_traits;
+
+ bool is_null (ptr_traits::null_ptr (v));
+ if (!is_null)
+ {
+ const obj_traits::id_type& ptr_id (
+ ptr_traits::object_id< ptr_traits::element_type > (v));
+
+ std::size_t cap (i.fragment_value.capacity ());
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_image (
+ i.fragment_value,
+ i.fragment_size,
+ is_null,
+ ptr_id);
+ i.fragment_null = is_null;
+ grew = grew || (cap != i.fragment_value.capacity ());
+ }
+ else
+ i.fragment_null = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::repository::fragment_type, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // friendly_name
+ //
+ {
+ ::std::string& v =
+ o.friendly_name;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.friendly_name_value,
+ i.friendly_name_size,
+ i.friendly_name_null);
+ }
+
+ // fragment
+ //
+ {
+ ::odb::lazy_shared_ptr< ::bpkg::repository_fragment >& v =
+ o.fragment;
+
+ typedef object_traits< ::bpkg::repository_fragment > obj_traits;
+ typedef odb::pointer_traits< ::odb::lazy_shared_ptr< ::bpkg::repository_fragment > > ptr_traits;
+
+ if (i.fragment_null)
+ v = ptr_traits::pointer_type ();
+ else
+ {
+ obj_traits::id_type ptr_id;
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_value (
+ ptr_id,
+ i.fragment_value,
+ i.fragment_size,
+ i.fragment_null);
+
+ v = ptr_traits::pointer_type (
+ *static_cast<sqlite::database*> (db), ptr_id);
+ }
+ }
+ }
+
+ // repository
+ //
+
+ struct access::object_traits_impl< ::bpkg::repository, id_sqlite >::extra_statement_cache_type
+ {
+ sqlite::container_statements_impl< fragments_traits > fragments;
+
+ extra_statement_cache_type (
+ sqlite::connection& c,
+ image_type&,
+ id_image_type&,
+ sqlite::binding& id,
+ sqlite::binding&)
+ : fragments (c, id)
+ {
+ }
+ };
+
+ // fragments
+ //
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ select_statement[] =
+ "SELECT "
+ "\"repository_fragments\".\"index\", "
+ "\"repository_fragments\".\"friendly_name\", "
+ "\"repository_fragments\".\"fragment\" "
+ "FROM \"repository_fragments\" "
+ "WHERE \"repository_fragments\".\"repository\"=? ORDER BY \"repository_fragments\".\"index\"";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ insert_statement[] =
+ "INSERT INTO \"repository_fragments\" "
+ "(\"repository\", "
+ "\"index\", "
+ "\"friendly_name\", "
+ "\"fragment\") "
+ "VALUES "
+ "(?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ delete_statement[] =
+ "DELETE FROM \"repository_fragments\" "
+ "WHERE \"repository\"=?";
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // index
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &d.index_value;
+ b[n].is_null = &d.index_null;
+ n++;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // index
+ //
+ t[0UL] = false;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 1UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ init (data_image_type& i,
+ index_type* j,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // index
+ //
+ if (j != 0)
+ {
+ bool is_null (false);
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_image (
+ i.index_value,
+ is_null,
+ *j);
+ i.index_null = is_null;
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ init (index_type& j,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // index
+ //
+ {
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_value (
+ j,
+ i.index_value,
+ i.index_null);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ insert (index_type i, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &i, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ select (index_type& i, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (i, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::fragments_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::erase (fs);
+ }
+
+ access::object_traits_impl< ::bpkg::repository, id_sqlite >::id_type
+ access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ id (const image_type& i)
+ {
+ sqlite::database* db (0);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ id_type id;
+ {
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ id,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ return id;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository, 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;
+ }
+
+ // location
+ //
+ if (composite_value_traits< ::bpkg::_repository_location, id_sqlite >::grow (
+ i.location_value, t + 1UL))
+ grew = true;
+
+ // certificate
+ //
+ if (t[3UL])
+ {
+ i.certificate_value.capacity (i.certificate_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+
+ // name
+ //
+ if (sk != statement_update)
+ {
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ 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++;
+ }
+
+ // location
+ //
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::bind (
+ b + n, i.location_value, sk);
+ n += 2UL;
+
+ // certificate
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.certificate_value.data ();
+ b[n].size = &i.certificate_size;
+ b[n].capacity = i.certificate_value.capacity ();
+ b[n].is_null = &i.certificate_null;
+ n++;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ bind (sqlite::bind* b, id_image_type& i)
+ {
+ std::size_t n (0);
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.id_value.data ();
+ b[n].size = &i.id_size;
+ b[n].capacity = i.id_value.capacity ();
+ b[n].is_null = &i.id_null;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ init (image_type& i,
+ const object_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
+ //
+ if (sk == statement_insert)
+ {
+ ::std::string const& v =
+ o.name;
+
+ bool is_null (false);
+ std::size_t cap (i.name_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ 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 ());
+ }
+
+ // location
+ //
+ {
+ ::bpkg::repository_location const& v =
+ o.location;
+
+ // From package.hxx:281:14
+ ::bpkg::_repository_location const& vt =
+ bpkg::_repository_location
+ {
+ (v).url (), (v).empty () ? bpkg::repository_type::pkg : (v).type ()
+ };
+
+
+ if (composite_value_traits< ::bpkg::_repository_location, id_sqlite >::init (
+ i.location_value,
+ vt,
+ sk))
+ grew = true;
+ }
+
+ // certificate
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.certificate;
+
+ bool is_null (true);
+ std::size_t cap (i.certificate_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.certificate_value,
+ i.certificate_size,
+ is_null,
+ v);
+ i.certificate_null = is_null;
+ grew = grew || (cap != i.certificate_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ init (object_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // name
+ //
+ {
+ ::std::string& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // location
+ //
+ {
+ // From package.hxx:405:7
+ ::bpkg::repository_location v;
+
+ ::bpkg::_repository_location vt;
+
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::init (
+ vt,
+ i.location_value,
+ db);
+
+ // From package.hxx:281:14
+ v = bpkg::repository_location (std::move ((vt).url), (vt).type);
+ // From package.hxx:405:7
+ o.location = std::move (v);
+ assert (o.name == o.location.canonical_name ());
+ }
+
+ // certificate
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.certificate;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.certificate_value,
+ i.certificate_size,
+ i.certificate_null);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ init (id_image_type& i, const id_type& id)
+ {
+ bool grew (false);
+ {
+ bool is_null (false);
+ std::size_t cap (i.id_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.id_value,
+ i.id_size,
+ is_null,
+ id);
+ i.id_null = is_null;
+ grew = grew || (cap != i.id_value.capacity ());
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::persist_statement[] =
+ "INSERT INTO \"repository\" "
+ "(\"name\", "
+ "\"url\", "
+ "\"type\", "
+ "\"certificate\") "
+ "VALUES "
+ "(?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::find_statement[] =
+ "SELECT "
+ "\"repository\".\"name\", "
+ "\"repository\".\"url\", "
+ "\"repository\".\"type\", "
+ "\"repository\".\"certificate\" "
+ "FROM \"repository\" "
+ "WHERE \"repository\".\"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::update_statement[] =
+ "UPDATE \"repository\" "
+ "SET "
+ "\"url\"=?, "
+ "\"type\"=?, "
+ "\"certificate\"=? "
+ "WHERE \"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::erase_statement[] =
+ "DELETE FROM \"repository\" "
+ "WHERE \"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::query_statement[] =
+ "SELECT "
+ "\"repository\".\"name\", "
+ "\"repository\".\"url\", "
+ "\"repository\".\"type\", "
+ "\"repository\".\"certificate\" "
+ "FROM \"repository\"";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::erase_query_statement[] =
+ "DELETE FROM \"repository\"";
+
+ const char access::object_traits_impl< ::bpkg::repository, id_sqlite >::table_name[] =
+ "\"repository\"";
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ persist (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ callback (db,
+ obj,
+ callback_event::pre_persist);
+
+ image_type& im (sts.image ());
+ binding& imb (sts.insert_image_binding ());
+
+ if (init (im, obj, statement_insert))
+ im.version++;
+
+ if (im.version != sts.insert_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_insert);
+ sts.insert_image_version (im.version);
+ imb.version++;
+ }
+
+ insert_statement& st (sts.persist_statement ());
+ if (!st.execute ())
+ throw object_already_persistent ();
+
+ id_image_type& i (sts.id_image ());
+ init (i, id (obj));
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // fragments
+ //
+ {
+ ::bpkg::repository::fragments_type const& v =
+ obj.fragments;
+
+ fragments_traits::persist (
+ v,
+ esc.fragments);
+ }
+
+ callback (db,
+ obj,
+ callback_event::post_persist);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ update (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+ using sqlite::update_statement;
+
+ callback (db, obj, callback_event::pre_update);
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ sqlite::connection& conn (tr.connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& idi (sts.id_image ());
+ init (idi, id (obj));
+
+ image_type& im (sts.image ());
+ if (init (im, obj, statement_update))
+ im.version++;
+
+ bool u (false);
+ binding& imb (sts.update_image_binding ());
+ if (im.version != sts.update_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_update);
+ sts.update_image_version (im.version);
+ imb.version++;
+ u = true;
+ }
+
+ binding& idb (sts.id_image_binding ());
+ if (idi.version != sts.update_id_image_version () ||
+ idb.version == 0)
+ {
+ if (idi.version != sts.id_image_version () ||
+ idb.version == 0)
+ {
+ bind (idb.bind, idi);
+ sts.id_image_version (idi.version);
+ idb.version++;
+ }
+
+ sts.update_id_image_version (idi.version);
+
+ if (!u)
+ imb.version++;
+ }
+
+ update_statement& st (sts.update_statement ());
+ if (st.execute () == 0)
+ throw object_not_persistent ();
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // fragments
+ //
+ {
+ ::bpkg::repository::fragments_type const& v =
+ obj.fragments;
+
+ fragments_traits::update (
+ v,
+ esc.fragments);
+ }
+
+ callback (db, obj, callback_event::post_update);
+ pointer_cache_traits::update (db, obj);
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ erase (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& i (sts.id_image ());
+ init (i, id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // fragments
+ //
+ {
+ fragments_traits::erase (
+ esc.fragments);
+ }
+
+ if (sts.erase_statement ().execute () != 1)
+ throw object_not_persistent ();
+
+ pointer_cache_traits::erase (db, id);
+ }
+
+ access::object_traits_impl< ::bpkg::repository, id_sqlite >::pointer_type
+ access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ find (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ {
+ pointer_type p (pointer_cache_traits::find (db, id));
+
+ if (!pointer_traits::null_ptr (p))
+ return p;
+ }
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+
+ if (l.locked ())
+ {
+ if (!find_ (sts, &id))
+ return pointer_type ();
+ }
+
+ pointer_type p (
+ access::object_factory<object_type, pointer_type>::create ());
+ pointer_traits::guard pg (p);
+
+ pointer_cache_traits::insert_guard ig (
+ pointer_cache_traits::insert (db, id, p));
+
+ object_type& obj (pointer_traits::get_ref (p));
+
+ if (l.locked ())
+ {
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ pointer_cache_traits::load (ig.position ());
+ }
+ else
+ sts.delay_load (id, obj, ig.position ());
+
+ ig.release ();
+ pg.release ();
+ return p;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ find (database& db, const id_type& id, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ reference_cache_traits::position_type pos (
+ reference_cache_traits::insert (db, id, obj));
+ reference_cache_traits::insert_guard ig (pos);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ reference_cache_traits::load (pos);
+ ig.release ();
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ reload (database& db, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ const id_type& id (object_traits_impl::id (obj));
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, true);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ find_ (statements_type& sts,
+ const id_type* id)
+ {
+ using namespace sqlite;
+
+ id_image_type& i (sts.id_image ());
+ init (i, *id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ select_statement& st (sts.find_statement ());
+
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ if (grow (im, sts.select_image_truncated ()))
+ im.version++;
+
+ if (im.version != sts.select_image_version ())
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ load_ (statements_type& sts,
+ object_type& obj,
+ bool reload)
+ {
+ ODB_POTENTIALLY_UNUSED (reload);
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // fragments
+ //
+ {
+ ::bpkg::repository::fragments_type& v =
+ obj.fragments;
+
+ fragments_traits::load (
+ v,
+ esc.fragments);
+ }
+ }
+
+ result< access::object_traits_impl< ::bpkg::repository, id_sqlite >::object_type >
+ access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ q.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::object_result_impl<object_type> > r (
+ new (shared) sqlite::object_result_impl<object_type> (
+ q, st, sts, 0));
+
+ return result<object_type> (r);
+ }
+
+ unsigned long long access::object_traits_impl< ::bpkg::repository, id_sqlite >::
+ erase_query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ std::string text (erase_query_statement);
+ if (!q.empty ())
+ {
+ text += ' ';
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ delete_statement st (
+ conn,
+ text,
+ q.parameters_binding ());
+
+ return st.execute ();
+ }
+
+ // repository_count
+ //
+
+ bool access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // result
+ //
+ t[0UL] = false;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // result
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.result_value;
+ b[n].is_null = &i.result_null;
+ n++;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // result
+ //
+ {
+ ::std::size_t& v =
+ o.result;
+
+ sqlite::value_traits<
+ ::std::size_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.result_value,
+ i.result_null);
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "count(*) ");
+
+ r += "FROM \"repository\"";
+
+ query_base_type c (
+ // From package.hxx:416:38
+ query_columns::name != "" && (q.empty () ? query_base_type::true_expr : q));
+
+ c.optimize ();
+
+ if (!c.empty ())
+ {
+ r += " ";
+ r += c.clause_prefix ();
+ r += c;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::repository_count, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ // package_location
+ //
+
+ bool access::composite_value_traits< ::bpkg::package_location, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // repository_fragment
+ //
+ if (t[0UL])
+ {
+ i.repository_fragment_value.capacity (i.repository_fragment_size);
+ grew = true;
+ }
+
+ // location
+ //
+ if (t[1UL])
+ {
+ i.location_value.capacity (i.location_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::package_location, 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);
+
+ // repository_fragment
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.repository_fragment_value.data ();
+ b[n].size = &i.repository_fragment_size;
+ b[n].capacity = i.repository_fragment_value.capacity ();
+ b[n].is_null = &i.repository_fragment_null;
+ n++;
+
+ // location
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.location_value.data ();
+ b[n].size = &i.location_size;
+ b[n].capacity = i.location_value.capacity ();
+ b[n].is_null = &i.location_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::package_location, 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);
+
+ // repository_fragment
+ //
+ {
+ ::odb::lazy_shared_ptr< ::bpkg::repository_fragment > const& v =
+ o.repository_fragment;
+
+ typedef object_traits< ::bpkg::repository_fragment > obj_traits;
+ typedef odb::pointer_traits< ::odb::lazy_shared_ptr< ::bpkg::repository_fragment > > ptr_traits;
+
+ bool is_null (ptr_traits::null_ptr (v));
+ if (!is_null)
+ {
+ const obj_traits::id_type& ptr_id (
+ ptr_traits::object_id< ptr_traits::element_type > (v));
+
+ std::size_t cap (i.repository_fragment_value.capacity ());
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_image (
+ i.repository_fragment_value,
+ i.repository_fragment_size,
+ is_null,
+ ptr_id);
+ i.repository_fragment_null = is_null;
+ grew = grew || (cap != i.repository_fragment_value.capacity ());
+ }
+ else
+ i.repository_fragment_null = true;
+ }
+
+ // location
+ //
+ {
+ ::butl::path const& v =
+ o.location;
+
+ // From package.hxx:56:14
+ ::std::string const& vt =
+ (v).representation ();
+
+ bool is_null (false);
+ std::size_t cap (i.location_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.location_value,
+ i.location_size,
+ is_null,
+ vt);
+ i.location_null = is_null;
+ grew = grew || (cap != i.location_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::package_location, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // repository_fragment
+ //
+ {
+ ::odb::lazy_shared_ptr< ::bpkg::repository_fragment >& v =
+ o.repository_fragment;
+
+ typedef object_traits< ::bpkg::repository_fragment > obj_traits;
+ typedef odb::pointer_traits< ::odb::lazy_shared_ptr< ::bpkg::repository_fragment > > ptr_traits;
+
+ if (i.repository_fragment_null)
+ v = ptr_traits::pointer_type ();
+ else
+ {
+ obj_traits::id_type ptr_id;
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_value (
+ ptr_id,
+ i.repository_fragment_value,
+ i.repository_fragment_size,
+ i.repository_fragment_null);
+
+ v = ptr_traits::pointer_type (
+ *static_cast<sqlite::database*> (db), ptr_id);
+ }
+ }
+
+ // location
+ //
+ {
+ ::butl::path& v =
+ o.location;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.location_value,
+ i.location_size,
+ i.location_null);
+
+ // From package.hxx:56:14
+ v = bpkg::path (vt);
+ }
+ }
+
+ // dependency_alternatives_ex
+ //
+
+ bool access::composite_value_traits< ::bpkg::dependency_alternatives_ex, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // dependency_alternatives base
+ //
+ if (composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::grow (
+ i, t + 0UL))
+ grew = true;
+
+ // type
+ //
+ if (t[3UL])
+ {
+ i.type_value.capacity (i.type_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency_alternatives_ex, 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);
+
+ // dependency_alternatives base
+ //
+ composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::bind (b + n, i, sk);
+ n += 3UL;
+
+ // type
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.type_value.data ();
+ b[n].size = &i.type_size;
+ b[n].capacity = i.type_value.capacity ();
+ b[n].is_null = &i.type_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::dependency_alternatives_ex, 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);
+
+ // dependency_alternatives base
+ //
+ if (composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::init (i, o, sk))
+ grew = true;
+
+ // type
+ //
+ {
+ ::butl::optional< ::bpkg::test_dependency_type > const& v =
+ o.type;
+
+ // From package.hxx:498:14
+ ::bpkg::optional_string const& vt =
+ (v) ? to_string ( * (v)) : bpkg::optional_string ();
+
+ bool is_null (true);
+ std::size_t cap (i.type_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_image (
+ i.type_value,
+ i.type_size,
+ is_null,
+ vt);
+ i.type_null = is_null;
+ grew = grew || (cap != i.type_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::dependency_alternatives_ex, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // dependency_alternatives base
+ //
+ composite_value_traits< ::bpkg::dependency_alternatives, id_sqlite >::init (o, i, db);
+
+ // type
+ //
+ {
+ ::butl::optional< ::bpkg::test_dependency_type >& v =
+ o.type;
+
+ ::bpkg::optional_string vt;
+
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.type_value,
+ i.type_size,
+ i.type_null);
+
+ // From package.hxx:498:14
+ v = (vt) ? bpkg::to_test_dependency_type ( * (vt)) : bpkg::optional_test_dependency_type ();
+ }
+ }
+
+ // available_package_id
+ //
+
+ bool access::composite_value_traits< ::bpkg::available_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::available_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::available_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::available_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);
+ }
+ }
+
+ // _dependency_key
+ //
+
+ bool access::composite_value_traits< ::bpkg::available_package::_dependency_key, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // outer
+ //
+ t[0UL] = false;
+
+ // inner
+ //
+ t[1UL] = false;
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::available_package::_dependency_key, 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);
+
+ // outer
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.outer_value;
+ b[n].is_null = &i.outer_null;
+ n++;
+
+ // inner
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.inner_value;
+ b[n].is_null = &i.inner_null;
+ n++;
+ }
+
+ bool access::composite_value_traits< ::bpkg::available_package::_dependency_key, 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);
+
+ // outer
+ //
+ {
+ ::bpkg::available_package::_dependency_alternatives_ex_type::key_type::outer_type const& v =
+ o.outer;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternatives_ex_type::key_type::outer_type,
+ sqlite::id_integer >::set_image (
+ i.outer_value,
+ is_null,
+ v);
+ i.outer_null = is_null;
+ }
+
+ // inner
+ //
+ {
+ ::bpkg::available_package::_dependency_alternatives_ex_type::key_type::inner_type const& v =
+ o.inner;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternatives_ex_type::key_type::inner_type,
+ sqlite::id_integer >::set_image (
+ i.inner_value,
+ is_null,
+ v);
+ i.inner_null = is_null;
+ }
+
+ return grew;
+ }
+
+ void access::composite_value_traits< ::bpkg::available_package::_dependency_key, id_sqlite >::
+ init (value_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // outer
+ //
+ {
+ ::bpkg::available_package::_dependency_alternatives_ex_type::key_type::outer_type& v =
+ o.outer;
+
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternatives_ex_type::key_type::outer_type,
+ sqlite::id_integer >::set_value (
+ v,
+ i.outer_value,
+ i.outer_null);
+ }
+
+ // inner
+ //
+ {
+ ::bpkg::available_package::_dependency_alternatives_ex_type::key_type::inner_type& v =
+ o.inner;
+
+ sqlite::value_traits<
+ ::bpkg::available_package::_dependency_alternatives_ex_type::key_type::inner_type,
+ sqlite::id_integer >::set_value (
+ v,
+ i.inner_value,
+ i.inner_null);
+ }
+ }
+
+ // available_package
+ //
+
+ struct access::object_traits_impl< ::bpkg::available_package, id_sqlite >::extra_statement_cache_type
+ {
+ sqlite::container_statements_impl< locations_traits > locations;
+ sqlite::container_statements_impl< dependencies_traits > dependencies;
+ sqlite::container_statements_impl< dependency_alternatives_ex_traits > dependency_alternatives_ex;
+ sqlite::container_statements_impl< tests_traits > tests;
+
+ extra_statement_cache_type (
+ sqlite::connection& c,
+ image_type&,
+ id_image_type&,
+ sqlite::binding& id,
+ sqlite::binding&)
+ : locations (c, id),
+ dependencies (c, id),
+ dependency_alternatives_ex (c, id),
+ tests (c, id)
+ {
+ }
+ };
+
+ // locations
+ //
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ select_statement[] =
+ "SELECT "
+ "\"available_package_locations\".\"repository_fragment\", "
+ "\"available_package_locations\".\"location\" "
+ "FROM \"available_package_locations\" "
+ "WHERE \"available_package_locations\".\"name\"=? AND \"available_package_locations\".\"version_epoch\"=? AND \"available_package_locations\".\"version_canonical_upstream\"=? AND \"available_package_locations\".\"version_canonical_release\"=? AND \"available_package_locations\".\"version_revision\"=? AND \"available_package_locations\".\"version_iteration\"=?";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ insert_statement[] =
+ "INSERT INTO \"available_package_locations\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"repository_fragment\", "
+ "\"location\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ delete_statement[] =
+ "DELETE FROM \"available_package_locations\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 0UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ init (data_image_type& i,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ init (value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ insert (index_type, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ select (index_type&, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = false;
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = false;
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = false;
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::locations_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = false;
+ container_traits_type::erase (fs);
+ }
+
+ // dependencies
+ //
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ select_statement[] =
+ "SELECT "
+ "\"available_package_dependencies\".\"index\", "
+ "\"available_package_dependencies\".\"conditional\", "
+ "\"available_package_dependencies\".\"buildtime\", "
+ "\"available_package_dependencies\".\"comment\", "
+ "\"available_package_dependencies\".\"type\" "
+ "FROM \"available_package_dependencies\" "
+ "WHERE \"available_package_dependencies\".\"name\"=? AND \"available_package_dependencies\".\"version_epoch\"=? AND \"available_package_dependencies\".\"version_canonical_upstream\"=? AND \"available_package_dependencies\".\"version_canonical_release\"=? AND \"available_package_dependencies\".\"version_revision\"=? AND \"available_package_dependencies\".\"version_iteration\"=? ORDER BY \"available_package_dependencies\".\"index\"";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ insert_statement[] =
+ "INSERT INTO \"available_package_dependencies\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"index\", "
+ "\"conditional\", "
+ "\"buildtime\", "
+ "\"comment\", "
+ "\"type\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ delete_statement[] =
+ "DELETE FROM \"available_package_dependencies\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // index
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &d.index_value;
+ b[n].is_null = &d.index_null;
+ n++;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // index
+ //
+ t[0UL] = false;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 1UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ init (data_image_type& i,
+ index_type* j,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // index
+ //
+ if (j != 0)
+ {
+ bool is_null (false);
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_image (
+ i.index_value,
+ is_null,
+ *j);
+ i.index_null = is_null;
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ init (index_type& j,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // index
+ //
+ {
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_value (
+ j,
+ i.index_value,
+ i.index_null);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ insert (index_type i, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &i, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ select (index_type& i, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (i, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependencies_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::erase (fs);
+ }
+
+ // dependency_alternatives_ex
+ //
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ select_statement[] =
+ "SELECT "
+ "\"available_package_dependency_alternatives\".\"dependency_index\", "
+ "\"available_package_dependency_alternatives\".\"index\", "
+ "\"available_package_dependency_alternatives\".\"dep_name\", "
+ "\"available_package_dependency_alternatives\".\"dep_min_version_epoch\", "
+ "\"available_package_dependency_alternatives\".\"dep_min_version_canonical_upstream\", "
+ "\"available_package_dependency_alternatives\".\"dep_min_version_canonical_release\", "
+ "\"available_package_dependency_alternatives\".\"dep_min_version_revision\", "
+ "\"available_package_dependency_alternatives\".\"dep_min_version_iteration\", "
+ "\"available_package_dependency_alternatives\".\"dep_min_version_upstream\", "
+ "\"available_package_dependency_alternatives\".\"dep_min_version_release\", "
+ "\"available_package_dependency_alternatives\".\"dep_max_version_epoch\", "
+ "\"available_package_dependency_alternatives\".\"dep_max_version_canonical_upstream\", "
+ "\"available_package_dependency_alternatives\".\"dep_max_version_canonical_release\", "
+ "\"available_package_dependency_alternatives\".\"dep_max_version_revision\", "
+ "\"available_package_dependency_alternatives\".\"dep_max_version_iteration\", "
+ "\"available_package_dependency_alternatives\".\"dep_max_version_upstream\", "
+ "\"available_package_dependency_alternatives\".\"dep_max_version_release\", "
+ "\"available_package_dependency_alternatives\".\"dep_min_open\", "
+ "\"available_package_dependency_alternatives\".\"dep_max_open\" "
+ "FROM \"available_package_dependency_alternatives\" "
+ "WHERE \"available_package_dependency_alternatives\".\"name\"=? AND \"available_package_dependency_alternatives\".\"version_epoch\"=? AND \"available_package_dependency_alternatives\".\"version_canonical_upstream\"=? AND \"available_package_dependency_alternatives\".\"version_canonical_release\"=? AND \"available_package_dependency_alternatives\".\"version_revision\"=? AND \"available_package_dependency_alternatives\".\"version_iteration\"=?";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ insert_statement[] =
+ "INSERT INTO \"available_package_dependency_alternatives\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"dependency_index\", "
+ "\"index\", "
+ "\"dep_name\", "
+ "\"dep_min_version_epoch\", "
+ "\"dep_min_version_canonical_upstream\", "
+ "\"dep_min_version_canonical_release\", "
+ "\"dep_min_version_revision\", "
+ "\"dep_min_version_iteration\", "
+ "\"dep_min_version_upstream\", "
+ "\"dep_min_version_release\", "
+ "\"dep_max_version_epoch\", "
+ "\"dep_max_version_canonical_upstream\", "
+ "\"dep_max_version_canonical_release\", "
+ "\"dep_max_version_revision\", "
+ "\"dep_max_version_iteration\", "
+ "\"dep_max_version_upstream\", "
+ "\"dep_max_version_release\", "
+ "\"dep_min_open\", "
+ "\"dep_max_open\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ delete_statement[] =
+ "DELETE FROM \"available_package_dependency_alternatives\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // key
+ //
+ composite_value_traits< key_type, id_sqlite >::bind (
+ b + n, d.key_value, sk);
+ n += 2UL;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // key
+ //
+ if (composite_value_traits< key_type, id_sqlite >::grow (
+ i.key_value, t + 0UL))
+ grew = true;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 2UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ init (data_image_type& i,
+ const key_type* k,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // key
+ //
+ if (k != 0)
+ {
+ composite_value_traits< key_type, id_sqlite >::init (
+ i.key_value,
+ *k,
+ sk);
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ init (key_type& k,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // key
+ //
+ {
+ composite_value_traits< key_type, id_sqlite >::init (
+ k,
+ i.key_value,
+ db);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ insert (const key_type& k, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &k, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ select (key_type& k, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (k, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::dependency_alternatives_ex_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::erase (fs);
+ }
+
+ // tests
+ //
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ select_statement[] =
+ "SELECT "
+ "\"available_package_tests\".\"index\", "
+ "\"available_package_tests\".\"test_name\", "
+ "\"available_package_tests\".\"test_min_version_epoch\", "
+ "\"available_package_tests\".\"test_min_version_canonical_upstream\", "
+ "\"available_package_tests\".\"test_min_version_canonical_release\", "
+ "\"available_package_tests\".\"test_min_version_revision\", "
+ "\"available_package_tests\".\"test_min_version_iteration\", "
+ "\"available_package_tests\".\"test_min_version_upstream\", "
+ "\"available_package_tests\".\"test_min_version_release\", "
+ "\"available_package_tests\".\"test_max_version_epoch\", "
+ "\"available_package_tests\".\"test_max_version_canonical_upstream\", "
+ "\"available_package_tests\".\"test_max_version_canonical_release\", "
+ "\"available_package_tests\".\"test_max_version_revision\", "
+ "\"available_package_tests\".\"test_max_version_iteration\", "
+ "\"available_package_tests\".\"test_max_version_upstream\", "
+ "\"available_package_tests\".\"test_max_version_release\", "
+ "\"available_package_tests\".\"test_min_open\", "
+ "\"available_package_tests\".\"test_max_open\", "
+ "\"available_package_tests\".\"test_type\" "
+ "FROM \"available_package_tests\" "
+ "WHERE \"available_package_tests\".\"name\"=? AND \"available_package_tests\".\"version_epoch\"=? AND \"available_package_tests\".\"version_canonical_upstream\"=? AND \"available_package_tests\".\"version_canonical_release\"=? AND \"available_package_tests\".\"version_revision\"=? AND \"available_package_tests\".\"version_iteration\"=? ORDER BY \"available_package_tests\".\"index\"";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ insert_statement[] =
+ "INSERT INTO \"available_package_tests\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"index\", "
+ "\"test_name\", "
+ "\"test_min_version_epoch\", "
+ "\"test_min_version_canonical_upstream\", "
+ "\"test_min_version_canonical_release\", "
+ "\"test_min_version_revision\", "
+ "\"test_min_version_iteration\", "
+ "\"test_min_version_upstream\", "
+ "\"test_min_version_release\", "
+ "\"test_max_version_epoch\", "
+ "\"test_max_version_canonical_upstream\", "
+ "\"test_max_version_canonical_release\", "
+ "\"test_max_version_revision\", "
+ "\"test_max_version_iteration\", "
+ "\"test_max_version_upstream\", "
+ "\"test_max_version_release\", "
+ "\"test_min_open\", "
+ "\"test_max_open\", "
+ "\"test_type\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ delete_statement[] =
+ "DELETE FROM \"available_package_tests\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // index
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &d.index_value;
+ b[n].is_null = &d.index_null;
+ n++;
+
+ // value
+ //
+ composite_value_traits< value_type, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // index
+ //
+ t[0UL] = false;
+
+ // value
+ //
+ if (composite_value_traits< value_type, id_sqlite >::grow (
+ i.value_value, t + 1UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ init (data_image_type& i,
+ index_type* j,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // index
+ //
+ if (j != 0)
+ {
+ bool is_null (false);
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_image (
+ i.index_value,
+ is_null,
+ *j);
+ i.index_null = is_null;
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< value_type, id_sqlite >::init (
+ i.value_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ init (index_type& j,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // index
+ //
+ {
+ sqlite::value_traits<
+ index_type,
+ sqlite::id_integer >::set_value (
+ j,
+ i.index_value,
+ i.index_null);
+ }
+
+ // value
+ //
+ {
+ composite_value_traits< value_type, id_sqlite >::init (
+ v,
+ i.value_value,
+ db);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ insert (index_type i, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &i, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ select (index_type& i, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (i, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::tests_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ fs.ordered_ = true;
+ container_traits_type::erase (fs);
+ }
+
+ access::object_traits_impl< ::bpkg::available_package, id_sqlite >::id_type
+ access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ id (const image_type& i)
+ {
+ sqlite::database* db (0);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ id_type id;
+ {
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::init (
+ id,
+ i.id_value,
+ db);
+ }
+
+ return id;
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // id
+ //
+ if (composite_value_traits< ::bpkg::available_package_id, id_sqlite >::grow (
+ i.id_value, t + 0UL))
+ grew = true;
+
+ // version
+ //
+ if (composite_value_traits< ::bpkg::upstream_version, id_sqlite >::grow (
+ i.version_value, t + 6UL))
+ grew = true;
+
+ // sha256sum
+ //
+ if (t[8UL])
+ {
+ i.sha256sum_value.capacity (i.sha256sum_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+
+ // id
+ //
+ if (sk != statement_update)
+ {
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::bind (
+ b + n, i.id_value, sk);
+ n += 6UL;
+ }
+
+ // version
+ //
+ composite_value_traits< ::bpkg::upstream_version, id_sqlite >::bind (
+ b + n, i.version_value, sk);
+ n += 2UL;
+
+ // sha256sum
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.sha256sum_value.data ();
+ b[n].size = &i.sha256sum_size;
+ b[n].capacity = i.sha256sum_value.capacity ();
+ b[n].is_null = &i.sha256sum_null;
+ n++;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ bind (sqlite::bind* b, id_image_type& i)
+ {
+ std::size_t n (0);
+ sqlite::statement_kind sk (sqlite::statement_select);
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::bind (
+ b + n, i.id_value, sk);
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ init (image_type& i,
+ const object_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // id
+ //
+ if (sk == statement_insert)
+ {
+ ::bpkg::available_package_id const& v =
+ o.id;
+
+ if (composite_value_traits< ::bpkg::available_package_id, id_sqlite >::init (
+ i.id_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ // version
+ //
+ {
+ ::bpkg::upstream_version const& v =
+ o.version;
+
+ if (composite_value_traits< ::bpkg::upstream_version, id_sqlite >::init (
+ i.version_value,
+ v,
+ sk))
+ grew = true;
+ }
+
+ // sha256sum
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.sha256sum;
+
+ bool is_null (true);
+ std::size_t cap (i.sha256sum_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.sha256sum_value,
+ i.sha256sum_size,
+ is_null,
+ v);
+ i.sha256sum_null = is_null;
+ grew = grew || (cap != i.sha256sum_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ init (object_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // id
+ //
+ {
+ ::bpkg::available_package_id& v =
+ o.id;
+
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::init (
+ v,
+ i.id_value,
+ db);
+ }
+
+ // version
+ //
+ {
+ // From package.hxx:653:32
+ ::bpkg::upstream_version v;
+
+ composite_value_traits< ::bpkg::upstream_version, id_sqlite >::init (
+ v,
+ i.version_value,
+ db);
+
+ // From package.hxx:653:32
+ o.version.init (o.id.version, (v));
+ }
+
+ // sha256sum
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.sha256sum;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.sha256sum_value,
+ i.sha256sum_size,
+ i.sha256sum_null);
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ init (id_image_type& i, const id_type& id)
+ {
+ bool grew (false);
+ sqlite::statement_kind sk (sqlite::statement_select);
+ {
+ if (composite_value_traits< ::bpkg::available_package_id, id_sqlite >::init (
+ i.id_value,
+ id,
+ sk))
+ grew = true;
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::persist_statement[] =
+ "INSERT INTO \"available_package\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"version_upstream\", "
+ "\"version_release\", "
+ "\"sha256sum\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::find_statement[] =
+ "SELECT "
+ "\"available_package\".\"name\", "
+ "\"available_package\".\"version_epoch\", "
+ "\"available_package\".\"version_canonical_upstream\", "
+ "\"available_package\".\"version_canonical_release\", "
+ "\"available_package\".\"version_revision\", "
+ "\"available_package\".\"version_iteration\", "
+ "\"available_package\".\"version_upstream\", "
+ "\"available_package\".\"version_release\", "
+ "\"available_package\".\"sha256sum\" "
+ "FROM \"available_package\" "
+ "WHERE \"available_package\".\"name\"=? AND \"available_package\".\"version_epoch\"=? AND \"available_package\".\"version_canonical_upstream\"=? AND \"available_package\".\"version_canonical_release\"=? AND \"available_package\".\"version_revision\"=? AND \"available_package\".\"version_iteration\"=?";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::update_statement[] =
+ "UPDATE \"available_package\" "
+ "SET "
+ "\"version_upstream\"=?, "
+ "\"version_release\"=?, "
+ "\"sha256sum\"=? "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::erase_statement[] =
+ "DELETE FROM \"available_package\" "
+ "WHERE \"name\"=? AND \"version_epoch\"=? AND \"version_canonical_upstream\"=? AND \"version_canonical_release\"=? AND \"version_revision\"=? AND \"version_iteration\"=?";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::query_statement[] =
+ "SELECT "
+ "\"available_package\".\"name\", "
+ "\"available_package\".\"version_epoch\", "
+ "\"available_package\".\"version_canonical_upstream\", "
+ "\"available_package\".\"version_canonical_release\", "
+ "\"available_package\".\"version_revision\", "
+ "\"available_package\".\"version_iteration\", "
+ "\"available_package\".\"version_upstream\", "
+ "\"available_package\".\"version_release\", "
+ "\"available_package\".\"sha256sum\" "
+ "FROM \"available_package\"";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::erase_query_statement[] =
+ "DELETE FROM \"available_package\"";
+
+ const char access::object_traits_impl< ::bpkg::available_package, id_sqlite >::table_name[] =
+ "\"available_package\"";
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ persist (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ callback (db,
+ obj,
+ callback_event::pre_persist);
+
+ image_type& im (sts.image ());
+ binding& imb (sts.insert_image_binding ());
+
+ if (init (im, obj, statement_insert))
+ im.version++;
+
+ if (im.version != sts.insert_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_insert);
+ sts.insert_image_version (im.version);
+ imb.version++;
+ }
+
+ insert_statement& st (sts.persist_statement ());
+ if (!st.execute ())
+ throw object_already_persistent ();
+
+ id_image_type& i (sts.id_image ());
+ init (i, id (obj));
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // locations
+ //
+ {
+ ::butl::small_vector< ::bpkg::package_location, 1 > const& v =
+ obj.locations;
+
+ locations_traits::persist (
+ v,
+ esc.locations);
+ }
+
+ // dependencies
+ //
+ {
+ ::bpkg::available_package::dependencies_type const& v =
+ obj.dependencies;
+
+ dependencies_traits::persist (
+ v,
+ esc.dependencies);
+ }
+
+ // dependency_alternatives_ex
+ //
+ {
+ // From package.hxx:672:7
+ ::std::map< ::odb::nested_key< ::bpkg::dependency_alternatives_ex >, ::bpkg::dependency > const& v =
+ odb::nested_get (obj.dependencies);
+
+ dependency_alternatives_ex_traits::persist (
+ v,
+ esc.dependency_alternatives_ex);
+ }
+
+ // tests
+ //
+ {
+ ::butl::small_vector< ::bpkg::test_dependency, 1 > const& v =
+ obj.tests;
+
+ tests_traits::persist (
+ v,
+ esc.tests);
+ }
+
+ callback (db,
+ obj,
+ callback_event::post_persist);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ update (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+ using sqlite::update_statement;
+
+ callback (db, obj, callback_event::pre_update);
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ sqlite::connection& conn (tr.connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& idi (sts.id_image ());
+ init (idi, id (obj));
+
+ image_type& im (sts.image ());
+ if (init (im, obj, statement_update))
+ im.version++;
+
+ bool u (false);
+ binding& imb (sts.update_image_binding ());
+ if (im.version != sts.update_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_update);
+ sts.update_image_version (im.version);
+ imb.version++;
+ u = true;
+ }
+
+ binding& idb (sts.id_image_binding ());
+ if (idi.version != sts.update_id_image_version () ||
+ idb.version == 0)
+ {
+ if (idi.version != sts.id_image_version () ||
+ idb.version == 0)
+ {
+ bind (idb.bind, idi);
+ sts.id_image_version (idi.version);
+ idb.version++;
+ }
+
+ sts.update_id_image_version (idi.version);
+
+ if (!u)
+ imb.version++;
+ }
+
+ update_statement& st (sts.update_statement ());
+ if (st.execute () == 0)
+ throw object_not_persistent ();
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // locations
+ //
+ {
+ ::butl::small_vector< ::bpkg::package_location, 1 > const& v =
+ obj.locations;
+
+ locations_traits::update (
+ v,
+ esc.locations);
+ }
+
+ // dependencies
+ //
+ {
+ ::bpkg::available_package::dependencies_type const& v =
+ obj.dependencies;
+
+ dependencies_traits::update (
+ v,
+ esc.dependencies);
+ }
+
+ // dependency_alternatives_ex
+ //
+ {
+ // From package.hxx:672:7
+ ::std::map< ::odb::nested_key< ::bpkg::dependency_alternatives_ex >, ::bpkg::dependency > const& v =
+ odb::nested_get (obj.dependencies);
+
+ dependency_alternatives_ex_traits::update (
+ v,
+ esc.dependency_alternatives_ex);
+ }
+
+ // tests
+ //
+ {
+ ::butl::small_vector< ::bpkg::test_dependency, 1 > const& v =
+ obj.tests;
+
+ tests_traits::update (
+ v,
+ esc.tests);
+ }
+
+ callback (db, obj, callback_event::post_update);
+ pointer_cache_traits::update (db, obj);
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ erase (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& i (sts.id_image ());
+ init (i, id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // locations
+ //
+ {
+ locations_traits::erase (
+ esc.locations);
+ }
+
+ // dependencies
+ //
+ {
+ dependencies_traits::erase (
+ esc.dependencies);
+ }
+
+ // dependency_alternatives_ex
+ //
+ {
+ dependency_alternatives_ex_traits::erase (
+ esc.dependency_alternatives_ex);
+ }
+
+ // tests
+ //
+ {
+ tests_traits::erase (
+ esc.tests);
+ }
+
+ if (sts.erase_statement ().execute () != 1)
+ throw object_not_persistent ();
+
+ pointer_cache_traits::erase (db, id);
+ }
+
+ access::object_traits_impl< ::bpkg::available_package, id_sqlite >::pointer_type
+ access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ find (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ {
+ pointer_type p (pointer_cache_traits::find (db, id));
+
+ if (!pointer_traits::null_ptr (p))
+ return p;
+ }
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+
+ if (l.locked ())
+ {
+ if (!find_ (sts, &id))
+ return pointer_type ();
+ }
+
+ pointer_type p (
+ access::object_factory<object_type, pointer_type>::create ());
+ pointer_traits::guard pg (p);
+
+ pointer_cache_traits::insert_guard ig (
+ pointer_cache_traits::insert (db, id, p));
+
+ object_type& obj (pointer_traits::get_ref (p));
+
+ if (l.locked ())
+ {
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ pointer_cache_traits::load (ig.position ());
+ }
+ else
+ sts.delay_load (id, obj, ig.position ());
+
+ ig.release ();
+ pg.release ();
+ return p;
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ find (database& db, const id_type& id, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ reference_cache_traits::position_type pos (
+ reference_cache_traits::insert (db, id, obj));
+ reference_cache_traits::insert_guard ig (pos);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ reference_cache_traits::load (pos);
+ ig.release ();
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ reload (database& db, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ const id_type& id (object_traits_impl::id (obj));
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, true);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ find_ (statements_type& sts,
+ const id_type* id)
+ {
+ using namespace sqlite;
+
+ id_image_type& i (sts.id_image ());
+ init (i, *id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ select_statement& st (sts.find_statement ());
+
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ if (grow (im, sts.select_image_truncated ()))
+ im.version++;
+
+ if (im.version != sts.select_image_version ())
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ load_ (statements_type& sts,
+ object_type& obj,
+ bool reload)
+ {
+ ODB_POTENTIALLY_UNUSED (reload);
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // locations
+ //
+ {
+ ::butl::small_vector< ::bpkg::package_location, 1 >& v =
+ obj.locations;
+
+ locations_traits::load (
+ v,
+ esc.locations);
+ }
+
+ // dependencies
+ //
+ {
+ ::bpkg::available_package::dependencies_type& v =
+ obj.dependencies;
+
+ dependencies_traits::load (
+ v,
+ esc.dependencies);
+ }
+
+ // dependency_alternatives_ex
+ //
+ {
+ ::std::map< ::odb::nested_key< ::bpkg::dependency_alternatives_ex >, ::bpkg::dependency > v;
+
+ dependency_alternatives_ex_traits::load (
+ v,
+ esc.dependency_alternatives_ex);
+
+ // From package.hxx:673:7
+ odb::nested_set (obj.dependencies, std::move (v));
+ }
+
+ // tests
+ //
+ {
+ ::butl::small_vector< ::bpkg::test_dependency, 1 >& v =
+ obj.tests;
+
+ tests_traits::load (
+ v,
+ esc.tests);
+ }
+ }
+
+ result< access::object_traits_impl< ::bpkg::available_package, id_sqlite >::object_type >
+ access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ q.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::object_result_impl<object_type> > r (
+ new (shared) sqlite::object_result_impl<object_type> (
+ q, st, sts, 0));
+
+ return result<object_type> (r);
+ }
+
+ unsigned long long access::object_traits_impl< ::bpkg::available_package, id_sqlite >::
+ erase_query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ std::string text (erase_query_statement);
+ if (!q.empty ())
+ {
+ text += ' ';
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ delete_statement st (
+ conn,
+ text,
+ q.parameters_binding ());
+
+ return st.execute ();
+ }
+
+ // available_package_count
+ //
+
+ bool access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // result
+ //
+ t[0UL] = false;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // result
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.result_value;
+ b[n].is_null = &i.result_null;
+ n++;
+ }
+
+ void access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // result
+ //
+ {
+ ::std::size_t& v =
+ o.result;
+
+ sqlite::value_traits<
+ ::std::size_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.result_value,
+ i.result_null);
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "count(*) ");
+
+ r += "FROM \"available_package\"";
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::available_package_count, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ // available_test
+ //
+
+ const char alias_traits< ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::available_test, id_sqlite >::package_tag>::
+ table_name[] = "\"package\"";
+
+ bool access::view_traits_impl< ::bpkg::available_test, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // package
+ //
+ if (object_traits_impl< ::bpkg::available_package, id_sqlite >::grow (
+ i.package_value, t + 0UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::available_test, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // package
+ //
+ object_traits_impl< ::bpkg::available_package, id_sqlite >::bind (
+ b + n, i.package_value, sk);
+ n += 9UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::available_test, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ // package pre
+ //
+ typedef ::bpkg::available_package package_object_type;
+ typedef object_traits_impl<package_object_type, id_sqlite> package_object_traits;
+ typedef package_object_traits::pointer_type package_pointer_type;
+ typedef package_object_traits::pointer_traits package_pointer_traits;
+ typedef package_object_traits::pointer_cache_traits package_cache_traits;
+
+ package_object_traits::id_type package_id;
+ package_pointer_type package_p;
+ package_pointer_traits::guard package_pg;
+ package_cache_traits::insert_guard package_ig;
+ package_object_type* package_o (0);
+
+ {
+ if (!composite_value_traits< package_object_traits::id_type, id_sqlite >::get_null (
+ i.package_value.id_value))
+ {
+ package_id = package_object_traits::id (i.package_value);
+ package_p = package_cache_traits::find (*db, package_id);
+
+ if (package_pointer_traits::null_ptr (package_p))
+ {
+ package_p = object_factory<package_object_type, package_pointer_type>::create ();
+ package_pg.reset (package_p);
+ package_ig.reset (package_cache_traits::insert (*db, package_id, package_p));
+ package_o = package_pointer_traits::get_ptr (package_p);
+ }
+ }
+ }
+
+ // package
+ //
+ {
+ if (package_o != 0)
+ {
+ package_object_traits::callback (*db, *package_o, callback_event::pre_load);
+ package_object_traits::init (*package_o, i.package_value, db);
+ package_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<package_object_type> ());
+ package_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ package_object_traits::id_image_type& i (sts.id_image ());
+ package_object_traits::init (i, package_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ package_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ package_object_traits::load_ (sts, *package_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // package post
+ //
+ {
+ if (package_o != 0)
+ {
+ package_object_traits::callback (*db, *package_o, callback_event::post_load);
+ package_cache_traits::load (package_ig.position ());
+ package_ig.release ();
+ package_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.package = ::std::shared_ptr< ::bpkg::available_package > (
+ std::move (package_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::available_test, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::available_test, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"package\".\"name\", "
+ "\"package\".\"version_epoch\", "
+ "\"package\".\"version_canonical_upstream\", "
+ "\"package\".\"version_canonical_release\", "
+ "\"package\".\"version_revision\", "
+ "\"package\".\"version_iteration\", "
+ "\"package\".\"version_upstream\", "
+ "\"package\".\"version_release\", "
+ "\"package\".\"sha256sum\" ");
+
+ r += "FROM \"available_package\" AS \"package\"";
+
+ r += " INNER JOIN \"available_package_dependencies\" AS \"pd\" ON";
+ // From package.hxx:701:5
+ r += "pd.type IN ('tests', 'examples', 'benchmarks') AND pd.name = " + query_columns::id.name + "AND" + "pd.version_epoch = " + query_columns::id.version.epoch + "AND" + "pd.version_canonical_upstream = " + query_columns::id.version.canonical_upstream + "AND" + "pd.version_canonical_release = " + query_columns::id.version.canonical_release + "AND" + "pd.version_revision = " + query_columns::id.version.revision + "AND" + "pd.version_iteration = " + query_columns::id.version.iteration;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::available_test, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::available_test, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ // available_main
+ //
+
+ const char alias_traits< ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::available_main, id_sqlite >::package_tag>::
+ table_name[] = "\"package\"";
+
+ bool access::view_traits_impl< ::bpkg::available_main, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // package
+ //
+ if (object_traits_impl< ::bpkg::available_package, id_sqlite >::grow (
+ i.package_value, t + 0UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::available_main, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // package
+ //
+ object_traits_impl< ::bpkg::available_package, id_sqlite >::bind (
+ b + n, i.package_value, sk);
+ n += 9UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::available_main, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ // package pre
+ //
+ typedef ::bpkg::available_package package_object_type;
+ typedef object_traits_impl<package_object_type, id_sqlite> package_object_traits;
+ typedef package_object_traits::pointer_type package_pointer_type;
+ typedef package_object_traits::pointer_traits package_pointer_traits;
+ typedef package_object_traits::pointer_cache_traits package_cache_traits;
+
+ package_object_traits::id_type package_id;
+ package_pointer_type package_p;
+ package_pointer_traits::guard package_pg;
+ package_cache_traits::insert_guard package_ig;
+ package_object_type* package_o (0);
+
+ {
+ if (!composite_value_traits< package_object_traits::id_type, id_sqlite >::get_null (
+ i.package_value.id_value))
+ {
+ package_id = package_object_traits::id (i.package_value);
+ package_p = package_cache_traits::find (*db, package_id);
+
+ if (package_pointer_traits::null_ptr (package_p))
+ {
+ package_p = object_factory<package_object_type, package_pointer_type>::create ();
+ package_pg.reset (package_p);
+ package_ig.reset (package_cache_traits::insert (*db, package_id, package_p));
+ package_o = package_pointer_traits::get_ptr (package_p);
+ }
+ }
+ }
+
+ // package
+ //
+ {
+ if (package_o != 0)
+ {
+ package_object_traits::callback (*db, *package_o, callback_event::pre_load);
+ package_object_traits::init (*package_o, i.package_value, db);
+ package_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<package_object_type> ());
+ package_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ package_object_traits::id_image_type& i (sts.id_image ());
+ package_object_traits::init (i, package_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ package_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ package_object_traits::load_ (sts, *package_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // package post
+ //
+ {
+ if (package_o != 0)
+ {
+ package_object_traits::callback (*db, *package_o, callback_event::post_load);
+ package_cache_traits::load (package_ig.position ());
+ package_ig.release ();
+ package_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.package = ::std::shared_ptr< ::bpkg::available_package > (
+ std::move (package_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::available_main, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::available_main, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT DISTINCT "
+ "\"package\".\"name\", "
+ "\"package\".\"version_epoch\", "
+ "\"package\".\"version_canonical_upstream\", "
+ "\"package\".\"version_canonical_release\", "
+ "\"package\".\"version_revision\", "
+ "\"package\".\"version_iteration\", "
+ "\"package\".\"version_upstream\", "
+ "\"package\".\"version_release\", "
+ "\"package\".\"sha256sum\" ");
+
+ r += "FROM \"available_package\" AS \"package\"";
+
+ r += " INNER JOIN \"available_package_tests\" AS \"pt\" ON";
+ // From package.hxx:720:5
+ r += "pt.name = " + query_columns::id.name + "AND" + "pt.version_epoch = " + query_columns::id.version.epoch + "AND" + "pt.version_canonical_upstream = " + query_columns::id.version.canonical_upstream + "AND" + "pt.version_canonical_release = " + query_columns::id.version.canonical_release + "AND" + "pt.version_revision = " + query_columns::id.version.revision + "AND" + "pt.version_iteration = " + query_columns::id.version.iteration;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::available_main, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::available_main, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ // selected_package
+ //
+
+ struct access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::extra_statement_cache_type
+ {
+ sqlite::container_statements_impl< prerequisites_traits > prerequisites;
+
+ extra_statement_cache_type (
+ sqlite::connection& c,
+ image_type&,
+ id_image_type&,
+ sqlite::binding& id,
+ sqlite::binding&)
+ : prerequisites (c, id)
+ {
+ }
+ };
+
+ // prerequisites
+ //
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ select_statement[] =
+ "SELECT "
+ "\"selected_package_prerequisites\".\"prerequisite\", "
+ "\"selected_package_prerequisites\".\"min_version_epoch\", "
+ "\"selected_package_prerequisites\".\"min_version_canonical_upstream\", "
+ "\"selected_package_prerequisites\".\"min_version_canonical_release\", "
+ "\"selected_package_prerequisites\".\"min_version_revision\", "
+ "\"selected_package_prerequisites\".\"min_version_iteration\", "
+ "\"selected_package_prerequisites\".\"min_version_upstream\", "
+ "\"selected_package_prerequisites\".\"min_version_release\", "
+ "\"selected_package_prerequisites\".\"max_version_epoch\", "
+ "\"selected_package_prerequisites\".\"max_version_canonical_upstream\", "
+ "\"selected_package_prerequisites\".\"max_version_canonical_release\", "
+ "\"selected_package_prerequisites\".\"max_version_revision\", "
+ "\"selected_package_prerequisites\".\"max_version_iteration\", "
+ "\"selected_package_prerequisites\".\"max_version_upstream\", "
+ "\"selected_package_prerequisites\".\"max_version_release\", "
+ "\"selected_package_prerequisites\".\"min_open\", "
+ "\"selected_package_prerequisites\".\"max_open\" "
+ "FROM \"selected_package_prerequisites\" "
+ "WHERE \"selected_package_prerequisites\".\"package\"=?";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ insert_statement[] =
+ "INSERT INTO \"selected_package_prerequisites\" "
+ "(\"package\", "
+ "\"prerequisite\", "
+ "\"min_version_epoch\", "
+ "\"min_version_canonical_upstream\", "
+ "\"min_version_canonical_release\", "
+ "\"min_version_revision\", "
+ "\"min_version_iteration\", "
+ "\"min_version_upstream\", "
+ "\"min_version_release\", "
+ "\"max_version_epoch\", "
+ "\"max_version_canonical_upstream\", "
+ "\"max_version_canonical_release\", "
+ "\"max_version_revision\", "
+ "\"max_version_iteration\", "
+ "\"max_version_upstream\", "
+ "\"max_version_release\", "
+ "\"min_open\", "
+ "\"max_open\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ delete_statement[] =
+ "DELETE FROM \"selected_package_prerequisites\" "
+ "WHERE \"package\"=?";
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ bind (sqlite::bind* b,
+ const sqlite::bind* id,
+ std::size_t id_size,
+ data_image_type& d)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ size_t n (0);
+
+ // object_id
+ //
+ if (id != 0)
+ std::memcpy (&b[n], id, id_size * sizeof (id[0]));
+ n += id_size;
+
+ // key
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::package_name,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = d.key_value.data ();
+ b[n].size = &d.key_size;
+ b[n].capacity = d.key_value.capacity ();
+ b[n].is_null = &d.key_null;
+ n++;
+
+ // value
+ //
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::bind (
+ b + n, d.value_value, sk);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ grow (data_image_type& i,
+ bool* t)
+ {
+ bool grew (false);
+
+ // key
+ //
+ if (t[0UL])
+ {
+ i.key_value.capacity (i.key_size);
+ grew = true;
+ }
+
+ // value
+ //
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::grow (
+ i.value_value, t + 1UL))
+ grew = true;
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ init (data_image_type& i,
+ const key_type* k,
+ const value_type& v)
+ {
+ using namespace sqlite;
+
+ statement_kind sk (statement_insert);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ bool grew (false);
+
+ // key
+ //
+ if (k != 0)
+ {
+ typedef object_traits< ::bpkg::selected_package > obj_traits;
+ typedef odb::pointer_traits< key_type > ptr_traits;
+
+ bool is_null (ptr_traits::null_ptr (*k));
+ if (!is_null)
+ {
+ const obj_traits::id_type& ptr_id (
+ ptr_traits::object_id< ptr_traits::element_type > (*k));
+
+ std::size_t cap (i.key_value.capacity ());
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_image (
+ i.key_value,
+ i.key_size,
+ is_null,
+ ptr_id);
+ i.key_null = is_null;
+ grew = grew || (cap != i.key_value.capacity ());
+ }
+ else
+ throw null_pointer ();
+ }
+
+ // value
+ //
+ {
+ if (wrapper_traits< value_type >::get_null (v))
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::set_null (
+ i.value_value, sk);
+ else
+ {
+ const::bpkg::version_constraint& vw =
+ wrapper_traits< value_type >::get_ref (v);
+
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::init (
+ i.value_value,
+ vw,
+ sk))
+ grew = true;
+ }
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ init (key_type& k,
+ value_type& v,
+ const data_image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // key
+ //
+ {
+ typedef object_traits< ::bpkg::selected_package > obj_traits;
+ typedef odb::pointer_traits< key_type > ptr_traits;
+
+ if (i.key_null)
+ k = ptr_traits::pointer_type ();
+ else
+ {
+ obj_traits::id_type ptr_id;
+ sqlite::value_traits<
+ obj_traits::id_type,
+ sqlite::id_text >::set_value (
+ ptr_id,
+ i.key_value,
+ i.key_size,
+ i.key_null);
+
+ k = ptr_traits::pointer_type (
+ *static_cast<sqlite::database*> (db), ptr_id);
+ }
+ }
+
+ // value
+ //
+ {
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::get_null (
+ i.value_value))
+ wrapper_traits< value_type >::set_null (v);
+ else
+ {
+ ::bpkg::version_constraint& vw =
+ wrapper_traits< value_type >::set_ref (v);
+
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::init (
+ vw,
+ i.value_value,
+ db);
+ }
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ insert (const key_type& k, const value_type& v, void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (di, &k, v);
+
+ if (sts.data_binding_test_version ())
+ {
+ const binding& id (sts.id_binding ());
+ bind (sts.data_bind (), id.bind, id.count, di);
+ sts.data_binding_update_version ();
+ }
+
+ if (!sts.insert_statement ().execute ())
+ throw object_already_persistent ();
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ select (key_type& k, value_type& v, void* d)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ data_image_type& di (sts.data_image ());
+
+ init (k, v, di, &sts.connection ().database ());
+
+ select_statement& st (sts.select_statement ());
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, sts.id_binding ().count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ delete_ (void* d)
+ {
+ using namespace sqlite;
+
+ statements_type& sts (*static_cast< statements_type* > (d));
+ sts.delete_statement ().execute ();
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ persist (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::persist (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ load (container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+ using sqlite::select_statement;
+
+ const binding& id (sts.id_binding ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), id.bind, id.count, sts.data_image ());
+ sts.data_binding_update_version ();
+ }
+
+ select_statement& st (sts.select_statement ());
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ data_image_type& di (sts.data_image ());
+ grow (di, sts.select_image_truncated ());
+
+ if (sts.data_binding_test_version ())
+ {
+ bind (sts.data_bind (), 0, id.count, di);
+ sts.data_binding_update_version ();
+ st.refetch ();
+ }
+ }
+
+ bool more (r != select_statement::no_data);
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::load (c, more, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ update (const container_type& c,
+ statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::update (c, fs);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::prerequisites_traits::
+ erase (statements_type& sts)
+ {
+ using namespace sqlite;
+
+ functions_type& fs (sts.functions ());
+ container_traits_type::erase (fs);
+ }
+
+ access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::id_type
+ access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ id (const image_type& i)
+ {
+ sqlite::database* db (0);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ id_type id;
+ {
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::set_value (
+ id,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ return id;
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, 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::_version, id_sqlite >::grow (
+ i.version_value, t + 1UL))
+ grew = true;
+
+ // state
+ //
+ if (t[8UL])
+ {
+ i.state_value.capacity (i.state_size);
+ grew = true;
+ }
+
+ // substate
+ //
+ if (t[9UL])
+ {
+ i.substate_value.capacity (i.substate_size);
+ grew = true;
+ }
+
+ // hold_package
+ //
+ t[10UL] = false;
+
+ // hold_version
+ //
+ t[11UL] = false;
+
+ // repository_fragment
+ //
+ if (composite_value_traits< ::bpkg::_repository_location, id_sqlite >::grow (
+ i.repository_fragment_value, t + 12UL))
+ grew = true;
+
+ // archive
+ //
+ if (t[14UL])
+ {
+ i.archive_value.capacity (i.archive_size);
+ grew = true;
+ }
+
+ // purge_archive
+ //
+ t[15UL] = false;
+
+ // src_root
+ //
+ if (t[16UL])
+ {
+ i.src_root_value.capacity (i.src_root_size);
+ grew = true;
+ }
+
+ // purge_src
+ //
+ t[17UL] = false;
+
+ // manifest_checksum
+ //
+ if (t[18UL])
+ {
+ i.manifest_checksum_value.capacity (i.manifest_checksum_size);
+ grew = true;
+ }
+
+ // out_root
+ //
+ if (t[19UL])
+ {
+ i.out_root_value.capacity (i.out_root_size);
+ grew = true;
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+
+ // name
+ //
+ if (sk != statement_update)
+ {
+ 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::_version, id_sqlite >::bind (
+ b + n, i.version_value, sk);
+ n += 7UL;
+
+ // state
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.state_value.data ();
+ b[n].size = &i.state_size;
+ b[n].capacity = i.state_value.capacity ();
+ b[n].is_null = &i.state_null;
+ n++;
+
+ // substate
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.substate_value.data ();
+ b[n].size = &i.substate_size;
+ b[n].capacity = i.substate_value.capacity ();
+ b[n].is_null = &i.substate_null;
+ n++;
+
+ // hold_package
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.hold_package_value;
+ b[n].is_null = &i.hold_package_null;
+ n++;
+
+ // hold_version
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.hold_version_value;
+ b[n].is_null = &i.hold_version_null;
+ n++;
+
+ // repository_fragment
+ //
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::bind (
+ b + n, i.repository_fragment_value, sk);
+ n += 2UL;
+
+ // archive
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.archive_value.data ();
+ b[n].size = &i.archive_size;
+ b[n].capacity = i.archive_value.capacity ();
+ b[n].is_null = &i.archive_null;
+ n++;
+
+ // purge_archive
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.purge_archive_value;
+ b[n].is_null = &i.purge_archive_null;
+ n++;
+
+ // src_root
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.src_root_value.data ();
+ b[n].size = &i.src_root_size;
+ b[n].capacity = i.src_root_value.capacity ();
+ b[n].is_null = &i.src_root_null;
+ n++;
+
+ // purge_src
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.purge_src_value;
+ b[n].is_null = &i.purge_src_null;
+ n++;
+
+ // manifest_checksum
+ //
+ b[n].type = sqlite::image_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.manifest_checksum_value.data ();
+ b[n].size = &i.manifest_checksum_size;
+ b[n].capacity = i.manifest_checksum_value.capacity ();
+ b[n].is_null = &i.manifest_checksum_null;
+ n++;
+
+ // out_root
+ //
+ b[n].type = sqlite::image_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.out_root_value.data ();
+ b[n].size = &i.out_root_size;
+ b[n].capacity = i.out_root_value.capacity ();
+ b[n].is_null = &i.out_root_null;
+ n++;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ bind (sqlite::bind* b, id_image_type& i)
+ {
+ std::size_t n (0);
+ b[n].type = sqlite::image_traits<
+ ::bpkg::package_name,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.id_value.data ();
+ b[n].size = &i.id_size;
+ b[n].capacity = i.id_value.capacity ();
+ b[n].is_null = &i.id_null;
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ init (image_type& i,
+ const object_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
+ //
+ if (sk == statement_insert)
+ {
+ ::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::selected_package::version_type const& v =
+ o.version;
+
+ // From package.hxx:221:14
+ ::bpkg::_version const& vt =
+ bpkg::_version
+ {
+ (v).epoch, (v).canonical_upstream, (v).canonical_release, (v).revision, (v).iteration, (v).upstream, (v).release
+ };
+
+
+ if (composite_value_traits< ::bpkg::_version, id_sqlite >::init (
+ i.version_value,
+ vt,
+ sk))
+ grew = true;
+ }
+
+ // state
+ //
+ {
+ ::bpkg::package_state const& v =
+ o.state;
+
+ // From package.hxx:804:14
+ ::std::string const& vt =
+ to_string (v);
+
+ bool is_null (false);
+ std::size_t cap (i.state_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.state_value,
+ i.state_size,
+ is_null,
+ vt);
+ i.state_null = is_null;
+ grew = grew || (cap != i.state_value.capacity ());
+ }
+
+ // substate
+ //
+ {
+ ::bpkg::package_substate const& v =
+ o.substate;
+
+ // From package.hxx:825:14
+ ::std::string const& vt =
+ to_string (v);
+
+ bool is_null (false);
+ std::size_t cap (i.substate_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.substate_value,
+ i.substate_size,
+ is_null,
+ vt);
+ i.substate_null = is_null;
+ grew = grew || (cap != i.substate_value.capacity ());
+ }
+
+ // hold_package
+ //
+ {
+ bool const& v =
+ o.hold_package;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.hold_package_value,
+ is_null,
+ v);
+ i.hold_package_null = is_null;
+ }
+
+ // hold_version
+ //
+ {
+ bool const& v =
+ o.hold_version;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.hold_version_value,
+ is_null,
+ v);
+ i.hold_version_null = is_null;
+ }
+
+ // repository_fragment
+ //
+ {
+ ::bpkg::repository_location const& v =
+ o.repository_fragment;
+
+ // From package.hxx:281:14
+ ::bpkg::_repository_location const& vt =
+ bpkg::_repository_location
+ {
+ (v).url (), (v).empty () ? bpkg::repository_type::pkg : (v).type ()
+ };
+
+
+ if (composite_value_traits< ::bpkg::_repository_location, id_sqlite >::init (
+ i.repository_fragment_value,
+ vt,
+ sk))
+ grew = true;
+ }
+
+ // archive
+ //
+ {
+ ::butl::optional< ::butl::basic_path< char, ::butl::any_path_kind< char > > > const& v =
+ o.archive;
+
+ // From package.hxx:59:14
+ ::bpkg::optional_string const& vt =
+ (v) ? (v)->string () : bpkg::optional_string ();
+
+ bool is_null (true);
+ std::size_t cap (i.archive_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_image (
+ i.archive_value,
+ i.archive_size,
+ is_null,
+ vt);
+ i.archive_null = is_null;
+ grew = grew || (cap != i.archive_value.capacity ());
+ }
+
+ // purge_archive
+ //
+ {
+ bool const& v =
+ o.purge_archive;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.purge_archive_value,
+ is_null,
+ v);
+ i.purge_archive_null = is_null;
+ }
+
+ // src_root
+ //
+ {
+ ::butl::optional< ::butl::basic_path< char, ::butl::dir_path_kind< char > > > const& v =
+ o.src_root;
+
+ // From package.hxx:66:14
+ ::bpkg::optional_string const& vt =
+ (v) ? (v)->string () : bpkg::optional_string ();
+
+ bool is_null (true);
+ std::size_t cap (i.src_root_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_image (
+ i.src_root_value,
+ i.src_root_size,
+ is_null,
+ vt);
+ i.src_root_null = is_null;
+ grew = grew || (cap != i.src_root_value.capacity ());
+ }
+
+ // purge_src
+ //
+ {
+ bool const& v =
+ o.purge_src;
+
+ bool is_null (false);
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_image (
+ i.purge_src_value,
+ is_null,
+ v);
+ i.purge_src_null = is_null;
+ }
+
+ // manifest_checksum
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > > const& v =
+ o.manifest_checksum;
+
+ bool is_null (true);
+ std::size_t cap (i.manifest_checksum_value.capacity ());
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_image (
+ i.manifest_checksum_value,
+ i.manifest_checksum_size,
+ is_null,
+ v);
+ i.manifest_checksum_null = is_null;
+ grew = grew || (cap != i.manifest_checksum_value.capacity ());
+ }
+
+ // out_root
+ //
+ {
+ ::butl::optional< ::butl::basic_path< char, ::butl::dir_path_kind< char > > > const& v =
+ o.out_root;
+
+ // From package.hxx:66:14
+ ::bpkg::optional_string const& vt =
+ (v) ? (v)->string () : bpkg::optional_string ();
+
+ bool is_null (true);
+ std::size_t cap (i.out_root_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_image (
+ i.out_root_value,
+ i.out_root_size,
+ is_null,
+ vt);
+ i.out_root_null = is_null;
+ grew = grew || (cap != i.out_root_value.capacity ());
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ init (object_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::selected_package::version_type& v =
+ o.version;
+
+ ::bpkg::_version vt;
+
+ composite_value_traits< ::bpkg::_version, id_sqlite >::init (
+ vt,
+ i.version_value,
+ db);
+
+ // From package.hxx:221:14
+ v = bpkg::version ((vt).epoch, std::move ((vt).upstream), std::move ((vt).release), (vt).revision, (vt).iteration);
+ }
+
+ // state
+ //
+ {
+ ::bpkg::package_state& v =
+ o.state;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.state_value,
+ i.state_size,
+ i.state_null);
+
+ // From package.hxx:804:14
+ v = bpkg::to_package_state (vt);
+ }
+
+ // substate
+ //
+ {
+ ::bpkg::package_substate& v =
+ o.substate;
+
+ ::std::string vt;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.substate_value,
+ i.substate_size,
+ i.substate_null);
+
+ // From package.hxx:825:14
+ v = bpkg::to_package_substate (vt);
+ }
+
+ // hold_package
+ //
+ {
+ bool& v =
+ o.hold_package;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.hold_package_value,
+ i.hold_package_null);
+ }
+
+ // hold_version
+ //
+ {
+ bool& v =
+ o.hold_version;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.hold_version_value,
+ i.hold_version_null);
+ }
+
+ // repository_fragment
+ //
+ {
+ ::bpkg::repository_location& v =
+ o.repository_fragment;
+
+ ::bpkg::_repository_location vt;
+
+ composite_value_traits< ::bpkg::_repository_location, id_sqlite >::init (
+ vt,
+ i.repository_fragment_value,
+ db);
+
+ // From package.hxx:281:14
+ v = bpkg::repository_location (std::move ((vt).url), (vt).type);
+ }
+
+ // archive
+ //
+ {
+ ::butl::optional< ::butl::basic_path< char, ::butl::any_path_kind< char > > >& v =
+ o.archive;
+
+ ::bpkg::optional_string vt;
+
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.archive_value,
+ i.archive_size,
+ i.archive_null);
+
+ // From package.hxx:59:14
+ v = (vt) ? bpkg::path ( * (vt)) : bpkg::optional_path ();
+ }
+
+ // purge_archive
+ //
+ {
+ bool& v =
+ o.purge_archive;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.purge_archive_value,
+ i.purge_archive_null);
+ }
+
+ // src_root
+ //
+ {
+ ::butl::optional< ::butl::basic_path< char, ::butl::dir_path_kind< char > > >& v =
+ o.src_root;
+
+ ::bpkg::optional_string vt;
+
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.src_root_value,
+ i.src_root_size,
+ i.src_root_null);
+
+ // From package.hxx:66:14
+ v = (vt) ? bpkg::dir_path ( * (vt)) : bpkg::optional_dir_path ();
+ }
+
+ // purge_src
+ //
+ {
+ bool& v =
+ o.purge_src;
+
+ sqlite::value_traits<
+ bool,
+ sqlite::id_integer >::set_value (
+ v,
+ i.purge_src_value,
+ i.purge_src_null);
+ }
+
+ // manifest_checksum
+ //
+ {
+ ::butl::optional< ::std::basic_string< char > >& v =
+ o.manifest_checksum;
+
+ sqlite::value_traits<
+ ::butl::optional< ::std::basic_string< char > >,
+ sqlite::id_text >::set_value (
+ v,
+ i.manifest_checksum_value,
+ i.manifest_checksum_size,
+ i.manifest_checksum_null);
+ }
+
+ // out_root
+ //
+ {
+ ::butl::optional< ::butl::basic_path< char, ::butl::dir_path_kind< char > > >& v =
+ o.out_root;
+
+ ::bpkg::optional_string vt;
+
+ sqlite::value_traits<
+ ::bpkg::optional_string,
+ sqlite::id_text >::set_value (
+ vt,
+ i.out_root_value,
+ i.out_root_size,
+ i.out_root_null);
+
+ // From package.hxx:66:14
+ v = (vt) ? bpkg::dir_path ( * (vt)) : bpkg::optional_dir_path ();
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ init (id_image_type& i, const id_type& id)
+ {
+ bool grew (false);
+ {
+ bool is_null (false);
+ std::size_t cap (i.id_value.capacity ());
+ sqlite::value_traits<
+ ::bpkg::package_name,
+ sqlite::id_text >::set_image (
+ i.id_value,
+ i.id_size,
+ is_null,
+ id);
+ i.id_null = is_null;
+ grew = grew || (cap != i.id_value.capacity ());
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::persist_statement[] =
+ "INSERT INTO \"selected_package\" "
+ "(\"name\", "
+ "\"version_epoch\", "
+ "\"version_canonical_upstream\", "
+ "\"version_canonical_release\", "
+ "\"version_revision\", "
+ "\"version_iteration\", "
+ "\"version_upstream\", "
+ "\"version_release\", "
+ "\"state\", "
+ "\"substate\", "
+ "\"hold_package\", "
+ "\"hold_version\", "
+ "\"repository_fragment_url\", "
+ "\"repository_fragment_type\", "
+ "\"archive\", "
+ "\"purge_archive\", "
+ "\"src_root\", "
+ "\"purge_src\", "
+ "\"manifest_checksum\", "
+ "\"out_root\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::find_statement[] =
+ "SELECT "
+ "\"selected_package\".\"name\", "
+ "\"selected_package\".\"version_epoch\", "
+ "\"selected_package\".\"version_canonical_upstream\", "
+ "\"selected_package\".\"version_canonical_release\", "
+ "\"selected_package\".\"version_revision\", "
+ "\"selected_package\".\"version_iteration\", "
+ "\"selected_package\".\"version_upstream\", "
+ "\"selected_package\".\"version_release\", "
+ "\"selected_package\".\"state\", "
+ "\"selected_package\".\"substate\", "
+ "\"selected_package\".\"hold_package\", "
+ "\"selected_package\".\"hold_version\", "
+ "\"selected_package\".\"repository_fragment_url\", "
+ "\"selected_package\".\"repository_fragment_type\", "
+ "\"selected_package\".\"archive\", "
+ "\"selected_package\".\"purge_archive\", "
+ "\"selected_package\".\"src_root\", "
+ "\"selected_package\".\"purge_src\", "
+ "\"selected_package\".\"manifest_checksum\", "
+ "\"selected_package\".\"out_root\" "
+ "FROM \"selected_package\" "
+ "WHERE \"selected_package\".\"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::update_statement[] =
+ "UPDATE \"selected_package\" "
+ "SET "
+ "\"version_epoch\"=?, "
+ "\"version_canonical_upstream\"=?, "
+ "\"version_canonical_release\"=?, "
+ "\"version_revision\"=?, "
+ "\"version_iteration\"=?, "
+ "\"version_upstream\"=?, "
+ "\"version_release\"=?, "
+ "\"state\"=?, "
+ "\"substate\"=?, "
+ "\"hold_package\"=?, "
+ "\"hold_version\"=?, "
+ "\"repository_fragment_url\"=?, "
+ "\"repository_fragment_type\"=?, "
+ "\"archive\"=?, "
+ "\"purge_archive\"=?, "
+ "\"src_root\"=?, "
+ "\"purge_src\"=?, "
+ "\"manifest_checksum\"=?, "
+ "\"out_root\"=? "
+ "WHERE \"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::erase_statement[] =
+ "DELETE FROM \"selected_package\" "
+ "WHERE \"name\"=?";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::query_statement[] =
+ "SELECT "
+ "\"selected_package\".\"name\", "
+ "\"selected_package\".\"version_epoch\", "
+ "\"selected_package\".\"version_canonical_upstream\", "
+ "\"selected_package\".\"version_canonical_release\", "
+ "\"selected_package\".\"version_revision\", "
+ "\"selected_package\".\"version_iteration\", "
+ "\"selected_package\".\"version_upstream\", "
+ "\"selected_package\".\"version_release\", "
+ "\"selected_package\".\"state\", "
+ "\"selected_package\".\"substate\", "
+ "\"selected_package\".\"hold_package\", "
+ "\"selected_package\".\"hold_version\", "
+ "\"selected_package\".\"repository_fragment_url\", "
+ "\"selected_package\".\"repository_fragment_type\", "
+ "\"selected_package\".\"archive\", "
+ "\"selected_package\".\"purge_archive\", "
+ "\"selected_package\".\"src_root\", "
+ "\"selected_package\".\"purge_src\", "
+ "\"selected_package\".\"manifest_checksum\", "
+ "\"selected_package\".\"out_root\" "
+ "FROM \"selected_package\"";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::erase_query_statement[] =
+ "DELETE FROM \"selected_package\"";
+
+ const char access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::table_name[] =
+ "\"selected_package\"";
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ persist (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ callback (db,
+ obj,
+ callback_event::pre_persist);
+
+ image_type& im (sts.image ());
+ binding& imb (sts.insert_image_binding ());
+
+ if (init (im, obj, statement_insert))
+ im.version++;
+
+ if (im.version != sts.insert_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_insert);
+ sts.insert_image_version (im.version);
+ imb.version++;
+ }
+
+ insert_statement& st (sts.persist_statement ());
+ if (!st.execute ())
+ throw object_already_persistent ();
+
+ id_image_type& i (sts.id_image ());
+ init (i, id (obj));
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // prerequisites
+ //
+ {
+ ::bpkg::package_prerequisites const& v =
+ obj.prerequisites;
+
+ prerequisites_traits::persist (
+ v,
+ esc.prerequisites);
+ }
+
+ callback (db,
+ obj,
+ callback_event::post_persist);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ update (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+ using sqlite::update_statement;
+
+ callback (db, obj, callback_event::pre_update);
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ sqlite::connection& conn (tr.connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& idi (sts.id_image ());
+ init (idi, id (obj));
+
+ image_type& im (sts.image ());
+ if (init (im, obj, statement_update))
+ im.version++;
+
+ bool u (false);
+ binding& imb (sts.update_image_binding ());
+ if (im.version != sts.update_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_update);
+ sts.update_image_version (im.version);
+ imb.version++;
+ u = true;
+ }
+
+ binding& idb (sts.id_image_binding ());
+ if (idi.version != sts.update_id_image_version () ||
+ idb.version == 0)
+ {
+ if (idi.version != sts.id_image_version () ||
+ idb.version == 0)
+ {
+ bind (idb.bind, idi);
+ sts.id_image_version (idi.version);
+ idb.version++;
+ }
+
+ sts.update_id_image_version (idi.version);
+
+ if (!u)
+ imb.version++;
+ }
+
+ update_statement& st (sts.update_statement ());
+ if (st.execute () == 0)
+ throw object_not_persistent ();
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // prerequisites
+ //
+ {
+ ::bpkg::package_prerequisites const& v =
+ obj.prerequisites;
+
+ prerequisites_traits::update (
+ v,
+ esc.prerequisites);
+ }
+
+ callback (db, obj, callback_event::post_update);
+ pointer_cache_traits::update (db, obj);
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ erase (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& i (sts.id_image ());
+ init (i, id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // prerequisites
+ //
+ {
+ prerequisites_traits::erase (
+ esc.prerequisites);
+ }
+
+ if (sts.erase_statement ().execute () != 1)
+ throw object_not_persistent ();
+
+ pointer_cache_traits::erase (db, id);
+ }
+
+ access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::pointer_type
+ access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ find (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ {
+ pointer_type p (pointer_cache_traits::find (db, id));
+
+ if (!pointer_traits::null_ptr (p))
+ return p;
+ }
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+
+ if (l.locked ())
+ {
+ if (!find_ (sts, &id))
+ return pointer_type ();
+ }
+
+ pointer_type p (
+ access::object_factory<object_type, pointer_type>::create ());
+ pointer_traits::guard pg (p);
+
+ pointer_cache_traits::insert_guard ig (
+ pointer_cache_traits::insert (db, id, p));
+
+ object_type& obj (pointer_traits::get_ref (p));
+
+ if (l.locked ())
+ {
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ pointer_cache_traits::load (ig.position ());
+ }
+ else
+ sts.delay_load (id, obj, ig.position ());
+
+ ig.release ();
+ pg.release ();
+ return p;
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ find (database& db, const id_type& id, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ reference_cache_traits::position_type pos (
+ reference_cache_traits::insert (db, id, obj));
+ reference_cache_traits::insert_guard ig (pos);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ reference_cache_traits::load (pos);
+ ig.release ();
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ reload (database& db, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ const id_type& id (object_traits_impl::id (obj));
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, true);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ find_ (statements_type& sts,
+ const id_type* id)
+ {
+ using namespace sqlite;
+
+ id_image_type& i (sts.id_image ());
+ init (i, *id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ select_statement& st (sts.find_statement ());
+
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ if (grow (im, sts.select_image_truncated ()))
+ im.version++;
+
+ if (im.version != sts.select_image_version ())
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ void access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ load_ (statements_type& sts,
+ object_type& obj,
+ bool reload)
+ {
+ ODB_POTENTIALLY_UNUSED (reload);
+
+ extra_statement_cache_type& esc (sts.extra_statement_cache ());
+
+ // prerequisites
+ //
+ {
+ ::bpkg::package_prerequisites& v =
+ obj.prerequisites;
+
+ prerequisites_traits::load (
+ v,
+ esc.prerequisites);
+ }
+ }
+
+ result< access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::object_type >
+ access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ q.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::object_result_impl<object_type> > r (
+ new (shared) sqlite::object_result_impl<object_type> (
+ q, st, sts, 0));
+
+ return result<object_type> (r);
+ }
+
+ unsigned long long access::object_traits_impl< ::bpkg::selected_package, id_sqlite >::
+ erase_query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ std::string text (erase_query_statement);
+ if (!q.empty ())
+ {
+ text += ' ';
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ delete_statement st (
+ conn,
+ text,
+ q.parameters_binding ());
+
+ return st.execute ();
+ }
+
+ // certificate
+ //
+
+ struct access::object_traits_impl< ::bpkg::certificate, id_sqlite >::extra_statement_cache_type
+ {
+ extra_statement_cache_type (
+ sqlite::connection&,
+ image_type&,
+ id_image_type&,
+ sqlite::binding&,
+ sqlite::binding&)
+ {
+ }
+ };
+
+ access::object_traits_impl< ::bpkg::certificate, id_sqlite >::id_type
+ access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ id (const image_type& i)
+ {
+ sqlite::database* db (0);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ id_type id;
+ {
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ id,
+ i.id_value,
+ i.id_size,
+ i.id_null);
+ }
+
+ return id;
+ }
+
+ bool access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // id
+ //
+ if (t[0UL])
+ {
+ i.id_value.capacity (i.id_size);
+ grew = true;
+ }
+
+ // fingerprint
+ //
+ if (t[1UL])
+ {
+ i.fingerprint_value.capacity (i.fingerprint_size);
+ grew = true;
+ }
+
+ // name
+ //
+ if (t[2UL])
+ {
+ i.name_value.capacity (i.name_size);
+ grew = true;
+ }
+
+ // organization
+ //
+ if (t[3UL])
+ {
+ i.organization_value.capacity (i.organization_size);
+ grew = true;
+ }
+
+ // email
+ //
+ if (t[4UL])
+ {
+ i.email_value.capacity (i.email_size);
+ grew = true;
+ }
+
+ // start_date
+ //
+ t[5UL] = false;
+
+ // end_date
+ //
+ t[6UL] = false;
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ std::size_t n (0);
+
+ // id
+ //
+ if (sk != statement_update)
+ {
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.id_value.data ();
+ b[n].size = &i.id_size;
+ b[n].capacity = i.id_value.capacity ();
+ b[n].is_null = &i.id_null;
+ n++;
+ }
+
+ // fingerprint
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.fingerprint_value.data ();
+ b[n].size = &i.fingerprint_size;
+ b[n].capacity = i.fingerprint_value.capacity ();
+ b[n].is_null = &i.fingerprint_null;
+ n++;
+
+ // name
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ 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++;
+
+ // organization
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.organization_value.data ();
+ b[n].size = &i.organization_size;
+ b[n].capacity = i.organization_value.capacity ();
+ b[n].is_null = &i.organization_null;
+ n++;
+
+ // email
+ //
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.email_value.data ();
+ b[n].size = &i.email_size;
+ b[n].capacity = i.email_value.capacity ();
+ b[n].is_null = &i.email_null;
+ n++;
+
+ // start_date
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.start_date_value;
+ b[n].is_null = &i.start_date_null;
+ n++;
+
+ // end_date
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.end_date_value;
+ b[n].is_null = &i.end_date_null;
+ n++;
+ }
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ bind (sqlite::bind* b, id_image_type& i)
+ {
+ std::size_t n (0);
+ b[n].type = sqlite::image_traits<
+ ::std::string,
+ sqlite::id_text>::bind_value;
+ b[n].buffer = i.id_value.data ();
+ b[n].size = &i.id_size;
+ b[n].capacity = i.id_value.capacity ();
+ b[n].is_null = &i.id_null;
+ }
+
+ bool access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ init (image_type& i,
+ const object_type& o,
+ sqlite::statement_kind sk)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ using namespace sqlite;
+
+ bool grew (false);
+
+ // id
+ //
+ if (sk == statement_insert)
+ {
+ ::std::string const& v =
+ o.id;
+
+ bool is_null (false);
+ std::size_t cap (i.id_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.id_value,
+ i.id_size,
+ is_null,
+ v);
+ i.id_null = is_null;
+ grew = grew || (cap != i.id_value.capacity ());
+ }
+
+ // fingerprint
+ //
+ {
+ ::std::string const& v =
+ o.fingerprint;
+
+ bool is_null (false);
+ std::size_t cap (i.fingerprint_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.fingerprint_value,
+ i.fingerprint_size,
+ is_null,
+ v);
+ i.fingerprint_null = is_null;
+ grew = grew || (cap != i.fingerprint_value.capacity ());
+ }
+
+ // name
+ //
+ {
+ ::std::string const& v =
+ o.name;
+
+ bool is_null (false);
+ std::size_t cap (i.name_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ 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 ());
+ }
+
+ // organization
+ //
+ {
+ ::std::string const& v =
+ o.organization;
+
+ bool is_null (false);
+ std::size_t cap (i.organization_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.organization_value,
+ i.organization_size,
+ is_null,
+ v);
+ i.organization_null = is_null;
+ grew = grew || (cap != i.organization_value.capacity ());
+ }
+
+ // email
+ //
+ {
+ ::std::string const& v =
+ o.email;
+
+ bool is_null (false);
+ std::size_t cap (i.email_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.email_value,
+ i.email_size,
+ is_null,
+ v);
+ i.email_null = is_null;
+ grew = grew || (cap != i.email_value.capacity ());
+ }
+
+ // start_date
+ //
+ {
+ ::butl::timestamp const& v =
+ o.start_date;
+
+ // From package.hxx:86:14
+ ::uint64_t const& vt =
+ std::chrono::duration_cast < std::chrono::nanoseconds > ((v).time_since_epoch ()).count ();
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::uint64_t,
+ sqlite::id_integer >::set_image (
+ i.start_date_value,
+ is_null,
+ vt);
+ i.start_date_null = is_null;
+ }
+
+ // end_date
+ //
+ {
+ ::butl::timestamp const& v =
+ o.end_date;
+
+ // From package.hxx:86:14
+ ::uint64_t const& vt =
+ std::chrono::duration_cast < std::chrono::nanoseconds > ((v).time_since_epoch ()).count ();
+
+ bool is_null (false);
+ sqlite::value_traits<
+ ::uint64_t,
+ sqlite::id_integer >::set_image (
+ i.end_date_value,
+ is_null,
+ vt);
+ i.end_date_null = is_null;
+ }
+
+ return grew;
+ }
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ init (object_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // id
+ //
+ {
+ ::std::string& v =
+ o.id;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.id_value,
+ i.id_size,
+ i.id_null);
+ }
+
+ // fingerprint
+ //
+ {
+ ::std::string& v =
+ o.fingerprint;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.fingerprint_value,
+ i.fingerprint_size,
+ i.fingerprint_null);
+ }
+
+ // name
+ //
+ {
+ ::std::string& v =
+ o.name;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.name_value,
+ i.name_size,
+ i.name_null);
+ }
+
+ // organization
+ //
+ {
+ ::std::string& v =
+ o.organization;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.organization_value,
+ i.organization_size,
+ i.organization_null);
+ }
+
+ // email
+ //
+ {
+ ::std::string& v =
+ o.email;
+
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_value (
+ v,
+ i.email_value,
+ i.email_size,
+ i.email_null);
+ }
+
+ // start_date
+ //
+ {
+ ::butl::timestamp& v =
+ o.start_date;
+
+ ::uint64_t vt;
+
+ sqlite::value_traits<
+ ::uint64_t,
+ sqlite::id_integer >::set_value (
+ vt,
+ i.start_date_value,
+ i.start_date_null);
+
+ // From package.hxx:86:14
+ v = butl::timestamp (std::chrono::duration_cast < butl::timestamp::duration > (std::chrono::nanoseconds (vt)));
+ }
+
+ // end_date
+ //
+ {
+ ::butl::timestamp& v =
+ o.end_date;
+
+ ::uint64_t vt;
+
+ sqlite::value_traits<
+ ::uint64_t,
+ sqlite::id_integer >::set_value (
+ vt,
+ i.end_date_value,
+ i.end_date_null);
+
+ // From package.hxx:86:14
+ v = butl::timestamp (std::chrono::duration_cast < butl::timestamp::duration > (std::chrono::nanoseconds (vt)));
+ }
+ }
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ init (id_image_type& i, const id_type& id)
+ {
+ bool grew (false);
+ {
+ bool is_null (false);
+ std::size_t cap (i.id_value.capacity ());
+ sqlite::value_traits<
+ ::std::string,
+ sqlite::id_text >::set_image (
+ i.id_value,
+ i.id_size,
+ is_null,
+ id);
+ i.id_null = is_null;
+ grew = grew || (cap != i.id_value.capacity ());
+ }
+
+ if (grew)
+ i.version++;
+ }
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::persist_statement[] =
+ "INSERT INTO \"certificate\" "
+ "(\"id\", "
+ "\"fingerprint\", "
+ "\"name\", "
+ "\"organization\", "
+ "\"email\", "
+ "\"start_date\", "
+ "\"end_date\") "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?)";
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::find_statement[] =
+ "SELECT "
+ "\"certificate\".\"id\", "
+ "\"certificate\".\"fingerprint\", "
+ "\"certificate\".\"name\", "
+ "\"certificate\".\"organization\", "
+ "\"certificate\".\"email\", "
+ "\"certificate\".\"start_date\", "
+ "\"certificate\".\"end_date\" "
+ "FROM \"certificate\" "
+ "WHERE \"certificate\".\"id\"=?";
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::update_statement[] =
+ "UPDATE \"certificate\" "
+ "SET "
+ "\"fingerprint\"=?, "
+ "\"name\"=?, "
+ "\"organization\"=?, "
+ "\"email\"=?, "
+ "\"start_date\"=?, "
+ "\"end_date\"=? "
+ "WHERE \"id\"=?";
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::erase_statement[] =
+ "DELETE FROM \"certificate\" "
+ "WHERE \"id\"=?";
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::query_statement[] =
+ "SELECT "
+ "\"certificate\".\"id\", "
+ "\"certificate\".\"fingerprint\", "
+ "\"certificate\".\"name\", "
+ "\"certificate\".\"organization\", "
+ "\"certificate\".\"email\", "
+ "\"certificate\".\"start_date\", "
+ "\"certificate\".\"end_date\" "
+ "FROM \"certificate\"";
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::erase_query_statement[] =
+ "DELETE FROM \"certificate\"";
+
+ const char access::object_traits_impl< ::bpkg::certificate, id_sqlite >::table_name[] =
+ "\"certificate\"";
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ persist (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ callback (db,
+ obj,
+ callback_event::pre_persist);
+
+ image_type& im (sts.image ());
+ binding& imb (sts.insert_image_binding ());
+
+ if (init (im, obj, statement_insert))
+ im.version++;
+
+ if (im.version != sts.insert_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_insert);
+ sts.insert_image_version (im.version);
+ imb.version++;
+ }
+
+ insert_statement& st (sts.persist_statement ());
+ if (!st.execute ())
+ throw object_already_persistent ();
+
+ callback (db,
+ obj,
+ callback_event::post_persist);
+ }
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ update (database& db, const object_type& obj)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+
+ using namespace sqlite;
+ using sqlite::update_statement;
+
+ callback (db, obj, callback_event::pre_update);
+
+ sqlite::transaction& tr (sqlite::transaction::current ());
+ sqlite::connection& conn (tr.connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& idi (sts.id_image ());
+ init (idi, id (obj));
+
+ image_type& im (sts.image ());
+ if (init (im, obj, statement_update))
+ im.version++;
+
+ bool u (false);
+ binding& imb (sts.update_image_binding ());
+ if (im.version != sts.update_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_update);
+ sts.update_image_version (im.version);
+ imb.version++;
+ u = true;
+ }
+
+ binding& idb (sts.id_image_binding ());
+ if (idi.version != sts.update_id_image_version () ||
+ idb.version == 0)
+ {
+ if (idi.version != sts.id_image_version () ||
+ idb.version == 0)
+ {
+ bind (idb.bind, idi);
+ sts.id_image_version (idi.version);
+ idb.version++;
+ }
+
+ sts.update_id_image_version (idi.version);
+
+ if (!u)
+ imb.version++;
+ }
+
+ update_statement& st (sts.update_statement ());
+ if (st.execute () == 0)
+ throw object_not_persistent ();
+
+ callback (db, obj, callback_event::post_update);
+ pointer_cache_traits::update (db, obj);
+ }
+
+ void access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ erase (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ id_image_type& i (sts.id_image ());
+ init (i, id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ if (sts.erase_statement ().execute () != 1)
+ throw object_not_persistent ();
+
+ pointer_cache_traits::erase (db, id);
+ }
+
+ access::object_traits_impl< ::bpkg::certificate, id_sqlite >::pointer_type
+ access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ find (database& db, const id_type& id)
+ {
+ using namespace sqlite;
+
+ {
+ pointer_type p (pointer_cache_traits::find (db, id));
+
+ if (!pointer_traits::null_ptr (p))
+ return p;
+ }
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+
+ if (l.locked ())
+ {
+ if (!find_ (sts, &id))
+ return pointer_type ();
+ }
+
+ pointer_type p (
+ access::object_factory<object_type, pointer_type>::create ());
+ pointer_traits::guard pg (p);
+
+ pointer_cache_traits::insert_guard ig (
+ pointer_cache_traits::insert (db, id, p));
+
+ object_type& obj (pointer_traits::get_ref (p));
+
+ if (l.locked ())
+ {
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ pointer_cache_traits::load (ig.position ());
+ }
+ else
+ sts.delay_load (id, obj, ig.position ());
+
+ ig.release ();
+ pg.release ();
+ return p;
+ }
+
+ bool access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ find (database& db, const id_type& id, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ reference_cache_traits::position_type pos (
+ reference_cache_traits::insert (db, id, obj));
+ reference_cache_traits::insert_guard ig (pos);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ reference_cache_traits::load (pos);
+ ig.release ();
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ reload (database& db, object_type& obj)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ const id_type& id (object_traits_impl::id (obj));
+ if (!find_ (sts, &id))
+ return false;
+
+ select_statement& st (sts.find_statement ());
+ ODB_POTENTIALLY_UNUSED (st);
+
+ callback (db, obj, callback_event::pre_load);
+ init (obj, sts.image (), &db);
+ load_ (sts, obj, true);
+ sts.load_delayed (0);
+ l.unlock ();
+ callback (db, obj, callback_event::post_load);
+ return true;
+ }
+
+ bool access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ find_ (statements_type& sts,
+ const id_type* id)
+ {
+ using namespace sqlite;
+
+ id_image_type& i (sts.id_image ());
+ init (i, *id);
+
+ binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ select_statement& st (sts.find_statement ());
+
+ st.execute ();
+ auto_result ar (st);
+ select_statement::result r (st.fetch ());
+
+ if (r == select_statement::truncated)
+ {
+ if (grow (im, sts.select_image_truncated ()))
+ im.version++;
+
+ if (im.version != sts.select_image_version ())
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ st.refetch ();
+ }
+ }
+
+ return r != select_statement::no_data;
+ }
+
+ result< access::object_traits_impl< ::bpkg::certificate, id_sqlite >::object_type >
+ access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ statements_type& sts (
+ conn.statement_cache ().find_object<object_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.select_image_binding ());
+
+ if (im.version != sts.select_image_version () ||
+ imb.version == 0)
+ {
+ bind (imb.bind, im, statement_select);
+ sts.select_image_version (im.version);
+ imb.version++;
+ }
+
+ std::string text (query_statement);
+ if (!q.empty ())
+ {
+ text += " ";
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ text,
+ false,
+ true,
+ q.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::object_result_impl<object_type> > r (
+ new (shared) sqlite::object_result_impl<object_type> (
+ q, st, sts, 0));
+
+ return result<object_type> (r);
+ }
+
+ unsigned long long access::object_traits_impl< ::bpkg::certificate, id_sqlite >::
+ erase_query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ std::string text (erase_query_statement);
+ if (!q.empty ())
+ {
+ text += ' ';
+ text += q.clause ();
+ }
+
+ q.init_parameters ();
+ delete_statement st (
+ conn,
+ text,
+ q.parameters_binding ());
+
+ return st.execute ();
+ }
+
+ // package_dependent
+ //
+
+ bool access::view_traits_impl< ::bpkg::package_dependent, 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;
+ }
+
+ // constraint
+ //
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::grow (
+ i.constraint_value, t + 1UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // 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++;
+
+ // constraint
+ //
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::bind (
+ b + n, i.constraint_value, sk);
+ n += 16UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::
+ init (view_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);
+ }
+
+ // constraint
+ //
+ {
+ ::butl::optional< ::bpkg::version_constraint >& v =
+ o.constraint;
+
+ if (composite_value_traits< ::bpkg::version_constraint, id_sqlite >::get_null (
+ i.constraint_value))
+ wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::set_null (v);
+ else
+ {
+ ::bpkg::version_constraint& vw =
+ wrapper_traits< ::butl::optional< ::bpkg::version_constraint > >::set_ref (v);
+
+ composite_value_traits< ::bpkg::version_constraint, id_sqlite >::init (
+ vw,
+ i.constraint_value,
+ db);
+ }
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"pp\".\"package\", "
+ "\"pp\".\"min_version_epoch\", "
+ "\"pp\".\"min_version_canonical_upstream\", "
+ "\"pp\".\"min_version_canonical_release\", "
+ "\"pp\".\"min_version_revision\", "
+ "\"pp\".\"min_version_iteration\", "
+ "\"pp\".\"min_version_upstream\", "
+ "\"pp\".\"min_version_release\", "
+ "\"pp\".\"max_version_epoch\", "
+ "\"pp\".\"max_version_canonical_upstream\", "
+ "\"pp\".\"max_version_canonical_release\", "
+ "\"pp\".\"max_version_revision\", "
+ "\"pp\".\"max_version_iteration\", "
+ "\"pp\".\"max_version_upstream\", "
+ "\"pp\".\"max_version_release\", "
+ "\"pp\".\"min_open\", "
+ "\"pp\".\"max_open\" ");
+
+ r += "FROM \"selected_package\"";
+
+ r += " INNER JOIN \"selected_package_prerequisites\" AS \"pp\" ON";
+ // From package.hxx:1191:5
+ r += "pp.prerequisite = " + query_columns::name;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::package_dependent, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ // fragment_repository_count
+ //
+
+ bool access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // result
+ //
+ t[0UL] = false;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // result
+ //
+ b[n].type = sqlite::bind::integer;
+ b[n].buffer = &i.result_value;
+ b[n].is_null = &i.result_null;
+ n++;
+ }
+
+ void access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ // result
+ //
+ {
+ ::std::size_t& v =
+ o.result;
+
+ sqlite::value_traits<
+ ::std::size_t,
+ sqlite::id_integer >::set_value (
+ v,
+ i.result_value,
+ i.result_null);
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "count(*) ");
+
+ r += "FROM \"repository_fragments\"";
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::fragment_repository_count, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ // fragment_repository
+ //
+
+ bool access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // object
+ //
+ if (object_traits_impl< ::bpkg::repository, id_sqlite >::grow (
+ i.object_value, t + 0UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // object
+ //
+ object_traits_impl< ::bpkg::repository, id_sqlite >::bind (
+ b + n, i.object_value, sk);
+ n += 4UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ // object pre
+ //
+ typedef ::bpkg::repository object_object_type;
+ typedef object_traits_impl<object_object_type, id_sqlite> object_object_traits;
+ typedef object_object_traits::pointer_type object_pointer_type;
+ typedef object_object_traits::pointer_traits object_pointer_traits;
+ typedef object_object_traits::pointer_cache_traits object_cache_traits;
+
+ object_object_traits::id_type object_id;
+ object_pointer_type object_p;
+ object_pointer_traits::guard object_pg;
+ object_cache_traits::insert_guard object_ig;
+ object_object_type* object_o (0);
+
+ {
+ if (!(i.object_value.name_null))
+ {
+ object_id = object_object_traits::id (i.object_value);
+ object_p = object_cache_traits::find (*db, object_id);
+
+ if (object_pointer_traits::null_ptr (object_p))
+ {
+ object_p = object_factory<object_object_type, object_pointer_type>::create ();
+ object_pg.reset (object_p);
+ object_ig.reset (object_cache_traits::insert (*db, object_id, object_p));
+ object_o = object_pointer_traits::get_ptr (object_p);
+ }
+ }
+ }
+
+ // object
+ //
+ {
+ if (object_o != 0)
+ {
+ object_object_traits::callback (*db, *object_o, callback_event::pre_load);
+ object_object_traits::init (*object_o, i.object_value, db);
+ object_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<object_object_type> ());
+ object_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ object_object_traits::id_image_type& i (sts.id_image ());
+ object_object_traits::init (i, object_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ object_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ object_object_traits::load_ (sts, *object_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // object post
+ //
+ {
+ if (object_o != 0)
+ {
+ object_object_traits::callback (*db, *object_o, callback_event::post_load);
+ object_cache_traits::load (object_ig.position ());
+ object_ig.release ();
+ object_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.object = ::std::shared_ptr< ::bpkg::repository > (
+ std::move (object_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"repository\".\"name\", "
+ "\"repository\".\"url\", "
+ "\"repository\".\"type\", "
+ "\"repository\".\"certificate\" ");
+
+ r += "FROM \"repository\"";
+
+ r += " INNER JOIN \"repository_fragments\" AS \"rfs\" ON";
+ // From package.hxx:1216:5
+ r += "rfs.repository = " + query_columns::repository::name;
+
+ r += " INNER JOIN \"repository_fragment\" ON";
+ // From package.hxx:1218:5
+ r += "rfs.fragment = " + query_columns::repository_fragment::name;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::fragment_repository, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ // repository_complement_dependent
+ //
+
+ const char alias_traits< ::bpkg::repository,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::complement_tag>::
+ table_name[] = "\"complement\"";
+
+ bool access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // object
+ //
+ if (object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::grow (
+ i.object_value, t + 0UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // object
+ //
+ object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::bind (
+ b + n, i.object_value, sk);
+ n += 3UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ // object pre
+ //
+ typedef ::bpkg::repository_fragment object_object_type;
+ typedef object_traits_impl<object_object_type, id_sqlite> object_object_traits;
+ typedef object_object_traits::pointer_type object_pointer_type;
+ typedef object_object_traits::pointer_traits object_pointer_traits;
+ typedef object_object_traits::pointer_cache_traits object_cache_traits;
+
+ object_object_traits::id_type object_id;
+ object_pointer_type object_p;
+ object_pointer_traits::guard object_pg;
+ object_cache_traits::insert_guard object_ig;
+ object_object_type* object_o (0);
+
+ {
+ if (!(i.object_value.name_null))
+ {
+ object_id = object_object_traits::id (i.object_value);
+ object_p = object_cache_traits::find (*db, object_id);
+
+ if (object_pointer_traits::null_ptr (object_p))
+ {
+ object_p = object_factory<object_object_type, object_pointer_type>::create ();
+ object_pg.reset (object_p);
+ object_ig.reset (object_cache_traits::insert (*db, object_id, object_p));
+ object_o = object_pointer_traits::get_ptr (object_p);
+ }
+ }
+ }
+
+ // object
+ //
+ {
+ if (object_o != 0)
+ {
+ object_object_traits::callback (*db, *object_o, callback_event::pre_load);
+ object_object_traits::init (*object_o, i.object_value, db);
+ object_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<object_object_type> ());
+ object_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ object_object_traits::id_image_type& i (sts.id_image ());
+ object_object_traits::init (i, object_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ object_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ object_object_traits::load_ (sts, *object_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // object post
+ //
+ {
+ if (object_o != 0)
+ {
+ object_object_traits::callback (*db, *object_o, callback_event::post_load);
+ object_cache_traits::load (object_ig.position ());
+ object_ig.release ();
+ object_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.object = ::std::shared_ptr< ::bpkg::repository_fragment > (
+ std::move (object_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"repository_fragment\".\"name\", "
+ "\"repository_fragment\".\"url\", "
+ "\"repository_fragment\".\"type\" ");
+
+ r += "FROM \"repository\" AS \"complement\"";
+
+ r += " INNER JOIN \"repository_fragment_complements\" AS \"rfc\" ON";
+ // From package.hxx:1231:5
+ r += "rfc.complement = " + query_columns::complement::name;
+
+ r += " INNER JOIN \"repository_fragment\" ON";
+ // From package.hxx:1233:5
+ r += "rfc.repository_fragment = " + query_columns::repository_fragment::name;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::repository_complement_dependent, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ // repository_prerequisite_dependent
+ //
+
+ const char alias_traits< ::bpkg::repository,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::prerequisite_tag>::
+ table_name[] = "\"prerequisite\"";
+
+ bool access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // object
+ //
+ if (object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::grow (
+ i.object_value, t + 0UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // object
+ //
+ object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::bind (
+ b + n, i.object_value, sk);
+ n += 3UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ // object pre
+ //
+ typedef ::bpkg::repository_fragment object_object_type;
+ typedef object_traits_impl<object_object_type, id_sqlite> object_object_traits;
+ typedef object_object_traits::pointer_type object_pointer_type;
+ typedef object_object_traits::pointer_traits object_pointer_traits;
+ typedef object_object_traits::pointer_cache_traits object_cache_traits;
+
+ object_object_traits::id_type object_id;
+ object_pointer_type object_p;
+ object_pointer_traits::guard object_pg;
+ object_cache_traits::insert_guard object_ig;
+ object_object_type* object_o (0);
+
+ {
+ if (!(i.object_value.name_null))
+ {
+ object_id = object_object_traits::id (i.object_value);
+ object_p = object_cache_traits::find (*db, object_id);
+
+ if (object_pointer_traits::null_ptr (object_p))
+ {
+ object_p = object_factory<object_object_type, object_pointer_type>::create ();
+ object_pg.reset (object_p);
+ object_ig.reset (object_cache_traits::insert (*db, object_id, object_p));
+ object_o = object_pointer_traits::get_ptr (object_p);
+ }
+ }
+ }
+
+ // object
+ //
+ {
+ if (object_o != 0)
+ {
+ object_object_traits::callback (*db, *object_o, callback_event::pre_load);
+ object_object_traits::init (*object_o, i.object_value, db);
+ object_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<object_object_type> ());
+ object_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ object_object_traits::id_image_type& i (sts.id_image ());
+ object_object_traits::init (i, object_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ object_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ object_object_traits::load_ (sts, *object_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // object post
+ //
+ {
+ if (object_o != 0)
+ {
+ object_object_traits::callback (*db, *object_o, callback_event::post_load);
+ object_cache_traits::load (object_ig.position ());
+ object_ig.release ();
+ object_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.object = ::std::shared_ptr< ::bpkg::repository_fragment > (
+ std::move (object_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"repository_fragment\".\"name\", "
+ "\"repository_fragment\".\"url\", "
+ "\"repository_fragment\".\"type\" ");
+
+ r += "FROM \"repository\" AS \"prerequisite\"";
+
+ r += " INNER JOIN \"repository_fragment_prerequisites\" AS \"rfp\" ON";
+ // From package.hxx:1246:5
+ r += "rfp.prerequisite = " + query_columns::prerequisite::name;
+
+ r += " INNER JOIN \"repository_fragment\" ON";
+ // From package.hxx:1248:5
+ r += "rfp.repository_fragment = " + query_columns::repository_fragment::name;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::repository_prerequisite_dependent, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ // repository_fragment_package
+ //
+
+ const char alias_traits< ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::package_tag>::
+ table_name[] = "\"package\"";
+
+ bool access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // package
+ //
+ if (object_traits_impl< ::bpkg::available_package, id_sqlite >::grow (
+ i.package_value, t + 0UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // package
+ //
+ object_traits_impl< ::bpkg::available_package, id_sqlite >::bind (
+ b + n, i.package_value, sk);
+ n += 9UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ // package pre
+ //
+ typedef ::bpkg::available_package package_object_type;
+ typedef object_traits_impl<package_object_type, id_sqlite> package_object_traits;
+ typedef package_object_traits::pointer_type package_pointer_type;
+ typedef package_object_traits::pointer_traits package_pointer_traits;
+ typedef package_object_traits::pointer_cache_traits package_cache_traits;
+
+ package_object_traits::id_type package_id;
+ package_pointer_type package_p;
+ package_pointer_traits::guard package_pg;
+ package_cache_traits::insert_guard package_ig;
+ package_object_type* package_o (0);
+
+ {
+ if (!composite_value_traits< package_object_traits::id_type, id_sqlite >::get_null (
+ i.package_value.id_value))
+ {
+ package_id = package_object_traits::id (i.package_value);
+ package_p = package_cache_traits::find (*db, package_id);
+
+ if (package_pointer_traits::null_ptr (package_p))
+ {
+ package_p = object_factory<package_object_type, package_pointer_type>::create ();
+ package_pg.reset (package_p);
+ package_ig.reset (package_cache_traits::insert (*db, package_id, package_p));
+ package_o = package_pointer_traits::get_ptr (package_p);
+ }
+ }
+ }
+
+ // package
+ //
+ {
+ if (package_o != 0)
+ {
+ package_object_traits::callback (*db, *package_o, callback_event::pre_load);
+ package_object_traits::init (*package_o, i.package_value, db);
+ package_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<package_object_type> ());
+ package_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ package_object_traits::id_image_type& i (sts.id_image ());
+ package_object_traits::init (i, package_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ package_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ package_object_traits::load_ (sts, *package_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // package post
+ //
+ {
+ if (package_o != 0)
+ {
+ package_object_traits::callback (*db, *package_o, callback_event::post_load);
+ package_cache_traits::load (package_ig.position ());
+ package_ig.release ();
+ package_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.package = ::std::shared_ptr< ::bpkg::available_package > (
+ std::move (package_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"package\".\"name\", "
+ "\"package\".\"version_epoch\", "
+ "\"package\".\"version_canonical_upstream\", "
+ "\"package\".\"version_canonical_release\", "
+ "\"package\".\"version_revision\", "
+ "\"package\".\"version_iteration\", "
+ "\"package\".\"version_upstream\", "
+ "\"package\".\"version_release\", "
+ "\"package\".\"sha256sum\" ");
+
+ r += "FROM \"repository_fragment\"";
+
+ r += " INNER JOIN \"available_package_locations\" AS \"pl\" ON";
+ // From package.hxx:1260:5
+ r += "pl.repository_fragment = " + query_columns::repository_fragment::name;
+
+ r += " INNER JOIN \"available_package\" AS \"package\" ON";
+ // From package.hxx:1262:5
+ r += "pl.name = " + query_columns::package::id.name + "AND" + "pl.version_epoch = " + query_columns::package::id.version.epoch + "AND" + "pl.version_canonical_upstream = " + query_columns::package::id.version.canonical_upstream + "AND" + "pl.version_canonical_release = " + query_columns::package::id.version.canonical_release + "AND" + "pl.version_revision = " + query_columns::package::id.version.revision + "AND" + "pl.version_iteration = " + query_columns::package::id.version.iteration;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::repository_fragment_package, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+
+ // package_repository_fragment
+ //
+
+ const char alias_traits< ::bpkg::available_package,
+ id_sqlite,
+ access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::package_tag>::
+ table_name[] = "\"package\"";
+
+ bool access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::
+ grow (image_type& i,
+ bool* t)
+ {
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (t);
+
+ bool grew (false);
+
+ // package_id
+ //
+ if (composite_value_traits< ::bpkg::available_package_id, id_sqlite >::grow (
+ i.package_id_value, t + 0UL))
+ grew = true;
+
+ // repository_fragment
+ //
+ if (object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::grow (
+ i.repository_fragment_value, t + 6UL))
+ grew = true;
+
+ return grew;
+ }
+
+ void access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::
+ bind (sqlite::bind* b,
+ image_type& i)
+ {
+ using namespace sqlite;
+
+ sqlite::statement_kind sk (statement_select);
+ ODB_POTENTIALLY_UNUSED (sk);
+
+ std::size_t n (0);
+
+ // package_id
+ //
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::bind (
+ b + n, i.package_id_value, sk);
+ n += 6UL;
+
+ // repository_fragment
+ //
+ object_traits_impl< ::bpkg::repository_fragment, id_sqlite >::bind (
+ b + n, i.repository_fragment_value, sk);
+ n += 3UL;
+ }
+
+ void access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::
+ init (view_type& o,
+ const image_type& i,
+ database* db)
+ {
+ ODB_POTENTIALLY_UNUSED (o);
+ ODB_POTENTIALLY_UNUSED (i);
+ ODB_POTENTIALLY_UNUSED (db);
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+
+ // repository_fragment pre
+ //
+ typedef ::bpkg::repository_fragment repository_fragment_object_type;
+ typedef object_traits_impl<repository_fragment_object_type, id_sqlite> repository_fragment_object_traits;
+ typedef repository_fragment_object_traits::pointer_type repository_fragment_pointer_type;
+ typedef repository_fragment_object_traits::pointer_traits repository_fragment_pointer_traits;
+ typedef repository_fragment_object_traits::pointer_cache_traits repository_fragment_cache_traits;
+
+ repository_fragment_object_traits::id_type repository_fragment_id;
+ repository_fragment_pointer_type repository_fragment_p;
+ repository_fragment_pointer_traits::guard repository_fragment_pg;
+ repository_fragment_cache_traits::insert_guard repository_fragment_ig;
+ repository_fragment_object_type* repository_fragment_o (0);
+
+ {
+ if (!(i.repository_fragment_value.name_null))
+ {
+ repository_fragment_id = repository_fragment_object_traits::id (i.repository_fragment_value);
+ repository_fragment_p = repository_fragment_cache_traits::find (*db, repository_fragment_id);
+
+ if (repository_fragment_pointer_traits::null_ptr (repository_fragment_p))
+ {
+ repository_fragment_p = object_factory<repository_fragment_object_type, repository_fragment_pointer_type>::create ();
+ repository_fragment_pg.reset (repository_fragment_p);
+ repository_fragment_ig.reset (repository_fragment_cache_traits::insert (*db, repository_fragment_id, repository_fragment_p));
+ repository_fragment_o = repository_fragment_pointer_traits::get_ptr (repository_fragment_p);
+ }
+ }
+ }
+
+ // package_id
+ //
+ {
+ ::bpkg::available_package_id& v =
+ o.package_id;
+
+ composite_value_traits< ::bpkg::available_package_id, id_sqlite >::init (
+ v,
+ i.package_id_value,
+ db);
+ }
+
+ // repository_fragment
+ //
+ {
+ if (repository_fragment_o != 0)
+ {
+ repository_fragment_object_traits::callback (*db, *repository_fragment_o, callback_event::pre_load);
+ repository_fragment_object_traits::init (*repository_fragment_o, i.repository_fragment_value, db);
+ repository_fragment_object_traits::statements_type& sts (
+ conn.statement_cache ().find_object<repository_fragment_object_type> ());
+ repository_fragment_object_traits::statements_type::auto_lock l (sts);
+ assert (l.locked ()) /* Must be a top-level call. */;
+
+ repository_fragment_object_traits::id_image_type& i (sts.id_image ());
+ repository_fragment_object_traits::init (i, repository_fragment_id);
+ sqlite::binding& idb (sts.id_image_binding ());
+ if (i.version != sts.id_image_version () || idb.version == 0)
+ {
+ repository_fragment_object_traits::bind (idb.bind, i);
+ sts.id_image_version (i.version);
+ idb.version++;
+ }
+
+ repository_fragment_object_traits::load_ (sts, *repository_fragment_o, false);
+ sts.load_delayed (0);
+ l.unlock ();
+ }
+ }
+
+ // repository_fragment post
+ //
+ {
+ if (repository_fragment_o != 0)
+ {
+ repository_fragment_object_traits::callback (*db, *repository_fragment_o, callback_event::post_load);
+ repository_fragment_cache_traits::load (repository_fragment_ig.position ());
+ repository_fragment_ig.release ();
+ repository_fragment_pg.release ();
+ }
+
+ // If a compiler error points to the line below, then
+ // it most likely means that a pointer used in view
+ // member cannot be initialized from an object pointer.
+ //
+ o.repository_fragment = ::std::shared_ptr< ::bpkg::repository_fragment > (
+ std::move (repository_fragment_p));
+ }
+ }
+
+ access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::query_base_type
+ access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::
+ query_statement (const query_base_type& q)
+ {
+ query_base_type r (
+ "SELECT "
+ "\"package\".\"name\", "
+ "\"package\".\"version_epoch\", "
+ "\"package\".\"version_canonical_upstream\", "
+ "\"package\".\"version_canonical_release\", "
+ "\"package\".\"version_revision\", "
+ "\"package\".\"version_iteration\", "
+ "\"repository_fragment\".\"name\", "
+ "\"repository_fragment\".\"url\", "
+ "\"repository_fragment\".\"type\" ");
+
+ r += "FROM \"repository_fragment\"";
+
+ r += " INNER JOIN \"available_package_locations\" AS \"pl\" ON";
+ // From package.hxx:1281:5
+ r += "pl.repository_fragment = " + query_columns::repository_fragment::name;
+
+ r += " INNER JOIN \"available_package\" AS \"package\" ON";
+ // From package.hxx:1283:5
+ r += "pl.name = " + query_columns::package::id.name + "AND" + "pl.version_epoch = " + query_columns::package::id.version.epoch + "AND" + "pl.version_canonical_upstream = " + query_columns::package::id.version.canonical_upstream + "AND" + "pl.version_canonical_release = " + query_columns::package::id.version.canonical_release + "AND" + "pl.version_revision = " + query_columns::package::id.version.revision + "AND" + "pl.version_iteration = " + query_columns::package::id.version.iteration;
+
+ if (!q.empty ())
+ {
+ r += " ";
+ r += q.clause_prefix ();
+ r += q;
+ }
+
+ return r;
+ }
+
+ result< access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::view_type >
+ access::view_traits_impl< ::bpkg::package_repository_fragment, id_sqlite >::
+ query (database&, const query_base_type& q)
+ {
+ using namespace sqlite;
+ using odb::details::shared;
+ using odb::details::shared_ptr;
+
+ sqlite::connection& conn (
+ sqlite::transaction::current ().connection ());
+ statements_type& sts (
+ conn.statement_cache ().find_view<view_type> ());
+
+ image_type& im (sts.image ());
+ binding& imb (sts.image_binding ());
+
+ if (im.version != sts.image_version () || imb.version == 0)
+ {
+ bind (imb.bind, im);
+ sts.image_version (im.version);
+ imb.version++;
+ }
+
+ const query_base_type& qs (query_statement (q));
+ qs.init_parameters ();
+ shared_ptr<select_statement> st (
+ new (shared) select_statement (
+ conn,
+ qs.clause (),
+ false,
+ true,
+ qs.parameters_binding (),
+ imb));
+
+ st->execute ();
+
+ shared_ptr< odb::view_result_impl<view_type> > r (
+ new (shared) sqlite::view_result_impl<view_type> (
+ qs, st, sts, 0));
+
+ return result<view_type> (r);
+ }
+}
+
+namespace odb
+{
+ static bool
+ create_schema (database& db, unsigned short pass, bool drop)
+ {
+ ODB_POTENTIALLY_UNUSED (db);
+ ODB_POTENTIALLY_UNUSED (pass);
+ ODB_POTENTIALLY_UNUSED (drop);
+
+ if (drop)
+ {
+ switch (pass)
+ {
+ case 1:
+ {
+ return true;
+ }
+ case 2:
+ {
+ db.execute ("DROP TABLE IF EXISTS \"certificate\"");
+ db.execute ("DROP TABLE IF EXISTS \"selected_package_prerequisites\"");
+ db.execute ("DROP TABLE IF EXISTS \"selected_package\"");
+ db.execute ("DROP TABLE IF EXISTS \"available_package_tests\"");
+ db.execute ("DROP TABLE IF EXISTS \"available_package_dependency_alternatives\"");
+ db.execute ("DROP TABLE IF EXISTS \"available_package_dependencies\"");
+ db.execute ("DROP TABLE IF EXISTS \"available_package_locations\"");
+ db.execute ("DROP TABLE IF EXISTS \"available_package\"");
+ db.execute ("DROP TABLE IF EXISTS \"repository_fragments\"");
+ db.execute ("DROP TABLE IF EXISTS \"repository\"");
+ db.execute ("DROP TABLE IF EXISTS \"repository_fragment_prerequisites\"");
+ db.execute ("DROP TABLE IF EXISTS \"repository_fragment_complements\"");
+ db.execute ("DROP TABLE IF EXISTS \"repository_fragment\"");
+ db.execute ("CREATE TABLE IF NOT EXISTS \"schema_version\" (\n"
+ " \"name\" TEXT NOT NULL PRIMARY KEY,\n"
+ " \"version\" INTEGER NOT NULL,\n"
+ " \"migration\" INTEGER NOT NULL)");
+ db.execute ("DELETE FROM \"schema_version\"\n"
+ " WHERE \"name\" = ''");
+ return false;
+ }
+ }
+ }
+ else
+ {
+ switch (pass)
+ {
+ case 1:
+ {
+ db.execute ("CREATE TABLE \"repository_fragment\" (\n"
+ " \"name\" TEXT NULL PRIMARY KEY,\n"
+ " \"url\" TEXT NULL,\n"
+ " \"type\" TEXT NULL)");
+ db.execute ("CREATE TABLE \"repository_fragment_complements\" (\n"
+ " \"repository_fragment\" TEXT NULL,\n"
+ " \"complement\" TEXT NULL,\n"
+ " CONSTRAINT \"repository_fragment_fk\"\n"
+ " FOREIGN KEY (\"repository_fragment\")\n"
+ " REFERENCES \"repository_fragment\" (\"name\")\n"
+ " ON DELETE CASCADE,\n"
+ " CONSTRAINT \"complement_fk\"\n"
+ " FOREIGN KEY (\"complement\")\n"
+ " REFERENCES \"repository\" (\"name\")\n"
+ " DEFERRABLE INITIALLY DEFERRED)");
+ db.execute ("CREATE INDEX \"repository_fragment_complements_repository_fragment_i\"\n"
+ " ON \"repository_fragment_complements\" (\"repository_fragment\")");
+ db.execute ("CREATE TABLE \"repository_fragment_prerequisites\" (\n"
+ " \"repository_fragment\" TEXT NULL,\n"
+ " \"prerequisite\" TEXT NULL,\n"
+ " CONSTRAINT \"repository_fragment_fk\"\n"
+ " FOREIGN KEY (\"repository_fragment\")\n"
+ " REFERENCES \"repository_fragment\" (\"name\")\n"
+ " ON DELETE CASCADE,\n"
+ " CONSTRAINT \"prerequisite_fk\"\n"
+ " FOREIGN KEY (\"prerequisite\")\n"
+ " REFERENCES \"repository\" (\"name\")\n"
+ " DEFERRABLE INITIALLY DEFERRED)");
+ db.execute ("CREATE INDEX \"repository_fragment_prerequisites_repository_fragment_i\"\n"
+ " ON \"repository_fragment_prerequisites\" (\"repository_fragment\")");
+ db.execute ("CREATE TABLE \"repository\" (\n"
+ " \"name\" TEXT NULL PRIMARY KEY,\n"
+ " \"url\" TEXT NULL,\n"
+ " \"type\" TEXT NULL,\n"
+ " \"certificate\" TEXT NULL)");
+ db.execute ("CREATE TABLE \"repository_fragments\" (\n"
+ " \"repository\" TEXT NULL,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"friendly_name\" TEXT NULL,\n"
+ " \"fragment\" TEXT NULL,\n"
+ " CONSTRAINT \"repository_fk\"\n"
+ " FOREIGN KEY (\"repository\")\n"
+ " REFERENCES \"repository\" (\"name\")\n"
+ " ON DELETE CASCADE,\n"
+ " CONSTRAINT \"fragment_fk\"\n"
+ " FOREIGN KEY (\"fragment\")\n"
+ " REFERENCES \"repository_fragment\" (\"name\")\n"
+ " DEFERRABLE INITIALLY DEFERRED)");
+ db.execute ("CREATE INDEX \"repository_fragments_repository_i\"\n"
+ " ON \"repository_fragments\" (\"repository\")");
+ db.execute ("CREATE INDEX \"repository_fragments_index_i\"\n"
+ " ON \"repository_fragments\" (\"index\")");
+ db.execute ("CREATE TABLE \"available_package\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"version_upstream\" TEXT NULL,\n"
+ " \"version_release\" TEXT NULL,\n"
+ " \"sha256sum\" TEXT NULL,\n"
+ " PRIMARY KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\"))");
+ db.execute ("CREATE TABLE \"available_package_locations\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"repository_fragment\" TEXT NULL,\n"
+ " \"location\" TEXT NULL,\n"
+ " CONSTRAINT \"object_id_fk\"\n"
+ " FOREIGN KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " REFERENCES \"available_package\" (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " ON DELETE CASCADE,\n"
+ " CONSTRAINT \"repository_fragment_fk\"\n"
+ " FOREIGN KEY (\"repository_fragment\")\n"
+ " REFERENCES \"repository_fragment\" (\"name\")\n"
+ " DEFERRABLE INITIALLY DEFERRED)");
+ db.execute ("CREATE INDEX \"available_package_locations_object_id_i\"\n"
+ " ON \"available_package_locations\" (\n"
+ " \"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")");
+ db.execute ("CREATE TABLE \"available_package_dependencies\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"conditional\" INTEGER NULL,\n"
+ " \"buildtime\" INTEGER NULL,\n"
+ " \"comment\" TEXT NULL,\n"
+ " \"type\" TEXT NULL,\n"
+ " CONSTRAINT \"object_id_fk\"\n"
+ " FOREIGN KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " REFERENCES \"available_package\" (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"available_package_dependencies_object_id_i\"\n"
+ " ON \"available_package_dependencies\" (\n"
+ " \"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")");
+ db.execute ("CREATE INDEX \"available_package_dependencies_index_i\"\n"
+ " ON \"available_package_dependencies\" (\"index\")");
+ db.execute ("CREATE TABLE \"available_package_dependency_alternatives\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"dependency_index\" INTEGER NULL,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"dep_name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"dep_min_version_epoch\" INTEGER NULL,\n"
+ " \"dep_min_version_canonical_upstream\" TEXT NULL,\n"
+ " \"dep_min_version_canonical_release\" TEXT NULL,\n"
+ " \"dep_min_version_revision\" INTEGER NULL,\n"
+ " \"dep_min_version_iteration\" INTEGER NULL,\n"
+ " \"dep_min_version_upstream\" TEXT NULL,\n"
+ " \"dep_min_version_release\" TEXT NULL,\n"
+ " \"dep_max_version_epoch\" INTEGER NULL,\n"
+ " \"dep_max_version_canonical_upstream\" TEXT NULL,\n"
+ " \"dep_max_version_canonical_release\" TEXT NULL,\n"
+ " \"dep_max_version_revision\" INTEGER NULL,\n"
+ " \"dep_max_version_iteration\" INTEGER NULL,\n"
+ " \"dep_max_version_upstream\" TEXT NULL,\n"
+ " \"dep_max_version_release\" TEXT NULL,\n"
+ " \"dep_min_open\" INTEGER NULL,\n"
+ " \"dep_max_open\" INTEGER NULL,\n"
+ " CONSTRAINT \"object_id_fk\"\n"
+ " FOREIGN KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " REFERENCES \"available_package\" (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"available_package_dependency_alternatives_object_id_i\"\n"
+ " ON \"available_package_dependency_alternatives\" (\n"
+ " \"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")");
+ db.execute ("CREATE TABLE \"available_package_tests\" (\n"
+ " \"name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL COLLATE BINARY,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"index\" INTEGER NULL,\n"
+ " \"test_name\" TEXT NULL COLLATE NOCASE,\n"
+ " \"test_min_version_epoch\" INTEGER NULL,\n"
+ " \"test_min_version_canonical_upstream\" TEXT NULL,\n"
+ " \"test_min_version_canonical_release\" TEXT NULL,\n"
+ " \"test_min_version_revision\" INTEGER NULL,\n"
+ " \"test_min_version_iteration\" INTEGER NULL,\n"
+ " \"test_min_version_upstream\" TEXT NULL,\n"
+ " \"test_min_version_release\" TEXT NULL,\n"
+ " \"test_max_version_epoch\" INTEGER NULL,\n"
+ " \"test_max_version_canonical_upstream\" TEXT NULL,\n"
+ " \"test_max_version_canonical_release\" TEXT NULL,\n"
+ " \"test_max_version_revision\" INTEGER NULL,\n"
+ " \"test_max_version_iteration\" INTEGER NULL,\n"
+ " \"test_max_version_upstream\" TEXT NULL,\n"
+ " \"test_max_version_release\" TEXT NULL,\n"
+ " \"test_min_open\" INTEGER NULL,\n"
+ " \"test_max_open\" INTEGER NULL,\n"
+ " \"test_type\" TEXT NULL,\n"
+ " CONSTRAINT \"object_id_fk\"\n"
+ " FOREIGN KEY (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " REFERENCES \"available_package\" (\"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")\n"
+ " ON DELETE CASCADE)");
+ db.execute ("CREATE INDEX \"available_package_tests_object_id_i\"\n"
+ " ON \"available_package_tests\" (\n"
+ " \"name\",\n"
+ " \"version_epoch\",\n"
+ " \"version_canonical_upstream\",\n"
+ " \"version_canonical_release\",\n"
+ " \"version_revision\",\n"
+ " \"version_iteration\")");
+ db.execute ("CREATE INDEX \"available_package_tests_index_i\"\n"
+ " ON \"available_package_tests\" (\"index\")");
+ db.execute ("CREATE TABLE \"selected_package\" (\n"
+ " \"name\" TEXT NULL PRIMARY KEY COLLATE NOCASE,\n"
+ " \"version_epoch\" INTEGER NULL,\n"
+ " \"version_canonical_upstream\" TEXT NULL,\n"
+ " \"version_canonical_release\" TEXT NULL,\n"
+ " \"version_revision\" INTEGER NULL,\n"
+ " \"version_iteration\" INTEGER NULL,\n"
+ " \"version_upstream\" TEXT NULL,\n"
+ " \"version_release\" TEXT NULL,\n"
+ " \"state\" TEXT NULL,\n"
+ " \"substate\" TEXT NULL,\n"
+ " \"hold_package\" INTEGER NULL,\n"
+ " \"hold_version\" INTEGER NULL,\n"
+ " \"repository_fragment_url\" TEXT NULL,\n"
+ " \"repository_fragment_type\" TEXT NULL,\n"
+ " \"archive\" TEXT NULL,\n"
+ " \"purge_archive\" INTEGER NULL,\n"
+ " \"src_root\" TEXT NULL,\n"
+ " \"purge_src\" INTEGER NULL,\n"
+ " \"manifest_checksum\" TEXT NULL,\n"
+ " \"out_root\" TEXT NULL)");
+ db.execute ("CREATE TABLE \"selected_package_prerequisites\" (\n"
+ " \"package\" TEXT NULL COLLATE NOCASE,\n"
+ " \"prerequisite\" TEXT NULL COLLATE NOCASE,\n"
+