mirror of
https://github.com/NixOS/nix.git
synced 2025-11-26 20:20:58 +01:00
major update
This commit is contained in:
parent
cc7d4c8bd7
commit
ca5fc7c582
15 changed files with 562 additions and 68 deletions
|
|
@ -456,22 +456,45 @@ void Database::splitStatePathRevision(const Path & revisionedStatePath, Path & s
|
|||
{
|
||||
string prefix = "-REV-";
|
||||
|
||||
int pos = revisionedStatePath.find_last_not_of(prefix);
|
||||
statePath = revisionedStatePath.substr(0, pos - prefix.length());
|
||||
//printMsg(lvlError, format("'%1%' '%2%'") % statePath % revisionedStatePath.substr(pos, revisionedStatePath.size()));
|
||||
bool succeed = string2Int(revisionedStatePath.substr(pos, revisionedStatePath.size()), revision);
|
||||
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 = string2Int(revisionedStatePath.substr(pos+1, revisionedStatePath.length()), revision);
|
||||
if(!succeed)
|
||||
throw Error(format("Malformed revision value of path '%1%'") % revisionedStatePath);
|
||||
}
|
||||
|
||||
|
||||
int Database::getNewRevisionNumber(const Transaction & txn, TableId table,
|
||||
const Path & statePath)
|
||||
{
|
||||
//query
|
||||
string data;
|
||||
bool notEmpty = queryString(txn, table, statePath, data);
|
||||
|
||||
if(!notEmpty){
|
||||
setString(txn, table, statePath, int2String(1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int revision;
|
||||
bool succeed = string2Int(data, revision);
|
||||
if(!succeed)
|
||||
throw Error(format("Malformed revision counter value of path '%1%'") % statePath);
|
||||
|
||||
revision++;
|
||||
setString(txn, table, statePath, int2String(revision));
|
||||
|
||||
return revision;
|
||||
}
|
||||
|
||||
void Database::setStateReferences(const Transaction & txn, TableId table,
|
||||
const Path & statePath, const int revision, const Strings & references)
|
||||
const Path & statePath, const Strings & references, int revision)
|
||||
{
|
||||
//printMsg(lvlError, format("setStateReferences/Referrers %1%") % table);
|
||||
|
||||
if(revision == -1)
|
||||
throw Error("-1 is not a valid revision value for SET-references/referrers");
|
||||
revision = getNewRevisionNumber(txn, table, statePath);
|
||||
|
||||
/*
|
||||
for (Strings::const_iterator i = references.begin(); i != references.end(); ++i)
|
||||
|
|
@ -490,6 +513,31 @@ void Database::setStateReferences(const Transaction & txn, TableId table,
|
|||
setStrings(txn, table, key, references);
|
||||
}
|
||||
|
||||
bool Database::lookupHighestRevivison(const Strings & keys, const Path & statePath, string & key)
|
||||
{
|
||||
int highestRev = -1;
|
||||
|
||||
//Lookup which key we need
|
||||
for (Strings::const_iterator i = keys.begin(); i != keys.end(); ++i) {
|
||||
|
||||
if((*i).substr(0, statePath.length()) != statePath || (*i).length() == statePath.length()) //dont check the new-revision key or other keys
|
||||
continue;
|
||||
|
||||
//printMsg(lvlError, format("'%1%' - '%2%'") % *i % statePath);
|
||||
Path getStatePath;
|
||||
int getRevision;
|
||||
splitStatePathRevision(*i, getStatePath, getRevision);
|
||||
if(getRevision > highestRev)
|
||||
highestRev = getRevision;
|
||||
}
|
||||
|
||||
if(highestRev == -1) //no records found (TODO throw error?)
|
||||
return false;
|
||||
|
||||
key = makeStatePathRevision(statePath, highestRev); //final key that matches revision + statePath
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Database::queryStateReferences(const Transaction & txn, TableId table,
|
||||
const Path & statePath, Strings & references, int revision)
|
||||
{
|
||||
|
|
@ -498,6 +546,16 @@ bool Database::queryStateReferences(const Transaction & txn, TableId table,
|
|||
Strings keys;
|
||||
enumTable(txn, table, keys); //get all revisions
|
||||
|
||||
string key;
|
||||
if(revision == -1){
|
||||
bool foundsomething = lookupHighestRevivison(keys, statePath, key);
|
||||
if(!foundsomething)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
key = makeStatePathRevision(statePath, revision);
|
||||
|
||||
/*
|
||||
///////////////?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! create function
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TODO
|
||||
string key = ""; //final key that matches revision + statePath
|
||||
|
|
@ -529,6 +587,7 @@ bool Database::queryStateReferences(const Transaction & txn, TableId table,
|
|||
|
||||
if(revision == -1)
|
||||
key = makeStatePathRevision(statePath, highestRev);
|
||||
*/
|
||||
|
||||
return queryStrings(txn, table, key, references); //now that we have the key, we can query the references
|
||||
}
|
||||
|
|
@ -551,12 +610,32 @@ bool Database::queryStateReferrers(const Transaction & txn, TableId table,
|
|||
|
||||
|
||||
void Database::setStateRevisions(const Transaction & txn, TableId table,
|
||||
const Path & statePath, const int revision, const RevisionNumbersClosure & revisions)
|
||||
const Path & statePath, const RevisionNumbersSetClosure & revisions, int revision)
|
||||
{
|
||||
if(revision == -1)
|
||||
revision = getNewRevisionNumber(txn, table, statePath);
|
||||
|
||||
//Sort based on statePath to RevisionNumbersClosure
|
||||
RevisionNumbersClosure sorted_revisions;
|
||||
vector<Path> sortedStatePaths;
|
||||
for (RevisionNumbersSetClosure::const_iterator i = revisions.begin(); i != revisions.end(); ++i)
|
||||
sortedStatePaths.push_back((*i).first);
|
||||
sort(sortedStatePaths.begin(), sortedStatePaths.end());
|
||||
for (vector<Path>::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i)
|
||||
sorted_revisions.push_back(revisions.at(*i));
|
||||
|
||||
//////////////////
|
||||
for (vector<Path>::const_iterator i = sortedStatePaths.begin(); i != sortedStatePaths.end(); ++i){
|
||||
printMsg(lvlError, format("Insert: %1%") % *i);
|
||||
for (RevisionNumbers::const_iterator e = (revisions.at(*i)).begin(); e != (revisions.at(*i)).end(); ++e)
|
||||
printMsg(lvlError, format("Rev: %1%") % *e);
|
||||
}
|
||||
//////////////////
|
||||
|
||||
//Pack the data into Strings
|
||||
const string seperator = "|";
|
||||
Strings data;
|
||||
for (RevisionNumbersClosure::const_iterator i = revisions.begin(); i != revisions.end(); ++i) {
|
||||
for (RevisionNumbersClosure::const_iterator i = sorted_revisions.begin(); i != sorted_revisions.end(); ++i) {
|
||||
RevisionNumbers revisionNumbers = *i;
|
||||
string packedNumbers = "";
|
||||
for (RevisionNumbers::iterator j = revisionNumbers.begin(); j != revisionNumbers.end(); ++j)
|
||||
|
|
@ -580,6 +659,16 @@ bool Database::queryStateRevisions(const Transaction & txn, TableId table,
|
|||
Strings keys;
|
||||
enumTable(txn, table, keys); //get all revisions
|
||||
|
||||
string key;
|
||||
if(revision == -1){
|
||||
bool foundsomething = lookupHighestRevivison(keys, statePath, key);
|
||||
if(!foundsomething)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
key = makeStatePathRevision(statePath, revision);
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
string key = ""; //final key that matches revision + statePath
|
||||
int highestRev = -1;
|
||||
|
|
@ -610,7 +699,8 @@ bool Database::queryStateRevisions(const Transaction & txn, TableId table,
|
|||
|
||||
if(revision == -1)
|
||||
key = makeStatePathRevision(statePath, highestRev);
|
||||
|
||||
*/
|
||||
|
||||
Strings data;
|
||||
bool succeed = queryStrings(txn, table, key, data); //now that we have the key, we can query the references
|
||||
|
||||
|
|
@ -632,14 +722,28 @@ bool Database::queryStateRevisions(const Transaction & txn, TableId table,
|
|||
return succeed;
|
||||
}
|
||||
|
||||
bool Database::queryAllStateRevisions(const Transaction & txn, TableId table,
|
||||
//TODO include comments into revisions?
|
||||
bool Database::queryAvailableStateRevisions(const Transaction & txn, TableId table,
|
||||
const Path & statePath, RevisionNumbers & revisions)
|
||||
{
|
||||
//TODO
|
||||
Strings keys;
|
||||
enumTable(txn, table, keys); //get all revisions
|
||||
|
||||
//LIST OF x ..... y which revisions are available for a rollback
|
||||
for (Strings::const_iterator i = keys.begin(); i != keys.end(); ++i) {
|
||||
|
||||
return false;
|
||||
if((*i).substr(0, statePath.length()) != statePath || (*i).length() == statePath.length()) //dont check the new-revision key or other keys
|
||||
continue;
|
||||
|
||||
Path getStatePath;
|
||||
int getRevision;
|
||||
splitStatePathRevision(*i, getStatePath, getRevision);
|
||||
revisions.push_back(getRevision);
|
||||
}
|
||||
|
||||
if(revisions.empty())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,13 @@ private:
|
|||
|
||||
void open2(const string & path, bool removeOldEnv);
|
||||
|
||||
/* TODO */
|
||||
bool lookupHighestRevivison(const Strings & keys, const Path & statePath, string & key);
|
||||
|
||||
/* TODO */
|
||||
int getNewRevisionNumber(const Transaction & txn, TableId table, const Path & statePath);
|
||||
|
||||
|
||||
public:
|
||||
Database();
|
||||
~Database();
|
||||
|
|
@ -98,7 +105,7 @@ public:
|
|||
|
||||
/* 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,
|
||||
const Path & statePath, const int revision, const Strings & references);
|
||||
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) */
|
||||
bool queryStateReferences(const Transaction & txn, TableId table,
|
||||
|
|
@ -110,14 +117,14 @@ public:
|
|||
|
||||
/* 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 table,
|
||||
const Path & statePath, const int revision, const RevisionNumbersClosure & revisions);
|
||||
const Path & statePath, const RevisionNumbersSetClosure & revisions, int revision = -1);
|
||||
|
||||
/* 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, RevisionNumbersClosure & revisions, int revision = -1);
|
||||
|
||||
/* Returns all available revision numbers of the given state path */
|
||||
bool queryAllStateRevisions(const Transaction & txn, TableId table,
|
||||
bool queryAvailableStateRevisions(const Transaction & txn, TableId table,
|
||||
const Path & statePath, RevisionNumbers & revisions);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,13 @@ static TableId dbStateCounters = 0;
|
|||
*/
|
||||
static TableId dbStateInfo = 0;
|
||||
|
||||
/* dbStateRevisions :: StatePath -> RevisionNumbersClosure
|
||||
|
||||
This table lists the statepaths + recursive (indirect) references and the revision numbers of their repositorys
|
||||
|
||||
*/
|
||||
static TableId dbStateRevisions = 0;
|
||||
|
||||
bool Substitute::operator == (const Substitute & sub) const
|
||||
{
|
||||
return program == sub.program
|
||||
|
|
@ -189,7 +196,8 @@ LocalStore::LocalStore(bool reserveSpace)
|
|||
dbComponentStateReferrers = nixDB.openTable("referrers_c_s", true);
|
||||
dbStateComponentReferrers = nixDB.openTable("referrers_s_c", true);
|
||||
dbStateStateReferrers = nixDB.openTable("referrers_s_s", true);
|
||||
|
||||
dbStateRevisions = nixDB.openTable("staterevisions", true);
|
||||
|
||||
|
||||
int curSchema = 0;
|
||||
Path schemaFN = nixDBPath + "/schema";
|
||||
|
|
@ -484,8 +492,8 @@ void setReferences(const Transaction & txn, const Path & store_or_statePath,
|
|||
oldReferences2 = PathSet(oldStateReferences_s_c.begin(), oldStateReferences_s_c.end());
|
||||
oldStateReferences2 = PathSet(oldStateReferences_s_s.begin(), oldStateReferences_s_s.end());
|
||||
|
||||
nixDB.setStateReferences(txn, dbStateComponentReferences, store_or_statePath, revision, Paths(references.begin(), references.end()));
|
||||
nixDB.setStateReferences(txn, dbStateStateReferences, store_or_statePath, revision, Paths(stateReferences.begin(), stateReferences.end()));
|
||||
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);
|
||||
|
||||
//set vars for the referrers update code below
|
||||
dbXComponentReferrers = dbStateComponentReferrers;
|
||||
|
|
@ -1702,6 +1710,8 @@ void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePa
|
|||
allReferencesKeys2.push_back(path);
|
||||
}
|
||||
|
||||
//TODO maybe only scan in the changeset (patch) for new references? (this will be difficult and depending on the underlying versioning system)
|
||||
|
||||
//Scan in for component and state references
|
||||
PathSet state_references = scanForReferences(statePath, PathSet(allReferencesKeys2.begin(), allReferencesKeys2.end()));
|
||||
PathSet state_stateReferences = scanForReferences(statePath, PathSet(allStateReferencesKeys.begin(), allStateReferencesKeys.end()));
|
||||
|
|
@ -1738,6 +1748,7 @@ void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePa
|
|||
printMsg(lvlError, format("Added state reference found!: '%1%' in state path '%2%'") % (*i) % statePath);
|
||||
|
||||
//TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
/*
|
||||
Register Valid again if neccesary
|
||||
update the extra references in a new table??? why???
|
||||
|
|
@ -1792,7 +1803,7 @@ void scanAndUpdateAllReferencesRecusively(const Transaction & txn, const Path &
|
|||
//call scanForAllReferences again on all newly found statePaths
|
||||
for (PathSet::iterator i = statePaths.begin(); i != statePaths.end(); ++i)
|
||||
{
|
||||
//... and merge
|
||||
//Scan, update, call recursively
|
||||
PathSet newFoundComponentReferences;
|
||||
PathSet newFoundStateReferences;
|
||||
scanAndUpdateAllReferencesTxn(txn, *i, newFoundComponentReferences, newFoundStateReferences);
|
||||
|
|
@ -1809,6 +1820,37 @@ void LocalStore::scanAndUpdateAllReferencesRecusively(const Path & storeOrStateP
|
|||
return nix::scanAndUpdateAllReferencesRecusively(noTxn, storeOrStatePath);
|
||||
}
|
||||
|
||||
void setStateRevisions(const Transaction & txn, const Path & statePath, const RevisionNumbersSetClosure & revisions, const int revision)
|
||||
{
|
||||
nixDB.setStateRevisions(txn, dbStateRevisions, statePath, revisions, revision);
|
||||
}
|
||||
|
||||
void LocalStore::setStateRevisions(const Path & statePath, const RevisionNumbersSetClosure & revisions, const int revision)
|
||||
{
|
||||
nix::setStateRevisions(noTxn, statePath, revisions, revision);
|
||||
}
|
||||
|
||||
bool queryStateRevisions(const Transaction & txn, const Path & statePath, RevisionNumbersClosure & revisions, const int revision)
|
||||
{
|
||||
return nixDB.queryStateRevisions(txn, dbStateRevisions, statePath, revisions, revision);
|
||||
}
|
||||
|
||||
bool LocalStore::queryStateRevisions(const Path & statePath, RevisionNumbersClosure & revisions, const int revision)
|
||||
{
|
||||
return nix::queryStateRevisions(noTxn, statePath, revisions, revision);
|
||||
}
|
||||
|
||||
bool queryAvailableStateRevisions(const Transaction & txn, const Path & statePath, RevisionNumbers & revisions)
|
||||
{
|
||||
return nixDB.queryAvailableStateRevisions(txn, dbStateRevisions, statePath, revisions);
|
||||
}
|
||||
|
||||
bool LocalStore::queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions)
|
||||
{
|
||||
return nix::queryAvailableStateRevisions(noTxn, statePath, revisions);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Upgrade from schema 1 (Nix <= 0.7) to schema 2 (Nix >= 0.8). */
|
||||
static void upgradeStore07()
|
||||
|
|
|
|||
|
|
@ -102,6 +102,12 @@ public:
|
|||
|
||||
void scanAndUpdateAllReferencesRecusively(const Path & storeOrstatePath);
|
||||
|
||||
void setStateRevisions(const Path & statePath, const RevisionNumbersSetClosure & revisions, const int revision);
|
||||
|
||||
bool queryStateRevisions(const Path & statePath, RevisionNumbersClosure & revisions, const int revision);
|
||||
|
||||
bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -474,6 +474,22 @@ void RemoteStore::scanAndUpdateAllReferencesRecusively(const Path & storeOrstate
|
|||
|
||||
}
|
||||
|
||||
//TODO
|
||||
void RemoteStore::setStateRevisions(const Path & statePath, const RevisionNumbersSetClosure & revisions, const int revision)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//TODO
|
||||
bool RemoteStore::queryStateRevisions(const Path & statePath, RevisionNumbersClosure & revisions, const int revision)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//TODO
|
||||
bool RemoteStore::queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,6 +89,12 @@ public:
|
|||
void scanAndUpdateAllReferences(const Path & statePath);
|
||||
|
||||
void scanAndUpdateAllReferencesRecusively(const Path & storeOrstatePath);
|
||||
|
||||
void setStateRevisions(const Path & statePath, const RevisionNumbersSetClosure & revisions, const int revision);
|
||||
|
||||
bool queryStateRevisions(const Path & statePath, RevisionNumbersClosure & revisions, const int revision);
|
||||
|
||||
bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions);
|
||||
|
||||
private:
|
||||
AutoCloseFD fdSocket;
|
||||
|
|
|
|||
|
|
@ -222,6 +222,15 @@ public:
|
|||
|
||||
/* TODO */
|
||||
virtual void scanAndUpdateAllReferencesRecusively(const Path & storeOrstatePath) = 0;
|
||||
|
||||
/* TODO */
|
||||
virtual void setStateRevisions(const Path & statePath, const RevisionNumbersSetClosure & revisions, const int revision) = 0;
|
||||
|
||||
/* TODO */
|
||||
virtual bool queryStateRevisions(const Path & statePath, RevisionNumbersClosure & revisions, const int revision) = 0;
|
||||
|
||||
/* TODO */
|
||||
virtual bool queryAvailableStateRevisions(const Path & statePath, RevisionNumbers & revisions) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue