diff options
-rw-r--r-- | bpkg/buildfile | 8 | ||||
-rw-r--r-- | bpkg/cfg-create.cxx | 5 | ||||
-rw-r--r-- | bpkg/database | 21 | ||||
-rw-r--r-- | bpkg/database.cxx | 60 |
4 files changed, 91 insertions, 3 deletions
diff --git a/bpkg/buildfile b/bpkg/buildfile index 0d9bf61..272e051 100644 --- a/bpkg/buildfile +++ b/bpkg/buildfile @@ -4,10 +4,12 @@ using cli -import libs = libbutl%lib{butl} -import libs += libbpkg%lib{bpkg} +import libs = libbpkg%lib{bpkg} +import libs += libbutl%lib{butl} +import libs += libodb%lib{odb} +import libs += libodb-sqlite%lib{odb-sqlite} -exe{bpkg}: cxx{diagnostics utility} \ +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} \ diff --git a/bpkg/cfg-create.cxx b/bpkg/cfg-create.cxx index 1875c75..08e64b1 100644 --- a/bpkg/cfg-create.cxx +++ b/bpkg/cfg-create.cxx @@ -11,6 +11,7 @@ #include <bpkg/types> #include <bpkg/utility> +#include <bpkg/database> #include <bpkg/diagnostics> using namespace std; @@ -145,6 +146,10 @@ namespace bpkg run (args); } + // Create the database. + // + open (d, true); + if (verb) { d.complete (); diff --git a/bpkg/database b/bpkg/database new file mode 100644 index 0000000..820555d --- /dev/null +++ b/bpkg/database @@ -0,0 +1,21 @@ +// file : bpkg/database -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BPKG_DATABASE +#define BPKG_DATABASE + +#include <odb/sqlite/database.hxx> + +#include <bpkg/types> + +namespace bpkg +{ + using odb::sqlite::database; + using odb::sqlite::transaction; + + database + open (const dir_path& configuration, bool create = false); +} + +#endif // BPKG_DATABASE diff --git a/bpkg/database.cxx b/bpkg/database.cxx new file mode 100644 index 0000000..18bb5af --- /dev/null +++ b/bpkg/database.cxx @@ -0,0 +1,60 @@ +// file : bpkg/database.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <bpkg/database> + +#include <memory> // unique_ptr +#include <utility> // move() + +#include <odb/sqlite/exceptions.hxx> + +#include <bpkg/types> +#include <bpkg/diagnostics> + +using namespace std; + +namespace bpkg +{ + using namespace odb::sqlite; + + database + open (const dir_path& d, bool create) + { + path f (d / path ("bpkg.sqlite3")); + + try + { + // We don't need the thread pool. + // + unique_ptr<connection_factory> cf (new single_connection_factory); + + database db (f.string (), + SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), + true, // Enable FKs. + "", // Default VFS. + move (cf)); + + // Lock the database for as long as the connection is active. First + // we set locking_mode to EXCLUSIVE which instructs SQLite not to + // release any locks until the connection is closed. Then we force + // SQLite to acquire the write lock by starting exclusive transaction. + // See the locking_mode pragma documentation for details. This will + // also fail if the database is inaccessible (e.g., file does not + // exist, already used by another process, etc). + // + { + db.connection ()->execute ("PRAGMA locking_mode = EXCLUSIVE"); + transaction t (db.begin_exclusive ()); + t.commit (); + } + + return db; + } + catch (const database_exception& e) + { + error << f << ": " << e.message (); + throw failed (); + } + } +} |