For a migration project from sps2001 to MOSS we had a requirement to keep the minor/major versioning intact. As we had to use sps2003 as a migration staging environment, the minor versions are lost and every version will be stored as a major version in MOSS. This was not acceptable, since major versions are visible to visitors of the site, while they are actual minor versions.
So, what to do? Fortunately, we also migrated the original source address in sps2001 as metadata column, so we are able to get the original version number without having to browse through the 2001 environment. It’s all there in the column "Source Address", in the format "http://localhost/ws/shadow/documents/testversiondoc(1.1).doc".
With a lot of help of this article on SharePoint blogs I decided to rebuild the version history. So, for example, if the version history of a document looks like this:
Version number in MOSS |
Original Version number in 2001 (found in column "Source Address") |
1.0 |
0.1 |
2.0 |
0.2 |
3.0 |
1.0 |
4.0 |
1.1 |
then all the minor versions have to be reverted back to a minor version, which will avoid readers to see the minor versions. There is no requirement to retain the original version number. So, we created a script to copy the versions as new versions and, based on the original file version number, only publish those which have a major version.
Few drawbacks here:
- original modified- and creation dates are not retained (I tried to figure this out, but since we use the publish method, the file will be published on the moment you call this method. Even the updateoverwriteversion does not seem to work) – tips appreciated!
- original version numbers are not retained, only the minor- and major versions will be in the history as minor- and major
The code looks like this:
==============================================================================
private SPFile AddFile(string urlFile, byte[] bytefile, Hashtable properties, bool overwrite, SPFileVersion origver)
{
SPFile add = rootfolder.Files.Add(urlFile, bytefile, properties, true);
string SourceAddress = (string)origver.Properties["Source Address"];
PublishVersion(int.Parse(GetVersion(SourceAddress, true)), add);
return add;
}
#endregion
private void RebuildVersionHistory(SPFile file)
{
ArrayList myIds=new ArrayList(); //to store ID’s of versions in
if (file.Versions.Count != 0)
{
//foreach (SPFileVersion newver in file.Versions)
for (int i = 0; i < file.Versions.Count; i++)
{
SPFileVersion oldver = file.Versions[i];
myIds.Add(oldver.ID);
AddFile(file.Url, oldver.OpenBinary(), oldver.Properties, true, oldver);
}
//add the latest version as current, then check if current version should be published
AddFile(file.Url, file.OpenBinary(), file.Properties, true, file.Versions[0]);
//and delete the old versions..
for (int i = 0; i < myIds.Count; i++)
{
SPFileVersion filetodelete = file.Versions.GetVersionFromID(int.Parse(myIds[i].ToString()));
filetodelete.Delete();
}
//and delete the first one in version history (this is the original published one
file.Versions[0].Delete();
}
else
{
//just check this one version if it should be published or not
string SourceAddress = (string)file.Properties["Source Address"];
PublishVersion(int.Parse(GetVersion(SourceAddress, true)), file);
}
}
public void PublishVersion(int num, SPFile setver)
{
int baseNum = 512;
decimal d = num / baseNum;
int i = (int)Math.Floor(d) * 512;
//major publish (eg 1.0, 2.0, 3.0)
if (num == i)
{
setver.Publish("");
}
}
private string GetVersion(string UrlIn, bool as512)
{
//format:blblalbalbal (1.0).xxx . We filter on combination ). an take everything before that till the ( sign
//Example: http://localhost/ws/shadow/documents/folder 1/documentx(1.0).docx –> 1.0
string ret="";
if(UrlIn.IndexOf(").") >0)
{
ret = UrlIn.Substring(UrlIn.LastIndexOf(").") – 3, 3);
if(as512)
{
//ok. now the fun stuff. We now have something like 1.0, or 2.1, 5.0 etc. However, MOSS uses a different system
//for storing this:
//URL number “1” = version “0.1”
//URL number “2” = version “0.2”
//URL number “3” = version “0.3”
//URL number “512” = version “1.0”
//URL number “1024” = version “2.0”
//URL number “1025” = version “2.1”
//URL number “2048” = version “3.0”
//URL number “2049” = version “3.1”
//etc. So, logic: (first digit X 512) + second digit = number to parse back
int temp1=int.Parse(ret.Substring(0,1)); //first digit
int temp2=int.Parse(ret.Substring(2,1)); //second digit
int result = temp1 * 512;
result = result + temp2;
ret = result.ToString();
}
}
return ret;
}
==============================================================================
Basically, these are the steps taken:
– get all versions, extract the original file versions and add them to a sortedlist. This list will ensure the ordering is being done on the version number
– then, copy each version as a new version and publish this version only if it is a major version originally.
– then, add the original latest version as the current one. Note here, this is not in the version history, this is the current version (see the article on SharePoint blogs for more details)
– delete all the old versions which have been copied already (we stored them in the list myIds)
– delete the original file (this was the original current version before we started this process).
Result: a document with a version history with the current major/minor versioning. Bear in mind the file numbers will not be the same as in the 2001 environment (if someone found a way, please let me know!!), but at least you will have the correct minor/major versioning in your history.