about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2003-10-15T12·42+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2003-10-15T12·42+0000
commitebff82222c7b946e70e539389c0027529b6c7ad0 (patch)
tree4f3352f66c91f6f21ef47b1b07f763f4be0ffeb0
parent5fc71276430e8e6a4588fa54da692f81d5ada585 (diff)
* Refactoring: move all database manipulation into store.cc.
* Removed `--query --generators'.

-rw-r--r--src/db.cc8
-rw-r--r--src/db.hh2
-rw-r--r--src/expr.cc11
-rw-r--r--src/globals.cc29
-rw-r--r--src/globals.hh64
-rw-r--r--src/nix-help.txt1
-rw-r--r--src/nix.cc22
-rw-r--r--src/normalise.cc53
-rw-r--r--src/store.cc105
-rw-r--r--src/store.hh18
10 files changed, 143 insertions, 170 deletions
diff --git a/src/db.cc b/src/db.cc
index f9d618b3b3..75f97a1e45 100644
--- a/src/db.cc
+++ b/src/db.cc
@@ -70,6 +70,14 @@ void Transaction::abort()
 }
 
 
+void Transaction::moveTo(Transaction & t)
+{
+    if (t.txn) throw Error("target txn already exists");
+    t.txn = txn;
+    txn = 0;
+}
+
+
 void Database::requireEnv()
 {
     if (!env) throw Error("database environment not open");
diff --git a/src/db.hh b/src/db.hh
index e3dc7ce7af..1c681b9b54 100644
--- a/src/db.hh
+++ b/src/db.hh
@@ -29,6 +29,8 @@ public:
 
     void abort();
     void commit();
+
+    void moveTo(Transaction & t);
 };
 
 
diff --git a/src/expr.cc b/src/expr.cc
index 521dffc9c6..cfc4af1f39 100644
--- a/src/expr.cc
+++ b/src/expr.cc
@@ -39,14 +39,11 @@ Path writeTerm(ATerm t, const string & suffix)
         (string) h + suffix + ".nix");
 
     if (!isValidPath(path)) {
-        if (!ATwriteToNamedTextFile(t, path.c_str()))
-            throw Error(format("cannot write aterm %1%") % path);
-
-        Transaction txn(nixDB);
-        registerValidPath(txn, path);
-        txn.commit();
+        char * s = ATwriteToString(t);
+        if (!s) throw Error(format("cannot write aterm to `%1%'") % path);
+        addTextToStore(path, string(s));
     }
-
+    
     return path;
 }
 
diff --git a/src/globals.cc b/src/globals.cc
index 22d2758b61..a292b49aea 100644
--- a/src/globals.cc
+++ b/src/globals.cc
@@ -1,37 +1,8 @@
 #include "globals.hh"
-#include "db.hh"
-
-
-Database nixDB;
-
-
-TableId dbValidPaths;
-TableId dbSuccessors;
-TableId dbSuccessorsRev;
-TableId dbSubstitutes;
-TableId dbSubstitutesRev;
-
 
 string nixStore = "/UNINIT";
 string nixDataDir = "/UNINIT";
 string nixLogDir = "/UNINIT";
 string nixDBPath = "/UNINIT";
 
-
 bool keepFailed = false;
-
-
-void openDB()
-{
-    nixDB.open(nixDBPath);
-    dbValidPaths = nixDB.openTable("validpaths");
-    dbSuccessors = nixDB.openTable("successors");
-    dbSuccessorsRev = nixDB.openTable("successors-rev");
-    dbSubstitutes = nixDB.openTable("substitutes");
-    dbSubstitutesRev = nixDB.openTable("substitutes-rev");
-}
-
-
-void initDB()
-{
-}
diff --git a/src/globals.hh b/src/globals.hh
index 816cb4766e..1b4d0bde3f 100644
--- a/src/globals.hh
+++ b/src/globals.hh
@@ -3,65 +3,8 @@
 
 #include <string>
 
-#include "db.hh"
-
 using namespace std;
 
-
-extern Database nixDB;
-
-
-/* Database tables. */
-
-
-/* dbValidPaths :: Path -> ()
-
-   The existence of a key $p$ indicates that path $p$ is valid (that
-   is, produced by a succesful build). */
-extern TableId dbValidPaths;
-
-
-/* dbSuccessors :: Path -> Path
-
-   Each pair $(p_1, p_2)$ in this mapping records the fact that the
-   Nix expression stored at path $p_1$ has a successor expression
-   stored at path $p_2$.
-
-   Note that a term $y$ is a successor of $x$ iff there exists a
-   sequence of rewrite steps that rewrites $x$ into $y$.
-*/
-extern TableId dbSuccessors;
-
-
-/* dbSuccessorsRev :: Path -> [Path]
-
-   The reverse mapping of dbSuccessors (i.e., it stores the
-   predecessors of a Nix expression).
-*/
-extern TableId dbSuccessorsRev;
-
-
-/* dbSubstitutes :: Path -> [Path]
-
-   Each pair $(p, [ps])$ tells Nix that it can realise any of the
-   Nix expressions stored at paths $ps$ to produce a path $p$.
-
-   The main purpose of this is for distributed caching of derivates.
-   One system can compute a derivate and put it on a website (as a Nix
-   archive), for instance, and then another system can register a
-   substitute for that derivate.  The substitute in this case might be
-   a Nix expression that fetches the Nix archive.
-*/
-extern TableId dbSubstitutes;
-
-
-/* dbSubstitutesRev :: Path -> [Path]
-
-   The reverse mapping of dbSubstitutes.
-*/
-extern TableId dbSubstitutesRev;
-
-
 /* Path names. */
 
 /* nixStore is the directory where we generally store atomic and
@@ -83,11 +26,4 @@ extern string nixDBPath;
 extern bool keepFailed;
 
 
-/* Open the database environment. */
-void openDB();
-
-/* Create the required database tables. */
-void initDB();
-
-
 #endif /* !__GLOBALS_H */
diff --git a/src/nix-help.txt b/src/nix-help.txt
index ceff114ae5..bf2afd0612 100644
--- a/src/nix-help.txt
+++ b/src/nix-help.txt
@@ -23,7 +23,6 @@ Query flags:
 
   --list / -l: query the output paths (roots) of a Nix expression (default)
   --requisites / -r: print all paths necessary to realise expression
-  --generators / -g: find expressions producing a subset of given ids
   --predecessors: print predecessors of a Nix expression
   --graph: print a dot graph rooted at given ids
 
diff --git a/src/nix.cc b/src/nix.cc
index 1012780af8..a4d2898f15 100644
--- a/src/nix.cc
+++ b/src/nix.cc
@@ -73,7 +73,7 @@ Path maybeNormalise(const Path & ne, bool normalise)
 /* Perform various sorts of queries. */
 static void opQuery(Strings opFlags, Strings opArgs)
 {
-    enum { qList, qRequisites, qGenerators, qPredecessors, qGraph 
+    enum { qList, qRequisites, qPredecessors, qGraph 
     } query = qList;
     bool normalise = false;
     bool includeExprs = true;
@@ -83,7 +83,6 @@ static void opQuery(Strings opFlags, Strings opArgs)
          i != opFlags.end(); i++)
         if (*i == "--list" || *i == "-l") query = qList;
         else if (*i == "--requisites" || *i == "-r") query = qRequisites;
-        else if (*i == "--generators" || *i == "-g") query = qGenerators;
         else if (*i == "--predecessors") query = qPredecessors;
         else if (*i == "--graph") query = qGraph;
         else if (*i == "--normalise" || *i == "-n") normalise = true;
@@ -124,22 +123,6 @@ static void opQuery(Strings opFlags, Strings opArgs)
             break;
         }
 
-#if 0
-        case qGenerators: {
-            FSIds outIds;
-            for (Strings::iterator i = opArgs.begin();
-                 i != opArgs.end(); i++)
-                outIds.push_back(checkPath(*i));
-
-            FSIds genIds = findGenerators(outIds);
-
-            for (FSIds::iterator i = genIds.begin(); 
-                 i != genIds.end(); i++)
-                cout << format("%s\n") % expandId(*i);
-            break;
-        }
-#endif
-
         case qPredecessors: {
             for (Strings::iterator i = opArgs.begin();
                  i != opArgs.end(); i++)
@@ -172,7 +155,8 @@ static void opSuccessor(Strings opFlags, Strings opArgs)
     if (!opFlags.empty()) throw UsageError("unknown flag");
     if (opArgs.size() % 2) throw UsageError("expecting even number of arguments");
 
-    Transaction txn(nixDB); /* !!! this could be a big transaction */ 
+    Transaction txn;
+    createStoreTransaction(txn);
     for (Strings::iterator i = opArgs.begin();
          i != opArgs.end(); )
     {
diff --git a/src/normalise.cc b/src/normalise.cc
index 0dfc9f8e4d..160130d966 100644
--- a/src/normalise.cc
+++ b/src/normalise.cc
@@ -2,7 +2,6 @@
 
 #include "normalise.hh"
 #include "references.hh"
-#include "db.hh"
 #include "exec.hh"
 #include "pathlocks.hh"
 #include "globals.hh"
@@ -11,7 +10,7 @@
 static Path useSuccessor(const Path & path)
 {
     string pathSucc;
-    if (nixDB.queryString(noTxn, dbSuccessors, path, pathSucc)) {
+    if (querySuccessor(path, pathSucc)) {
         debug(format("successor %1% -> %2%") % (string) path % pathSucc);
         return pathSucc;
     } else
@@ -349,7 +348,8 @@ Path normaliseNixExpr(const Path & _nePath, PathSet pending)
        for recoverability: unregistered paths in the store can be
        deleted arbitrarily, while registered paths can only be deleted
        by running the garbage collector. */
-    Transaction txn(nixDB);
+    Transaction txn;
+    createStoreTransaction(txn);
     for (PathSet::iterator i = ne.derivation.outputs.begin(); 
          i != ne.derivation.outputs.end(); i++)
         registerValidPath(txn, *i);
@@ -434,50 +434,3 @@ PathSet nixExprRequisites(const Path & nePath,
         paths, doneSet);
     return paths;
 }
-
-
-#if 0
-PathSet findGenerators(const PathSet & outputs)
-{
-    FSIdSet ids(_ids.begin(), _ids.end());
-    FSIds generators;
-
-    /* !!! hack; for performance, we just look at the rhs of successor
-       mappings, since we know that those are Nix expressions. */
-
-    Strings sucs;
-    nixDB.enumTable(noTxn, dbSuccessors, sucs);
-
-    for (Strings::iterator i = sucs.begin();
-         i != sucs.end(); i++)
-    {
-        string s;
-        if (!nixDB.queryString(noTxn, dbSuccessors, *i, s)) continue;
-        FSId id = parseHash(s);
-
-        NixExpr ne;
-        try {
-            /* !!! should substitutes be used? */
-            ne = parseNixExpr(termFromId(id));
-        } catch (...) { /* !!! only catch parse errors */
-            continue;
-        }
-
-        if (ne.type != NixExpr::neClosure) continue;
-        
-        bool okay = true;
-        for (ClosureElems::const_iterator i = ne.closure.elems.begin();
-             i != ne.closure.elems.end(); i++)
-            if (ids.find(i->second.id) == ids.end()) {
-                okay = false;
-                break;
-            }
-        
-        if (!okay) continue;
-        
-        generators.push_back(id);
-    }
-
-    return generators;
-}
-#endif
diff --git a/src/store.cc b/src/store.cc
index 3e755a0d1a..7f10c6377d 100644
--- a/src/store.cc
+++ b/src/store.cc
@@ -1,7 +1,10 @@
 #include <iostream>
 
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/wait.h>
+#include <fcntl.h>
+#include <unistd.h>
 
 #include "store.hh"
 #include "globals.hh"
@@ -10,6 +13,81 @@
 #include "pathlocks.hh"
 
 
+/* Nix database. */
+static Database nixDB;
+
+
+/* Database tables. */
+
+/* dbValidPaths :: Path -> ()
+
+   The existence of a key $p$ indicates that path $p$ is valid (that
+   is, produced by a succesful build). */
+static TableId dbValidPaths;
+
+/* dbSuccessors :: Path -> Path
+
+   Each pair $(p_1, p_2)$ in this mapping records the fact that the
+   Nix expression stored at path $p_1$ has a successor expression
+   stored at path $p_2$.
+
+   Note that a term $y$ is a successor of $x$ iff there exists a
+   sequence of rewrite steps that rewrites $x$ into $y$.
+*/
+static TableId dbSuccessors;
+
+/* dbSuccessorsRev :: Path -> [Path]
+
+   The reverse mapping of dbSuccessors (i.e., it stores the
+   predecessors of a Nix expression).
+*/
+static TableId dbSuccessorsRev;
+
+/* dbSubstitutes :: Path -> [Path]
+
+   Each pair $(p, [ps])$ tells Nix that it can realise any of the
+   Nix expressions stored at paths $ps$ to produce a path $p$.
+
+   The main purpose of this is for distributed caching of derivates.
+   One system can compute a derivate and put it on a website (as a Nix
+   archive), for instance, and then another system can register a
+   substitute for that derivate.  The substitute in this case might be
+   a Nix expression that fetches the Nix archive.
+*/
+static TableId dbSubstitutes;
+
+/* dbSubstitutesRev :: Path -> [Path]
+
+   The reverse mapping of dbSubstitutes.
+*/
+static TableId dbSubstitutesRev;
+
+
+void openDB()
+{
+    nixDB.open(nixDBPath);
+    dbValidPaths = nixDB.openTable("validpaths");
+    dbSuccessors = nixDB.openTable("successors");
+    dbSuccessorsRev = nixDB.openTable("successors-rev");
+    dbSubstitutes = nixDB.openTable("substitutes");
+    dbSubstitutesRev = nixDB.openTable("substitutes-rev");
+}
+
+
+void initDB()
+{
+}
+
+
+void createStoreTransaction(Transaction & txn)
+{
+    Transaction txn2(nixDB);
+    txn2.moveTo(txn);
+}
+
+
+/* Path copying. */
+
 struct CopySink : DumpSink
 {
     int fd;
@@ -104,6 +182,12 @@ void registerSuccessor(const Transaction & txn,
 }
 
 
+bool querySuccessor(const Path & srcPath, Path & sucPath)
+{
+    return nixDB.queryString(noTxn, dbSuccessors, srcPath, sucPath);
+}
+
+
 Paths queryPredecessors(const Path & sucPath)
 {
     Paths revs;
@@ -204,6 +288,27 @@ Path addToStore(const Path & _srcPath)
 }
 
 
+void addTextToStore(const Path & dstPath, const string & s)
+{
+    if (!isValidPath(dstPath)) {
+
+        /* !!! locking? -> parallel writes are probably idempotent */
+
+        int fd = open(dstPath.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0666);
+        if (fd == -1) throw SysError(format("creating store file `%1%'") % dstPath);
+
+        if (write(fd, s.c_str(), s.size()) != (ssize_t) s.size())
+            throw SysError(format("writing store file `%1%'") % dstPath);
+
+        close(fd); /* !!! close on exception */
+
+        Transaction txn(nixDB);
+        registerValidPath(txn, dstPath);
+        txn.commit();
+    }
+}
+
+
 void deleteFromStore(const Path & _path)
 {
     Path path(canonPath(_path));
diff --git a/src/store.hh b/src/store.hh
index 7851b1e3d8..3d7575c3e8 100644
--- a/src/store.hh
+++ b/src/store.hh
@@ -9,6 +9,15 @@
 using namespace std;
 
 
+/* Open the database environment. */
+void openDB();
+
+/* Create the required database tables. */
+void initDB();
+
+/* Get a transaction object. */
+void createStoreTransaction(Transaction & txn);
+
 /* Copy a path recursively. */
 void copyPath(const Path & src, const Path & dst);
 
@@ -24,6 +33,10 @@ void registerSuccessor(const Transaction & txn,
 
 /* Return the predecessors of the Nix expression stored at the given
    path. */
+bool querySuccessor(const Path & srcPath, Path & sucPath);
+
+/* Return the predecessors of the Nix expression stored at the given
+   path. */
 Paths queryPredecessors(const Path & sucPath);
 
 /* Register a substitute. */
@@ -42,6 +55,11 @@ bool isValidPath(const Path & path);
    the resulting path.  The resulting path is returned. */
 Path addToStore(const Path & srcPath);
 
+/* Like addToStore, but the path of the output is given, and the
+   contents written to the output path is a regular file containing
+   the given string. */
+void addTextToStore(const Path & dstPath, const string & s);
+
 /* Delete a value from the nixStore directory. */
 void deleteFromStore(const Path & path);