about summary refs log tree commit diff
path: root/src/store.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2003-07-31T16·05+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2003-07-31T16·05+0000
commit06d3d7355d1b0ec05e61d2e7fe67f8d7153c1ff9 (patch)
tree424a162babe37ef113f8f908715e095f180d001f /src/store.cc
parent177a7782aee4c4789ad5377b5993bfa0b692282e (diff)
* Enclose most operations that update the database in transactions.
* Open all database tables (Db objects) at initialisation time, not
  every time they are used.  This is necessary because tables have to
  outlive all transactions that refer to them.

Diffstat (limited to 'src/store.cc')
-rw-r--r--src/store.cc57
1 files changed, 38 insertions, 19 deletions
diff --git a/src/store.cc b/src/store.cc
index 3dc625a7b2..6d7861d0be 100644
--- a/src/store.cc
+++ b/src/store.cc
@@ -32,6 +32,8 @@ struct CopySource : RestoreSource
 
 void copyPath(string src, string dst)
 {
+    debug(format("copying `%1%' to `%2%'") % src % dst);
+
     /* Unfortunately C++ doesn't support coprocedures, so we have no
        nice way to chain CopySink and CopySource together.  Instead we
        fork off a child to run the sink.  (Fork-less platforms should
@@ -96,54 +98,69 @@ void registerSubstitute(const FSId & srcId, const FSId & subId)
     /* For now, accept only one substitute per id. */
     Strings subs;
     subs.push_back(subId);
-    nixDB.setStrings(noTxn, dbSubstitutes, srcId, subs);
+    
+    Transaction txn(nixDB);
+    nixDB.setStrings(txn, dbSubstitutes, srcId, subs);
+    txn.commit();
 }
 
 
 void registerPath(const string & _path, const FSId & id)
 {
     string path(canonPath(_path));
+    Transaction txn(nixDB);
 
-    nixDB.setString(noTxn, dbPath2Id, path, id);
+    debug(format("registering path `%1%' with id %2%")
+        % path % (string) id);
 
-    Strings paths;
-    nixDB.queryStrings(noTxn, dbId2Paths, id, paths); /* non-existence = ok */
+    string oldId;
+    if (nixDB.queryString(txn, dbPath2Id, path, oldId)) {
+        txn.abort();
+        if (id != parseHash(oldId))
+            throw Error(format("path `%1%' already contains id %2%")
+                % path % oldId);
+        return;
+    }
 
-    for (Strings::iterator it = paths.begin();
-         it != paths.end(); it++)
-        if (*it == path) return;
+    nixDB.setString(txn, dbPath2Id, path, id);
+
+    Strings paths;
+    nixDB.queryStrings(txn, dbId2Paths, id, paths); /* non-existence = ok */
     
     paths.push_back(path);
     
-    nixDB.setStrings(noTxn, dbId2Paths, id, paths);
+    nixDB.setStrings(txn, dbId2Paths, id, paths);
+
+    txn.commit();
 }
 
 
 void unregisterPath(const string & _path)
 {
     string path(canonPath(_path));
+    Transaction txn(nixDB);
+
+    debug(format("unregistering path `%1%'") % path);
 
     string _id;
-    if (!nixDB.queryString(noTxn, dbPath2Id, path, _id)) return;
+    if (!nixDB.queryString(txn, dbPath2Id, path, _id)) {
+        txn.abort();
+        return;
+    }
     FSId id(parseHash(_id));
 
-    nixDB.delPair(noTxn, dbPath2Id, path);
+    nixDB.delPair(txn, dbPath2Id, path);
 
-    /* begin transaction */
-    
     Strings paths, paths2;
-    nixDB.queryStrings(noTxn, dbId2Paths, id, paths); /* non-existence = ok */
+    nixDB.queryStrings(txn, dbId2Paths, id, paths); /* non-existence = ok */
 
-    bool changed = false;
     for (Strings::iterator it = paths.begin();
          it != paths.end(); it++)
-        if (*it != path) paths2.push_back(*it); else changed = true;
+        if (*it != path) paths2.push_back(*it);
 
-    if (changed)
-        nixDB.setStrings(noTxn, dbId2Paths, id, paths2);
-
-    /* end transaction */
+    nixDB.setStrings(txn, dbId2Paths, id, paths2);
 
+    txn.commit();
 }
 
 
@@ -230,6 +247,8 @@ string expandId(const FSId & id, const string & target,
 void addToStore(string srcPath, string & dstPath, FSId & id,
     bool deterministicName)
 {
+    debug(format("adding `%1%' to the store") % srcPath);
+
     srcPath = absPath(srcPath);
     id = hashPath(srcPath);