diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 25af0dda4..559416795 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1781,7 +1781,7 @@ void DerivationGoal::computeClosure() contentHashes[i->second.path], allReferences[i->second.path], //set of component-references allStateReferences[i->second.path], //set of state-references - drvPath); + drvPath, 0); } //Register the state path valid @@ -1795,7 +1795,7 @@ void DerivationGoal::computeClosure() Hash(), //emtpy hash state_references, state_stateReferences, - drvPath); + drvPath, 0); } txn.commit(); @@ -2199,7 +2199,7 @@ void SubstitutionGoal::finished() Transaction txn; createStoreTransaction(txn); registerValidPath(txn, storePath, contentHash, //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! how about substituing a state path ????? - references, stateReferences, sub.deriver); + references, stateReferences, sub.deriver, 0); txn.commit(); outputLock->setDeletion(true); diff --git a/src/libstore/db.cc b/src/libstore/db.cc index 8fc298931..03737d0a8 100644 --- a/src/libstore/db.cc +++ b/src/libstore/db.cc @@ -447,30 +447,52 @@ void Database::enumTable(const Transaction & txn, TableId table, void Database::setStateReferences(const Transaction & txn, TableId table, const Path & statePath, const int revision, const Strings & references) { - //get all previous StateReferences - StateReferences newReferences; + //Create the key + string key = statePath + "-" + int2String(revision); - //Merge - newReferences[revision] = references; - - - - //Insert - string data = ""; - checkInterrupt(); - try { - Db * db = getDb(table); - Dbt kt((void *) statePath.c_str(), statePath.length()); - Dbt dt((void *) data.c_str(), data.length()); - db->put(txn.txn, &kt, &dt, 0); - } catch (DbException e) { rethrow(e); } + //Insert + setStrings(txn, table, key, references); } bool Database::queryStateReferences(const Transaction & txn, TableId table, const Path & statePath, Strings & references, int revision) { - //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - return false; + Strings keys; + enumTable(txn, table, keys); //get all revisions + + string key = ""; //final key that matches revision + statePath + int highestRev = -1; + + //Lookup which key we need + for (Strings::iterator i = keys.begin(); i != keys.end(); ++i) { + string getStatePath = *i; + + if(getStatePath.substr(0, statePath.size()) == statePath){ + int getRev; + bool succeed = string2Int(getStatePath.substr(statePath.size() + 1, getStatePath.size()), getRev); + if(!succeed) + throw Error("Malformed revision value after statePath in stateRefereneces"); + + printMsg(lvlError, format("KEY: %1% of %2%") % getStatePath % getRev); + + if(revision == -1){ //the user wants the last revision + if(getRev > highestRev) + highestRev = getRev; + } + else if(revision == getRev){ + key = getStatePath; + break; + } + } + } + + if(key == "" && highestRev == -1) //no records found + return false; + + if(revision == -1) + key = statePath + "-" + int2String(highestRev); + + return queryStrings(txn, table, key, references); //now that we have the key, we can query the references } void Database::setStateRevisions(const Transaction & txn, TableId table, @@ -478,13 +500,13 @@ void Database::setStateRevisions(const Transaction & txn, TableId table, { //TODO } -/* + bool Database::queryStateRevisions(const Transaction & txn, TableId table, - const Path & statePath, RevisionNumbers & revisions, int revision = -1) + const Path & statePath, RevisionNumbers & revisions, int revision) { //TODO return false; -}*/ +} bool Database::queryAllStateRevisions(const Transaction & txn, TableId table, const Path & statePath, RevisionNumbers & revisions) diff --git a/src/libstore/db.hh b/src/libstore/db.hh index 120fe9a87..50951b199 100644 --- a/src/libstore/db.hh +++ b/src/libstore/db.hh @@ -103,8 +103,8 @@ public: const Path & statePath, const int revision, const RevisionNumbers & revisions); /* Returns all the revision numbers of the state references closure of the given state path */ - //bool queryStateRevisions(const Transaction & txn, TableId table, - // const Path & statePath, RevisionNumbers & revisions, int revision = -1); + bool queryStateRevisions(const Transaction & txn, TableId table, + const Path & statePath, RevisionNumbers & revisions, int revision = -1); /* Returns all available revision numbers of the given state path */ bool queryAllStateRevisions(const Transaction & txn, TableId table, diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 45e2c8fcf..2e2e5837d 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -392,7 +392,7 @@ static PathSet getStateReferrers(const Transaction & txn, const Path & storePath } void setReferences(const Transaction & txn, const Path & store_or_statePath, - const PathSet & references, const PathSet & stateReferences) + const PathSet & references, const PathSet & stateReferences, const int revision) { /* For unrealisable paths, we can only clear the references. */ if (references.size() > 0 && !isRealisableComponentOrStatePath(txn, store_or_statePath)) @@ -422,6 +422,16 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath, nixDB.setStrings(txn, dbStateReferences, store_or_statePath, Paths(stateReferences.begin(), stateReferences.end())); + + /* + + //TODO SPECIAL + + nixDB.setStateReferences(txn, dbReferences, statePath, revision, Paths(references.begin(), references.end())); + nixDB.setStateReferences(txn, dbStateReferences, statePath, revision, Paths(stateReferences.begin(), stateReferences.end())); + + */ + /* Update the referrers mappings of all new referenced paths. */ for (PathSet::const_iterator i = references.begin(); i != references.end(); ++i) @@ -829,13 +839,14 @@ Path LocalStore::queryStatePathDrv(const Path & statePath) void registerValidPath(const Transaction & txn, const Path & component_or_state_path, const Hash & hash, const PathSet & references, const PathSet & stateReferences, - const Path & deriver) + const Path & deriver, const int revision) { ValidPathInfo info; info.path = component_or_state_path; info.hash = hash; - info.references = references; + info.references = references; //TODO Add revision number !!!!!!!!!!!! info.stateReferences = stateReferences; + info.revision = revision; info.deriver = deriver; ValidPathInfos infos; infos.push_back(info); @@ -869,7 +880,7 @@ void registerValidPaths(const Transaction & txn, const ValidPathInfos & infos) else setStateValid(txn, i->path, i->deriver); //or set state path valid - setReferences(txn, i->path, i->references, i->stateReferences); + setReferences(txn, i->path, i->references, i->stateReferences, i->revision); /* 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) @@ -897,7 +908,7 @@ static void invalidatePath(Transaction & txn, const Path & path) //TODO Adjust if there are no substitutes for this path. This maintains the cleanup invariant. */ if (querySubstitutes(txn, path).size() == 0) { - setReferences(txn, path, PathSet(), PathSet()); + setReferences(txn, path, PathSet(), PathSet(), -1); //Set last references empty (TODO is this ok?) nixDB.delPair(txn, dbDerivers, path); //TODO!!!!! also for state Derivers!!!!!!!!!!!!!!! } @@ -939,7 +950,7 @@ Path LocalStore::addToStore(const Path & _srcPath, bool fixed, canonicalisePathMetaData(dstPath); Transaction txn(nixDB); - registerValidPath(txn, dstPath, h, PathSet(), PathSet(), ""); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!! CHECK (probabyly ok?) + registerValidPath(txn, dstPath, h, PathSet(), PathSet(), "", 0); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!! CHECK (probabyly ok?) txn.commit(); } @@ -973,7 +984,7 @@ Path LocalStore::addTextToStore(const string & suffix, const string & s, canonicalisePathMetaData(dstPath); Transaction txn(nixDB); - registerValidPath(txn, dstPath, hashPath(htSHA256, dstPath), references, PathSet(), ""); //There are no stateReferences in drvs..... so we dont need to register them (I think) + registerValidPath(txn, dstPath, hashPath(htSHA256, dstPath), references, PathSet(), "", 0); //There are no stateReferences in drvs..... so we dont need to register them (I think) //A drvs has also no statepath, so that is ok... txn.commit(); } @@ -1180,7 +1191,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source) here. */ if (!isValidPath(deriver)) deriver = ""; registerValidPath(txn, dstPath, //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!! replace how about state paths ?????? - hashPath(htSHA256, dstPath), references, stateReferences, deriver); + hashPath(htSHA256, dstPath), references, stateReferences, deriver, 0); txn.commit(); } @@ -1313,7 +1324,7 @@ void verifyStore(bool checkContents) if (realisablePaths.find(*i) == realisablePaths.end()) { printMsg(lvlError, format("removing references entry for unrealisable path `%1%'") % *i); - setReferences(txn, *i, PathSet(), PathSet()); + setReferences(txn, *i, PathSet(), PathSet(), 0); //TODO? } else { bool isValid = validPaths.find(*i) != validPaths.end(); @@ -1375,7 +1386,7 @@ void verifyStore(bool checkContents) if (find(references.begin(), references.end(), to) == references.end()) { printMsg(lvlError, format("adding missing referrer mapping from `%1%' to `%2%'") % from % to); references.insert(to); - setReferences(txn, from, references, stateReferences); + setReferences(txn, from, references, stateReferences, -1); } } @@ -1789,7 +1800,7 @@ static void upgradeStore07() printMsg(lvlError, format("warning: conflicting references for `%1%'") % path); if (references != prevReferences) - setReferences(txn, path, references, PathSet()); + setReferences(txn, path, references, PathSet(), 0); } std::cerr << "."; diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 077547ca4..baa91eec5 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -127,7 +127,7 @@ void clearSubstitutes(); void registerValidPath(const Transaction & txn, const Path & component_or_state_path, const Hash & hash, const PathSet & references, const PathSet & stateReferences, - const Path & deriver); + const Path & deriver, const int revision); struct ValidPathInfo { @@ -136,6 +136,7 @@ struct ValidPathInfo Hash hash; PathSet references; PathSet stateReferences; + int revision; }; typedef list ValidPathInfos; @@ -157,9 +158,12 @@ void canonicalisePathMetaData(const Path & path); bool isValidPathTxn(const Transaction & txn, const Path & path); /* Sets the set of outgoing FS (also state) references for a store path. Use with - care! */ + care! + + -1 for revision means overwrite the last revision + */ void setReferences(const Transaction & txn, const Path & store_or_statePath, - const PathSet & references, const PathSet & stateReferences); + const PathSet & references, const PathSet & stateReferences, const int revision); /* Sets the deriver of a store path. Use with care! */ void setDeriver(const Transaction & txn, const Path & path, @@ -210,6 +214,7 @@ bool isStateComponentTxn(const Transaction & txn, const Path & path); bool isStateDrvPathTxn(const Transaction & txn, const Path & drvPath); bool isStateDrvTxn(const Transaction & txn, const Derivation & drv); + } diff --git a/src/nix-state/nix-state.cc b/src/nix-state/nix-state.cc index af372cbe2..fc6d89be4 100644 --- a/src/nix-state/nix-state.cc +++ b/src/nix-state/nix-state.cc @@ -399,11 +399,12 @@ void run(Strings args) pathSets_difference(p1,p2,p3,p4); pathSets_union(p1,p2); - - - store = openStore(); store->scanForAllReferences("/nix/state/i06flm2ahq5s0x3633z30dnav9f1wkb5-hellohardcodedstateworld-dep1-1.0-test"); + + store = openStore(); + //setReferences_statePath("/nix/state/afsdsdafsdaf-sdaf", 7); return; + */ /* test */ diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 3d603dbf0..e9d8784e6 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -443,7 +443,7 @@ static void opRegisterSubstitutes(Strings opFlags, Strings opArgs) } if (!cin || cin.eof()) throw Error("missing input"); registerSubstitute(txn, srcPath, sub); - setReferences(txn, srcPath, references, stateReferences); + setReferences(txn, srcPath, references, stateReferences, 0); //state revision 0, e.g. first commit } txn.commit();