Export (0) Print
Expand All
This topic has not yet been rated - Rate this topic

SPChangeTokenCollection Class

Represents a collection of SPChangeToken objects.

Namespace:  Microsoft.SharePoint
Assembly:  Microsoft.SharePoint (in Microsoft.SharePoint.dll)
Available in Sandboxed Solutions: Yes
Available in SharePoint Online
[SubsetCallableTypeAttribute]
public sealed class SPChangeTokenCollection : SPBaseCollection

This collection is provided so that you can easily manage change logs at the Web application level. Each content database in a Web application maintains its own change log. If you want a consolidated change report for multiple content databases, you can use an SPChangeTokenCollection object to store change tokens for all databases in a single collection. Once you have a collection of change tokens, you can enumerate the collection and ask each database in turn for its changes by calling the GetChanges(SPChangeToken) method. You can also serialize a collection using the ToString() method, and store it on disk. Later, when you want to revisit the change logs, you can reconstruct the collection using a variation of the constructor that accepts a string argument, and then use the deserialized change token collection to query the change logs again.

The following example is a console application that queries the change log for each content database in a Web application. On the program’s first run, all changes are retrieved from each log. After processing each collection of changes, the program saves the last change token in the change collection to an SPChangeTokenCollection collection. When all logs have been processed, the SPChangeTokenCollection object is serialized, and the resulting string is stored in a file on disk.

On subsequent runs of the program, the data file is read, the string representation of the collection is retrieved, and the SPChangeTokenCollection object is reconstructed. The change tokens in the collection are then used to fetch changes made since the last run of the program.

This example makes no attempt to save the information that it retrieves from the change logs. It simply prints the output to the console. A useful enhancement would be to add code for consolidating changes in a file or database, where they could be subjected to further analysis.

using System;
using System.IO;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace Test
{
   class ConsoleApp
   {
      private const string DATA_FILE_PATH = "ChangeTokens.dat";

      static void Main(string[] args)
      {
         // Get a collection of content databases
         SPWebApplication wa = SPWebApplication.Lookup(new Uri("http://localhost"));
         SPContentDatabaseCollection dbs = wa.ContentDatabases;

         // Get a collection of change tokens
         SPChangeTokenCollection tokens = GetTokens();

         // Process the changes for each database
         foreach (SPContentDatabase db in dbs)
         {
            // Get an Id for the current database
            SPPersistedObject o = db as SPPersistedObject;
            Guid id = o.Id;
            Console.WriteLine("\nContent database ID = {0}", id.ToString());

            // Create a query.
            SPChangeQuery query = new SPChangeQuery(true, true);

            /* Get the starting token. 
             * Note that if the token is not
             * found, the indexer returns null.
             * Passing a null token fetches changes
             * from the beginning of the log.
             */
            query.ChangeTokenStart = tokens[id];

            while (true)
            {
               // Get a batch of changes
               SPChangeCollection changes = db.GetChanges(query);

               // Process them
               foreach (SPChange change in changes)
               {
                  Console.WriteLine("Date: {0}  Type of object: {1}  Type of change: {2}",
                     change.Time.ToShortDateString(), change.GetType().ToString(), change.ChangeType);
               }

               // If this is the last batch, exit
               if (changes.Count < query.FetchLimit)
               {
                  // Save the last token as a starting point for the next run
                  tokens.Add(changes.LastChangeToken, true);
                  break;
               }
               else
               {                
                  // Starting point for next batch
                  query.ChangeTokenStart = changes.LastChangeToken;
               }
            }
         }

         // Persist the token collection
         SaveTokens(tokens);

         Console.Write("\nPress ENTER to continue...");
         Console.ReadLine();
      }

      static SPChangeTokenCollection GetTokens()
      {
         SPChangeTokenCollection tokens = new SPChangeTokenCollection();

         // If we have tokens from the last run, use them
         if (File.Exists(DATA_FILE_PATH))
         {
            using (FileStream fs = File.OpenRead(DATA_FILE_PATH))
            {
               BinaryReader br = new BinaryReader(fs);
               try
               {
                  string s = br.ReadString();
                  // Construct a change token from string
                  tokens = new SPChangeTokenCollection(s);
               }
               catch (EndOfStreamException e)
               {
                  // No serialized string, so do nothing
               }
               finally
               {
                  br.Close();
               }
            }
         }

         return tokens;
      }

      static void SaveTokens(SPChangeTokenCollection tokens)
      {
         using (FileStream fs = File.Create(DATA_FILE_PATH))
         {
            // Serialize the tokens
            BinaryWriter bw = new BinaryWriter(fs);
            string s = tokens.ToString();
            bw.Write(s);

            // flush and close
            bw.Flush();
            bw.Close();
         }
      }
   }
}
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback

Community Additions

ADD
Show:
© 2014 Microsoft. All rights reserved.