Sunday, October 28, 2012

Count Keywords Occurance in a Directory

I searched google for a Word Counter, I wanted to read in files in a directory and output the number of times that word occurs in those files. So I created this command line application that takes an input file of keywords and then searches for those keywords in the local directory and prints out the "File - Keyword - Number of occurances".

I wrote this years ago, today I would have probably written it as a PowerShell script =)



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
namespace CountKeywords
{
    class Program
    {
        public static void Main(string[] args)
        {
            List<string> Keywords = new List<string>();
            StreamReader SR = File.OpenText(args[0]);
            string S = SR.ReadLine();
            while (S != null)
            {
                Keywords.Add(S.Trim());
                S = SR.ReadLine();
            }
            if (!string.IsNullOrEmpty(S))
                Keywords.Add(S.Trim());
            SR.Close();
            string AssemName = System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName;
            List<string> files =Directory.GetFiles(System.IO.Path.GetDirectoryName(AssemName)).ToList();
            foreach (string file in files)
            {
                SR = File.OpenText(file);
                string content = SR.ReadToEnd();
                foreach (string key in Keywords)
                {
                    if (!string.IsNullOrEmpty(content))
                    {
                        Regex reg = new Regex(key, RegexOptions.IgnoreCase);
                        MatchCollection mt = reg.Matches(content);
                        Console.WriteLine("{0},{1},{2}", file, key, mt.Count.ToString());
                    }
                }
                SR.Close();
            }
        }
    }
}

Tuesday, October 23, 2012

Leadership and Team Morale

Team Morale is a serious issue for all leaders to consider. The Masters of Project Management introduced me to a model I found applicable to my role of work and lined up with experience as to what causes work dissatisfaction and satisfaction. The model below is the result of a study:



Through this model we find that achievement and recongition triumph over company policy and administration which remain the strongest causes of dissatisfaction. As a leader it is important to target aspects of achieving success and warranted recognitioning whilst avoiding highly administrative policies so that these factors do not compound to create high dissatisfaction.

Negative Example:


I remember a position where the new assistant manager would discuss how new policies were going to be introduced and how everything would need to be checked by her (she was not a domain knowledge expert) and as things progressed her policies got more petty, you could only gain access to stationary by asking her directly as it was all locked in her desk.

The business owner was sold that this was an improvement but not that these policies were resolving any real quantifiable problems such as stationary abuse, this was not the case.

The staff unimously agreed they did not approve of the new policies, nor the assistant manager and the anger felt in the team was quite intense.

Positive Example:


On the opposite side my most positive working experience was at Bank of Queensland. Our manager ensured we were free of policies we had our own development network and sat outside the restrictions observed by most users, fridays always included a team event at lunch and end of month fridays included free achohol and snacks between 5-7pm. The product was put into production and it was a true feeling if achievement to get positive feedback when visiting branches and asking for comments. It had a true sense of achievement.

Also the boss routinely praised the team each morning for their effort and observed a 5 minute scrum each day. As a result I carry fond memories of Bank of Queensland and note the positive experience.

Conclusion:


I think the main observations which line up with Hertzberg's model is the fact that administrative policies only cause dissatisfaction and routine praise of staff performance along with real achievements will go much further than high pay or work environment. I think it is important for managers to routinely target these intrinsic motivators if they aim to excel in their role.

VIEMU for VS2010/12 Cheatsheet

Published by VIEmu this cheatsheet to keep around when learning VIM fortunately I almost never use it nowadays :-)


NeuroPower Framework to Effective Leadership

This blog is to provide an introduction to the NeuroPower framework and reduces a highly technical well referenced material into simple, yet real world examples. This framework will assist project managers in building effective teams that work in a harmonious network maintaining respect for each other.

Introduction:


Phycology is one of the oldest fields of study, there were notes on the reoccurrences of patterns within the brain since prior to Ancient Egypt. These studies linked phycology with religion but nevertheless represented patterns in behaviour and techniques for the modification of behaviour.

NueroPower combines the intellect of a master of Artificial Intelligence and Phycology to produce a logical representation of behaviour patterns and leaders can use this model to predict behaviour, allowing leaders to mitigate risk and create a harmonious team.

Tension and the Amygdala

This was best explained to me as a story; imagine for a moment that you are a bunny rabbit, nibbling at grass on a field, enjoying the breeze and flavour of your meal when a saber tooth tiger jumps out of the brush. At this point as a bunny your brain is flooded with adrenaline and your Amigyla takes over, making you run for your life, at the point when you are running, you have lost the ability to feel the breeze, enjoy a meal or little lone perform any mathematics. This is the amigyla taking over in times of high stress.

People will tolerate stress based on their level of maturity, stress prevails when person experiences their Amygdala taking over. The tension does not have to be life threatening for the amigyla to take over, once taken over this person is using a lower-brain and can no longer contribute fully to the situation. This diagram illustrate the Archetype (Nuero Rational) vs the Amygdala (Neuro Limbic) response to tension. Maturity controls which response is most likely to occur, people that are lower on the maturity will naturally respond with their Core Belief.

It is important to note that tension could be a conversation around work, a debate with your boss for example could be a trigger that will create tension as described and the response will depend on how the individual handles the tension, if it is a threat the Amygdala will take over and a Nuero Limbic response will be triggered.

Assumptions

For the neuropower framework to work for you, you must agree on the following assumptions. The published NeuroPower book properly references the sources for these assumptions but I will briefly summarise these:
  1. The brain is a massive neural network, it works as most neural networks by assigning more weight to a given input and therefore leading weights to a correct output. For example: If you like pizza more than pasta and you taste a new pizza which is so good you like it better than any pasta, your brain will re-weight pizza so that next time it is asked which it prefers, it will output "pizza".
  2. These networks do not change easily, this is why learning is a process which takes time and in larger neural networks such as the brain once this pattern has been defined the network can be mapped at a high level such as the ones provided by NeuroPower.
  3. Six Core Intelligence Centers, assume these 6 attributes define a person, these are the building blocks used to identify the archetypes, all people have these six core intelligence centers and the dominance of a certain intelligence centre over another is how the persons behaviour is defined at a high level, briefly I have summarised these as follows:
    1. i1 Empathy
    2. i2 Clarity
    3. c1 Spontanousity
    4. c2 Idealism
    5. p1 Logic
    6. p2 Drive
  4. Of the Six Core Intelligence Centers exists 3 pairs, c1/c2, p1/p2 and i1/i2. Of these pairs a person will find that one characteristic dominates over the other, this is because these parts are mutually exclusive when used, so a person cannot be experiencing empathy when clarity is sought (empathy requires experiencing another persons emotions which blurs clarity), equally one cannot be spontaneous when idealism is sought and one cannot be logically and planning when a high drive exists. This distinction allows the categorising of archetypes for a person will have an individual response to which Core Intelligence of the 3 pairs dominates. This leads us to the existence of 8 archetypes as 2 to the power of 3 is 8 and 8 combinations of these attributes exist.

Spiral Up, Spiral Down

The formula to spiral up is IPCIPC and the formula to spiral down is CPICPI .

This denotes that for a certain archetype when high amounts of tension are experienced, their C attribute will invert so a person who is predominately c1 will experience a dominance of c2, during times of stress and to spiral upwards the person will instead invert the I attribute for example from i1 to i2. This will require the person to be more connected with those around them and experience more i2 (empathy).


The Mirror

The existence of the subconscious is not usually debated, for this instance we need to identify two entities, ourselves and our active consciousness. As a person you discuss issues with your mirror, a person's mirror will be focusing on the issues that are opposite to their Archetype. If a person exhibits attributes that are c1, p1 and i1. Then they're mirror will be pre-occupied with issues of opposing attributes c2, p2 and i2. Due to the nature of the 6 Core Intelligence Centers and their mutually exclusivity the denominating attributes will mean that for a person whom is for example predominantly c1 - Spontanousity, their subconscious will focus on the attribute of c2 - Idealism. As a matter of personal development and fulfilment it is crucial for a person to not ignore their exlusive attribute but to continuously promote them and in this example, focusing on c2 - Idealism, will bring contentness to the individual. Ignore the c2 - Idealism attribute and drown it with c1 - Spontanousity will only cause unfulfillment.

One does not exhibit the subconsious whilst engaged in conversation with another person. Generally achetypes will find fulfilling conversations from individuals that exhibit attributes that match their mirror rather than their own.

NueroPower Models

NeuroPower provides 3 Models and I have summarised this diagram integrates them as follows:


The first layer are the 6 Core Intelligence Centers.

Maturity Model

Which runs on the left side of the model, simply illustrates that for a greater maturity a full archetype (or Nueral Rational) response will be given. This depends on the person's archetype. The five simple levels (there are more) are:

  1. Purple - The world is for the most part large and mysterious. You believe in the virtues of your family and contribute to their goals. As a child this is the first level of maturity above instinct
  2. Red - You understand the world and control your environment for yourself through aggression and submission.
  3. Blue - You believe in order and society, you maintain task lists and promote processes
  4. Orange - Where others see lemons you see lemonade. You focus on the future and focus on actions that will benefit your future
  5. Green - You believe that everyone has a place in the world, you recognize and contribute to goals for the benefit of the community

Core Belief

Many people accept the fact that the Amygdala responds to tension in three basic ways: fight, flight or distrust, NeuroPower adds further depth to this theory by breaking these into 3 subclasses for each primary reaction:
  1. Compliance - The person demands perfection, but those victimized feel judgement
  2. Compliance - The person feels they are a helper, the victims feel manipulated
  3. Fight - The person feels they are promoting a success image, the victim feels slimey lies
  4. Flight - The person feels like they need to be a "drama queen", the victim feels selfishness and avoidance.
  5. Flight - The person responds by hiding and breaking empathic connections with others, usually require distance or isolation, the victim feels avoidance.
  6. Compliance - The person sees pure logic, the victim feels like they are being accused of conspiring
  7. Fight - The person feels the need to display happiness, the victim feels a false happiness and deciet about the authenticity of the happiness.
  8. Flight - The person asserts their needs for boundaries and dominance, others will be bullied or feel bullied.
  9. Flight - The person will promote peace through submission, the victim will feel avoidance and false state of resolution.
Archetype Overview
  1. The Navigators mind is structured and visionary. These opposites create a person with a clear vision and the discipline and structure to achieve it. Regardless of their development Navigators are super-dependable and likes to be respected contributor of the community, a pillar of society. Very emotionally detached, Navigators are inflexible when it comes to discussing plans, directions, approaches and logistics. If they are not given warning, however, they can cope with flexibility and ambiguity and perform brilliantly 'on the hop'. This seems contradictory, but is achieved because they flip to their mirror. Navigators enjoy the very best quality in things and particular enjoy collecting things which will appreciate in value. Navigators are very focused when their is a clear vision, executing enormous mind over matter, supressing unwanted emotions and disciplining themselves and the people around them. They will follow systems to the letter of the law, any shortcutting or variance from approves process will be stopped and the perpetrator reprimanded. The Navigators way is the right way and they will want an audit trail to demonstrate compliance. If the Navigator has no vision or plan to follow, they freewheel and become obsessed with experiencing life, experiencing every form of physical sensation.
    • Idealism, Logic, Clarity
  2. The Chancellors are enthusiastic, energetic and ambitious. They have an unmatched ability to sell ice to Eskimos and have the Eskimos thank them, pay for their airfare and invite them back. Regardless of level of development Chancellors like competition, negotiation and rising to the top. Chancellors are excellent at creating a successful image. They rarely look concerned and appear to have the perfect lifestyle, living in the right suburbs, driving the right cars and holidaying in the right places.
    • Spontanousity, Drive, Empathy
  3. The Architects mind is able to see the big picture and the sequential order of activity required to achieve a given outcome. By nature they think in terms of flow charts. Although they usually feel more comfortable supporting the leadership rather than taking a high profile, they have no hesitation in stepping up to the line and outlining the most efficient way of achieving the desired outcomes if they leadership seems to be hesitating. Even though Architects are rational and calm, they are ambitious and driven to achieve whatever goals they have set themselves. All their activity must be another step towards achieving their objectives. For the Architect work is work and play is work. Everyday they expect to closer to their planned outcomes. Very emotionally detached, the Architect rarely gives positive feedback to those living or working with them. Others sometimes think of them as removed or distant and sometimes find it difficult to understand why they run hot and cold. Architects are brilliant at strategic systems and will instantly see why a system isn't working and what can be done about it.
    • Idealism, Logic, Empathy
  4. The Judges mind is fast, efficient, clear, certain and razor sharp. It can remember details and likes to keep discussions concrete, ideas practical and tasks specific. It is driven by a constant desire to complete large amounts of work. While quality is important, Judges enjoy following efficient systems that enable them to do two days work in one. Constantly changing, refining and improving systems is an annoyance to Judges who prefer to 'get on with it'. Regardless of level of development, Judges like working quickly and efficiently in an area of personal interest where they are recognised and rewarded financially. Emotionally passionate, Judges see strong relationships as being central to achievement and will protect those they are responsible for, defend those they respect and confront those they believe are wrong. They do not, however have an abiding trust in their leaders and so constantly ask hard questions to 'keep the bastards honest'. They often join social clubs or groups and enjoy meeting new people and doing the 'right thing'. They are energetic, enthusiastic, focused and quick working and have an excellent eye for ensuring all the details are right and lose ends are tied up.
    • Spontanousity, Drive, Clarity
  5. The Crusaders (White Knight archetype) are passionate, disciplined and dependable protectors of morality, justice and honesty. They are defenders of what is true and correct. With a clear sense of what is 'right', Crusaders work long hours doing many of the tasks that the rest of us take for granted - cleaning, maintenance work, completing checks and audits, checking the quality is right, rechecking figures and finalizing project plans or lesson outlines or doing whatever it takes to get it right or as close to perfect as possible. Crusaders respect rules quality management and accepted procedures. They respect authority and established protocol. Serious, stern-looking and always ready to correct others, Crusaders are by nature frugal, independent, reliable conservative and task oriented. They teach us the true meaning of honour and in team foster commitment from others.
    • Idealism, Drive, Clarity
  6. The Commanders are inventors by nature and have an unquenchable thirst for knowing how things work. They love challenge, variety and new and interesting problems to solve. They get frustrated and demotivated by routine. Regardless of development, Commanders like to work to a system that is efficient and practical. If 'the way it has always been done' does not achieve this, the Commander will not hesitate to redesign the system or rewrite the handbook. Commanders are usually easy-going with a childlike curiosity and a fascinating general knowledge about just about everything. They are gregarious, party animals that enjoy having fun and forgetting the time. They are rational and systematic and can take over command in a real crisis. Commanders will often create problems to solve when things become to routine, this cycle of creating and solving problems seriously limits their ability to accumulate wealth.
    • Spontanousity, Logic, Empathy
  7. The Bards have a unique ability to see potential in others and create environments that empower them or enable them to reach their full potential. They have a natural fascination with their own quest for meaning, the purpose of life and the deeper and more mystical parts of life.  Bards can inspire with their amazing ideas and big dreams, their zest for life and their optimism, passion and warmth. For the Bard everything is interdependent, so their home and work lives will merge as will their various business ventures, their ideas and philosophies. This can sometimes mean that relatively small issues are combined to create large, complex and difficult situations. When this happens the Bards can see that any movement will impact on so many areas that they can become paralysed for fear of upsetting the status quo. Bards are very sensitive and 'pick up' the feelings of others. This can mean that the internal emotions of Bards are greatly affected by the people around them.
    • Idealism, Drive, Empathy
  8. The Treasurers mind is highly intellectual, analytical and detailed, with an excellent memory for facts. This personality has an outstanding ability to analyse situations and has a calm and detached approach to life. Treasurers are not judgemental, are slow to anger and are naturally intrigued by money, scorecards and balance sheets. They have an inbuilt fascination with the game of life. Regardless of level of development, Treasurers like order and organisation. Their mind naturally separates their life into different compartments. The way they interact with a colleague at work and at home therefore can be quite different, with work issues kept at work and leisure issues kept for leisure time. Self-sufficient emotionally, with or without company, Treasurers love excitement, activity and crisis.
    • Spontanousity, Logic, Clarity

From here...

There is a lot of content on this subject, specifically the 4 maxims that form NeuroPower are not covered in depth in this article but rather portions of introduced. Thus I recommend if you have questions or would like a deeper understanding to buy the book called NueroPower by Peter Burow. There are also courses and certifications on the framework which I believe would help anyone not just at work but also in giving clarity to personal relationships.

Monday, October 22, 2012

Recursive T-SQL Backup All Databases Script

I had this script running as a job on my production server.


I had to modify this script to include a TRY-CATCH block so that if a backup command failed it will continue on to the next database and not exit the script. This was an issue with the script that I had to resolve. 

DECLARE @name VARCHAR(50) -- database name DECLARE @path VARCHAR(256) -- path for backup files DECLARE @fileName VARCHAR(256) -- filename for backup DECLARE @fileDate VARCHAR(20) -- used for file name -- specify database backup directory SET @path = 'C:\Backup\' -- specify filename format SELECT @fileDate = CONVERT(VARCHAR(20),GETDATE(),112) DECLARE db_cursor CURSOR FOR SELECT name FROM master.dbo.sysdatabases WHERE name NOT IN ('master','model','msdb','tempdb') -- exclude these databases OPEN db_cursor FETCH NEXT FROM db_cursor INTO @name WHILE @@FETCH_STATUS = 0 BEGIN SET @fileName = @path + @name + '_' + @fileDate + '.BAK'
BEGIN TRY BACKUP DATABASE @name TO DISK = @fileName END TRY BEGIN CATCH -- Execute error retrieval routine. EXECUTE usp_GetErrorInfo; END CATCH FETCH NEXT FROM db_cursor INTO @name END CLOSE db_cursor DEALLOCATE db_cursor

Erlang Cheatsheet

For my own benefit and of any others out of convenience. This is a useful Erlang Cheat sheet with some common commands.

.NET Framework Posters & ASP.NET Page Lifecycle Poster

Some handy .NET Framework posters to hang around the office and also a ASP.NET page lifecycle poster:



Saturday, October 20, 2012

SharePoint - Delete Manager from UserProfile

Today's task revolved around removing the Manager I set when testing the profile pages on the my site portal. I had set the manager on a service account so it had to be removed to stop appearing as a colleague to team members and potentially exposing a security risk in giving away the service account username.

Setting it is possible directly from the Organisational View page that comes as part of the site template. There is a link called "Set My Manager", which allows you to set the current UserProfile's manager. Once set though I wanted to remove this profile.

Unfortunately, there is no way for the user to remove their manager only set the manager. So only an administrator can remove the manager.

Initially, being a powershell fanatic. I tried to remove the manager using the object model using the following powershell commands:

$site = get-spsite http://localhost
$context = Get-SPServiceContext $site
$mgr = new-object "Microsoft.Office.Server.UserProfiles.UserProfileManager" -ArgumentList $context
$enum = $mgr.GetEnumerator()
do {$enum.MoveNext();$usr = $enum.Current} until ($enum.Current["AccountName"] = "domain\username")

The following commands failed to remove the manager from the UserProfile:


$usr.Parent = $null     //Throws exception: "Setting Parent of a UserProfile is not allowed via OM."

$usr.Properties.RemovePropertyByName("Manager") // Throws exception: "Property update's Stored Procedure call returned an error. Error Code: 4. Errors removing P propert"

Funny, most things can be done easier through powershell. But in this instance Central Admin did the trick!

Central Administration -> Application Management -> Manage Service Applications -> User Profile Service (click Manager) -> Manager User Profiles.

Using "Find profile" enter the account name, and select "Edit My Profile" from the drop down when selecting the account. From this page you can change the manager and set it to nothing and click "Save and Close" to apply the new value.

That's it! There is no single way to manage Sharepoint, you need to know all the tools available as some have strengths over others. Central Admin wins over powershell on this one for user-friendlyness (it just worked).

T-SQL script to pull Active Directory Users

This script allowed us to query AD and pull all the users into our asp_net membership system. Its a handy script and shows some real strengths of using T-SQL.


set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go



CREATE PROCEDURE [dbo].[config_PullADUsers]
            -- Add the parameters for the stored procedure here
            @LDAProot nvarchar(MAX) 
AS
BEGIN
            -- SET NOCOUNT ON added to prevent extra result sets from
            -- interfering with SELECT statements.
            SET NOCOUNT ON;
                       
            if exists (select * from tempdb.dbo.sysobjects where id = object_id('tempdb.dbo.#ldap'))
            drop table #ldap

            create table [dbo].[#ldap] (
                        [row_id] [int] IDENTITY (1, 1) NOT NULL , 
                        [userAccountControl] nvarchar(512), 
                        [objectSid] nvarchar(256), 
                        [objectSidSddl] nvarchar(256) collate Latin1_General_CI_AS_KS_WS, 
                        [samAccountName] nvarchar(256), 
                        [userPrincipalName] nvarchar(256),
                        [userPrincipalNameLower] nvarchar(256)
            )

            DECLARE @ADQLast nvarchar(MAX)
            DECLARE @ADQ nvarchar(MAX)
            SET @ADQLast = NULL

            WHILE 1=1
            BEGIN

                        IF (@ADQLast is NULL)
                        BEGIN
                                    SET @ADQ = 'SELECT userAccountControl, objectSid, samAccountName, userPrincipalName 
                                    FROM '''+@LDAProot+'''
                                    WHERE objectCategory=''user''
                                    ORDER BY samAccountName ASC'
                        END
                        ELSE
                        BEGIN
                                    SET @ADQ = 'SELECT userAccountControl, objectSid, samAccountName, userPrincipalName 
                                    FROM '''+@LDAProot+'''
                                    WHERE objectCategory=''user''
                                    AND (samAccountName > '''+@ADQLast+''')
                                    ORDER BY samAccountName ASC'
                        END

                        SET @ADQ = REPLACE(@ADQ, '''', '''''')

                        --INSERT INTO @TempA
                        --                       master.dbo.fn_sqlvarbasetostr([objectSid]), 
                        EXEC('INSERT INTO #ldap ([userAccountControl], [objectSid], [objectSidSddl],[samAccountName], [userPrincipalName], [userPrincipalNameLower]) 
                                     SELECT TOP 100 [userAccountControl],
                                     master.dbo.fn_sqlvarbasetostr(objectSid) AS objectSid, 
                                     [SigmaPlant].[dbo].[SID_hextosddl] (master.dbo.fn_sqlvarbasetostr(objectSid)) AS objectSidSddl,
                                     [samAccountName], [userPrincipalName], lower([userPrincipalName])
                                     FROM OPENQUERY(DCSERVER, '''+@ADQ+''')
                                     WHERE ((userAccountControl & 2) = 0)
                                     AND (userPrincipalName is not null)')

                        IF @@rowcount >= 100
                        BEGIN
                                    SELECT TOP 1 @ADQLast=[samAccountName] FROM #ldap ORDER BY [samAccountName] DESC
                        END
                        ELSE
                        BEGIN
                                    BREAK
                        END
            END

            DECLARE @UserCount bigint

            --SELECT * FROM #ldap ORDER BY [samAccountName] ASC
           
            SET @UserCount = (SELECT COUNT(UserId) FROM aspnet_Users)
           
            INSERT INTO aspnet_Users ([ApplicationId], [UserName], [LoweredUserName], [IsAnonymous], [Enabled], [SuperUser], [ADSID], [LastActivityDate])
            SELECT (SELECT TOP 1 [ApplicationId] FROM (SELECT DISTINCT TOP 1 [ApplicationId], COUNT([UserId]) AS UserCount FROM aspnet_Users GROUP BY [ApplicationId] ORDER BY COUNT([UserId]) DESC) A),
            [userPrincipalName], [userPrincipalNameLower], 0, 1, 0, [objectSidSddl], GETDATE() 
            FROM #ldap 
            WHERE (NOT ([objectSidSddl] IN (SELECT ADSID 
                                                                                                            FROM aspnet_Users 
                                                                                                            WHERE (ADSID IS NOT NULL))))
           
            SET @UserCount = (SELECT COUNT(UserId) FROM aspnet_Users) - @UserCount
           
            RETURN @UserCount

            --------
            --http://blog.tech-cats.com/2007/11/getting-enabled-disabled-active.html
            --SELECT samAccountName, userAccountControl, objectSid, userPrincipalName, SN, mail, ADSPath, distinguishedName
END

SharePoint PageLayout MissingMethodException and ErrorWebPart

PART 1 (FIX IN PART 2):

Another SharePoint boggling issue. I defined a Page Layout as illustrated below. It has two columns left and right with 80% and 20% width respectively. When deploying this page on my local system I found that creating a page resulted in an error. Entering web part maintenance mode on the pagelayout page revealed there were several ErrorWebPart components listed for my page layout? At the moment I do not have time to investigate why or how they are there. But removing these through the maintenance protal fixed the defect. If I get around to tracing the source of the issue I will post. Hopefully the latest cumulative update will prevent this sort of defect from occuring!


 <%@ Page ClassName="BOQTwoColumnPageLayout" AutoEventWireup="true"  language="C#"   Inherits="Microsoft.SharePoint.Publishing.PublishingLayoutPage,Microsoft.SharePoint.Publishing,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePointWebControls" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="PublishingWebControls" Namespace="Microsoft.SharePoint.Publishing.WebControls" Assembly="Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="PublishingNavigation" Namespace="Microsoft.SharePoint.Publishing.Navigation" Assembly="Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<asp:Content ID="Content1" ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">
 <SharePoint:ProjectProperty ID="ProjectProperty1" Property="Title" runat="server"/>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderId="PlaceHolderMain" runat="server">
 <table cellspacing="0" border="0" width="100%">
   <tr class="s4-die">
    <td class="ms-pagebreadcrumb">
    <asp:SiteMapPath SiteMapProvider="SPContentMapProvider" id="ContentMap" SkipLinkText="" NodeStyle-CssClass="ms-sitemapdirectional" runat="server"/>
    </td>
   </tr>
   <tr>
  <td>
   <table width="100%" cellpadding="0" cellspacing="0" style="padding: 5px 10px 10px 10px;">
    <tr>
     <td valign="top" width="80%">
      <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Left" Title="loc:Left" >
      </WebPartPages:webpartzone>&#160;
     </td>
     <td>&#160;</td>
     <td valign="top" width="20%">
      <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Right" Title="loc:Right" >
      </WebPartPages:webpartzone>&#160;
     </td>
     <td>&#160;</td>
    </tr>
   </table>
  </td>
   </tr>
 </table>
</asp:Content>


PART 2 (INCLUDES FIX):


Turns out that the source of the error was in my definition of the Page Layout, which was creating 3 ErrorWebPart's. I had a second Content panel for the breadcrumb which I simply removed to resolve one ErrorWebPart. The other is that my web part zones didn't have a zonetemplate. Adding an empty "ZoneTemplate" to the left and right web part zones resolved the remaining 2 ErrorWebPart's. I have also copy-pasted my Elements.xml just in case for others to use =D.


PageLayout.aspx

 <%@ Page ClassName="BOQTwoColumnPageLayout" language="C#"   Inherits="Microsoft.SharePoint.Publishing.PublishingLayoutPage,Microsoft.SharePoint.Publishing,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" meta:webpartpageexpansion="full" meta:progid="SharePoint.WebPartPage.Document" %>
<%@ Register Tagprefix="SharePointWebControls" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="PublishingWebControls" Namespace="Microsoft.SharePoint.Publishing.WebControls" Assembly="Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="PublishingNavigation" Namespace="Microsoft.SharePoint.Publishing.Navigation" Assembly="Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<asp:Content ID="Content" ContentPlaceHolderId="PlaceHolderMain" runat="server">
 <table cellspacing="0" border="0" width="100%">
   <tr>
  <td>
   <table width="100%" cellpadding="0" cellspacing="0" style="padding: 5px 10px 10px 10px;">
    <tr>
     <td valign="top" width="80%">
      <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Left" Title="loc:Left" >
      <ZoneTemplate></ZoneTemplate>
      </WebPartPages:webpartzone>
     </td>
     <td valign="top" width="20%">
      <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Right" Title="loc:Right" >
      <ZoneTemplate></ZoneTemplate>
      </WebPartPages:webpartzone>
     </td>
    </tr>
   </table>
  </td>
   </tr>
 </table>
</asp:Content>

ELEMENTS.XML


<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/ ">
  <Module Name="PageLayout" Url="_catalogs/masterpage">
  <File Path="PageLayout\BOQTwoColumnLayout.aspx" Url="BOQTwoColumnLayout.aspx" Type="GhostableInLibrary">
    <Property Name="Title" Value="BOQ TwoColumn Layout" />
    <Property Name="ContentType" Value="$Resources:cmscore,contenttype_pagelayout_name;" />
    <Property Name="PublishingPreviewImage" Value="~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/CustomPageLayout.png, ~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/CustomPageLayout.png" />
  </File>
</Module>
</Elements> 

Install/Migrate a New SharePoint Farm 2010 "Got Ya's"

This is a short-sweet post of the problems we experienced when reinstalling our SharePoint Farm, we've all setup SharePoint 2010 locally as a single server SharePoint farm, with no glitches or hiccups from the automated installer. But when installing SharePoint on a 4 server farm we had some hiccups that I thought I might jot down for future reference and anyone else who has the luxury of running into some of these issues:

Some prerequisites we had setup from our previous farm:
1. An instance of SQL Server running and db_owner role by our domain "SPSetup" account.
2. 4 VM's excluding the database server running WIN2k8 R2 with "SPSetup" having full access on those too.
3. A seperate "Svcspfarm" account with less access to the rest of the network =), (refer to msdn for better articles on permission setups we had ours configured by Hewlett-Packard).
4. Experience installing SharePoint, there are plenty of A,B,C guides on installing so I won't cover that here, just some issues and resolutions.

The issues
1. A simple but strange issue some machines without User Access Control would not prompt to reboot after installing SharePoint or service application. I suggest after each of these you simply restart the server. Espicially restart after running the Product Configuration wizard.
2. The Managed Meta Data Service needed to be started manually using Central Administration, some service applications will start straight away others won't, this is one.
3. Identity Manager, our Managed Service Account needed more permissions on Active Directory. Our "SPSetup" account did not have sufficient permissions to access AD properly. Fortunately the svcspfarm account did.
4. ***** User Profile Service was impossible to setup via "Central Administration" with all sorts of errors. Setting it up via PowerShell resulted in no hiccups!?! Just a big warning for everyone that there is a difference and some additional parameters resulted in no errors when done through powershell.

That's it. We we're ready to spend the whole weekend but 6 hours later we had a running SharePoint farm with all old packages reinstalled and 2GB site collection backups restored.

SharePoint 2010: How To Enable the Developer Console

This is a powershell script that will enable the developer console on a sharepoint farm:
$consoleSettings =[Microsoft.Sharepoint.Administration.SPWebService]::ContentService.DeveloperDashboardSettings
$consoleSettings.DisplayLevel = "OnDemand"
$consoleSettings.RequiredPermissions = "EmptyMask"
$consoleSettings.TraceEnabled = $true
$consoleSettings.Update()
Short but sweet, now once you visit your SharePoint site you will see a diagnostics icon next to your username on the top bar.

In case you receive errors saying that PowerShell could not find the type Microsoft.Sharepoint.Administration.SPWebService, load the SharePoint dll using following command:
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

Enable PowerShell Remoting with Client Outside of Server's Domain (Trusted Host and Double Hop Issue)

To enable remote powershelling with servers not in the same domain as the client machine you will need to perform the following steps:
Note: Do not allow unencrypted communication for internet use.

On the client PC type:
PS c:\users\root> cd wsman:localhost\Client
PS WSMan:\localhost\Client> Set-Item AllowUnencrypted -Value $true -force
PS WSMan:\localhost\Client> Set-Item TrustedHosts -Value * -force

On the server PC type:
PS c:\users\root> Enable-PSRemoting
Then using regedit set the key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Service\allow_unencrypted to 0x00000001



To connect from the client type:
PS WSMan:\localhost\Client> New-PSSession -name Server01 -computername boqsource -credential boq\spsetup  -Port 5985
PS WSMan:\localhost\Client> Enter-PSSession Server01

You should be on a command line on your server!

To add Sharepoint commands to your shell type:
[server] c:\> Add-PSSnapin Microsoft.Sharepoint.Powershell
Now you can execute any SP cmdlets!
But wait, you get access denied to the farm :O. This is due to a known issue in the double hop of credentials. My server credentials are different to my client credentials and my Powershell is using my client credentials. The solution is to configure CredSSP authentication.

Here are the steps to enable CredSSP on the server:

1. Login to your server.
2. In powershell type: PS C:\> Enable-WSManCredSSP -Role Server

Here are the steps to enable CredSSP on the client:
1. Enable CredSSP through powershell by typing: PS C:\> Enable-WSManCredSSP -Role Client -DelegateComputer <FQDN of the server>
2. Run "gpedit.msc" drill down: Local Computer Policy > Computer Configuration > Administrative Templates > Credentials Delegation > Allow Delegating Fresh Credentials with NTLM-only.
3. Enable "Allow Delegating Fresh Credentials with NTLM-only" and click "Show" next to "Add servers to list:". Add the server "WSMAN/*" this will add all servers, you can be specific if you wish.
4. Apply the new policy and click Start -> Run -> and type: "gpupdate"


Logging in using CredSSP:
PS C:> Enter-PSSession server -Authentication CredSSP -Credential (Get-Credential)
[server]: PS C:> Add-PSSnapin Microsoft.Sharepoint.Powershell
alternatively, put this into a ps1 script file:

$session = New-PSSession -Name server -ComputerName server -Authentication CredSSP -Credential (Get-Credential)
Invoke-Command -Session $session -ScriptBlock { Add-PSSnapin Microsoft.SharePoint.PowerShell }
Enter-PSsession $session

Now you have full access to the server and Sharepoint cmdlets!! Phew.

SharePoint AAM Storage Location

Recently, I had changed the AAM on the production farm. Shortly after I rolled back the configuration database but alas the old settings were still there.

I desperately began looking for the storage location of the AAM settings. I found very little information on google and thought that it would be good to post regarding this issue. Fortunately microsoft does have a KB article on the matter, but it was not easy to find.

So a little extra under the bonnet information when it comes to SharePoint. The AAM configuration does live in the Configuration Database, so why didn't it update on restore?

The answer lies with the WFE which also caches these values, Central Administration also displays the values from the cache and not the configuration database...In the event that they are out of sync you need to nuke the WFE by deleting the cache folders and allowing them to rebuild/refresh. Then your new settings will apply.

Also I found that whilst this was an issue I could not change the AAM settings, this is where I found the KB article.

http://support.microsoft.com/kb/939308

The database stores only one XML string for each application containing the AAM configuration.

The following SQL queries will let you find the Alternate Access Mapping settings in the configuration database stored in the table dbo.Objects:


SELECT

[Id],[ClassId],[ParentId],[Name],[Status],[Version],[Properties]
 FROM [StaffNetTest_ConfigDB].[dbo].[Objects]
 Where Properties like '<object type="Microsoft.SharePoint.Administration.SPAlternateUrlCollection%'
GO

Thursday, October 18, 2012

SQL 2005/2008 Query Current Version and Configuration Settings

This T-SQL query will list the current SQL version and configuration settings for the current instance for SQL Server:  
 
sp_configure 'show advanced options', 1
reconfigure
GO
sp_configure
GO
SELECT SERVERPROPERTY('productversion') as ProductVersion
SELECT SERVERPROPERTY ('productlevel') as Level
SELECT SERVERPROPERTY('edition') as EDITION
SELECT @@VERSION as VERSION

Mnesia - Create a Fragmented Table

I have created and worked with fragmented tables before. But not having done so in so long it took abit of effort to remember how to do it without looking at my old source code.

Ignore the delete and create schema, you will need to fix these if you want to turn this into a real database as it may delete your database if your not careful when you run install()!

This simple fragmented test table will allow you to create new users calling the add_user() function with a username/password/email address. Keep in mind you can only create the table as type bag or set for disc based tables. There are third party efforts to create a disc based ordered_set (tcerl is one that I use), but these are not straight forward to setup and not part of the OTP framework.

The tuple we have added is frag_properties for the mnesia:create_table function this allows us to configure this table as a fragmented table. In this case the node_pool consists of only this node retrieved by node() function call. 20 fragments specified by n_fragments and 1 disc copy of each fragment specified by n_disc_copies. There are more options and more complex configurations, these depend on the task at hand so it is best to use the reference manual. This code is just a example of one way you can create a new fragmented mnesia table.

-module(test).
-export([install/0,add_user/3]).

-record(user,{username,password,email}).

install() ->
    mnesia:delete_schema([node()]),
    mnesia:create_schema([node()]),
    mnesia:start(),
    io:format("ok\n",[]),
    mnesia:create_table(user,
        [
            {frag_properties,
                [
                {node_pool,[node()]},
                {n_fragments,20},
                {n_disc_copies,1}
                ]
            },
            {attributes,record_info(fields,user)},
            {type,bag}
        ]
    ).
    

add_user({user,Name},{pass,Password},{email,Email}) -> 
    ok = mnesia:activity(async_dirty,fun() -> mnesia:write(user,#user{username=Name,password=Password,email=Email},write) end,[],mnesia_frag).
Further details on the options available regarding fragmented table properties can be found here in the official mnesia documentation: http://www.erlang.org/doc/apps/mnesia/Mnesia_chap5.html#Fragmentation%20Properties

T-SQL Script Detach, Move & Attach

One of my tasks recently involved moving the physical files from a set of MSSQL databases from one partition to another.

There were a number of databases so I created the following script in order to detach, move and re-attach the databases.

This script was used to move databases on the same box. But I believe with the use of a Linked Server, a mapped drive and a nice OPENQUERY on the linked server you could adapt this script to move this to another server as well. I don't have that itch at the moment, but if it does come up I will make another post with the updated script (otherwise if you make the change please share!)

DECLARE @name VARCHAR(50) -- database name  
DECLARE @nameDB VARCHAR(50) -- database name  
DECLARE @nameLog VARCHAR(50) -- database log name  
DECLARE @path VARCHAR(256) -- path for backup files  
DECLARE @fileNameDB VARCHAR(256) -- filename for backup
DECLARE @fileNameLog VARCHAR(256) -- filename for backup  
DECLARE @destinationPath VARCHAR(256) -- new path for db
DECLARE @dbid bigint -- db id
DECLARE @enableCMDPermanently bit

-- ============USER CONFIGURABLE VARIABLES START=============
SET @path = 'D:\Databases\'   -- Destination Path for all Databases
SET @enableCMDPermanently = 1
-- ============USER CONFIGURABLE VARIABLES FINISH============



-- =====Please do not edit variables below this line=========


-- Enabled CMD from T-SQL Script
EXEC master.dbo.sp_configure 'show advanced options', 1
RECONFIGURE
EXEC master.dbo.sp_configure 'xp_cmdshell', 1 -- enable CMD
RECONFIGURE


-- Table variable for name/id key/values
DECLARE @sysdb TABLE
(
 dbname nvarchar(max),
 database_id bigint
)
INSERT INTO @sysdb (dbname,database_id) SELECT [name],[dbid] FROM master.dbo.sysdatabases WHERE name NOT IN ('master','model','msdb','tempdb')  
 
-- Table variable for db file details
DECLARE @sysfiles TABLE
(
 dbname nvarchar(max),
 physical_name nvarchar(max),
 database_id bigint,
 type_desc nvarchar(max)
)
INSERT INTO @sysfiles (dbname,physical_name,database_id,type_desc) SELECT [name], [physical_name],[database_id],type_desc FROM sys.master_files

-- Start CURSOR to iterate through database ids
DECLARE db_cursor CURSOR FOR SELECT [database_id] FROM @sysdb
OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @dbid   

-- BEGIN LOOP
WHILE @@FETCH_STATUS = 0   
BEGIN
 --Read DB Details & File Locations
 PRINT @dbid
 SET @name = (SELECT [dbname] FROM @sysdb WHERE database_id = @dbid)
 PRINT @name
 SET @nameDB = (SELECT [dbname] FROM @sysfiles WHERE [database_id] = @dbid AND [type_desc] = 'ROWS')
 SET @fileNameDB = (SELECT [physical_name] FROM @sysfiles WHERE [database_id] = @dbid AND [type_desc] = 'ROWS')
 PRINT @fileNameDB
 SET @nameLog = (SELECT [dbname] FROM @sysfiles WHERE [database_id] = @dbid AND [type_desc] = 'LOG')
 SET @fileNameLog = (SELECT [physical_name] FROM @sysfiles WHERE [database_id] = @dbid AND [type_desc] = 'LOG')

 DECLARE @cmd nvarchar(500) -- temp string for dynamic sql queries
 
 -- Force Disconnect Active Connections to Database
 SET @cmd = 'ALTER DATABASE ' +  quotename(@name) + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE'
 PRINT @cmd
 EXECUTE sp_executesql @cmd

 SET @cmd = 'ALTER DATABASE ' +  quotename(@name) + ' SET OFFLINE WITH ROLLBACK IMMEDIATE'
 PRINT @cmd
 EXECUTE sp_executesql @cmd
 
 -- Point DB to new file location
 SET @cmd = 'ALTER DATABASE '+ quotename(@name) +' MODIFY FILE ( NAME = '+quotename(@nameDB)+', FILENAME = '+quotename(@path + @nameDB  + '.mdf')+ ' )'
 EXECUTE sp_executesql @cmd

 SET @cmd = 'ALTER DATABASE '+ quotename(@name) +' MODIFY FILE ( NAME = '+quotename(@nameLog)+', FILENAME = '+quotename(@path + @nameLog  + '.LDF')+ ' )'
 EXECUTE sp_executesql @cmd

 -- Detach DB
 SET @cmd = 'sp_detach_db ' + quotename(@name)
 PRINT @cmd
 EXECUTE sp_executesql @cmd

 -- Execute move command on shell to move physical file to new directory
 PRINT @fileNameLog
 PRINT 'cp ' + @fileNameDB + ' ' + @path + @nameDB + '.mdf'
 PRINT @path + @nameDB + '.mdf'
 SET @cmd = 'xp_cmdshell ' + quotename('move ' + '"'+@fileNameDB+'"' + ' ' + '"'+@path + @nameDB + '.mdf'+'"')
 EXECUTE sp_executesql @cmd

 -- Execute move command on shell to move physical file to new directory
 PRINT @path + @nameLog + '.LDF'
 PRINT 'cp ' + @fileNameLog + ' ' + @path + @nameLog + '.LDF'
 SET @cmd = 'xp_cmdshell ' + quotename('move ' + '"'+@fileNameLog+'"' + ' ' + '"'+@path + @nameLog + '.LDF'+'"')
 EXECUTE sp_executesql @cmd

 -- Reattach Database to SQL Instance
 PRINT 'sp_attach_db ' + quotename(@name) + ', ' + quotename( @path + @nameDB + '.mdf') + ',' + quotename(@path + @nameLog + '.LDF')
 SET @cmd = 'sp_attach_db ' + quotename(@name) + ', ' + quotename( @path + @nameDB + '.mdf') + ',' + quotename(@path + @nameLog + '.LDF')
 EXECUTE sp_executesql @cmd

    FETCH NEXT FROM db_cursor INTO @dbid   
END   

--Close Cursor
CLOSE db_cursor   
DEALLOCATE db_cursor 


--OPTIONAL
IF @enableCMDPermanently = 0
BEGIN
 EXEC master.dbo.sp_configure 'show advanced options', 1
 RECONFIGURE
 EXEC master.dbo.sp_configure 'xp_cmdshell', 0 --disable CMD
 RECONFIGURE
END

Installing Sharepoint Server 2010 on a Windows 7 Machine

A quick simple guide to installing Microsoft Sharepoint Server 2010 on a Windows 7 PC.

Step 1: Load the CD or Image onto a drive.

Step 2: Save the following block of xml into a file named "Config.xml" in the root of your C drive. The path of the file will be "C:\Config.xml"

<Configuration>
  <Package Id="sts">
    <Setting Id="LAUNCHEDFROMSETUPSTS" Value="Yes"/>
  </Package>
  <Package Id="spswfe">
    <Setting Id="SETUPCALLED" Value="1"/>
    <Setting Id="OFFICESERVERPREMIUM" Value="1" />
  </Package>
  <ARP ARPCOMMENTS="" ARPCONTACT="" />
  <Logging Type="verbose" Path="%temp%" Template="SharePoint Server Setup(*).log"/>
  <Display Level="basic" CompletionNotice="No" AcceptEula="Yes"/>
  <PIDKEY Value="XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"/>
  <Setting Id="SERVERROLE" Value="APPLICATION"/>
  <Setting Id="USINGUIINSTALLMODE" Value="1"/>
  <Setting Id="SETUPTYPE" Value="CLEAN_INSTALL"/>
  <Setting Id="SETUP_REBOOT" Value="Never"/>
  <Setting Id="AllowWindowsClientInstall" Value="True"/>
</Configuration>
NOTE: This is for a server farm install, if you wish to install SharePoint for standalone, change the word APPLICATION to SINGLESERVER.

Step 3: Update PIDKEY with your actual product key in the config.xml file.

Step 4: Open command prompt by going Start -> All Programs -> Accessories -> Command Prompt

Step 5: Type into the prompt "<drive>", replace <drive> with the drive you've used, e.g. "D:"

Step 6: Type into the prompt "setup.exe /config c:\Config.xml"

Step 7: Follow the Wizard and configure sharepoint as you would on a Windows 2008 system. Example guide: http://blogs.msdn.com/b/uksharepoint/archive/2009/11/17/installing-sharepoint-server-2010-beta-2-on-a-single-machine.aspx

Similarities between F# and Erlang

Funnily enough my main goal at the moment is to become a good functional programmer. I have been in the OO world since I was a baby =D.

To that end, this will be my first living post, I aim to list all the parallels between F# and Erlang. There are many parallels between them and the truth is that F# is a hybrid language as it supports objects (oh no). But whilst that is helpful when dealing with the .NET Framework it can lead to working in a completely OO manner in a supposedly functional language. Also in order to easily move back and forward between two very good platforms I believe this table is key in maintaining patterns that can be used across both platforms.

A short example would be the need to perform tail recursion on a list. In F# there are a number of methods using while/until/do and in erlang I find a tail recursion is normally required. To that end when I reach a need to iterate I try to implement a tail recursion so that when I'm writing programs I solve them the same way regardless of language and platform (minding the minor syntax differences of course). So here is my living list which I will update as regularly as possible:

None of these examples have been compiled. Variable names like String might need to be changed before compiling any of the code.








Tuples:



Erlang: {A,B} = {1, 2}

F#: (A, B) = (1, 2)


Notes: In erlang lower case variable names are atoms, in a tuple this is similar to an object type for example {person, Name, Phone, Address} would be a typical example of a "Person" object. F# does not support atoms and an additional variable maybe needed to store the object type (as string maybe) =(. Both languages support pattern matching.


Static List:


Erlang: [1,2,3]

F#: [1;2;3]

Notes: The structure is almost the same, minor different in the seperator's syntax. The pattern matching and recursion works the same for both instances.


Strings:


Erlang: recursion(String) ->
   case String of
      [head | tail] -> io:fwrite("~w",[head]),
      recursion[tail];
      [] -> done;
      _ -> fail
   end.

F#:
let rec recursion(String) ->
   match String with
      | String -> Console.WriteLine(String.sub s 0 1)
            recursion(String.sub s 1 (String.length s))
      | "" -> "done"
      | _ -> "fail"
    
Notes: I believe Erlang has a big positive in this part of the comparison. Erlang treats strings as a List of ints and conceptually this makes learning programming make a bit more sense and you are using list functions all the time. So to manipulate a string is simply a list manipulation and you can use the list manipulation functions. In F# strings as treated similar to C#/VB .NET where they're are string specific functions in the framework. The above is a good example of the difference in iterating through strings although the F# recursion is a best match equivalent but their are probably built in functions that will allow you to perform the changes you want with less code.


Tail Recursion:


Erlang:
recursion(List) ->
   case List of
      [head | tail] -> recursion[tail];
      [] -> done;
      _ -> fail
   end.

F#:
let rec recursion(List) ->
   match List with
      | [head :: tail] -> recursion(tail)
      | [] -> "done"
      | _ -> "fail"
    

Notes: The ease of recursion is a big plus to functional programming. F# has almost no terminators so the end of each block is harder to visualize although this is by design for "code resuability".  In F#, "members" are automatically recursive and don't need the "rec" prefix keyword.


Funs (Anonymous Functions):


Erlang: fun (x) -> x + 1 end

F#: fun (x) -> x + 1


Notes: Both are very similar but F# doesn't use a terminator and relies on indentation to determine where the fun is finished. They both support currying functions and can be quite useful with many of the built-in functions that take a fun as an argument.

T-SQL Select Distinct on Single Column of Multi Column Select

After a long day at work I realized I needed to do a distinct select on a integer column and read any value in the other columns. Seemed simple but was a bit of a pain to grasp the query syntax.

An example implementation:

SELECT DISTINCT Rating, MAX(Title) FROM WallpaperGallery
Group By Rating
 
Two important notes about the query. We run a distinct on [Rating] and we also need an aggregate function on the next column (can be max, min, etc.)  The second note is that the grouping need to happen on the distinct column and no other so that we have one row per distinct value in the [Rating] column. This query will disregard [Title]s that are not distinct for each distinct [Rating]. So if we have 10 rows with five distinct [Rating]s and all the titles are distinct then we will get 5 rows returned with the result of the Max() function on the Title column.

Modify DataView XSLT to Add Url in Grid to Workflow Initiation Form

I recently created a data view. I wanted a simple link to the list items workflow initiation form, to simply allow the user to access and start the workflow.

The confusing aspect of all this is that normally we could do something simple such as

<a href=http://someurl/page.aspx?ID={@ID}></a>


The xsl transform will resolve {@ID} to the value of @ID.


The problem with this was that I actually also needed to include ListID and TemplateID both of these query parameters require the Guid to be wrapped in curly braces. So I modified the above and added a ListID to create the following:


<a href=http://someurl/page.aspx?ID={@ID}&List={05cf277f-5d2e-4b46-8dc9-27a1e1c5ff36}></a>

The first I problem I had with this was an error occured due to the & ampersand. I needed to encode it to and to prevent Sharepoint from erroring as a result of unencoded text.


The second problem is that curly braces resolve variables. So the second error was relating to Sharepoint failing to resolve the GUID. Which I didn't want to occur I wanted it to be taken as literal text. To escape the curly braces I imagined \{ would be the fix but instead as it turns out it's {{.


Great, I found out how to escape the curly brace....When executing the page it worked BUT it also encoded the curly brace (I didn't tell it to do this, it did it automatically) and printed %7B in the url! Not what I needed and Sharepoint wouldn't process that as a curly brace in the query string either.


So to cut a long story short the following does exactly what I want. It reads the parameter value of the datasource and escapes the curly braces


THE SOLUTION:




The following is a fair step away from a simple url with some encoding and escaped characters. But it works!


We still have an anchor but we assign the value via XSLT. The xsl transform for attribute allows us to append the resulting (resolved) inner block to the href attribute value. So following through I needed a couple more transforms before it became str1 + str2.


In order to properly escape the curly braces I needed to wrap the static text in an xsl:text block. Then I called for an xsl:value-of to get the ID.



<a>
   <xsl:attribute name="href">
      <xsl:text disable-output-escaping="no">http://website/_layouts/IniWrkflIP.aspx?List={05cf277f-5d2e-4b46-8dc9-27a1e1c5ff36}&amp;TemplateID={7aabfd9c-9a82-4a12-a82a-ad74cb0029c7}&amp;Source=http://teamsource/OperationalRisk/SitePages/Admin Home.aspx&amp;ID=</xsl:text>
      <xsl:value-of select="@ID"></xsl:value-of>
   </xsl:attribute>
<img alt="reassign" style="border-width:0px;" src="http://website/_layouts/images/edititem.gif"></img></a>
  

Finally, I added an image to represent the button and all done!