diff --git a/src/libstore/build.cc b/src/libstore/build.cc index f506a8c29..8529bca81 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1889,9 +1889,8 @@ void DerivationGoal::computeClosure() for (DerivationOutputs::iterator i = drv.outputs.begin(); i != drv.outputs.end(); ++i) { - //Register the path as a store-state path if(isStateDrvPathTxn(txn, drvPath)) - setStateComponentTxn(txn, i->second.path); + setStateComponentTxn(txn, i->second.path); //Register the path as a store-state path registerValidPath(txn, i->second.path, //component path @@ -1919,6 +1918,27 @@ void DerivationGoal::computeClosure() //Save the new revision setStateRevisionsTxn(txn, rivisionMapping, statePath, "Initial build revision."); + + //Convert stateInfo from drv to DB format + DerivationStateOutputDirs stateOutputDirs = drv.stateOutputDirs; + StateInfos infos; + for (DerivationStateOutputDirs::const_reverse_iterator j = stateOutputDirs.rbegin(); j != stateOutputDirs.rend(); ++j){ + DerivationStateOutputDir d = j->second; + StateInfo si; + si.path = d.path; + si.type = d.type; + + if(d.interval != ""){ + bool succeed = string2UnsignedInt(d.interval, si.interval); + if(!succeed) + throw Error(format("Malformed interval value '%1%' in drv '%2%'") % d.interval % drvPath); + } + else + si.interval = 0; + infos.push_back(si); + } + setVersionedStateEntriesTxn(txn, statePath, infos); //register subdirs/files and their types of versioning + setStateUserGroupTxn(txn, statePath, queryCallingUsername(), "nixbld", 700); //register the user and group //Shared state Path sharedState = drv.stateOutputs.find("state")->second.sharedState; @@ -2598,7 +2618,7 @@ void Worker::getInfo() args.push_back("--query-info"); args.insert(args.end(), paths2.begin(), paths2.end()); string res = runProgram(sub, false, args); - printMsg(lvlError, format("run: '%1%' res: '%2%'") % sub % res); + //printMsg(lvlError, format("run: '%1%' res: '%2%'") % sub % res); std::istringstream str(res); while (true) { @@ -2623,8 +2643,6 @@ void Worker::getInfo() } } } - - printMsg(lvlError, format("AAAAAAAAA: '%1%'") % store->isStateComponent("/nix/store/3pw7vmdwdf3ccx6h6i2w0j52ribjswzn-hellotest-1.0")); } } diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 0377599ad..e52c6022b 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -449,7 +449,7 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, bool gcKeepDerivations = queryBoolSetting("gc-keep-derivations", true); - printMsg(lvlError, format("gcKeepOutputs %1% gcKeepDerivations: %2%") % gcKeepOutputs % gcKeepDerivations); + //printMsg(lvlError, format("gcKeepOutputs %1% gcKeepDerivations: %2%") % gcKeepOutputs % gcKeepDerivations); /* Acquire the global GC root. This prevents a) New roots from being added. @@ -483,8 +483,6 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, for (PathSet::const_iterator i = roots.begin(); i != roots.end(); ++i) computeFSClosure(canonPath(*i), livePaths, true, true, 0); - printMsg(lvlError, format("STAGE X")); - /* Note that the deriver need not be valid (e.g., if we previously ran the collector with `gcKeepDerivations' turned off). */ @@ -519,8 +517,6 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, } } - printMsg(lvlError, format("STAGE Y")); - if (gcKeepOutputs) { /* Hmz, identical to storePathRequisites in nix-store. */ for (PathSet::iterator i = livePaths.begin(); i != livePaths.end(); ++i) @@ -591,7 +587,7 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, */ PathSet allStatePathDerivations; for (PathSet::iterator i = allLiveStatePaths.begin(); i != allLiveStatePaths.end(); ++i){ - printMsg(lvlError, format("Live state path `%1%'") % *i); + //printMsg(lvlError, format("Live state path `%1%'") % *i); Path stateDrv = queryStatePathDrvTxn(noTxn, *i); allStatePathDerivations.insert(stateDrv); //printMsg(lvlError, format("Live state path drv `%1%'") % stateDrv); @@ -640,8 +636,6 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, if(*i != "/nix/store/zg8x9wdhcs4j0hvf33vg34c7m65adrpa-env-manifest") continue; - printMsg(lvlError, format("Consider DEL `%1%'") % *i); - PathSet references; store->queryStoreReferences(*i, references, 0); for (PathSet::iterator j = references.begin(); j != references.end(); ++j) { diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index b278344b0..1525172c1 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -158,6 +158,18 @@ static TableId dbStateSnapshots = 0; */ static TableId dbSharedState = 0; +/* + * StatePath :: string + * the string is converted to something of type StateInfos + */ +static TableId dbVersionItems = 0; + +/* + * StatePath :: string + * the string contains the user,group and chmod + */ +static TableId dbStateRights = 0; + static void upgradeStore07(); static void upgradeStore09(); @@ -228,6 +240,8 @@ LocalStore::LocalStore(bool reserveSpace) dbStateSnapshots = nixDB.openTable("stateSnapshots"); dbSharedState = nixDB.openTable("sharedState"); dbSolidStateReferences = nixDB.openTable("references_solid_c_s"); /* The contents of this table is included in references_c_s */ + dbVersionItems = nixDB.openTable("stateItems"); + dbStateRights = nixDB.openTable("stateRights"); int curSchema = 0; Path schemaFN = nixDBPath + "/schema"; @@ -556,7 +570,7 @@ static PathSet getXReferrers(const Transaction & txn, const Path & store_or_stat for (Strings::const_iterator i = keys.begin(); i != keys.end(); ++i){ Path getStatePath; unsigned int getRevision; - splitDBKey(*i, getStatePath, getRevision); + splitDBRevKey(*i, getStatePath, getRevision); if(latest[getStatePath] == 0) //either it is unset latest[getStatePath] = getRevision; @@ -575,7 +589,7 @@ static PathSet getXReferrers(const Transaction & txn, const Path & store_or_stat //printMsg(lvlError, format("AAAAA '%1%'") % (*i).first); Strings references; - nixDB.queryStrings(txn, table, mergeToDBKey((*i).first, (*i).second), references); + nixDB.queryStrings(txn, table, mergeToDBRevKey((*i).first, (*i).second), references); for (Strings::iterator j = references.begin(); j != references.end(); ++j){ //printMsg(lvlError, format("TEST: '%1%' has ref '%2%' check with '%3%'") % (*i).first % *j % path); if(*j == path) @@ -1852,6 +1866,29 @@ void LocalStore::revertToRevision(const Path & statePath, const unsigned int rev txn.commit(); } +void setVersionedStateEntriesTxn(const Transaction & txn, const Path & statePath, + const StateInfos & infos, const unsigned int revision, const unsigned int timestamp) +{ + setVersionedStateEntries(nixDB, txn, dbVersionItems, dbStateRevisions, + statePath, infos, revision, timestamp); +} + +bool getVersionedStateEntriesTxn(const Transaction & txn, const Path & statePath, + StateInfos & infos, const unsigned int revision, const unsigned int timestamp) +{ + return getVersionedStateEntries(nixDB, txn, dbVersionItems, dbStateRevisions, + statePath, infos, revision, timestamp); +} + +void setStateUserGroupTxn(const Transaction & txn, const Path & statePath, const string & user, const string & group, int chmod) +{ + setStateUserGroup(nixDB, txn, dbStateRights, statePath, user, group, chmod); +} + +void getStateUserGroupTxn(const Transaction & txn, const Path & statePath, string & user, string & group, int & chmod) +{ + getStateUserGroup(nixDB, txn, dbStateRights, statePath, user, group, chmod); +} typedef std::map > HashToPath; diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index edc20f28d..7cd63d571 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -275,6 +275,12 @@ bool querySharedStateTxn(const Transaction & txn, const Path & statePath, Path & void setStateComponentTxn(const Transaction & txn, const Path & storePath); +void setVersionedStateEntriesTxn(const Transaction & txn, const Path & statePath, const StateInfos & infos, const unsigned int revision = 0, const unsigned int timestamp = 0); +bool getVersionedStateEntriesTxn(const Transaction & txn, const Path & statePath, StateInfos & infos, const unsigned int revision = 0, const unsigned int timestamp = 0); + +void setStateUserGroupTxn(const Transaction & txn, const Path & statePath, const string & user, const string & group, int chmod); +void getStateUserGroupTxn(const Transaction & txn, const Path & statePath, string & user, string & group, int & chmod); + } diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index f8aa927eb..1cc12907e 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -219,8 +219,6 @@ ValidPathInfo decodeValidPathInfo(std::istream & str) { ValidPathInfo info; - printMsg(lvlError, format("BEFORE decodeValidPathInfo")); - getline(str, info.path); if (str.eof()) { info.path = ""; return info; } @@ -238,8 +236,6 @@ ValidPathInfo decodeValidPathInfo(std::istream & str) if(store->isStateComponent(info.path)){ - printMsg(lvlError, format("STATE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")); - getline(str, s); if (!string2Int(s, n)) throw Error("number expected"); @@ -258,8 +254,6 @@ ValidPathInfo decodeValidPathInfo(std::istream & str) if (!str || str.eof()) throw Error("missing input"); - printMsg(lvlError, format("AFTER decodeValidPathInfo")); - return info; } diff --git a/src/libstore/store-state.cc b/src/libstore/store-state.cc index 5bb957926..7cda932db 100644 --- a/src/libstore/store-state.cc +++ b/src/libstore/store-state.cc @@ -359,24 +359,70 @@ void scanAndUpdateAllReferencesRecusivelyTxn(const Transaction & txn, const Path } } +void rsyncPaths(const Path & from, const Path & to, const bool addSlashes) //TODO bool shellexpansion, bool failure for nix-env +{ + //TODO Could be a symlink (to a non-existing dir) + /* + if(!DirectoryExist(from)) + throw Error(format("Path `%1%' doenst exist ...") % from); + if(!DirectoryExist(to)) + throw Error(format("Path `%1%' doenst exist ...") % to); + */ + + Path from2 = from; + Path to2 = to; + if(addSlashes){ + //We add a slash / to the end to ensure the contents is copyed + if(from2[from2.length() - 1] != '/') + from2 = from2 + "/"; + if(to2[to2.length() - 1] != '/') + to2 = to2 + "/"; + } + + printMsg(lvlError, format("Rsync from: '%1%' to: '%2%'") % from2 % to2); + + //Rsync from --> to and also with '-avHx --delete' + //This makes the paths completely equal (also deletes) and retains times ownership etc. + Strings p_args; + p_args.push_back("-avHx"); + p_args.push_back("--delete"); + p_args.push_back(from2); + p_args.push_back(to2); + runProgram_AndPrintOutput(nixRsync, true, p_args, "rsync"); +} + // ******************************************************* DB FUNCTIONS ******************************************************************** /* State specific db functions */ -Path mergeToDBKey(const Path & statePath, const unsigned int intvalue) +Path mergeToDBKey(const string & s1, const string & s2) { string prefix = "-KEY-"; - return statePath + prefix + unsignedInt2String(intvalue); + return s1 + prefix + s2; +} +Path mergeToDBRevKey(const Path & statePath, const unsigned int intvalue) +{ + return mergeToDBKey(statePath, unsignedInt2String(intvalue)); } -void splitDBKey(const Path & revisionedStatePath, Path & statePath, unsigned int & intvalue) +void splitDBKey(const string & s, string & s1, string & s2) { string prefix = "-KEY-"; + size_t getPos = s.find_last_of(prefix); - int pos = revisionedStatePath.find_last_of(prefix); - statePath = revisionedStatePath.substr(0, pos - prefix.length() + 1); - //printMsg(lvlError, format("'%2%' - '%1%'") % revisionedStatePath.substr(pos+1, revisionedStatePath.length()) % int2String(pos)); - bool succeed = string2UnsignedInt(revisionedStatePath.substr(pos+1, revisionedStatePath.length()), intvalue); + if(getPos == string::npos) + throw Error(format("No prefx '%1%' found in '%2%' so we cannot split") % prefix % s); + + int pos = getPos; + s1 = s.substr(0, pos - prefix.length() + 1); + s2 = s.substr(pos+1, s.length()); +} +void splitDBRevKey(const Path & revisionedStatePath, Path & statePath, unsigned int & intvalue) +{ + string s2; + splitDBKey(revisionedStatePath, statePath, s2); + + bool succeed = string2UnsignedInt(s2, intvalue); if(!succeed) throw Error(format("Malformed revision value of path '%1%'") % revisionedStatePath); } @@ -417,7 +463,7 @@ bool lookupHighestRevivison(const Strings & keys, const Path & statePath, string //printMsg(lvlError, format("'%1%' - '%2%'") % *i % statePath); Path getStatePath; unsigned int getRevision; - splitDBKey(*i, getStatePath, getRevision); + splitDBRevKey(*i, getStatePath, getRevision); if(getRevision > highestRev){ if(lowerthan != 0){ @@ -432,19 +478,19 @@ bool lookupHighestRevivison(const Strings & keys, const Path & statePath, string if(highestRev == 0) //no records found return false; - key = mergeToDBKey(statePath, highestRev); //final key that matches revision + statePath + key = mergeToDBRevKey(statePath, highestRev); //final key that matches revision + statePath return true; } bool revisionToTimeStamp(Database & nixDB, const Transaction & txn, TableId revisions_table, const Path & statePath, const int revision, unsigned int & timestamp) { - string key = mergeToDBKey(statePath, revision); + string key = mergeToDBRevKey(statePath, revision); Strings references; bool notempty = nixDB.queryStrings(txn, revisions_table, key, references); if(notempty){ Path empty; - splitDBKey(*(references.begin()), empty, timestamp); //extract the timestamp + splitDBRevKey(*(references.begin()), empty, timestamp); //extract the timestamp //printMsg(lvlError, format("PRINT '%1%'") % timestamp); return true; } @@ -472,17 +518,13 @@ void setStateReferences(Database & nixDB, const Transaction & txn, TableId refer //Warning if it already exists Strings empty; - if( nixDB.queryStrings(txn, references_table, mergeToDBKey(statePath, timestamp2), empty) ) + if( nixDB.queryStrings(txn, references_table, mergeToDBRevKey(statePath, timestamp2), empty) ) printMsg(lvlError, format("Warning: The timestamp '%1%' (now: '%5%') / revision '%4%' already exists for set-references of path '%2%' with db '%3%'") % timestamp2 % statePath % references_table % revision % getTimeStamp()); //Create the key - string key = mergeToDBKey(statePath, timestamp2); + string key = mergeToDBRevKey(statePath, timestamp2); - //printMsg(lvlError, format("Set references '%1%'") % key); - //for (Strings::const_iterator i = references.begin(); i != references.end(); ++i) - // printMsg(lvlError, format("reference '%1%'") % *i); - //Insert nixDB.setStrings(txn, references_table, key, references, false); //The false makes sure also empty references are set } @@ -514,12 +556,12 @@ bool queryStateReferences(Database & nixDB, const Transaction & txn, TableId ref } //If a specific key is given: check if this timestamp exists key in the table - key = mergeToDBKey(statePath, timestamp2); + key = mergeToDBRevKey(statePath, timestamp2); bool found = false; for (Strings::const_iterator i = keys.begin(); i != keys.end(); ++i) { if(key == *i){ found = true; - key = mergeToDBKey(statePath, timestamp2); + key = mergeToDBRevKey(statePath, timestamp2); } } @@ -555,10 +597,10 @@ void removeAllStatePathRevisions(Database & nixDB, const Transaction & txn, Tabl for (RevisionInfos::iterator i = revisions.begin(); i != revisions.end(); ++i){ unsigned int rev = (*i).first; - nixDB.delPair(txn, revisions_table, mergeToDBKey(statePath, rev)); + nixDB.delPair(txn, revisions_table, mergeToDBRevKey(statePath, rev)); //Remove all comments - nixDB.delPair(txn, revisions_comments, mergeToDBKey(statePath, rev)); + nixDB.delPair(txn, revisions_comments, mergeToDBRevKey(statePath, rev)); } //Remove all snapshots @@ -588,11 +630,11 @@ void setStateRevisions(Database & nixDB, const Transaction & txn, TableId revisi //Insert all ss_epochs into snapshots_table with the current ts. for (RevisionClosure::const_iterator i = revisions.begin(); i != revisions.end(); ++i){ - string key = mergeToDBKey((*i).first, timestamp); + string key = mergeToDBRevKey((*i).first, timestamp); Strings data; //the map<> takes care of the sorting on the Path for (Snapshots::const_iterator j = (*i).second.begin(); j != (*i).second.end(); ++j) - data.push_back(mergeToDBKey((*j).first, (*j).second)); + data.push_back(mergeToDBRevKey((*j).first, (*j).second)); nixDB.setStrings(txn, snapshots_table, key, data); } @@ -602,7 +644,7 @@ void setStateRevisions(Database & nixDB, const Transaction & txn, TableId revisi unsigned int revision = getNewRevisionNumber(nixDB, txn, revisions_table, statePath); //get a new revision number - string key = mergeToDBKey(statePath, revision); + string key = mergeToDBRevKey(statePath, revision); //get all its requisites PathSet statePath_references; @@ -612,7 +654,7 @@ void setStateRevisions(Database & nixDB, const Transaction & txn, TableId revisi //save in db Strings data; for (PathSet::const_iterator j = statePath_references.begin(); j != statePath_references.end(); ++j) - data.push_back(mergeToDBKey(*j, timestamp)); + data.push_back(mergeToDBRevKey(*j, timestamp)); nixDB.setStrings(txn, revisions_table, key, data, false); //The false makes sure also empty revisions are set @@ -644,7 +686,7 @@ bool queryStateRevisions(Database & nixDB, const Transaction & txn, TableId revi return false; } else - key = mergeToDBKey(statePath, root_revision); + key = mergeToDBRevKey(statePath, root_revision); //Get references pointing to snapshots_table from revisions_table with root_revision Strings statePaths; @@ -658,7 +700,7 @@ bool queryStateRevisions(Database & nixDB, const Transaction & txn, TableId revi Path getStatePath; unsigned int getTimestamp; - splitDBKey(*i, getStatePath, getTimestamp); + splitDBRevKey(*i, getStatePath, getTimestamp); //query state versioined directorys/files /* @@ -684,7 +726,7 @@ bool queryStateRevisions(Database & nixDB, const Transaction & txn, TableId revi Path snapshottedPath; unsigned int revision; - splitDBKey(*j, snapshottedPath, revision); + splitDBRevKey(*j, snapshottedPath, revision); snapshots[snapshottedPath] = revision; counter++; @@ -713,7 +755,7 @@ bool queryAvailableStateRevisions(Database & nixDB, const Transaction & txn, Tab Path getStatePath; unsigned int getRevision; - splitDBKey(*i, getStatePath, getRevision); + splitDBRevKey(*i, getStatePath, getRevision); //save the date and comments RevisionInfo rev; @@ -735,36 +777,93 @@ bool queryAvailableStateRevisions(Database & nixDB, const Transaction & txn, Tab return true; } -void rsyncPaths(const Path & from, const Path & to, const bool addSlashes) //TODO bool shellexpansion, bool failure for nix-env +void setVersionedStateEntries(Database & nixDB, const Transaction & txn, TableId versionItems, TableId revisions_table, + const Path & statePath, const StateInfos & infos, const unsigned int revision, const unsigned int timestamp) { - //TODO Could be a symlink (to a non-existing dir) - /* - if(!DirectoryExist(from)) - throw Error(format("Path `%1%' doenst exist ...") % from); - if(!DirectoryExist(to)) - throw Error(format("Path `%1%' doenst exist ...") % to); - */ - - Path from2 = from; - Path to2 = to; - if(addSlashes){ - //We add a slash / to the end to ensure the contents is copyed - if(from2[from2.length() - 1] != '/') - from2 = from2 + "/"; - if(to2[to2.length() - 1] != '/') - to2 = to2 + "/"; + if( !isValidStatePathTxn(txn, statePath) ) + throw Error(format("path '%1%' is not a statepath") % statePath); + + //TODO THIS IS THE SAME CODE AS IN SETSTATEREFERENCES !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //Find the timestamp if we need + unsigned int timestamp2 = timestamp; + if(revision == 0 && timestamp == 0) + timestamp2 = getTimeStamp(); + else if(revision != 0 && timestamp == 0){ + bool found = revisionToTimeStamp(nixDB, txn, revisions_table, statePath, revision, timestamp2); + if(!found) + throw Error(format("Revision '%1%' cannot be matched to a timestamp...") % revision); } - printMsg(lvlError, format("Rsync from: '%1%' to: '%2%'") % from2 % to2); + Strings ss; + for (StateInfos::const_iterator i = infos.begin(); i != infos.end(); ++i) { + StateInfo si = *i; + ss.push_back(mergeToDBKey(si.path, mergeToDBKey(si.type, unsignedInt2String(si.interval)))); + } + nixDB.setStrings(txn, versionItems, statePath, ss); +} + +bool getVersionedStateEntries(Database & nixDB, const Transaction & txn, TableId versionItems, TableId revisions_table, + const Path & statePath, StateInfos & infos, const unsigned int revision, const unsigned int timestamp) +{ + if( !isValidStatePathTxn(txn, statePath) ) + throw Error(format("path '%1%' is not a statepath") % statePath); + + //TODO THIS IS THE SAME CODE AS IN QUERY STATEREFERRERS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 + //Convert revision to timestamp number useing the revisions_table + unsigned int timestamp2 = timestamp; + if(timestamp == 0 && revision != 0){ + bool found = revisionToTimeStamp(nixDB, txn, revisions_table, statePath, revision, timestamp2); + if(!found) //we are asked for references of some revision, but there are no references registered yet, so we return false; + return false; + } - //Rsync from --> to and also with '-avHx --delete' - //This makes the paths completely equal (also deletes) and retains times ownership etc. - Strings p_args; - p_args.push_back("-avHx"); - p_args.push_back("--delete"); - p_args.push_back(from2); - p_args.push_back(to2); - runProgram_AndPrintOutput(nixRsync, true, p_args, "rsync"); + Strings ss; + bool found = nixDB.queryStrings(txn, versionItems, statePath, ss); + if(!found) + return false; + + for (Strings::const_iterator i = ss.begin(); i != ss.end(); ++i) { + + StateInfo si; + + string s1; + string interval; + splitDBKey(*i, s1, interval); + bool succeed = string2UnsignedInt(interval, si.interval); + if(!succeed) + throw Error(format("Malformed TS value of record '%1%'") % *i); + + string path; + string type; + splitDBKey(s1, si.path, si.type); + + infos.push_back(si); + } + + return true; +} + +void setStateUserGroup(Database & nixDB, const Transaction & txn, TableId stateRights, const Path & statePath, const string & user, const string & group, int chmod) +{ + string value = mergeToDBKey(user,mergeToDBKey(group, int2String(chmod))); + nixDB.setString(txn, stateRights, statePath, value); +} + +void getStateUserGroup(Database & nixDB, const Transaction & txn, TableId stateRights, const Path & statePath, string & user, string & group, int & chmod) +{ + string value; + bool notEmpty = nixDB.queryString(txn, stateRights, statePath, value); + if(!notEmpty) + throw Error(format("No rights found for path '%1%'") % statePath); + + string s1; + string chmod_s; + splitDBKey(value, s1, chmod_s); + bool succeed = string2Int(chmod_s, chmod); + if(!succeed) + throw Error(format("Malformed chmod value of path '%1%'") % statePath); + + splitDBKey(s1, user, group); } } diff --git a/src/libstore/store-state.hh b/src/libstore/store-state.hh index eba0720d3..7ad6cf128 100644 --- a/src/libstore/store-state.hh +++ b/src/libstore/store-state.hh @@ -42,10 +42,14 @@ namespace nix { unsigned int getNewRevisionNumber(Database & nixDB, const Transaction & txn, TableId table, const Path & statePath); /* TODO */ - Path mergeToDBKey(const Path & statePath, const unsigned int intvalue); + Path mergeToDBKey(const string & s1, const string & s2); + Path mergeToDBRevKey(const Path & statePath, const unsigned int intvalue); /* TODO */ - void splitDBKey(const Path & revisionedStatePath, Path & statePath, unsigned int & intvalue); + void splitDBKey(const string & s, string & s1, string & s2); + void splitDBRevKey(const Path & revisionedStatePath, Path & statePath, unsigned int & intvalue); + + /* TODO */ bool revisionToTimeStamp(Database & nixDB, const Transaction & txn, TableId revisions_table, const Path & statePath, const int revision, unsigned int & timestamp); @@ -70,11 +74,28 @@ namespace nix { bool queryAvailableStateRevisions(Database & nixDB, const Transaction & txn, TableId revisions_table, TableId revisions_comments, const Path & statePath, RevisionInfos & revisions); + /**/ void invalidateAllStateReferences(Database & nixDB, const Transaction & txn, TableId references_table, const Path & statePath); + /**/ void removeAllStatePathRevisions(Database & nixDB, const Transaction & txn, TableId revisions_table, TableId revisions_comments, TableId snapshots_table, TableId statecounters, const Path & statePath); + /**/ + void setVersionedStateEntries(Database & nixDB, const Transaction & txn, TableId versionItems, TableId revisions_table, + const Path & statePath, const StateInfos & infos, const unsigned int revision = 0, const unsigned int timestamp = 0); + + /**/ + bool getVersionedStateEntries(Database & nixDB, const Transaction & txn, TableId versionItems, TableId revisions_table, + const Path & statePath, StateInfos & infos, const unsigned int revision = 0, const unsigned int timestamp = 0); + + /**/ + void setStateUserGroup(Database & nixDB, const Transaction & txn, TableId stateRights, const Path & statePath, const string & user, const string & group, int chmod); + + /**/ + void getStateUserGroup(Database & nixDB, const Transaction & txn, TableId stateRights, const Path & statePath, string & user, string & group, int & chmod); + + } diff --git a/src/libutil/types.hh b/src/libutil/types.hh index af5f9828f..f32ae2add 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -76,6 +76,15 @@ typedef map RevisionClosure; typedef map RevisionClosureTS; //Paht with a timestamp about when the revision was made. typedef map StateReferences; + +struct StateInfo +{ + string path; + string type; + unsigned int interval; +}; +typedef list StateInfos; + typedef enum { lvlError, diff --git a/src/nix-state/nix-state.cc b/src/nix-state/nix-state.cc index 8c6f91660..57e4c9308 100644 --- a/src/nix-state/nix-state.cc +++ b/src/nix-state/nix-state.cc @@ -621,9 +621,35 @@ void run(Strings args) printMsg(lvlError, format("REF `%1%'") % *j); } } + store = openStore(); + Path statePath = "/mySTATEPATH"; + unsigned int revision = 0; + unsigned int timestamp = 1234; + StateInfos infos; + StateInfo s1; + s1.path = "a"; s1.type = "t1"; s1.interval = 0; + StateInfo s2; + s2.path = "b"; s2.type = "t2"; s2.interval = 1000; + infos.push_back(s1); + infos.push_back(s2); + setVersionedStateEntries(nixDB, txn, dbVersionItems, dbStateRevisions, + statePath, infos, revision, timestamp); + + StateInfos getInfos; + bool b = getVersionedStateEntries(nixDB, txn, dbVersionItems, dbStateRevisions, + statePath, getInfos, revision, timestamp); + + printMsg(lvlError, format("B: %1%") % b); + + for (StateInfos::const_iterator i = getInfos.begin(); i != getInfos.end(); ++i) { + StateInfo si = *i; + printMsg(lvlError, format("SI: %1% %2% %3%") % si.path % si.type % si.interval); + } + return; + */ /* test */