Thursday, March 14, 2013

How to find SharePoint List and Libraries true Size?




Overview
I wanted to get size of list and libraries for my portal in a reporting fashion. For Publishing Portal site collection you can access the list and library size from site actions> under the Site Collection Administration group, you have access to “Storage space allocation”. This is great info. But not something I can consume the same information programmatically.
image
If you notice this page is server through /_layouts/storman.aspx. Further digging on this page gives me the inherited  name space “Microsoft.SharePoint.ApplicationPages.StorMan” which is obfuscated and hence not sure how this above data is retrieved.
 

Further exploration

So still hoping to find the little nugget that is producing this information, I started diggings in to the Content Database Stored Procedures.
Then I came across two interesting stored procedures: proc_GetListSizes and proc_GetDocLibrarySizes
Both stored procedures take the Site Collection GUID. When test ran, the result was the same as the above Storage space allocation page.
 

So what I did with these stored procedures?

I took these two stored procedures, ran against the content database of my portal site collection. Merged the results of both stored procedures. Used some rudimentary caching  to store and retain the results set. Now you can list or get size for your given SPList object in MB.

Warning

This is not recommended against the production system as this is not a Microsoft Supported operation. Also be aware that the results could be huge and may impact your system.

Well here is all you are waiting for… the code base:

I have tested this against the MOSS 2007 and have not had chance to validate for any other SharePoint versions yet.
  • I have also included the Web Lists Size GetWebSizeWithUnitMeasure().
  • I have also included the Lists Size GetListSizeInBytes().
  • Then I have also included a function to determined the best way to represent the size in Bytes or KB or MB or GB or TB DefineSizeWithUnitMeasure

Your calls examples

To get size of a list:
string SizeWithUnitMeasure;
double webSizeInBytes = GetWebSizeWithUnitMeasure(web, out withUnitMeasure);
//Use the SizeWithUnitMeasure to print with the measure.


To get size of a web:


string listSizeWithMeasure;
double listSizeInBytes = GetListSizeWithUnit(list, out listSizeWithMeasure);
//Use the listSizeWithMeasureto print with the measure.



Common Function




 




public static double DefineSizeWithUnitMeasure(double sizeInBytes, out string unitMeasure)
       {
           unitMeasure = "Bytes";
           double size = sizeInBytes;

           if (size > 1024)
           {
               size = sizeInBytes / 1024d;//KB
               unitMeasure = "KB";
           }
           if (size > 1024)
           {
               size = size / 1024d;//MB
               unitMeasure = "MB";
           }
           if (size > 1024)
           {
               size = size / 1024d; //GB
               unitMeasure = "GB";
           }

           if (size > 1024)
           {
               size = size / 1024d; //TB
               unitMeasure = "TB";
           }

           return size;
       }

       public static double GetWebSizeWithUnitMeasure(SPWeb web, out string withUnitMeasure)
       {
       
           double storageUsage = 0d;

           
           foreach (SPList list in web.Lists)
           {
               storageUsage += (double) GetListSizeInBytes(list);
           }
           


           string unitMeasure = "";
           double webSize = DefineSizeWithUnitMeasure(storageUsage, out unitMeasure);

           withUnitMeasure = string.Format("{0} {1}", webSize.ToString("f"), unitMeasure);

           return storageUsage;
       }
       

       


       public static double GetListSizeWithUnit(SPList list, out string withUnitMeasure )
       {
           double listSizeinBytes = (double) GetListSizeInBytes(list);
           string unitMeasure = "";
           double listSize = DefineSizeWithUnitMeasure(listSizeinBytes, out unitMeasure);

           withUnitMeasure=string.Format("{0} {1}", listSize.ToString("f"), unitMeasure);

           return listSizeinBytes;
       }



        public static long GetListSizeInBytes(SPList list)
        {
            long listSize = 0;

            string filter = string.Format("tp_id='{0}'", list.ID);

            DataTable myDataTable = GetCachedSiteCollectionListSizes(list.ParentWeb.Site);
            DataRow[] dataRows = myDataTable.Select(filter);

            if (dataRows.Length > 0)
            {
                listSize = (long)dataRows[0]["TotalSize"];
            }

            return listSize;
        }



        private static DataTable m_SiteCollectionListSizes;
        private static Guid m_SiteCollectionListSizesSiteID;

        private static DataTable GetCachedSiteCollectionListSizes(SPSite site)
        {
            if (m_SiteCollectionListSizes == null || m_SiteCollectionListSizesSiteID != site.ID)
            {
                m_SiteCollectionListSizes = GetSiteCollectionListSizes(site);
                m_SiteCollectionListSizesSiteID = site.ID;
            }

            return m_SiteCollectionListSizes;

        }

        private static DataTable GetSiteCollectionListSizes(SPSite site)
        {

            DataTable dataTable = GetDocLibSizes(site);
            //Combine both list and doc lib size results
            dataTable.Merge(GetListSizes(site));
            
            return dataTable;

        }

        private static DataTable GetDocLibSizes(SPSite site)
        {
           
            string connectionString = site.WebApplication.ContentDatabases[site.ContentDatabase.Id].DatabaseConnectionString;


           string storedProcName = "proc_GetDocLibrarySizes";
            
            System.Data.SqlClient.SqlConnection connection = null;
            System.Data.SqlClient.SqlDataReader reader = null;
            DataTable dataTable = null;
            
            try
            {
                connection = new System.Data.SqlClient.SqlConnection(connectionString);
                connection.Open();

                System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand(storedProcName, connection);
                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.Add(new System.Data.SqlClient.SqlParameter("@SiteId", site.ID.ToString()));

                reader = command.ExecuteReader();

                dataTable = new DataTable();
                dataTable.Load(reader);

            }
            finally
            {
                if (reader != null)
                    reader.Close();
                if (connection != null)
                    connection.Close();
            }
            return dataTable;
        }

        private static DataTable GetListSizes(SPSite site)
        {

            string connectionString = site.WebApplication.ContentDatabases[site.ContentDatabase.Id].DatabaseConnectionString;
            string storedProcName = "proc_GetListSizes";

            System.Data.SqlClient.SqlConnection connection = null;
            System.Data.SqlClient.SqlDataReader reader = null;
            DataTable dataTable = null;

            try
            {
                connection = new System.Data.SqlClient.SqlConnection(connectionString);
                connection.Open();

                System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand(storedProcName, connection);
                command.CommandType = CommandType.StoredProcedure;

                command.Parameters.Add(new System.Data.SqlClient.SqlParameter("@SiteId", site.ID.ToString()));

                reader = command.ExecuteReader();

                dataTable = new DataTable();
                dataTable.Load(reader);
               
            }
            finally
            {
                if (reader != null)
                    reader.Close();
                if (connection != null)
                    connection.Close();
            }
            return dataTable;
        }

No comments:

Post a Comment