My current playlist of codin’ Music

Depending on how busy the day is, it’s always nice to do some deep coding (Rather than troubleshooting, being on the phone with support, and other distractions).  When I do, I have to have some tunes playing.

Just thought I’d share my current playlist I’m using while coding…

Everthing from the following artists/albums

4 StringsBelieve

4 StringsMainline

4 StringsTurn it Around

Armin Van Buuren  – 10 Years Disc 1 and Disc 2

Armin Van BuurenBurned with Desire   (Yeah, I know…It’s a remix CD of the same song, but I just dig that song too much :))

Otis ReddingThe Very Best of Otis Redding (Ok, Kinda different from the above, but someone I know has been asking me to play Otis for her quite often, and well..I got hooked on this classic.)

a-haHunting High and Low

a-haScoundrel Days

a-haStay on These Roads

a-haMinor Earth Major Sky

The CarsComplete Greatest Hits

Christopher FrankePacific Coast HIghway (My ABSOLUTE FAVORITE CD!!!)

DeleriumEuphoric EP

DeleriumKarma [UK Enhanced]

DeleriumPoem – [Limited Edition Bonus CD] Disc 1 and Disc 2

HoobastankThe Reason (Got to see them in concert opening up for Linkin Park with my oldest daughter)

RushChronicles Disc1 and Disc 2

Tangerine DreamLogos: Live at the Dominion (Probably my second favorite CD)

Bassic – Everything he’s ever done (All the way back from the mp3.com days to now)

Deep ForestDeep Forest

Deep ForestBoheme

Deep ForestComparsa

KraftwerkMinimum-Maximum Disc 1 and Disc 2

Mars LasarThe Eleventh Hour

The following are specific selections from some of my other favorite artists

Depeche Mode – Everything Counts [12″ Mix]

Depeche Mode – Get the Balance Right [Original 12″ Mix]

Depeche Mode – Love in Itself [Original 12″ Mix]

Depeche Mode – Stripped [Highland Mix]

Diana Krall – The Look of Love

Enigma – “Why!”

Tears for Fears – Woman in Chains

Roxy Music – More than This

Tangerine Dream – White Eagle

The Police – Wrapped Around Your Finger

Vangelis – Love Them [From Blade Runner]

Tangerine Dream/Bryan Ferry – Is Your Love Strong Enough

Tangerine Dream – Monolight (Yellow Part) from the Tangents box set, Disc 3

Metallica – Master of Puppets

Coldplay – Yellow

Just thought this would be interesting.  What’s in your list?

– Keith

Wherefore Art Thou Author?

Just discovered this and thought I would share

Ever site (web) within a site collection has a property called Author which is set to the account that created the site (Wether it be via the SharePoint UI, or the OM).  To the best of my knowledge, this is not exposed in the UI.  So for example, if I’m logged in a “John Doe” to a site, and create a subsite, the Author property of the new subsite will be set to “John Doe”.

The problem, is that if “John Doe” is ever removed from the site collection, accessing this property will result in a User not found exception such as the following:

Unhandled Exception: Microsoft.SharePoint.SPException: User cannot be found.
at Microsoft.SharePoint.SPUserCollection.GetByID(Int32 id)
at Microsoft.SharePoint.SPWeb.get_Author()

This doesn’t present itself as a problem by just using the SharePoint UI, but if you have custom code that inspects this property, be sure to add some additional exception handling.The problem, is that if “John Doe” is ever removed from the site collection, accessing this property will result in an exception.

To see an example of this problem, do the following:

  1. Create a new site collection
  2. Add a test account with Full Control to the root site (Web) of this site collection
  3. Login to that site as the test account, and create a subsite (Subweb in OM talk)
  4. Run the following sample code that dumps out the fields of the Author property
  5. As a site collection admin, or another account with rights to manage permissions, remove the test account from the site collection via  “People and Groups: All People”
  6. Run the following sample code again, and you’ll see it throw the exception when you try to access any of the fields of the property.

Sample Code

using System;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace WhereforeArtThou
{
    class Program
    {
        static void Main(string[] args)
        {
            // Open the site collection
            Console.WriteLine("Opening site");
            SPSite site = new SPSite(args[0]);

            Console.WriteLine("Access properties from the web");
            // Open the web via the URL passed in
            SPWeb web = site.OpenWeb();
            Console.WriteLine("web title: " + web.Title);
            Console.WriteLine("Author ID: " + web.Author.ID.ToString());
            Console.WriteLine("Author Name: " + web.Author.Name);
        }
    }
}

Is it a bug?  No, not really IMHO, just something to watch out for.  Besides, if the user is removed from the site collection, who is the author supposed to be replaced with?  Regardless of who it was replaced with, the property will no longer hold a valid value of the original author of the site.

Hope this helps!

– Keith

Exporting site content from a SharePoint Content Database for recovery purposes.

My good friend Todd Klindt pointed me to this posting written by Mark Jen which showed some sample code to export site content from a SharePoint Content Database directly.

!!! DISCLAIMER !!!!

Everyone who knows me, knows that I am TOTALLY AGAINST doing direct database calls to the SharePoint databases UNLESS it is for complete disaster recovery, or complete offline reporting.   This is one of the reasons DeliverPoint will NEVER have any direct SharePoint database calls in it.

For additional information, see the following Microsoft articles:

“Support for changes to the databases that are used by Office Server products and by Windows SharePoint Services”

http://support.microsoft.com/kb/841057/en-us

“SharePoint Database Access”

http://msdn.microsoft.com/en-us/library/bb861829.aspx

Do NOT run this code against Live SharePoint databases.

Ok, now with that out the way…The problem with Mark’s original code, is that it was written for V2 (WSS 2.0/SPS2003), not V3 (WSS 3.0/MOSS 2007).  Also, his query is targeted at specific files (such as .doc/.ppt/.etc).

With a couple of slight changes, I updated the query and code to work with a V3 content database, and also just have it export everything.

Since his code was also just a snippit, I’m placing an updated version  with complete source here.

// BEGIN SPDBEX.CS

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.IO;

namespace spdbex
{
    class Program
    {
        static void Main(string[] args)
        {
            // replace this string with your 

            // Sharepoint content DB connection string
            string DBConnString =
             "Server=DATABASESERVER;" +
             "Database=CONTENTDBNAME;Trusted_Connection=True;";

            // create a DB connection
            SqlConnection con = new SqlConnection(DBConnString);
            con.Open();

            // the query to grab all the files.
            SqlCommand com = con.CreateCommand();
            com.CommandText = "SELECT ad.SiteId, ad.Id, ad.DirName," +
                " ad.LeafName, ads.Content" +
                " FROM AllDocs ad, AllDocStreams ads" +
                " WHERE ad.SiteId = ads.SiteId" +
                " AND ad.Id = ads.Id" +
                " AND ads.Content IS NOT NULL" +
                " Order by DirName";

            // execute query
            SqlDataReader reader = com.ExecuteReader();

            while (reader.Read())
            {
                // grab the file’s directory and name
                string DirName = (string)reader["DirName"];
                string LeafName = (string)reader["LeafName"];

                // create directory for the file if it doesn’t yet exist
                if (!Directory.Exists(DirName))
                {
                    Directory.CreateDirectory(DirName);
                    Console.WriteLine("Creating directory: " + DirName);
                }

                // create a filestream to spit out the file
                FileStream fs = new FileStream(DirName + "/" + LeafName,
                    FileMode.Create, FileAccess.Write);
                BinaryWriter writer = new BinaryWriter(fs);

                // depending on the speed of your network,
                // you may want to change the buffer size (it’s in bytes)
                int bufferSize = 1000000;
                long startIndex = 0;
                long retval = 0;
                byte[] outByte = new byte[bufferSize];

                // grab the file out of the db one chunk
                // (of size bufferSize) at a time
                do
                {
                    retval = reader.GetBytes(4, startIndex, outByte, 0,
                        bufferSize);
                    startIndex += bufferSize;

                    writer.Write(outByte, 0, (int)retval);
                    writer.Flush();
                } while (retval == bufferSize);

                // finish writing the file
                writer.Close();
                fs.Close();

                Console.WriteLine("Finished writing file: " + LeafName);
            }

            // close the DB connection and whatnots
            reader.Close();
            con.Close();
        }
    }
}

// END SPDBEX.CS

Be sure to change the DATABASESERVER and CONTENTDBNAME for the connection string, then simply execute the C# compiler on your server as follows:

%WINDIR%\Microsoft.NET\Framework\v2.0.50727\csc /target:exe /out:spdbex.exe spdbex.cs

The code in Marks’ original form, does not allow you to specify any target directory etc, and just begins exporting in the CURRENT DIRECTORY you’re in for any root site, so be sure to run this from a directory/folder you create to hold the data from the root.

I’ll ping Mark and see if he’ll allow me to take that code and polish it up with other options (Such as site selection, specific folder targeting etc) if he doesn’t want to update it.

HTH

– Keith