aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/buildfile8
-rw-r--r--bpkg/cfg-create.cxx5
-rw-r--r--bpkg/database21
-rw-r--r--bpkg/database.cxx60
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 ();
+ }
+ }
+}