CacheManager Causes Corruption in Category Dictionary (300389)



The information in this article applies to:

  • Microsoft SharePoint Portal Server 2001

This article was previously published under Q300389

SYMPTOMS

When you check in a document or assign categories in the properties of a document, an incorrect category dictionary may be displayed. The category dictionary may contain some or all of the categories from a separate workspace on the same server. However, the category hierarchy is displayed properly when you browse through categories in the dashboard site or in Web folders.

CAUSE

The CacheManager in SharePoint Portal Server caches data on both the server and client to improve performance. This problem can occur if, under certain conditions, the Web Storage System (WSS) is down, the CacheManager shows the same data for different workspaces. This type of cache corruption most often occurs in the category dictionary.

RESOLUTION

First run the following scripts, Getcatdict.vbs and Querycats.vbs, to determine if the category dictionary in the workspace is corrupted.

IMPORTANT: The following scripts must be run by a user with workspace Coordinator permissions.

Diagnosing Category Dictionary Corruption

To diagnose category dictionary corruption:
  1. Save the following script to a text file as Getcatdict.vbs.
    const adModeRead        = 	1
    const adModeReadWrite   =       3
    
    Sub Usage
    	WScript.Echo "Use PKMCDO to list the category dictionary in WSS."
    	WScript.Echo
    	WScript.Echo "Usage:    getcatdict.vbs ""<http url to your workspace>"""
    	WScript.Echo "Example:  getcatdict.vbs ""http://servername/workspacename"""
    	WScript.Echo
    end Sub
    
    call main
    
    sub main
    
        if WScript.Arguments.Count = 1 then
    		if WScript.Arguments(0) = "/?" or WScript.Arguments(0) = "-?" then
    			Usage
    		    WScript.Quit(1)
    		end if
        end if
    
        if WScript.Arguments.Count < 1 then
            Usage
            wscript.Quit(1)
        end if
    
        strDoc = wscript.arguments(0) & "/system/schema/d_categories.xml"
    
        Set oDoc = createobject("CDO.KnowledgeDocument")
        oDoc.DataSource.Open strDoc, Nothing, adModeRead
        dictCats = oDoc.Property("urn:schemas-microsoft-com:publishing:dictionaryvalues")
        
        Wscript.echo "Category dictionary for " & wscript.arguments(0) & ":"
        for i = 0 to UBound(dictCats,1)
            wscript.echo dictCats(i)
        next
    
    end sub
    						
    Run the following command from a command prompt on the server:

    getcatdict.vbs "http://server_name/workspace"

    This script retrieves the category dictionary from a SharePoint Portal Server workspace. The category dictionary is defined by the urn:schemas-microsoft-com:publishing:dictionaryvalues property. The CacheManager can corrupt a workspace's category dictionary by committing (saving) the category dictionary from one workspace to the category dictionary for another workspace.
  2. Save the following script to a text file as Querycats.vbs.
    const adModeRead        = 	1
    const adModeReadWrite   =       3
    const   cdostrURI_CategoriesFolder      =   "urn:schemas-microsoft-com:workspace#CategoriesFolder"
    
    '+------------------------------------------------------------------------
    '
    '  Member:      Sub Usage
    '
    '  Synopsis:    Prints help
    '
    '  Effects:
    '
    '  Arguments:
    '
    '  Returns:
    '
    '  History:     01-06-2001                  Created
    '
    '  Notes:
    '
    '------------------------------------------------------------------------
    Sub Usage
    	WScript.Echo "Queries WSS for the categories."
    	WScript.Echo
    	WScript.Echo "Usage:    querycats.vbs ""<http url to your workspace>"""
    	WScript.Echo "Example:  querycats.vbs ""http://servername/workspacename"""
    	WScript.Echo
    end Sub
    
    call main
    
    '+------------------------------------------------------------------------
    '
    '  Member:      Sub Main
    '
    '  Synopsis:    Main entry pt
    '
    '  Effects:
    '
    '  Arguments:
    '
    '  Returns:
    '
    '  History:     01-06-2001                  Created
    '
    '  Notes:
    '
    '------------------------------------------------------------------------
    sub main
    
        Dim oRS
        Dim strCatsName
        Dim strCatsURL
        Dim strCmd
    
        if WScript.Arguments.Count = 1 then
            if WScript.Arguments(0) = "/?" or WScript.Arguments(0) = "-?" then
                Usage
                WScript.Quit(1)
            end if
        end if
    
        if WScript.Arguments.Count < 1 then
            Usage
            wscript.Quit(1)
        end if
    
        strCatsName = GetPropUsingPKMCDO(wscript.arguments(0), cdostrURI_CategoriesFolder, true)
        strCatsURL = wscript.arguments(0) & "/" & strCatsName
        strCmd = "select ""urn:schemas-microsoft-com:office:office#Category"" from scope ('DEEP TRAVERSAL OF """ & strCatsURL & """') WHERE ""DAV:contentclass"" = 'urn:content-classes:categoryfolder'"
        Set oRS = ExecuteDBCmd("ADODB.Connection", "MSDAIPP.DSO", "ADODB.Command", strCmd, strCatsURL)
    
        Dim rgCat()
        cnt=0
    
        If Not oRS.BOF Then
                oRS.MoveFirst
                Redim rgCat(1)
                While Not oRS.EOF               
                    Redim preserve rgCat(cnt)
                        rgCat(cnt) = oRS.fields("urn:schemas-microsoft-com:office:office#Category").Value 
                    cnt = cnt+1
                    oRS.MoveNext
                Wend
        end if
    
        Wscript.echo "Categories for " & wscript.arguments(0) & " from WSS:"
        for i = 0 to UBound(rgCat,1)
            wscript.echo rgCat(i)
        next
    
    end sub
    
    '+------------------------------------------------------------------------
    '
    '  Member:      Function ExecuteDBCmd
    '
    '  Synopsis:    Executes the command
    '
    '  Effects:
    '
    '  Arguments:   strConnectionObj:   Connection object to instantiate and use
    '               strProviderObj:     Provider object to use
    '               strCommandObj:      Command object to use
    '               strCmdText:         The command
    '               strURL:             The URL
    '
    '  Returns:     The RecordSet from the execution of the command
    '
    '  History:     01-06-2001                  Created
    '
    '  Notes:
    '
    '------------------------------------------------------------------------
    Function ExecuteDBCmd(strConnectionObj, strProviderObj, strCommandObj, strCmdText, strURL)
    
        Dim oCon
        Dim oCmd
        Dim oRS
    
        Set oCon = CreateObject(strConnectionObj)
    
        oCon.Provider = strProviderObj
    
        oCon.Open strURL
    
        Set oCmd = CreateObject(strCommandObj)
    
        oCmd.ActiveConnection = oCon
    
        oCmd.CommandText = strCmdText
    
        Set oRS = oCmd.Execute
    
        Set oCmd = Nothing
        Set oCon = Nothing
    
        Set ExecuteDBCmd = oRS
    
    end Function
    
    '+------------------------------------------------------------------------
    '
    '  Member:      Function GetPropUsingPKMCDO
    '
    '  Synopsis:    Gets the property from the row using PKMCDO
    '
    '  Effects:
    '
    '  Arguments:   strURL:  URL to bind to
    '               strProp: URI to get
    '               fLog: Log failures?
    '
    '  Returns:     Array collection of categories for this workspace.
    '               The array returned can be empty.
    '
    '  History:     01-06-2001                  Created
    '
    '  Notes:
    '
    '-------------------------------------------------------------------------
    Function GetPropUsingPKMCDO(strURL, strProp, fLog)
     
        Dim oDoc
        Dim oCon
    
        Set oDoc = CreateObject("CDO.KnowledgeDocument")
    
        Set oCon = CreateObject("ADODB.Connection")
        
        oCon.Provider = "MSDAIPP.DSO"
    
        oCon.Open "Provider=MSDAIPP.DSO; Data Source=" + strURL
    
        oDoc.DataSource.Open strURL, oCon, adModeRead
    
        GetPropUsingPKMCDO = oDoc.Property(strProp)
    
        Set oDoc = Nothing
        Set oCon = Nothing    
    
    end Function
    						
    Run the following command from a command prompt on the server:

    querycats.vbs "http://server_name/workspace"

    This script queries the WSS for the list of categories from "http://server_name/workspace/Categories." The list of categories is the same as the list that is displayed when you browse through the category folders from the dashboard site or from Web folders.
  3. Compare the output of each script. If the categories that are listed from the Querycats.vbs and Getcatdict.vbs scripts are not identical, the category dictionary is corrupted.
If the category dictionary is not corrupted (both scripts return the same values), an available fix is described in the "Applying the Fix" section of this article that prevents cache corruption from occurring.

If the category dictionary is corrupted (the scripts return different values), you must first repair the corrupted dictionary, and then apply the fix to prevent the issue from re-occurring.

Repairing the Corrupted Dictionary

To repair a corrupted dictionary:
  1. Save the following script to a text file as Verifycatdict.vbs.
    const adModeRead        = 	1
    const adModeReadWrite   =       3
    const   cdostrURI_CategoriesFolder      =   "urn:schemas-microsoft-com:workspace#CategoriesFolder"
    
    '+------------------------------------------------------------------------
    '
    '  Member:      Sub Usage
    '
    '  Synopsis:    Prints help
    '
    '  Effects:
    '
    '  Arguments:
    '
    '  Returns:
    '
    '  History:     01-06-2001                  Created
    '
    '  Notes:
    '
    '------------------------------------------------------------------------
    Sub Usage
    	WScript.Echo "Displays the category dictionary from WSS (i.e., not from the cahce)."
    	WScript.Echo
    	WScript.Echo "Usage:    verifycatdict.vbs ""<http url to your workspace>"""
    	WScript.Echo "Example:  verifycatdict.vbs ""http://servername/workspacename"""
    	WScript.Echo
    end Sub
    
    call main
    
    '+------------------------------------------------------------------------
    '
    '  Member:      Sub Main
    '
    '  Synopsis:    Main entry pt
    '
    '  Effects:
    '
    '  Arguments:
    '
    '  Returns:
    '
    '  History:     01-06-2001                  Created
    '
    '  Notes:
    '
    '------------------------------------------------------------------------
    sub main
    
        Dim oRS
        Dim strCatsName
        Dim strCatsURL
        Dim strCmd
    
        if WScript.Arguments.Count = 1 then
    		if WScript.Arguments(0) = "/?" or WScript.Arguments(0) = "-?" then
    			Usage
    		    WScript.Quit(1)
    		end if
        end if
    
        if WScript.Arguments.Count < 1 then
            Usage
            wscript.Quit(1)
        end if
    
        strCatsName = GetPropUsingPKMCDO(wscript.arguments(0), cdostrURI_CategoriesFolder, true)
        strCatsURL = wscript.arguments(0) & "/" & strCatsName
        strCmd = "select ""urn:schemas-microsoft-com:office:office#Category"" from scope ('DEEP TRAVERSAL OF """ & strCatsURL & """') WHERE ""DAV:contentclass"" = 'urn:content-classes:categoryfolder'"
        Set oRS = ExecuteDBCmd("ADODB.Connection", "MSDAIPP.DSO", "ADODB.Command", strCmd, strCatsURL)
    
        Dim rgCat()
        cnt=0
    
        If Not oRS.BOF Then
                oRS.MoveFirst
                Redim rgCat(1)
                While Not oRS.EOF               
                    Redim preserve rgCat(cnt)
                        rgCat(cnt) = oRS.fields("urn:schemas-microsoft-com:office:office#Category").Value 
                    cnt = cnt+1
                    oRS.MoveNext
                Wend
        end if
    
        Wscript.echo "Categories for " & wscript.arguments(0) & " from WSS (not from the cache):"
        for i = 0 to UBound(rgCat,1)
            wscript.echo rgCat(i)
        next
        
        Wscript.echo
        Wscript.echo "Attempting to write the categories to WSS"
        Wscript.echo
    
        Set oRec = CreateObject("ADODB.Record")
        oRec.Open wscript.arguments(0) & "/system/schema/d_categories.xml", "url=" & wscript.arguments(0) & "/system/schema/d_categories.xml", 3
        oRec.Fields("urn:schemas-microsoft-com:publishing:dictionaryvalues") = rgCat
        oRec.Fields.Update
    
        Wscript.echo "Successfully saved the categories to WSS"
    
    end sub
    
    '+------------------------------------------------------------------------
    '
    '  Member:      Function ExecuteDBCmd
    '
    '  Synopsis:    Executes the command
    '
    '  Effects:
    '
    '  Arguments:   strConnectionObj:   Connection object to instantiate and use
    '               strProviderObj:     Provider object to use
    '               strCommandObj:      Command object to use
    '               strCmdText:         The command
    '               strURL:             The URL
    '
    '  Returns:     The RecordSet from the execution of the command
    '
    '  History:     01-06-2001                  Created
    '
    '  Notes:
    '
    '------------------------------------------------------------------------
    Function ExecuteDBCmd(strConnectionObj, strProviderObj, strCommandObj, strCmdText, strURL)
    
        Dim oCon
        Dim oCmd
        Dim oRS
    
        Set oCon = CreateObject(strConnectionObj)
    
        oCon.Provider = strProviderObj
    
        oCon.Open strURL
    
        Set oCmd = CreateObject(strCommandObj)
    
        oCmd.ActiveConnection = oCon
    
        oCmd.CommandText = strCmdText
    
        Set oRS = oCmd.Execute
    
        Set oCmd = Nothing
        Set oCon = Nothing
    
        Set ExecuteDBCmd = oRS
    
    end Function
    
    '+------------------------------------------------------------------------
    '
    '  Member:      Function GetPropUsingPKMCDO
    '
    '  Synopsis:    Gets the property from the row using PKMCDO
    '
    '  Effects:
    '
    '  Arguments:   strURL:  URL to bind to
    '               strProp: URI to get
    '               fLog: Log failures?
    '
    '  Returns:     Array collection of categories for this workspace.
    '               The array returned can be empty.
    '
    '  History:     01-06-2001                  Created
    '
    '  Notes:
    '
    '-------------------------------------------------------------------------
    Function GetPropUsingPKMCDO(strURL, strProp, fLog)
     
        Dim oDoc
        Dim oCon
    
        Set oDoc = CreateObject("CDO.KnowledgeDocument")
    
        Set oCon = CreateObject("ADODB.Connection")
        
        oCon.Provider = "MSDAIPP.DSO"
    
        oCon.Open "Provider=MSDAIPP.DSO; Data Source=" + strURL
    
        oDoc.DataSource.Open strURL, oCon, adModeRead
    
        GetPropUsingPKMCDO = oDoc.Property(strProp)
    
        Set oDoc = Nothing
        Set oCon = Nothing    
    
    end Function
    						
    Run the following command from a command prompt on the server:

    verifycatdict.vbs "http://server_name/workspace"

  2. Follow steps 1 through 3 in the "Diagnosing Category Dictionary Corruption" section of this article to verify that the list of categories from Querycats.vbs and Getcatdict.vbs are now identical.
  3. At this point, the corruption is fixed; however, the corrupted information may still exist in the cache on the server and client computers. If you restart the server, you update the cache with the correct information. If clients continue to see corrupted information, restart the clients as well.
  4. Apply the fix that is described in the "Applying the Fix" section of this article.

Applying the Fix

To resolve this problem, obtain the latest service pack for SharePoint Portal Server 2001. For additional information, click the following article number to view the article in the Microsoft Knowledge Base:

312963 How to Obtain the Latest SharePoint Portal Server 2001 Service Pack

The English version of this feature should have the following file attributes or later:

File nameVersion
Vaiddmgr.dll3914.11

STATUS

This problem was first corrected in SharePoint Portal Server 2001 Service Pack 1.

Modification Type:MinorLast Reviewed:9/26/2005
Keywords:kbHotfixServer kbQFE kbbug kbfix kbSharePtPortalSvr2001preSP1fix kbSharePtPortalSvr2001sp1fix KB300389