aboutsummaryrefslogtreecommitdiff
path: root/migrate
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-03-07 19:11:31 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2016-03-09 16:22:06 +0300
commited0dd177c63bb7758e8633ffe26de2a8bc315d1b (patch)
tree0d4c9b987ef79a96e1509bceb98e8d254bd99669 /migrate
parentb72424fca7a6af6ff7921101c450850fef875152 (diff)
Display sha256sum on the package version details page
Diffstat (limited to 'migrate')
-rw-r--r--migrate/buildfile4
-rw-r--r--migrate/migrate.cli31
-rw-r--r--migrate/migrate.cxx110
3 files changed, 107 insertions, 38 deletions
diff --git a/migrate/buildfile b/migrate/buildfile
index cd0b9c8..1722fea 100644
--- a/migrate/buildfile
+++ b/migrate/buildfile
@@ -2,6 +2,7 @@
# copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
# license : MIT; see accompanying LICENSE file
+import libs += libbutl%lib{butl}
import libs += libodb-pgsql%lib{odb-pgsql}
import libs += libodb%lib{odb}
@@ -13,6 +14,7 @@ exe{brep-migrate}: \
../brep/lib{brep} $libs
cli.options += -I $src_root --include-with-brackets --include-prefix migrate \
---guard-prefix MIGRATE
+--guard-prefix MIGRATE --generate-specifier --page-usage print_ --ansi-color \
+--long-usage
{hxx ixx cxx}{migrate-options}: cli{migrate}
diff --git a/migrate/migrate.cli b/migrate/migrate.cli
index 35d082f..dcbf667 100644
--- a/migrate/migrate.cli
+++ b/migrate/migrate.cli
@@ -2,6 +2,7 @@
// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+include <vector>;
include <string>;
include <cstdint>; // uint16_t
@@ -85,6 +86,36 @@ class options
"Database port number. If not specified, the default port is used."
}
+ std::string --pager // String to allow empty value.
+ {
+ "<path>",
+ "The pager program to be used to show long text. Commonly used pager
+ programs are \cb{less} and \cb{more}. You can also specify additional
+ options that should be passed to the pager program with
+ \cb{--pager-option}. If an empty string is specified as the pager
+ program, then no pager will be used. If the pager program is not
+ explicitly specified, then \cb{brep-migrate} will try to use \cb{less}.
+ If it is not available, then no pager will be used."
+ }
+
+ std::vector<std::string> --pager-option
+ {
+ "<opt>",
+ "Additional option to be passed to the pager program. See \cb{--pager}
+ for more information on the pager program. Repeat this option to
+ specify multiple pager options."
+ }
+
bool --help {"Print usage information and exit."}
bool --version {"Print version and exit."}
};
+
+"\h|EXIT STATUS|
+
+\cb{0} Successful termination.
+
+\cb{1} \cb{brep-migrate} or \l{brep-load(1)} instance is running. Try
+ again.
+
+\cb{2} Fatal error.
+"
diff --git a/migrate/migrate.cxx b/migrate/migrate.cxx
index 702eba0..70ba54f 100644
--- a/migrate/migrate.cxx
+++ b/migrate/migrate.cxx
@@ -13,6 +13,8 @@
#include <odb/pgsql/database.hxx>
+#include <butl/pager>
+
#include <brep/types>
#include <brep/utility>
#include <brep/version>
@@ -25,6 +27,13 @@ using namespace std;
using namespace odb::core;
using namespace brep;
+// Operation failed, diagnostics has already been issued.
+//
+struct failed: std::exception {};
+
+static const char* help_info (
+ " info: run 'brep-migrate --help' for more information");
+
// Helper class that encapsulates both the ODB-generated schema and the
// extra that comes from a .sql file (via xxd).
//
@@ -108,19 +117,28 @@ schema (const char* s)
if (strcasecmp (kw.c_str (), "FUNCTION") == 0)
{
if (!read_until ("$$") || !read_until ("$$"))
- throw invalid_argument (
- "function body must be defined using $$-quoted strings");
+ {
+ cerr << "error: function body must be defined using $$-quoted "
+ "strings" << endl;
+ throw failed ();
+ }
}
else if (strcasecmp (kw.c_str (), "TYPE") == 0)
{
// Fall through.
}
else
- throw invalid_argument ("unexpected CREATE statement");
+ {
+ cerr << "error: unexpected CREATE statement" << endl;
+ throw failed ();
+ }
if (!read_until (";\n"))
- throw invalid_argument (
- "expected ';\\n' at the end of CREATE statement");
+ {
+ cerr << "error: expected ';\\n' at the end of CREATE statement"
+ << endl;
+ throw failed ();
+ }
assert (!statement.empty ());
create_statements_.emplace_back (move (statement));
@@ -128,15 +146,21 @@ schema (const char* s)
else if (strcasecmp (op.c_str (), "DROP") == 0)
{
if (!read_until (";\n"))
- throw invalid_argument (
- "expected ';\\n' at the end of DROP statement");
+ {
+ cerr << "error: expected ';\\n' at the end of DROP statement"
+ << endl;
+ throw failed ();
+ }
assert (!statement.empty ());
drop_statements_.emplace_back (move (statement));
}
else
- throw invalid_argument (
- "unexpected statement starting with '" + op + "'");
+ {
+ cerr << "error: unexpected statement starting with '" << op << "'"
+ << endl;
+ throw failed ();
+ }
}
}
}
@@ -166,17 +190,6 @@ create (database& db) const
db.execute (s);
}
-// Utility functions
-//
-static void
-usage (ostream& os)
-{
- os << "Usage: brep-migrate [options]" << endl
- << "Options:" << endl;
-
- options::print_usage (os);
-}
-
// main() function
//
int
@@ -204,22 +217,30 @@ try
//
if (ops.help ())
{
- usage (cout);
- return 0;
+ butl::pager p ("brep-migrate help",
+ false,
+ ops.pager_specified () ? &ops.pager () : nullptr,
+ &ops.pager_option ());
+
+ print_usage (p.stream ());
+
+ // If the pager failed, assume it has issued some diagnostics.
+ //
+ return p.wait () ? 0 : 2;
}
if (argc > 1)
{
- cerr << "unexpected argument encountered" << endl;
- usage (cerr);
- return 1;
+ cerr << "error: unexpected argument encountered" << endl
+ << help_info << endl;
+ return 2;
}
if (ops.recreate () && ops.drop ())
{
- cerr << "inconsistent options specified" << endl;
- usage (cerr);
- return 1;
+ cerr << "error: inconsistent options specified" << endl
+ << help_info << endl;
+ return 2;
}
odb::pgsql::database db (ops.db_user (),
@@ -247,10 +268,16 @@ try
if (schema_version > 0)
{
if (schema_version < schema_catalog::base_version (db))
- throw runtime_error ("database schema is too old");
+ {
+ cerr << "error: database schema is too old" << endl;
+ throw failed ();
+ }
if (schema_version > schema_catalog::current_version (db))
- throw runtime_error ("database schema is too new");
+ {
+ cerr << "error: database schema is too new" << endl;
+ throw failed ();
+ }
}
bool drop (ops.drop ());
@@ -264,7 +291,12 @@ try
//
if ((create || drop) && schema_version != 0 &&
schema_version != schema_catalog::current_version (db))
- throw runtime_error ("database schema requires migration");
+ {
+ cerr << "error: database schema requires migration" << endl
+ << " info: either migrate the database first or drop the entire "
+ "database using, for example, psql" << endl;
+ throw failed ();
+ }
transaction t (db.begin ());
@@ -292,22 +324,26 @@ try
}
t.commit ();
+ return 0;
}
catch (const database_locked&)
{
cerr << "brep-migrate or brep-load instance is running" << endl;
- return 2;
+ return 1;
}
catch (const cli::exception& e)
{
- cerr << e << endl;
- usage (cerr);
- return 1;
+ cerr << "error: " << e << endl << help_info << endl;
+ return 2;
+}
+catch (const failed&)
+{
+ return 2; // Diagnostics has already been issued.
}
// Fully qualified to avoid ambiguity with odb exception.
//
catch (const std::exception& e)
{
- cerr << e.what () << endl;
- return 1;
+ cerr << "error: " << e.what () << endl;
+ return 2;
}