mirror of
https://github.com/NixOS/nix.git
synced 2025-11-26 04:00:59 +01:00
This commit is contained in:
parent
856251df03
commit
83ec65edf5
10 changed files with 262 additions and 179 deletions
|
|
@ -1794,7 +1794,7 @@ void DerivationGoal::computeClosure()
|
||||||
contentHashes[i->second.path],
|
contentHashes[i->second.path],
|
||||||
allReferences[i->second.path], //set of component-references
|
allReferences[i->second.path], //set of component-references
|
||||||
allStateReferences[i->second.path], //set of state-references
|
allStateReferences[i->second.path], //set of state-references
|
||||||
drvPath, 0);
|
drvPath, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Register the state path valid
|
//Register the state path valid
|
||||||
|
|
@ -1807,14 +1807,14 @@ void DerivationGoal::computeClosure()
|
||||||
Hash(), //emtpy hash
|
Hash(), //emtpy hash
|
||||||
state_references,
|
state_references,
|
||||||
state_stateReferences,
|
state_stateReferences,
|
||||||
drvPath, 0);
|
drvPath, -1);
|
||||||
|
|
||||||
//Commit state (we only include our own state in the rivisionMapping (but other build component states might have been changed !!!! TODO)
|
//Commit state (we only include our own state in the rivisionMapping (but other build component states might have been changed !!!! TODO)
|
||||||
RevisionClosure rivisionMapping;
|
RevisionClosure rivisionMapping;
|
||||||
rivisionMapping[statePath] = commitStatePathTxn(txn, statePath);
|
rivisionMapping[statePath] = commitStatePathTxn(txn, statePath);
|
||||||
|
|
||||||
//Save the new revision
|
//Save the new revision
|
||||||
setStateRevisionsTxn(txn, statePath, rivisionMapping);
|
setStateRevisionsTxn(txn, rivisionMapping);
|
||||||
|
|
||||||
//Shared state
|
//Shared state
|
||||||
Path sharedState = drv.stateOutputs.find("state")->second.sharedState;
|
Path sharedState = drv.stateOutputs.find("state")->second.sharedState;
|
||||||
|
|
|
||||||
|
|
@ -451,13 +451,13 @@ void Database::enumTable(const Transaction & txn, TableId table,
|
||||||
|
|
||||||
Path Database::makeStatePathRevision(const Path & statePath, const int revision)
|
Path Database::makeStatePathRevision(const Path & statePath, const int revision)
|
||||||
{
|
{
|
||||||
string prefix = "-REV-";
|
string prefix = "-KEY-";
|
||||||
return statePath + prefix + int2String(revision);
|
return statePath + prefix + int2String(revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::splitStatePathRevision(const Path & revisionedStatePath, Path & statePath, int & revision)
|
void Database::splitStatePathRevision(const Path & revisionedStatePath, Path & statePath, int & revision)
|
||||||
{
|
{
|
||||||
string prefix = "-REV-";
|
string prefix = "-KEY-";
|
||||||
|
|
||||||
int pos = revisionedStatePath.find_last_of(prefix);
|
int pos = revisionedStatePath.find_last_of(prefix);
|
||||||
statePath = revisionedStatePath.substr(0, pos - prefix.length() + 1);
|
statePath = revisionedStatePath.substr(0, pos - prefix.length() + 1);
|
||||||
|
|
@ -515,95 +515,128 @@ bool Database::lookupHighestRevivison(const Strings & keys, const Path & statePa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(highestRev == -1) //no records found (TODO throw error?)
|
if(highestRev == -1) //no records found
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
key = makeStatePathRevision(statePath, highestRev); //final key that matches revision + statePath
|
key = makeStatePathRevision(statePath, highestRev); //final key that matches revision + statePath
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
bool Database::revisionToTimeStamp(const Transaction & txn, TableId revisions_table, const Path & statePath, const int revision, int & timestamp)
|
||||||
|
{
|
||||||
|
string key = makeStatePathRevision(statePath, revision);
|
||||||
|
Strings references;
|
||||||
|
bool notempty = queryStrings(txn, revisions_table, key, references);
|
||||||
|
|
||||||
|
if(notempty){
|
||||||
|
Path empty;
|
||||||
|
splitStatePathRevision(*(references.begin()), empty, timestamp); //extract the timestamp
|
||||||
|
//printMsg(lvlError, format("PRINT '%1%'") % timestamp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Database::setStateReferences(const Transaction & txn, TableId table,
|
void Database::setStateReferences(const Transaction & txn, TableId references_table, TableId revisions_table,
|
||||||
const Path & statePath, const Strings & references, int revision)
|
const Path & statePath, const Strings & references, int revision)
|
||||||
{
|
{
|
||||||
//printMsg(lvlError, format("setStateReferences/Referrers %1%") % table);
|
//printMsg(lvlError, format("setStateReferences/Referrers %1%") % table);
|
||||||
|
|
||||||
|
int timestamp;
|
||||||
if(revision == -1)
|
if(revision == -1)
|
||||||
revision = getNewRevisionNumber(txn, table, statePath);
|
timestamp = getTimeStamp();
|
||||||
|
else{
|
||||||
|
bool found = revisionToTimeStamp(txn, revisions_table, statePath, revision, timestamp);
|
||||||
|
if(!found)
|
||||||
|
throw Error(format("Revision '%1%' cannot be matched to a timestamp...") % revision);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
//for (Strings::const_iterator i = references.begin(); i != references.end(); ++i)
|
||||||
for (Strings::const_iterator i = references.begin(); i != references.end(); ++i)
|
// printMsg(lvlError, format("setStateReferences::: '%1%'") % *i);
|
||||||
printMsg(lvlError, format("setStateReferences::: '%1%'") % *i);
|
|
||||||
*/
|
|
||||||
|
|
||||||
//Warning if it already exists
|
//Warning if it already exists
|
||||||
Strings empty;
|
Strings empty;
|
||||||
if( queryStateReferences(txn, table, statePath, empty, revision) )
|
if( queryStateReferences(txn, references_table, revisions_table, statePath, empty, -1, timestamp) )
|
||||||
printMsg(lvlError, format("Warning: The revision '%1%' already exists for set-references/referrers of path '%2%' with db '%3%'") % revision % statePath % table);
|
printMsg(lvlError, format("Warning: The timestamp '%1%' already exists for set-references/referrers of path '%2%' with db '%3%'") % timestamp % statePath % references_table);
|
||||||
|
|
||||||
//Create the key
|
//Create the key
|
||||||
string key = makeStatePathRevision(statePath, revision);
|
string key = makeStatePathRevision(statePath, timestamp);
|
||||||
|
|
||||||
//Insert
|
//Insert
|
||||||
setStrings(txn, table, key, references);
|
setStrings(txn, references_table, key, references);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::queryStateReferences(const Transaction & txn, TableId table,
|
bool Database::queryStateReferences(const Transaction & txn, TableId references_table, TableId revisions_table,
|
||||||
const Path & statePath, Strings & references, int revision)
|
const Path & statePath, Strings & references, int revision, int timestamp)
|
||||||
{
|
{
|
||||||
//printMsg(lvlError, format("queryStateReferences/Referrers %1%") % table);
|
//printMsg(lvlError, format("queryStateReferences/Referrers '%1%' with revision '%2%'") % references_table % revision);
|
||||||
|
|
||||||
|
//Convert revision to timestamp number useing the revisions_table
|
||||||
|
if(timestamp == -1 && revision != -1){
|
||||||
|
bool found = revisionToTimeStamp(txn, revisions_table, statePath, revision, timestamp);
|
||||||
|
if(!found) //we are asked for references of some revision, but there are no references registered yet, so we return false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Strings keys;
|
Strings keys;
|
||||||
enumTable(txn, table, keys); //get all revisions
|
enumTable(txn, references_table, keys);
|
||||||
|
|
||||||
//Check if this revision exists key in the table, if it doesnt well find the highest key lower than it
|
//Mabye we need the latest timestamp?
|
||||||
string key = makeStatePathRevision(statePath, revision);
|
string key = "";
|
||||||
bool found = false;
|
if(timestamp == -1){
|
||||||
for (Strings::const_iterator i = keys.begin(); i != keys.end(); ++i) {
|
|
||||||
if(key == *i)
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
key = "";
|
|
||||||
if(revision == -1){
|
|
||||||
bool foundsomething = lookupHighestRevivison(keys, statePath, key);
|
bool foundsomething = lookupHighestRevivison(keys, statePath, key);
|
||||||
if(!foundsomething)
|
if(!foundsomething)
|
||||||
return false;
|
return false;
|
||||||
|
else
|
||||||
|
return queryStrings(txn, references_table, key, references);
|
||||||
}
|
}
|
||||||
else if(!found){
|
|
||||||
|
//If a specific key is given: check if this timestamp exists key in the table
|
||||||
|
key = makeStatePathRevision(statePath, timestamp);
|
||||||
|
bool found = false;
|
||||||
|
for (Strings::const_iterator i = keys.begin(); i != keys.end(); ++i) {
|
||||||
|
if(key == *i){
|
||||||
|
found = true;
|
||||||
|
key = makeStatePathRevision(statePath, timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//If it doesn't exist in the table then find the highest key lower than it
|
||||||
|
if(!found){
|
||||||
bool foundsomething = lookupHighestRevivison(keys, statePath, key, -1);
|
bool foundsomething = lookupHighestRevivison(keys, statePath, key, -1);
|
||||||
if(!foundsomething)
|
if(!foundsomething)
|
||||||
return false;
|
return false;
|
||||||
//printMsg(lvlError, format("Warning: References for revision '%1%' not was not found, so taking the highest rev-key possible for statePath '%2%'") % revision % statePath);
|
//printMsg(lvlError, format("Warning: References for timestamp '%1%' not was not found, so taking the highest rev-key possible for statePath '%2%'") % timestamp % statePath);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
key = makeStatePathRevision(statePath, revision);
|
|
||||||
|
|
||||||
|
return queryStrings(txn, references_table, key, references); //now that we have the key, we can query the references
|
||||||
return queryStrings(txn, table, key, references); //now that we have the key, we can query the references
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::queryStateReferrers(const Transaction & txn, TableId table,
|
void Database::setStateReferrers(const Transaction & txn, TableId referrers_table, TableId revisions_table,
|
||||||
const Path & statePath, Strings & referrers, int revision)
|
const Path & statePath, const Strings & referrers, int revision)
|
||||||
|
{
|
||||||
|
//Exactly the same as the setStateReferences
|
||||||
|
setStateReferences(txn, referrers_table, revisions_table, statePath, referrers, revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Database::queryStateReferrers(const Transaction & txn, TableId referrers_table, TableId revisions_table,
|
||||||
|
const Path & statePath, Strings & referrers, int revision, int timestamp)
|
||||||
{
|
{
|
||||||
//Exactly the same as queryStateReferences
|
//Exactly the same as queryStateReferences
|
||||||
return queryStateReferences(txn, table, statePath, referrers, revision);
|
return queryStateReferences(txn, referrers_table, revisions_table, statePath, referrers, revision, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
void Database::setStateRevisions(const Transaction & txn, TableId revisions_table, TableId snapshots_table,
|
void Database::setStateRevisions(const Transaction & txn, TableId revisions_table, TableId snapshots_table,
|
||||||
const Path & root_statePath, const RevisionClosure & revisions)
|
const RevisionClosure & revisions)
|
||||||
{
|
{
|
||||||
int ts = getTimeStamp();
|
int ts = getTimeStamp();
|
||||||
|
|
||||||
//Insert all ss_epochs into table ...... with the current ts.
|
//Insert all ss_epochs into snapshots_table with the current ts.
|
||||||
for (RevisionClosure::const_iterator i = revisions.begin(); i != revisions.end(); ++i){
|
for (RevisionClosure::const_iterator i = revisions.begin(); i != revisions.end(); ++i){
|
||||||
string key = makeStatePathRevision((*i).first, ts);
|
string key = makeStatePathRevision((*i).first, ts);
|
||||||
Strings data;
|
Strings data;
|
||||||
//the map<> takes care of the sorting on
|
//the map<> takes care of the sorting on the Path
|
||||||
for (Snapshots::const_iterator j = (*i).second.begin(); j != (*i).second.end(); ++j)
|
for (Snapshots::const_iterator j = (*i).second.begin(); j != (*i).second.end(); ++j)
|
||||||
data.push_back(int2String((*j).second));
|
data.push_back(int2String((*j).second));
|
||||||
setStrings(txn, snapshots_table, key, data);
|
setStrings(txn, snapshots_table, key, data);
|
||||||
|
|
@ -612,24 +645,25 @@ void Database::setStateRevisions(const Transaction & txn, TableId revisions_tabl
|
||||||
//Insert for each statePath a new revision record linked to the ss_epochs
|
//Insert for each statePath a new revision record linked to the ss_epochs
|
||||||
for (RevisionClosure::const_iterator i = revisions.begin(); i != revisions.end(); ++i){
|
for (RevisionClosure::const_iterator i = revisions.begin(); i != revisions.end(); ++i){
|
||||||
Path statePath = (*i).first;
|
Path statePath = (*i).first;
|
||||||
|
|
||||||
int revision = getNewRevisionNumber(txn, revisions_table, statePath); //get a new revision number
|
int revision = getNewRevisionNumber(txn, revisions_table, statePath); //get a new revision number
|
||||||
string key = makeStatePathRevision(statePath, revision);
|
string key = makeStatePathRevision(statePath, revision);
|
||||||
|
|
||||||
//get all its requisites
|
//get all its requisites
|
||||||
PathSet statePaths;
|
PathSet statePath_references;
|
||||||
storePathRequisitesTxn(txn, statePath, false, statePaths, false, true, -1);
|
storePathRequisitesTxn(txn, statePath, false, statePath_references, false, true, -1);
|
||||||
statePaths.insert(statePath);
|
statePath_references.insert(statePath);
|
||||||
|
|
||||||
//save in db
|
//save in db
|
||||||
Strings data;
|
Strings data;
|
||||||
for (PathSet::const_iterator j = statePaths.begin(); j != statePaths.end(); ++j)
|
for (PathSet::const_iterator j = statePath_references.begin(); j != statePath_references.end(); ++j)
|
||||||
data.push_back(makeStatePathRevision(*j, ts));
|
data.push_back(makeStatePathRevision(*j, ts));
|
||||||
setStrings(txn, revisions_table, key, data);
|
setStrings(txn, revisions_table, key, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::queryStateRevisions(const Transaction & txn, TableId revisions_table, TableId snapshots_table,
|
bool Database::queryStateRevisions(const Transaction & txn, TableId revisions_table, TableId snapshots_table,
|
||||||
const Path & statePath, RevisionClosure & revisions, int root_revision)
|
const Path & statePath, RevisionClosure & revisions, RevisionClosureTS & timestamps, int root_revision)
|
||||||
{
|
{
|
||||||
string key;
|
string key;
|
||||||
|
|
||||||
|
|
@ -643,15 +677,15 @@ bool Database::queryStateRevisions(const Transaction & txn, TableId revisions_ta
|
||||||
else
|
else
|
||||||
key = makeStatePathRevision(statePath, root_revision);
|
key = makeStatePathRevision(statePath, root_revision);
|
||||||
|
|
||||||
//Get references pointingg to snapshots_table from revisions_table with root_revision
|
//Get references pointing to snapshots_table from revisions_table with root_revision
|
||||||
Strings references;
|
Strings statePaths;
|
||||||
bool notempty = queryStrings(txn, revisions_table, key, references);
|
bool notempty = queryStrings(txn, revisions_table, key, statePaths);
|
||||||
|
|
||||||
if(!notempty)
|
if(!notempty)
|
||||||
throw Error(format("Root revision '%1%' not found of statePath '%2%'") % int2String(root_revision) % statePath);
|
throw Error(format("Root revision '%1%' not found of statePath '%2%'") % int2String(root_revision) % statePath);
|
||||||
|
|
||||||
//
|
//For each statePath add the revisions
|
||||||
for (Strings::iterator i = references.begin(); i != references.end(); ++i){
|
for (Strings::iterator i = statePaths.begin(); i != statePaths.end(); ++i){
|
||||||
|
|
||||||
Path getStatePath;
|
Path getStatePath;
|
||||||
int getTimestamp;
|
int getTimestamp;
|
||||||
|
|
@ -687,6 +721,7 @@ bool Database::queryStateRevisions(const Transaction & txn, TableId revisions_ta
|
||||||
}
|
}
|
||||||
|
|
||||||
revisions[getStatePath] = snapshots;
|
revisions[getStatePath] = snapshots;
|
||||||
|
timestamps[getStatePath] = getTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,9 @@ private:
|
||||||
/* TODO */
|
/* TODO */
|
||||||
int getNewRevisionNumber(const Transaction & txn, TableId table, const Path & statePath);
|
int getNewRevisionNumber(const Transaction & txn, TableId table, const Path & statePath);
|
||||||
|
|
||||||
|
/* */
|
||||||
|
bool revisionToTimeStamp(const Transaction & txn, TableId revisions_table, const Path & statePath, const int revision, int & timestamp);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Database();
|
Database();
|
||||||
~Database();
|
~Database();
|
||||||
|
|
@ -103,24 +106,28 @@ public:
|
||||||
void splitStatePathRevision(const Path & revisionedStatePath, Path & statePath, int & revision);
|
void splitStatePathRevision(const Path & revisionedStatePath, Path & statePath, int & revision);
|
||||||
|
|
||||||
/* Set the stateReferences for a specific revision (and older until the next higher revision number in the table) */
|
/* Set the stateReferences for a specific revision (and older until the next higher revision number in the table) */
|
||||||
void setStateReferences(const Transaction & txn, TableId table,
|
void setStateReferences(const Transaction & txn, TableId references_table, TableId revisions_table,
|
||||||
const Path & statePath, const Strings & references, int revision = -1);
|
const Path & statePath, const Strings & references, int revision = -1);
|
||||||
|
|
||||||
/* Returns the references for a specific revision (and older until the next higher revision number in the table) */
|
/* Returns the references for a specific revision (and older until the next higher revision number in the table) */
|
||||||
bool queryStateReferences(const Transaction & txn, TableId table,
|
bool queryStateReferences(const Transaction & txn, TableId references_table, TableId revisions_table,
|
||||||
const Path & statePath, Strings & references, int revision = -1);
|
const Path & statePath, Strings & references, int revision = -1, int timestamp = -1);
|
||||||
|
|
||||||
/* Returns the referrers for a specific revision (and older until the next higher revision number in the table) */
|
/* Set the stateReferences for a specific revision (and older until the next higher revision number in the table) */
|
||||||
bool queryStateReferrers(const Transaction & txn, TableId table,
|
void setStateReferrers(const Transaction & txn, TableId referrers_table, TableId revisions_table,
|
||||||
const Path & statePath, Strings & referrers, int revision = -1);
|
const Path & statePath, const Strings & referrers, int revision = -1);
|
||||||
|
|
||||||
|
/* Returns the referrers for a specific revision (and older until the next higher revision number in the table) */
|
||||||
|
bool queryStateReferrers(const Transaction & txn, TableId referrers_table, TableId revisions_table,
|
||||||
|
const Path & statePath, Strings & referrers, int revision = -1, int timestamp = -1);
|
||||||
|
|
||||||
/* Set the revision number of the statePath and the revision numbers of all state paths in the references closure */
|
/* Set the revision number of the statePath and the revision numbers of all state paths in the references closure */
|
||||||
void setStateRevisions(const Transaction & txn, TableId revisions_table, TableId snapshots_table,
|
void setStateRevisions(const Transaction & txn, TableId revisions_table, TableId snapshots_table,
|
||||||
const Path & statePath, const RevisionClosure & revisions);
|
const RevisionClosure & revisions);
|
||||||
|
|
||||||
/* Returns all the revision numbers of the state references closure of the given state path */
|
/* Returns all the revision numbers of the state references closure of the given state path */
|
||||||
bool queryStateRevisions(const Transaction & txn, TableId revisions_table, TableId snapshots_table,
|
bool queryStateRevisions(const Transaction & txn, TableId revisions_table, TableId snapshots_table,
|
||||||
const Path & statePath, RevisionClosure & revisions, int root_revision = -1);
|
const Path & statePath, RevisionClosure & revisions, RevisionClosureTS & timestamps, int root_revision = -1);
|
||||||
|
|
||||||
/* Returns all available revision numbers of the given state path */
|
/* Returns all available revision numbers of the given state path */
|
||||||
bool queryAvailableStateRevisions(const Transaction & txn, TableId revisions_table,
|
bool queryAvailableStateRevisions(const Transaction & txn, TableId revisions_table,
|
||||||
|
|
|
||||||
|
|
@ -434,53 +434,84 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath,
|
||||||
printMsg(lvlError, format("'%2%' has stateReferences: %1%") % *i % store_or_statePath);
|
printMsg(lvlError, format("'%2%' has stateReferences: %1%") % *i % store_or_statePath);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static TableId dbXComponentReferrers;
|
|
||||||
static TableId dbXStateReferrers;
|
|
||||||
PathSet oldReferences2;
|
|
||||||
PathSet oldStateReferences2;
|
|
||||||
Paths oldReferences_X_c;
|
|
||||||
Paths oldReferences_X_s;
|
|
||||||
|
|
||||||
if(isRealisablePath(txn, store_or_statePath))
|
if(isRealisablePath(txn, store_or_statePath))
|
||||||
{
|
{
|
||||||
|
//Just overwrite the old references, since there is oly 1 revision of a storePath
|
||||||
|
|
||||||
Paths oldReferences_c_c;
|
Paths oldReferences_c_c;
|
||||||
Paths oldReferences_c_s;
|
Paths oldReferences_c_s;
|
||||||
|
|
||||||
nixDB.queryStrings(txn, dbComponentComponentReferences, store_or_statePath, oldReferences_c_c);
|
nixDB.queryStrings(txn, dbComponentComponentReferences, store_or_statePath, oldReferences_c_c);
|
||||||
nixDB.queryStrings(txn, dbComponentStateReferences, store_or_statePath, oldReferences_c_s);
|
nixDB.queryStrings(txn, dbComponentStateReferences, store_or_statePath, oldReferences_c_s);
|
||||||
|
|
||||||
oldReferences2 = PathSet(oldReferences_c_c.begin(), oldReferences_c_c.end());
|
PathSet oldReferences = PathSet(oldReferences_c_c.begin(), oldReferences_c_c.end());
|
||||||
oldStateReferences2 = PathSet(oldReferences_c_s.begin(), oldReferences_c_s.end());
|
PathSet oldStateReferences = PathSet(oldReferences_c_s.begin(), oldReferences_c_s.end());
|
||||||
if (oldReferences2 == references && oldStateReferences2 == stateReferences) return;
|
if (oldReferences == references && oldStateReferences == stateReferences) return;
|
||||||
|
|
||||||
nixDB.setStrings(txn, dbComponentComponentReferences, store_or_statePath, Paths(references.begin(), references.end()));
|
nixDB.setStrings(txn, dbComponentComponentReferences, store_or_statePath, Paths(references.begin(), references.end()));
|
||||||
nixDB.setStrings(txn, dbComponentStateReferences, store_or_statePath, Paths(stateReferences.begin(), stateReferences.end()));
|
nixDB.setStrings(txn, dbComponentStateReferences, store_or_statePath, Paths(stateReferences.begin(), stateReferences.end()));
|
||||||
|
|
||||||
//set vars for the referrers update code below
|
//Handle referrers ......
|
||||||
dbXComponentReferrers = dbComponentComponentReferrers;
|
|
||||||
dbXStateReferrers = dbComponentStateReferrers;
|
//dbComponentComponentReferrers
|
||||||
oldReferences_X_c = oldReferences_c_c;
|
//dbComponentStateReferrers
|
||||||
oldReferences_X_s = oldReferences_c_s;
|
/*
|
||||||
|
references c -> c
|
||||||
|
oldReferences
|
||||||
|
stateReferences c -> s
|
||||||
|
oldStateReferences
|
||||||
|
*/
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(isRealisableStatePath(txn, store_or_statePath))
|
else if(isRealisableStatePath(txn, store_or_statePath))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//Write references and referrers to a special revision (since there are multiple revisions of a statePath)
|
||||||
|
|
||||||
|
//query the references of revision (-1 is query the latest references)
|
||||||
Paths oldStateReferences_s_c;
|
Paths oldStateReferences_s_c;
|
||||||
Paths oldStateReferences_s_s;
|
Paths oldStateReferences_s_s;
|
||||||
|
nixDB.queryStateReferences(txn, dbStateComponentReferences, dbStateRevisions, store_or_statePath, oldStateReferences_s_c, revision);
|
||||||
|
nixDB.queryStateReferences(txn, dbStateStateReferences, dbStateRevisions, store_or_statePath, oldStateReferences_s_s, revision);
|
||||||
|
|
||||||
nixDB.queryStateReferences(txn, dbStateComponentReferences, store_or_statePath, oldStateReferences_s_c, revision);
|
PathSet oldReferences = PathSet(oldStateReferences_s_c.begin(), oldStateReferences_s_c.end());
|
||||||
nixDB.queryStateReferences(txn, dbStateStateReferences, store_or_statePath, oldStateReferences_s_s, revision);
|
PathSet oldStateReferences = PathSet(oldStateReferences_s_s.begin(), oldStateReferences_s_s.end());
|
||||||
|
//if (oldReferences == references && oldStateReferences == stateReferences) return; //TODO Turn on ????????????
|
||||||
|
|
||||||
oldReferences2 = PathSet(oldStateReferences_s_c.begin(), oldStateReferences_s_c.end());
|
//set the references of revision (-1 insert as a new timestamp)
|
||||||
oldStateReferences2 = PathSet(oldStateReferences_s_s.begin(), oldStateReferences_s_s.end());
|
nixDB.setStateReferences(txn, dbStateComponentReferences, dbStateRevisions, store_or_statePath, Paths(references.begin(), references.end()), revision);
|
||||||
|
nixDB.setStateReferences(txn, dbStateStateReferences, dbStateRevisions, store_or_statePath, Paths(stateReferences.begin(), stateReferences.end()), revision);
|
||||||
|
|
||||||
nixDB.setStateReferences(txn, dbStateComponentReferences, store_or_statePath, Paths(references.begin(), references.end()), revision);
|
|
||||||
nixDB.setStateReferences(txn, dbStateStateReferences, store_or_statePath, Paths(stateReferences.begin(), stateReferences.end()), revision);
|
//REFERRERS
|
||||||
|
|
||||||
//set vars for the referrers update code below
|
//for all references old and new, state and component
|
||||||
dbXComponentReferrers = dbStateComponentReferrers;
|
PathSet all = pathSets_union(pathSets_union(references, oldReferences), pathSets_union(oldStateReferences, stateReferences)); //TODO SPLIT in state and non state
|
||||||
dbXStateReferrers = dbStateStateReferrers;
|
for (PathSet::const_iterator i = all.begin(); i != all.end(); ++i){
|
||||||
oldReferences_X_c = oldStateReferences_s_c;
|
|
||||||
oldReferences_X_s = oldStateReferences_s_s;
|
Path referredPath = *i; //Path referred to by the statePath
|
||||||
|
|
||||||
|
//query the refererrers of revision (-1 is query the latest refererrers)
|
||||||
|
Paths referrers_s_c;
|
||||||
|
Paths referrers_s_s;
|
||||||
|
nixDB.queryStateReferrers(txn, dbStateComponentReferrers, dbStateRevisions, referredPath, referrers_s_c, revision); //may contain other referred by paths
|
||||||
|
nixDB.queryStateReferrers(txn, dbStateStateReferrers, dbStateRevisions, referredPath, referrers_s_s, revision);
|
||||||
|
PathSet oldReferrers = PathSet(referrers_s_c.begin(), referrers_s_c.end());
|
||||||
|
PathSet oldStateReferrers = PathSet(referrers_s_s.begin(), referrers_s_s.end());
|
||||||
|
|
||||||
|
|
||||||
|
//Add store_or_statePath in if nessacary (if in references)
|
||||||
|
//TODO
|
||||||
|
|
||||||
|
//Remove store_or_statePath if nessacary (if not in references)
|
||||||
|
//TODO
|
||||||
|
|
||||||
|
//set the new referrers of revision (-1 insert as a new timestamp)
|
||||||
|
//nixDB.setStateReferrers(txn, dbStateComponentReferences, dbStateRevisions, referredPath, ........, revision);
|
||||||
|
//nixDB.setStateReferrers(txn, dbStateStateReferences, dbStateRevisions, referredPath, ......, revision);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw Error(format("Path '%1%' is not a valid component or state path") % store_or_statePath);
|
throw Error(format("Path '%1%' is not a valid component or state path") % store_or_statePath);
|
||||||
|
|
@ -488,32 +519,14 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath,
|
||||||
//store_or_statePath must be postfixed in case it is a statePath
|
//store_or_statePath must be postfixed in case it is a statePath
|
||||||
Path store_or_statePath2 = store_or_statePath;
|
Path store_or_statePath2 = store_or_statePath;
|
||||||
if(isRealisableStatePath(txn, store_or_statePath))
|
if(isRealisableStatePath(txn, store_or_statePath))
|
||||||
store_or_statePath2 = nixDB.makeStatePathRevision(store_or_statePath, revision);
|
store_or_statePath2 = nixDB.makeStatePathRevision(store_or_statePath, revision); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! THIS OK ???
|
||||||
|
//NO ???? SINCE THE KEYS SHOULD BE TIMESTAMPED ??
|
||||||
|
//WE NEEED TO inlcude the revision !!
|
||||||
|
|
||||||
|
|
||||||
//The follow 4 for-loops haved been made generic with variables, they work in the case of statePaths and storePaths
|
|
||||||
|
|
||||||
/* Update the referrers mappings of all new referenced paths. */
|
|
||||||
for (PathSet::const_iterator i = references.begin(); i != references.end(); ++i)
|
|
||||||
if (oldReferences2.find(*i) == oldReferences2.end())
|
|
||||||
nixDB.setString(txn, dbXComponentReferrers, addPrefix(*i, store_or_statePath2), "");
|
|
||||||
|
|
||||||
/* Remove referrer mappings from paths that are no longer references. */
|
|
||||||
for (Paths::iterator i = oldReferences_X_c.begin(); i != oldReferences_X_c.end(); ++i)
|
|
||||||
if (references.find(*i) == references.end())
|
|
||||||
nixDB.delPair(txn, dbXComponentReferrers, addPrefix(*i, store_or_statePath2));
|
|
||||||
|
|
||||||
/* Update the state referrers mappings of all new referenced paths. */
|
|
||||||
for (PathSet::const_iterator i = stateReferences.begin(); i != stateReferences.end(); ++i)
|
|
||||||
if (oldStateReferences2.find(*i) == oldStateReferences2.end())
|
|
||||||
nixDB.setString(txn, dbXStateReferrers, addPrefix(*i, store_or_statePath2), "");
|
|
||||||
|
|
||||||
/* Remove referrer mappings from paths that are no longer state references. */
|
|
||||||
for (Paths::iterator i = oldReferences_X_s.begin(); i != oldReferences_X_s.end(); ++i)
|
|
||||||
if (stateReferences.find(*i) == stateReferences.end())
|
|
||||||
nixDB.delPair(txn, dbXStateReferrers, addPrefix(*i, store_or_statePath2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void queryReferencesTxn(const Transaction & txn, const Path & store_or_statePath, PathSet & references, const int revision)
|
void queryReferencesTxn(const Transaction & txn, const Path & store_or_statePath, PathSet & references, const int revision, int timestamp)
|
||||||
{
|
{
|
||||||
Paths references2;
|
Paths references2;
|
||||||
|
|
||||||
|
|
@ -521,7 +534,7 @@ void queryReferencesTxn(const Transaction & txn, const Path & store_or_statePath
|
||||||
nixDB.queryStrings(txn, dbComponentComponentReferences, store_or_statePath, references2);
|
nixDB.queryStrings(txn, dbComponentComponentReferences, store_or_statePath, references2);
|
||||||
else if(isRealisableStatePath(txn, store_or_statePath)){
|
else if(isRealisableStatePath(txn, store_or_statePath)){
|
||||||
Path statePath_ns = toNonSharedPathTxn(txn, store_or_statePath); //Lookup its where it points to if its shared
|
Path statePath_ns = toNonSharedPathTxn(txn, store_or_statePath); //Lookup its where it points to if its shared
|
||||||
nixDB.queryStateReferences(txn, dbStateComponentReferences, statePath_ns, references2, revision);
|
nixDB.queryStateReferences(txn, dbStateComponentReferences, dbStateRevisions, statePath_ns, references2, revision, timestamp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw Error(format("Path '%1%' is not a valid component or state path") % store_or_statePath);
|
throw Error(format("Path '%1%' is not a valid component or state path") % store_or_statePath);
|
||||||
|
|
@ -534,7 +547,8 @@ void LocalStore::queryReferences(const Path & storePath, PathSet & references, c
|
||||||
nix::queryReferencesTxn(noTxn, storePath, references, revision);
|
nix::queryReferencesTxn(noTxn, storePath, references, revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
void queryStateReferencesTxn(const Transaction & txn, const Path & store_or_statePath, PathSet & stateReferences, const int revision)
|
/* TODO this is just a copy of queryReferencesTxn with small differences */
|
||||||
|
void queryStateReferencesTxn(const Transaction & txn, const Path & store_or_statePath, PathSet & stateReferences, const int revision, int timestamp)
|
||||||
{
|
{
|
||||||
Paths stateReferences2;
|
Paths stateReferences2;
|
||||||
|
|
||||||
|
|
@ -542,7 +556,7 @@ void queryStateReferencesTxn(const Transaction & txn, const Path & store_or_stat
|
||||||
nixDB.queryStrings(txn, dbComponentStateReferences, store_or_statePath, stateReferences2);
|
nixDB.queryStrings(txn, dbComponentStateReferences, store_or_statePath, stateReferences2);
|
||||||
else if(isRealisableStatePath(txn, store_or_statePath)){
|
else if(isRealisableStatePath(txn, store_or_statePath)){
|
||||||
Path statePath_ns = toNonSharedPathTxn(txn, store_or_statePath); //Lookup its where it points to if its shared
|
Path statePath_ns = toNonSharedPathTxn(txn, store_or_statePath); //Lookup its where it points to if its shared
|
||||||
nixDB.queryStateReferences(txn, dbStateStateReferences, statePath_ns, stateReferences2, revision);
|
nixDB.queryStateReferences(txn, dbStateStateReferences, dbStateRevisions, statePath_ns, stateReferences2, revision, timestamp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw Error(format("Path '%1%' is not a valid component or state path") % store_or_statePath);
|
throw Error(format("Path '%1%' is not a valid component or state path") % store_or_statePath);
|
||||||
|
|
@ -582,7 +596,7 @@ static PathSet getXReferrers(const Transaction & txn, const Path & store_or_stat
|
||||||
else if(isValidStatePathTxn(txn, store_or_statePath)){
|
else if(isValidStatePathTxn(txn, store_or_statePath)){
|
||||||
Path statePath_ns = toNonSharedPathTxn(txn, store_or_statePath); //Lookup its where it points to if its shared
|
Path statePath_ns = toNonSharedPathTxn(txn, store_or_statePath); //Lookup its where it points to if its shared
|
||||||
Paths referrers;
|
Paths referrers;
|
||||||
nixDB.queryStateReferrers(txn, table, statePath_ns, referrers, revision);
|
nixDB.queryStateReferrers(txn, table, dbStateRevisions, statePath_ns, referrers, revision);
|
||||||
PathSet p(referrers.begin(), referrers.end());
|
PathSet p(referrers.begin(), referrers.end());
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
@ -1669,24 +1683,24 @@ void queryAllValidPaths(const Transaction & txn, PathSet & allComponentPaths, Pa
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void setStateRevisionsTxn(const Transaction & txn, const Path & statePath, const RevisionClosure & revisions)
|
void setStateRevisionsTxn(const Transaction & txn, const RevisionClosure & revisions)
|
||||||
{
|
{
|
||||||
nixDB.setStateRevisions(txn, dbStateRevisions, dbStateSnapshots, statePath, revisions);
|
nixDB.setStateRevisions(txn, dbStateRevisions, dbStateSnapshots, revisions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalStore::setStateRevisions(const Path & statePath, const RevisionClosure & revisions)
|
void LocalStore::setStateRevisions(const RevisionClosure & revisions)
|
||||||
{
|
{
|
||||||
nix::setStateRevisionsTxn(noTxn, statePath, revisions);
|
nix::setStateRevisionsTxn(noTxn, revisions);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool queryStateRevisionsTxn(const Transaction & txn, const Path & statePath, RevisionClosure & revisions, const int revision)
|
bool queryStateRevisionsTxn(const Transaction & txn, const Path & statePath, RevisionClosure & revisions, RevisionClosureTS & timestamps, const int revision)
|
||||||
{
|
{
|
||||||
return nixDB.queryStateRevisions(txn, dbStateRevisions, dbStateSnapshots, statePath, revisions, revision);
|
return nixDB.queryStateRevisions(txn, dbStateRevisions, dbStateSnapshots, statePath, revisions, timestamps, revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LocalStore::queryStateRevisions(const Path & statePath, RevisionClosure & revisions, const int revision)
|
bool LocalStore::queryStateRevisions(const Path & statePath, RevisionClosure & revisions, RevisionClosureTS & timestamps, const int revision)
|
||||||
{
|
{
|
||||||
return nix::queryStateRevisionsTxn(noTxn, statePath, revisions, revision);
|
return nix::queryStateRevisionsTxn(noTxn, statePath, revisions, timestamps, revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool queryAvailableStateRevisionsTxn(const Transaction & txn, const Path & statePath, RevisionNumbers & revisions)
|
bool queryAvailableStateRevisionsTxn(const Transaction & txn, const Path & statePath, RevisionNumbers & revisions)
|
||||||
|
|
|
||||||
|
|
@ -100,9 +100,9 @@ public:
|
||||||
|
|
||||||
void storePathRequisites(const Path & storeOrstatePath, const bool includeOutputs, PathSet & paths, const bool & withComponents, const bool & withState, const int revision);
|
void storePathRequisites(const Path & storeOrstatePath, const bool includeOutputs, PathSet & paths, const bool & withComponents, const bool & withState, const int revision);
|
||||||
|
|
||||||
void setStateRevisions(const Path & statePath, const RevisionClosure & revisions);
|
void setStateRevisions(const RevisionClosure & revisions);
|
||||||
|
|
||||||
bool queryStateRevisions(const Path & statePath, RevisionClosure & revisions, const int revision);
|
bool queryStateRevisions(const Path & statePath, RevisionClosure & revisions, RevisionClosureTS & timestamps, const int revision);
|
||||||
|
|
||||||
bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions);
|
bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions);
|
||||||
|
|
||||||
|
|
@ -224,16 +224,15 @@ bool isStateDrvTxn(const Transaction & txn, const Derivation & drv);
|
||||||
void queryAllValidPaths(const Transaction & txn, PathSet & allComponentPaths, PathSet & allStatePaths);
|
void queryAllValidPaths(const Transaction & txn, PathSet & allComponentPaths, PathSet & allStatePaths);
|
||||||
bool isValidStatePathTxn(const Transaction & txn, const Path & path);
|
bool isValidStatePathTxn(const Transaction & txn, const Path & path);
|
||||||
|
|
||||||
void queryReferencesTxn(const Transaction & txn, const Path & path, PathSet & references, const int revision);
|
void queryReferencesTxn(const Transaction & txn, const Path & path, PathSet & references, const int revision, int timestamp = -1);
|
||||||
void queryStateReferencesTxn(const Transaction & txn, const Path & storePath, PathSet & stateReferences, const int revision);
|
void queryStateReferencesTxn(const Transaction & txn, const Path & storePath, PathSet & stateReferences, const int revision, int timestamp = -1);
|
||||||
|
|
||||||
void queryReferrersTxn(const Transaction & txn, const Path & storePath, PathSet & referrers, const int revision);
|
void queryReferrersTxn(const Transaction & txn, const Path & storePath, PathSet & referrers, const int revision);
|
||||||
void queryStateReferrersTxn(const Transaction & txn, const Path & storePath, PathSet & stateReferrers, const int revision);
|
void queryStateReferrersTxn(const Transaction & txn, const Path & storePath, PathSet & stateReferrers, const int revision);
|
||||||
|
|
||||||
|
|
||||||
Path queryStatePathDrvTxn(const Transaction & txn, const Path & statePath);
|
Path queryStatePathDrvTxn(const Transaction & txn, const Path & statePath);
|
||||||
void storePathRequisitesTxn(const Transaction & txn, const Path & storeOrstatePath, const bool includeOutputs, PathSet & paths, const bool & withComponents, const bool & withState, const int revision);
|
void storePathRequisitesTxn(const Transaction & txn, const Path & storeOrstatePath, const bool includeOutputs, PathSet & paths, const bool & withComponents, const bool & withState, const int revision);
|
||||||
void setStateRevisionsTxn(const Transaction & txn, const Path & statePath, const RevisionClosure & revisions);
|
void setStateRevisionsTxn(const Transaction & txn, const RevisionClosure & revisions);
|
||||||
|
|
||||||
bool isValidPathTxn(const Transaction & txn, const Path & path);
|
bool isValidPathTxn(const Transaction & txn, const Path & path);
|
||||||
bool isValidStatePathTxn(const Transaction & txn, const Path & path);
|
bool isValidStatePathTxn(const Transaction & txn, const Path & path);
|
||||||
|
|
|
||||||
|
|
@ -469,13 +469,13 @@ void RemoteStore::storePathRequisites(const Path & storeOrstatePath, const bool
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
void RemoteStore::setStateRevisions(const Path & statePath, const RevisionClosure & revisions)
|
void RemoteStore::setStateRevisions(const RevisionClosure & revisions)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
bool RemoteStore::queryStateRevisions(const Path & statePath, RevisionClosure & revisions, const int revision)
|
bool RemoteStore::queryStateRevisions(const Path & statePath, RevisionClosure & revisions, RevisionClosureTS & timestamps, const int revision)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,9 +88,9 @@ public:
|
||||||
|
|
||||||
void storePathRequisites(const Path & storeOrstatePath, const bool includeOutputs, PathSet & paths, const bool & withComponents, const bool & withState, const int revision);
|
void storePathRequisites(const Path & storeOrstatePath, const bool includeOutputs, PathSet & paths, const bool & withComponents, const bool & withState, const int revision);
|
||||||
|
|
||||||
void setStateRevisions(const Path & statePath, const RevisionClosure & revisions);
|
void setStateRevisions(const RevisionClosure & revisions);
|
||||||
|
|
||||||
bool queryStateRevisions(const Path & statePath, RevisionClosure & revisions, const int revision);
|
bool queryStateRevisions(const Path & statePath, RevisionClosure & revisions, RevisionClosureTS & timestamps, const int revision);
|
||||||
|
|
||||||
bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions);
|
bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -220,14 +220,15 @@ public:
|
||||||
virtual void storePathRequisites(const Path & storeOrstatePath, const bool includeOutputs, PathSet & paths, const bool & withComponents, const bool & withState, const int revision) = 0;
|
virtual void storePathRequisites(const Path & storeOrstatePath, const bool includeOutputs, PathSet & paths, const bool & withComponents, const bool & withState, const int revision) = 0;
|
||||||
|
|
||||||
/* TODO */
|
/* TODO */
|
||||||
virtual void setStateRevisions(const Path & statePath, const RevisionClosure & revisions) = 0;
|
virtual void setStateRevisions(const RevisionClosure & revisions) = 0;
|
||||||
|
|
||||||
/* TODO */
|
/* TODO */
|
||||||
virtual bool queryStateRevisions(const Path & statePath, RevisionClosure & revisions, const int revision) = 0;
|
virtual bool queryStateRevisions(const Path & statePath, RevisionClosure & revisions, RevisionClosureTS & timestamps, const int revision) = 0;
|
||||||
|
|
||||||
/* TODO */
|
/* TODO */
|
||||||
virtual bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions) = 0;
|
virtual bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions) = 0;
|
||||||
|
|
||||||
|
/* TODO */
|
||||||
virtual void commitStatePath(const Path & statePath) = 0;
|
virtual void commitStatePath(const Path & statePath) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,8 @@ typedef set<Path> PathSet;
|
||||||
//state types
|
//state types
|
||||||
typedef list<int> RevisionNumbers; //the Strings (list) of StateReferences and this list are connected by position
|
typedef list<int> RevisionNumbers; //the Strings (list) of StateReferences and this list are connected by position
|
||||||
typedef map<Path, unsigned int> Snapshots; //Automatically sorted on Path :)
|
typedef map<Path, unsigned int> Snapshots; //Automatically sorted on Path :)
|
||||||
typedef map<Path, Snapshots > RevisionClosure;
|
typedef map<Path, Snapshots> RevisionClosure;
|
||||||
|
typedef map<Path, int> RevisionClosureTS;
|
||||||
typedef map<int, Strings> StateReferences;
|
typedef map<int, Strings> StateReferences;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -236,10 +236,11 @@ static void revertToRevision(Strings opFlags, Strings opArgs)
|
||||||
bool isStateComponent;
|
bool isStateComponent;
|
||||||
string program_args;
|
string program_args;
|
||||||
Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, binary, derivationPath, isStateComponent, program_args);
|
Derivation drv = getDerivation_andCheckArgs(opFlags, opArgs, componentPath, statePath, binary, derivationPath, isStateComponent, program_args);
|
||||||
DerivationStateOutputDirs stateOutputDirs = drv.stateOutputDirs;
|
|
||||||
|
|
||||||
bool recursive = true; //TODO !!!!!!!!!!!!!!!!!
|
bool recursive = true; //TODO !!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
//TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! add TXN here ???????????
|
||||||
|
|
||||||
PathSet statePaths;
|
PathSet statePaths;
|
||||||
if(recursive)
|
if(recursive)
|
||||||
PathSet statePaths = getAllStateDerivationsRecursively(componentPath, revision_arg); //get dependecies (if neccecary | recusively) of all state components that need to be updated
|
PathSet statePaths = getAllStateDerivationsRecursively(componentPath, revision_arg); //get dependecies (if neccecary | recusively) of all state components that need to be updated
|
||||||
|
|
@ -248,12 +249,21 @@ static void revertToRevision(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
//Get the revisions recursively to also roll them back
|
//Get the revisions recursively to also roll them back
|
||||||
RevisionClosure getRivisions;
|
RevisionClosure getRivisions;
|
||||||
bool b = store->queryStateRevisions(statePath, getRivisions, revision_arg);
|
RevisionClosureTS getTimestamps;
|
||||||
|
bool b = store->queryStateRevisions(statePath, getRivisions, getTimestamps, revision_arg);
|
||||||
|
|
||||||
//Revert each statePath in the list
|
//Revert each statePath in the list
|
||||||
for (RevisionClosure::iterator i = getRivisions.begin(); i != getRivisions.end(); ++i){
|
for (RevisionClosure::iterator i = getRivisions.begin(); i != getRivisions.end(); ++i){
|
||||||
Path statePath = (*i).first;
|
Path statePath = (*i).first;
|
||||||
Snapshots revisioned_paths = (*i).second;
|
Snapshots revisioned_paths = (*i).second;
|
||||||
|
int timestamp = getTimestamps[statePath];
|
||||||
|
|
||||||
|
//get new timestamp (just before restoring the path) for references update ???
|
||||||
|
|
||||||
|
|
||||||
|
//get its derivation-state-items
|
||||||
|
Derivation statePath_drv = derivationFromPath(queryStatePathDrvTxn(noTxn, statePath));
|
||||||
|
DerivationStateOutputDirs stateOutputDirs = statePath_drv.stateOutputDirs;
|
||||||
|
|
||||||
//TODO Sort snapshots??? eg first restore root, then the subdirs??
|
//TODO Sort snapshots??? eg first restore root, then the subdirs??
|
||||||
|
|
||||||
|
|
@ -275,19 +285,18 @@ static void revertToRevision(Strings opFlags, Strings opArgs)
|
||||||
//Now that were still here, we need to copy the state from the previous version back
|
//Now that were still here, we need to copy the state from the previous version back
|
||||||
Strings p_args;
|
Strings p_args;
|
||||||
p_args.push_back("-c"); //we use the shell to execute the cp command becuase the shell expands the '*'
|
p_args.push_back("-c"); //we use the shell to execute the cp command becuase the shell expands the '*'
|
||||||
string cpcommand = "cp -R";
|
string cpcommand = "cp";
|
||||||
if(revertPathOrFile.substr(revertPathOrFile.length() -1 , revertPathOrFile.length()) == "/"){ //is dir
|
if(revertPathOrFile.substr(revertPathOrFile.length() -1 , revertPathOrFile.length()) == "/"){ //is dir
|
||||||
string revert_to_path = revertPathOrFile.substr(0, revertPathOrFile.length() -1) + "@" + unsignedInt2String(epoch);
|
string revert_to_path = revertPathOrFile.substr(0, revertPathOrFile.length() -1) + "@" + unsignedInt2String(epoch);
|
||||||
cpcommand += " " + revert_to_path + "/*";
|
cpcommand += " -R " + revert_to_path + "/*";
|
||||||
|
|
||||||
//clean all contents of the folder first (so were sure the path is clean)
|
//clean all contents of the folder first (so were sure the path is clean)
|
||||||
if(pathExists(revertPathOrFile))
|
if(pathExists(revertPathOrFile))
|
||||||
deletePath(revertPathOrFile);
|
deletePath(revertPathOrFile);
|
||||||
|
|
||||||
//If path was not deleted in the previous version, we need to make sure it exists or cp will fail
|
if(epoch == 0) //Path was deleted so were done
|
||||||
if(epoch == 0)
|
|
||||||
continue;
|
continue;
|
||||||
else
|
else //If path was not deleted in the previous version, we need to make sure it exists or cp will fail
|
||||||
ensureDirExists(revertPathOrFile);
|
ensureDirExists(revertPathOrFile);
|
||||||
|
|
||||||
//If the the dir has not contents then a cp ..../* will error since * cannot be expanded. So in this case were done and dont have to revert.
|
//If the the dir has not contents then a cp ..../* will error since * cannot be expanded. So in this case were done and dont have to revert.
|
||||||
|
|
@ -310,20 +319,40 @@ static void revertToRevision(Strings opFlags, Strings opArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Revert
|
//Revert
|
||||||
printMsg(lvlError, format("Reverting '%1%'") % revertPathOrFile);
|
printMsg(lvlError, format("Reverting '%1%@%2%'") % revertPathOrFile % unsignedInt2String(epoch));
|
||||||
|
printMsg(lvlError, format("Command: '%1%'") % cpcommand);
|
||||||
cpcommand += " " + revertPathOrFile;
|
cpcommand += " " + revertPathOrFile;
|
||||||
p_args.push_back(cpcommand);
|
p_args.push_back(cpcommand);
|
||||||
runProgram_AndPrintOutput("sh", true, p_args, "sh-cp"); //TODO does this work on windows?
|
runProgram_AndPrintOutput("sh", true, p_args, "sh-cp"); //TODO does this work on windows?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Also revert state references to the specific revision (the revision is already converted to a timestamp here)
|
||||||
|
PathSet state_stateReferences;
|
||||||
|
queryStateReferencesTxn(noTxn, statePath, state_stateReferences, -1, timestamp);
|
||||||
|
|
||||||
|
PathSet state_references;
|
||||||
|
queryReferencesTxn(noTxn, statePath, state_references, -1, timestamp);
|
||||||
|
|
||||||
|
//nixDB.setStateReferences(txn, dbStateComponentReferences, dbStateRevisions, statePath, ..., -1, NEWTIMESTAMP);
|
||||||
|
//nixDB.setStateReferences(txn, dbStateStateReferences, dbStateRevisions, statePath, ........, -1, NEWTIMESTAMP);
|
||||||
|
|
||||||
|
//TODO SET REFERRERS ALSO BACK !!!!!!!!!!
|
||||||
|
//setReferences is based on a revision, but make can change that ??
|
||||||
|
|
||||||
printMsg(lvlError, format("Reverted state of '%1%' to revision '%2%'") % statePath % revision_arg);
|
printMsg(lvlError, format("Reverted state of '%1%' to revision '%2%'") % statePath % revision_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO include this call in the validate function
|
//TODO include this call in the validate function
|
||||||
//TODO ONLY CALL THIS FUNCTION ON A NON-SHARED STATE PATH!!!!!!!!!!!
|
//TODO ONLY CALL THIS FUNCTION ON A NON-SHARED STATE PATH!!!!!!!!!!!
|
||||||
void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePath
|
void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePath
|
||||||
, PathSet & newFoundComponentReferences, PathSet & newFoundStateReferences, const int revision) //only for recursion
|
, PathSet & newFoundComponentReferences, PathSet & newFoundStateReferences) //only for recursion
|
||||||
{
|
{
|
||||||
//Check if is a state Path
|
//Check if is a state Path
|
||||||
if(! isValidStatePathTxn(txn, statePath))
|
if(! isValidStatePathTxn(txn, statePath))
|
||||||
|
|
@ -389,7 +418,7 @@ void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePa
|
||||||
if(diff_references_added.size() != 0 || diff_references_removed.size() != 0 ||
|
if(diff_references_added.size() != 0 || diff_references_removed.size() != 0 ||
|
||||||
diff_state_references_added.size() != 0 || diff_state_references_removed.size() != 0 )
|
diff_state_references_added.size() != 0 || diff_state_references_removed.size() != 0 )
|
||||||
{
|
{
|
||||||
printMsg(lvlError, format("Updating new references to revision %1% for statepath: '%2%'") % revision % statePath);
|
printMsg(lvlError, format("Updating new references for statepath: '%1%'") % statePath);
|
||||||
Path drvPath = queryStatePathDrvTxn(txn, statePath);
|
Path drvPath = queryStatePathDrvTxn(txn, statePath);
|
||||||
registerValidPath(txn,
|
registerValidPath(txn,
|
||||||
statePath,
|
statePath,
|
||||||
|
|
@ -397,7 +426,7 @@ void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePa
|
||||||
state_references,
|
state_references,
|
||||||
state_stateReferences,
|
state_stateReferences,
|
||||||
drvPath,
|
drvPath,
|
||||||
revision);
|
-1); //Set at a new timestamp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -417,15 +446,10 @@ void scanAndUpdateAllReferencesRecusivelyTxn(const Transaction & txn, const Path
|
||||||
//call scanForAllReferences again on all statePaths
|
//call scanForAllReferences again on all statePaths
|
||||||
for (PathSet::iterator i = statePaths.begin(); i != statePaths.end(); ++i){
|
for (PathSet::iterator i = statePaths.begin(); i != statePaths.end(); ++i){
|
||||||
|
|
||||||
//TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
int revision = 0;
|
|
||||||
//Get last revision number from DB !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
//TODO first snapshot all paths....?
|
|
||||||
|
|
||||||
//Scan, update, call recursively
|
//Scan, update, call recursively
|
||||||
PathSet newFoundComponentReferences;
|
PathSet newFoundComponentReferences;
|
||||||
PathSet newFoundStateReferences;
|
PathSet newFoundStateReferences;
|
||||||
scanAndUpdateAllReferencesTxn(txn, *i, newFoundComponentReferences, newFoundStateReferences, revision);
|
scanAndUpdateAllReferencesTxn(txn, *i, newFoundComponentReferences, newFoundStateReferences);
|
||||||
|
|
||||||
//Call the function recursively again on all newly found references //TODO test if this works
|
//Call the function recursively again on all newly found references //TODO test if this works
|
||||||
PathSet allNewReferences = pathSets_union(newFoundComponentReferences, newFoundStateReferences);
|
PathSet allNewReferences = pathSets_union(newFoundComponentReferences, newFoundStateReferences);
|
||||||
|
|
@ -452,34 +476,33 @@ static void opRunComponent(Strings opFlags, Strings opArgs)
|
||||||
//add locks ... ?
|
//add locks ... ?
|
||||||
//svn lock ... ?
|
//svn lock ... ?
|
||||||
|
|
||||||
//get all current dependecies (if neccecary | recusively) of all state components that need to be updated
|
|
||||||
PathSet statePaths;
|
|
||||||
store->storePathRequisites(root_componentPath, false, statePaths, false, true, -1);
|
|
||||||
statePaths.insert(root_statePath);
|
|
||||||
|
|
||||||
//Replace all shared paths in the set for their real paths
|
|
||||||
statePaths = toNonSharedPathSetTxn(noTxn, statePaths);
|
|
||||||
|
|
||||||
//TODO maybe also scan the parameters for state or component hashes?
|
//TODO maybe also scan the parameters for state or component hashes?
|
||||||
//program_args
|
//program_args
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
Transaction txn;
|
Transaction txn;
|
||||||
//createStoreTransaction(txn);
|
//createStoreTransaction(txn);
|
||||||
|
|
||||||
|
|
||||||
//******************* Run ****************************
|
//******************* Run ****************************
|
||||||
|
|
||||||
if(!only_commit)
|
if(!only_commit)
|
||||||
executeShellCommand(root_componentPath + root_binary + " " + root_program_args);
|
executeShellCommand(root_componentPath + root_binary + " " + root_program_args);
|
||||||
|
|
||||||
//******************* With everything in place, we call the commit script on all statePaths (in)directly referenced **********************
|
//******************* Scan for new references if neccecary
|
||||||
|
|
||||||
//Start transaction TODO
|
|
||||||
|
|
||||||
//Scan for new references if neccecary
|
|
||||||
if(scanforReferences)
|
if(scanforReferences)
|
||||||
scanAndUpdateAllReferencesRecusivelyTxn(txn, root_statePath);
|
scanAndUpdateAllReferencesRecusivelyTxn(txn, root_statePath);
|
||||||
|
|
||||||
|
//get all current (maybe updated by the scan) dependecies (if neccecary | recusively) of all state components that need to be updated
|
||||||
|
PathSet statePaths;
|
||||||
|
store->storePathRequisites(root_componentPath, false, statePaths, false, true, -1);
|
||||||
|
statePaths.insert(root_statePath);
|
||||||
|
|
||||||
|
//Start transaction TODO
|
||||||
|
|
||||||
|
//Replace all shared paths in the set for their real paths
|
||||||
|
statePaths = toNonSharedPathSetTxn(noTxn, statePaths);
|
||||||
|
|
||||||
|
//******************* With everything in place, we call the commit script on all statePaths (in)directly referenced **********************
|
||||||
|
|
||||||
//Commit all statePaths
|
//Commit all statePaths
|
||||||
RevisionClosure rivisionMapping;
|
RevisionClosure rivisionMapping;
|
||||||
|
|
@ -487,14 +510,15 @@ static void opRunComponent(Strings opFlags, Strings opArgs)
|
||||||
rivisionMapping[*i] = commitStatePathTxn(txn, *i);
|
rivisionMapping[*i] = commitStatePathTxn(txn, *i);
|
||||||
|
|
||||||
//Save new revisions
|
//Save new revisions
|
||||||
setStateRevisionsTxn(txn, root_statePath, rivisionMapping);
|
setStateRevisionsTxn(txn, rivisionMapping);
|
||||||
|
|
||||||
//Commit transaction
|
//Commit transaction
|
||||||
//txn.commit();
|
//txn.commit();
|
||||||
|
|
||||||
//Debugging
|
//Debugging
|
||||||
RevisionClosure getRivisions;
|
RevisionClosure getRivisions;
|
||||||
bool b = store->queryStateRevisions(root_statePath, getRivisions, -1);
|
RevisionClosureTS empty;
|
||||||
|
bool b = store->queryStateRevisions(root_statePath, getRivisions, empty, -1);
|
||||||
for (RevisionClosure::iterator i = getRivisions.begin(); i != getRivisions.end(); ++i){
|
for (RevisionClosure::iterator i = getRivisions.begin(); i != getRivisions.end(); ++i){
|
||||||
//printMsg(lvlError, format("State %1% has revision %2%") % (*i).first % int2String((*i).second));
|
//printMsg(lvlError, format("State %1% has revision %2%") % (*i).first % int2String((*i).second));
|
||||||
}
|
}
|
||||||
|
|
@ -607,8 +631,6 @@ void run(Strings args)
|
||||||
//updateRevisionNumbers("/nix/state/xf582zrz6xl677llr07rvskgsi3dli1d-hellohardcodedstateworld-dep1-1.0-test");
|
//updateRevisionNumbers("/nix/state/xf582zrz6xl677llr07rvskgsi3dli1d-hellohardcodedstateworld-dep1-1.0-test");
|
||||||
//return;
|
//return;
|
||||||
|
|
||||||
//printMsg(lvlError, format("NOW: '%1%'") % getTimeStamp());
|
|
||||||
|
|
||||||
//auto sort
|
//auto sort
|
||||||
map<string, string> test;
|
map<string, string> test;
|
||||||
test["q"] = "324";
|
test["q"] = "324";
|
||||||
|
|
@ -616,6 +638,10 @@ void run(Strings args)
|
||||||
test["a"] = "a";
|
test["a"] = "a";
|
||||||
for (map<string, string>::const_iterator j = test.begin(); j != test.end(); ++j)
|
for (map<string, string>::const_iterator j = test.begin(); j != test.end(); ++j)
|
||||||
printMsg(lvlError, format("KEY: '%1%'") % (*j).first);
|
printMsg(lvlError, format("KEY: '%1%'") % (*j).first);
|
||||||
|
|
||||||
|
printMsg(lvlError, format("NOW: '%1%'") % getTimeStamp());
|
||||||
|
return;
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* test */
|
/* test */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue