about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/store.cc50
-rw-r--r--src/libstore/store.hh13
-rw-r--r--src/nix-store/main.cc25
3 files changed, 63 insertions, 25 deletions
diff --git a/src/libstore/store.cc b/src/libstore/store.cc
index e9d65404400e..5742bbb73870 100644
--- a/src/libstore/store.cc
+++ b/src/libstore/store.cc
@@ -508,24 +508,48 @@ Hash queryPathHash(const Path & path)
 
 
 void registerValidPath(const Transaction & txn,
-    const Path & _path, const Hash & hash, const PathSet & references,
+    const Path & path, const Hash & hash, const PathSet & references,
     const Path & deriver)
 {
-    Path path(canonPath(_path));
-    assertStorePath(path);
+    ValidPathInfo info;
+    info.path = path;
+    info.hash = hash;
+    info.references = references;
+    info.deriver = deriver;
+    ValidPathInfos infos;
+    infos.push_back(info);
+    registerValidPaths(txn, infos);
+}
 
-    debug(format("registering path `%1%'") % path);
-    setHash(txn, path, hash);
 
-    setReferences(txn, path, references);
-    
-    /* Check that all referenced paths are also valid. */
-    for (PathSet::iterator i = references.begin(); i != references.end(); ++i)
-        if (!isValidPathTxn(txn, *i))
-            throw Error(format("cannot register path `%1%' as valid, since its reference `%2%' is invalid")
-                % path % *i);
+void registerValidPaths(const Transaction & txn,
+    const ValidPathInfos & infos)
+{
+    PathSet newPaths;
+    for (ValidPathInfos::const_iterator i = infos.begin();
+         i != infos.end(); ++i)
+        newPaths.insert(i->path);
+        
+    for (ValidPathInfos::const_iterator i = infos.begin();
+         i != infos.end(); ++i)
+    {
+        assertStorePath(i->path);
+
+        debug(format("registering path `%1%'") % i->path);
+        setHash(txn, i->path, i->hash);
 
-    setDeriver(txn, path, deriver);
+        setReferences(txn, i->path, i->references);
+    
+        /* Check that all referenced paths are also valid (or about to
+           become valid). */
+        for (PathSet::iterator j = i->references.begin();
+             j != i->references.end(); ++j)
+            if (!isValidPathTxn(txn, *j) && newPaths.find(*j) == newPaths.end())
+                throw Error(format("cannot register path `%1%' as valid, since its reference `%2%' is invalid")
+                    % i->path % *j);
+
+        setDeriver(txn, i->path, i->deriver);
+    }
 }
 
 
diff --git a/src/libstore/store.hh b/src/libstore/store.hh
index 4a37a66322aa..01a971404c5c 100644
--- a/src/libstore/store.hh
+++ b/src/libstore/store.hh
@@ -66,6 +66,19 @@ void registerValidPath(const Transaction & txn,
     const Path & path, const Hash & hash, const PathSet & references,
     const Path & deriver);
 
+struct ValidPathInfo 
+{
+    Path path;
+    Path deriver;
+    Hash hash;
+    PathSet references;
+};
+
+typedef list<ValidPathInfo> ValidPathInfos;
+
+void registerValidPaths(const Transaction & txn,
+    const ValidPathInfos & infos);
+
 /* Throw an exception if `path' is not directly in the Nix store. */
 void assertStorePath(const Path & path);
 
diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc
index 956cbb4fbbe4..42783e108a2f 100644
--- a/src/nix-store/main.cc
+++ b/src/nix-store/main.cc
@@ -405,31 +405,32 @@ static void opRegisterValidity(Strings opFlags, Strings opArgs)
     if (!opFlags.empty()) throw UsageError("unknown flag");
     if (!opArgs.empty()) throw UsageError("no arguments expected");
 
-    Transaction txn;
-    createStoreTransaction(txn);
-
+    ValidPathInfos infos;
+    
     while (1) {
-        Path path;
-        Path deriver;
-        PathSet references;
-        getline(cin, path);
+        ValidPathInfo info;
+        getline(cin, info.path);
         if (cin.eof()) break;
-        getline(cin, deriver);
+        getline(cin, info.deriver);
         string s; int n;
         getline(cin, s);
         if (!string2Int(s, n)) throw Error("number expected");
         while (n--) {
             getline(cin, s);
-            references.insert(s);
+            info.references.insert(s);
         }
         if (!cin || cin.eof()) throw Error("missing input");
-        if (!isValidPathTxn(txn, path)) {
+        if (!isValidPath(info.path)) {
             /* !!! races */
-            canonicalisePathMetaData(path);
-            registerValidPath(txn, path, hashPath(htSHA256, path), references, deriver);
+            canonicalisePathMetaData(info.path);
+            info.hash = hashPath(htSHA256, info.path);
+            infos.push_back(info);
         }
     }
 
+    Transaction txn;
+    createStoreTransaction(txn);
+    registerValidPaths(txn, infos);
     txn.commit();
 }