#
# patch "ChangeLog"
# from [6d6babd353a051b7b5d6028319c3c98c8d81f7b2]
# to [8828e452a0ac7dcf37a61eef52a908415cb90615]
#
# patch "automate.cc"
# from [5416a4b51b9029e98cede29f658fb1120ee7bb65]
# to [b303e2282502365cfd91af081afa85b6df03de8b]
#
# patch "commands.cc"
# from [002c7e8b171019ed9c19cb1f15dcfebdec5c1257]
# to [e91738f6920ce61beca85f8703a8efbab058a53e]
#
# patch "database.cc"
# from [7fbf000b889c6a9e67179e405279c17c08f8b1ff]
# to [d2b9a3f2fb7aae0006bd60e1266f0d9e7f882bfd]
#
# patch "database.hh"
# from [5e52b0b84dd9cdcd155ee9af48481f8476ac2d8b]
# to [a25c05b9b4ae523a61d846f7d21817cde40580bb]
#
========================================================================
--- ChangeLog 6d6babd353a051b7b5d6028319c3c98c8d81f7b2
+++ ChangeLog 8828e452a0ac7dcf37a61eef52a908415cb90615
@@ -1,3 +1,15 @@
+2005-11-27 Grahame Bowland
+
+ * automate.cc (automate_certs,automate_keys): use non-exclusive
+ transaction guard
+ * commands.cc (ls_certs,ls_keys,cat): use non-exclusive
+ transaction guard
+ * database.cc (begin_transaction): used BEGIN DEFERRED (only attempt
+ exclusive lock once a write is attempted on DB) when not exclusive
+ (transaction_guard::transaction_guard): new argument exclusive indicating
+ whether an immediate exclusive lock is requested, defaults to true
+ * database.hh: update prototype for transaction_guard
+
2005-11-26 Nathaniel Smith
* UPGRADE: Add note about serve changing syntax.
@@ -33,7 +45,7 @@
* configure.ac, Makefile.am, po/Makevars: Avoid using xgettext's
--flag option on versions that do not support it.
-2005-11-26 Grahame Bowland
+2005-11-26 Grahame Bowland
* automate.cc (automate_stdio) add wrapper function to read()
so that loops will not wind backwards possibly overrunning buffers
========================================================================
--- automate.cc 5416a4b51b9029e98cede29f658fb1120ee7bb65
+++ automate.cc b303e2282502365cfd91af081afa85b6df03de8b
@@ -834,7 +834,7 @@
std::vector certs;
- transaction_guard guard(app.db);
+ transaction_guard guard(app.db, false);
revision_id rid(idx(args, 0)());
N(app.db.revision_exists(rid), F("No such revision %s") % rid);
@@ -1331,7 +1331,7 @@
std::vector > > items;
if (app.db.database_specified())
{
- transaction_guard guard(app.db);
+ transaction_guard guard(app.db, false);
app.db.get_key_ids("", dbkeys);
guard.commit();
}
========================================================================
--- commands.cc 002c7e8b171019ed9c19cb1f15dcfebdec5c1257
+++ commands.cc e91738f6920ce61beca85f8703a8efbab058a53e
@@ -523,7 +523,7 @@
vector certs;
- transaction_guard guard(app.db);
+ transaction_guard guard(app.db, false);
revision_id ident;
complete(app, idx(args, 0)(), ident);
@@ -626,7 +626,7 @@
if (app.db.database_specified())
{
- transaction_guard guard(app.db);
+ transaction_guard guard(app.db, false);
app.db.get_key_ids(pattern, pubs);
guard.commit();
}
@@ -1363,7 +1363,7 @@
if (app.revision_selectors.size() == 0)
app.require_working_copy();
- transaction_guard guard(app.db);
+ transaction_guard guard(app.db, false);
file_id ident;
revision_id rid;
========================================================================
--- database.cc 7fbf000b889c6a9e67179e405279c17c08f8b1ff
+++ database.cc d2b9a3f2fb7aae0006bd60e1266f0d9e7f882bfd
@@ -675,10 +675,20 @@
}
void
-database::begin_transaction()
+database::begin_transaction(bool exclusive)
{
if (transaction_level == 0)
- execute("BEGIN EXCLUSIVE");
+ {
+ if (exclusive)
+ execute("BEGIN EXCLUSIVE");
+ else
+ execute("BEGIN DEFERRED");
+ transaction_exclusive = exclusive;
+ }
+ else
+ {
+ E(!exclusive || transaction_exclusive, F("Attempt to start exclusive transaction within non-exclusive transaction."));
+ }
transaction_level++;
}
@@ -2549,10 +2559,11 @@
// transaction guards
-transaction_guard::transaction_guard(database & d) : committed(false), db(d)
+transaction_guard::transaction_guard(database & d, bool exclusive) : committed(false), db(d)
{
- db.begin_transaction();
+ db.begin_transaction(exclusive);
}
+
transaction_guard::~transaction_guard()
{
if (committed)
@@ -2567,6 +2578,8 @@
committed = true;
}
+
+
// called to avoid foo.db-journal files hanging around if we exit cleanly
// without unwinding the stack (happens with SIGINT & SIGTERM)
void
========================================================================
--- database.hh 5e52b0b84dd9cdcd155ee9af48481f8476ac2d8b
+++ database.hh a25c05b9b4ae523a61d846f7d21817cde40580bb
@@ -88,6 +88,7 @@
struct sqlite3 * __sql;
struct sqlite3 * sql(bool init = false);
int transaction_level;
+ bool transaction_exclusive;
void install_functions(app_state * app);
void install_views();
@@ -188,7 +189,7 @@
std::vector & certs,
std::string const & table);
- void begin_transaction();
+ void begin_transaction(bool exclusive);
void commit_transaction();
void rollback_transaction();
friend class transaction_guard;
@@ -451,12 +452,21 @@
// transaction-protected, and it'll make sure the db aborts a
// txn if there's any exception before you call commit()
+// by default, locks the database exclusively.
+// if the transaction is intended to be read-only, call with exclusive=False
+// in this case, if a database update is attempted and another process is accessing
+// the database an exception will be thrown - uglier and more confusing for the user -
+// however no data inconsistency should result.
+//
+// an exception is thrown if an exclusive transaction_guard is created while
+// a non-exclusive transaction_guard exists.
+
class transaction_guard
{
bool committed;
database & db;
public:
- transaction_guard(database & d);
+ transaction_guard(database & d, bool exclusive=true);
~transaction_guard();
void commit();
};