Document ID Provider, the last one?

For a client of ours we wanted to create a Custom SP2010 Document ID Provider. For this provider I wanted to be able to adjust and configure it so I can use it for other customers also.
First I needed to know how to create a Document ID Provider and found that: Tobias Zimmergren had an excelent article on creating you own SP2010 Document ID Provider.

Next in order to create a unique sequenced number I immediatly thought of SQL Server. And found that Ton Stegeman had an equally usefull post on how to create your own SPDatabase object in a SharePoint Farm.

Now I was set to create “the last Document ID Provider” for SP2010 I was ever going to write. Perhaps not but still, it should suffice for a LOT of clients of us!

I wanted to end up with an admin page like this:



This should then result in this document id:



So how to do this?
Step 1
Create a Database with a Table where I can store my generated document id’s

CREATE TABLE [dbo].[scoped_docid](
	[id] [bigint] IDENTITY(1,1) NOT NULL,
	[scopeid] [uniqueidentifier] NOT NULL,
	[objectid] [uniqueidentifier] NOT NULL,
	[scopedocid] [bigint] NULL,
	[scope] [varchar](100) NULL,
	[generateddocid] [varchar](150) NULL,
	[listid] [uniqueidentifier] NULL,
	[webid] [uniqueidentifier] NULL,
	[siteid] [uniqueidentifier] NULL,
	[webapplicationid] [uniqueidentifier] NULL,
	[farmid] [uniqueidentifier] NULL,
	[created] [datetime] NULL,
	CONSTRAINT [PK_scoped_docid] PRIMARY KEY CLUSTERED
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

And a stored procedure to Get/Insert ID’s:

-- =============================================
-- Author:		Stef van Hooijdonk
-- Create date: juni 2010
-- Description:
-- =============================================
CREATE PROCEDURE GetNextScopedDocID
	-- Add the parameters for the stored procedure here

	@scopeid uniqueidentifier  ,
	@scope varchar(100),
	@itemid uniqueidentifier
AS
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;
	SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

	BEGIN TRANSACTION

	declare @result bigint
	declare @scopedindex bigint

	select @scopedindex=COALESCE([scopedocid],-1),@result=[id] from scoped_docid where [objectid] = lower(@itemid)

	if (@scopedindex is null)  begin
		-- coalesce for the first record will have MAX = null, and then we add 1
		select @scopedindex=COALESCE(MAX(scopedocid),0)+1 from scoped_docid where scope = lower(@scope)

		insert into [scoped_docid] (scopeid ,scope,objectid, scopedocid ) values( lower(@scopeid), lower(@scope),LOWER( @itemid), @scopedindex)
		select @result = SCOPE_IDENTITY()
	end
	COMMIT
	select @result as record,@scopedindex as docid
END
GO

There is more to it than this, but you can check out the downloads for all the details.
Step 2
Create an SPDatabase object for this Database, see the Ton Stegeman post!

Step 3
Create a Document ID Provider that uses this SPDatabase and generates Document ID’s based on some settings. What I did was generate the sequenced number in SQL and then format that in a method with the other variables. Generating a YEAR or DAY into a string is fairly easy.

Step 4
Create an Central Admin page to change the settings of our Document ID Provider ( see screenshot ).
You can use the SPFarm.Local.Properties to score your settings Farm Wide:

/// <summary>
/// The default farm wide scope setting for this DocumentProvider
/// </summary>
public ProviderScope Scope {
  get {
    ProviderScope result = ProviderScope.Farm;
    try {
      string setting = Settings.GetFarmSetting("CustomDocumentIDProvider.Scope");
      if (!string.IsNullOrEmpty(setting))
        result = (ProviderScope)Enum.Parse(typeof(ProviderScope), setting);
      }
    }
    catch (Exception exc) {
      LogException(exc);
    }
    return result;
  }
  set {
    Settings.SetFarmSetting("CustomDocumentIDProvider.Scope", value.ToString());
  }
}

The scope:

/// <summary>
/// Scopes for the Document ID Provider
/// </summary>
public enum ProviderScope {
	/// <summary>Farm wide scope</summary>
        Farm=1,
        /// <summary>Webapplication scope</summary>
        Webapplication = 2,
        /// <summary>SPSite/Site collection scope</summary>
        SiteCollection = 3,
        /// <summary>Site/Subweb (SPWeb) scope</summary>
        Site = 4,
        /// <summary>List scope</summary>
        List = 5,
        /// <summary>No scope</summary>
        None = 100
}

Downloads
Download solution
Download sources

How to use the solution

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: