diff options
-rw-r--r-- | bpkg/.gitignore | 2 | ||||
-rw-r--r-- | bpkg/buildfile | 12 | ||||
-rw-r--r-- | bpkg/database.cxx | 22 | ||||
-rwxr-xr-x | bpkg/odb.sh | 15 | ||||
-rw-r--r-- | bpkg/package | 94 | ||||
-rw-r--r-- | bpkg/package.cxx | 38 | ||||
-rw-r--r-- | bpkg/package.xml | 15 |
7 files changed, 192 insertions, 6 deletions
diff --git a/bpkg/.gitignore b/bpkg/.gitignore index dabfb06..38ecb79 100644 --- a/bpkg/.gitignore +++ b/bpkg/.gitignore @@ -1,3 +1,5 @@ bpkg *-options *-options.?xx +*-odb +*-odb.?xx diff --git a/bpkg/buildfile b/bpkg/buildfile index 272e051..b393780 100644 --- a/bpkg/buildfile +++ b/bpkg/buildfile @@ -9,12 +9,12 @@ import libs += libbutl%lib{butl} import libs += libodb%lib{odb} import libs += libodb-sqlite%lib{odb-sqlite} -exe{bpkg}: cxx{database diagnostics utility} \ - cli.cxx{common-options} cxx{types-parsers} \ - cxx{bpkg} cli.cxx{bpkg-options} \ - cxx{help} cli.cxx{help-options} \ - cxx{cfg-create} cli.cxx{cfg-create-options} \ - cxx{rep-create} cli.cxx{rep-create-options} \ +exe{bpkg}: cxx{package package-odb database diagnostics utility} \ + cli.cxx{common-options} cxx{types-parsers} \ + cxx{bpkg} cli.cxx{bpkg-options} \ + cxx{help} cli.cxx{help-options} \ + cxx{cfg-create} cli.cxx{cfg-create-options} \ + cxx{rep-create} cli.cxx{rep-create-options} \ $libs cli.options += -I $src_root --include-with-brackets --include-prefix bpkg \ diff --git a/bpkg/database.cxx b/bpkg/database.cxx index 18bb5af..01488c6 100644 --- a/bpkg/database.cxx +++ b/bpkg/database.cxx @@ -7,6 +7,7 @@ #include <memory> // unique_ptr #include <utility> // move() +#include <odb/schema-catalog.hxx> #include <odb/sqlite/exceptions.hxx> #include <bpkg/types> @@ -17,6 +18,7 @@ using namespace std; namespace bpkg { using namespace odb::sqlite; + using odb::schema_catalog; database open (const dir_path& d, bool create) @@ -49,6 +51,26 @@ namespace bpkg t.commit (); } + if (create) + { + // Create the new schema. + // + if (db.schema_version () != 0) + fail << f << ": already has database schema"; + + transaction t (db.begin ()); + schema_catalog::create_schema (db); + t.commit (); + } + else + { + // Migrate the database if necessary. + // + transaction t (db.begin ()); + schema_catalog::migrate (db); + t.commit (); + } + return db; } catch (const database_exception& e) diff --git a/bpkg/odb.sh b/bpkg/odb.sh new file mode 100755 index 0000000..12ac408 --- /dev/null +++ b/bpkg/odb.sh @@ -0,0 +1,15 @@ +#! /usr/bin/env bash + +trap 'exit 1' ERR + +odb=/home/boris/work/odb/odb/odb/odb +lib="\ +-I/home/boris/work/odb/libodb-sqlite-default \ +-I/home/boris/work/odb/libodb-sqlite \ +-I/home/boris/work/odb/libodb-default \ +-I/home/boris/work/odb/libodb" + +$odb -d sqlite --std c++11 --hxx-suffix "" --generate-query --generate-schema \ + $lib -I.. -I../../libbpkg -I../../libbutl \ + --include-with-brackets --include-prefix bpkg --guard-prefix BPKG \ + --sqlite-override-null package diff --git a/bpkg/package b/bpkg/package new file mode 100644 index 0000000..2aa7412 --- /dev/null +++ b/bpkg/package @@ -0,0 +1,94 @@ +// file : bpkg/package -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BPKG_PACKAGE +#define BPKG_PACKAGE + +#include <memory> // shared_ptr +#include <cstdint> // uint16 +#include <ostream> +#include <utility> // move() + +#include <odb/core.hxx> + +#include <bpkg/types> + +#pragma db model version(1, 1, open) + +namespace bpkg +{ + // Use an image type to map version to the database since there + // is no way to modify individual components directly. + // + #pragma db value + struct _version + { + std::uint16_t epoch; + std::string upstream; + std::uint16_t revision; + std::string canonical_upstream; + }; +} + +#include <bpkg/manifest> + +namespace bpkg +{ + // version + // + #pragma db map type(version) as(_version) \ + to(bpkg::_version{(?).epoch (), \ + (?).upstream (), \ + (?).revision (), \ + (?).canonical_upstream ()}) \ + from(bpkg::version ((?).epoch, std::move ((?).upstream), (?).revision)) + + // state + // + enum class state + { + fetched, + unpacked, + configured, + updated, + broken + }; + + string + to_string (state); + + state + from_string (const string&); // May throw invalid_argument. + + inline std::ostream& + operator<< (std::ostream& os, state s) {return os << to_string (s);} + + #pragma db map type(state) as(string) \ + to(to_string (?)) \ + from(bpkg::from_string (?)) + + // package + // + #pragma db object pointer(std::shared_ptr) + class package + { + public: + using version_type = bpkg::version; + using state_type = bpkg::state; + + string name; + version_type version; + state_type state; + + // Database mapping. + // + #pragma db member(name) id + + private: + friend class odb::access; + package () = default; + }; +} + +#endif // BPKG_PACKAGE diff --git a/bpkg/package.cxx b/bpkg/package.cxx new file mode 100644 index 0000000..7ffb99d --- /dev/null +++ b/bpkg/package.cxx @@ -0,0 +1,38 @@ +// file : bpkg/package.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <bpkg/package> + +#include <stdexcept> // invalid_argument + +using namespace std; + +namespace bpkg +{ + string + to_string (state s) + { + switch (s) + { + case state::fetched: return "fetched"; + case state::unpacked: return "unpacked"; + case state::configured: return "configured"; + case state::updated: return "updated"; + case state::broken: return "broken"; + } + + return string (); // Should never reach. + } + + state + from_string (const string& s) + { + if (s == "fetched") return state::fetched; + else if (s == "unpacked") return state::unpacked; + else if (s == "configured") return state::configured; + else if (s == "updated") return state::updated; + else if (s == "broken") return state::broken; + else throw invalid_argument (s); + } +} diff --git a/bpkg/package.xml b/bpkg/package.xml new file mode 100644 index 0000000..dc5f197 --- /dev/null +++ b/bpkg/package.xml @@ -0,0 +1,15 @@ +<changelog xmlns="http://www.codesynthesis.com/xmlns/odb/changelog" database="sqlite" version="1"> + <model version="1"> + <table name="package" kind="object"> + <column name="name" type="TEXT" null="true"/> + <column name="version_epoch" type="INTEGER" null="true"/> + <column name="version_upstream" type="TEXT" null="true"/> + <column name="version_revision" type="INTEGER" null="true"/> + <column name="version_canonical_upstream" type="TEXT" null="true"/> + <column name="state" type="TEXT" null="true"/> + <primary-key> + <column name="name"/> + </primary-key> + </table> + </model> +</changelog> |