Grunt.Js examination

Lately I have been looking at VS2015 / ASP vNext, and it did not take a genius to see that you need to know NPM/Bower and Gulp/Grunt. I have used NPM before and Bower is easy to pick up. I have not used (but have heard of) Gulp and Grunt before.

I looked at both of these over the past couple of weeks, and decided I liked Grunt better. For those that have not heard of Grunt it is a task runner for running repetitive tasks. There are lots of examples/resources available for Grunt, but I kind of wanted to look/try it myself. I have written up my findings in the following article.

http://www.codeproject.com/Articles/995334/Small-Grunt-js-examination

Like I say this is nothing new, and I expect most web developers would be like, yeah obviously, it was however interesting for me as a grunt newbie, which others may be.

CQRS Demo

For a while now I have found myself becoming interested in CQRS, and I am fortunate enough to work with a practitioner of CQRS. As such it seemed like a good time to try and learn a bit more about this pattern.

I have created a small demo app that is a fully asynchronous CQRS example.

If this sounds like it may of interest to you, you can read more about it over at codeproject : CQRS : A Cross Examination Of How It Works

Git protocol errors when using Bower package manager

I have just got back from a month long holiday (which was great). Anyway back to work now…..sigh

So the other day I was trying to get Yeoman to scaffold a new angular.js app for me, which worked fine. I then wanted to use the Bower package manager to download a package, and whoever created the package hosted it on Git. Bower can deal with this just fine. But if like me your network is locked down, where there are all sorts of firewall/proxy rules, you may not be able to use the git protocol.

Luckily this is an easy fix, and all you need to do is issue this command line to have git add a configuration rule to re-write git urls to https

git config --global url."https://".insteadOf git://

What Changes Did This Command Make?

Take a look at your global configuration using:

git config --list

You’ll see the following line in the output:

url.https://.insteadof=git://

You can see how this looks on file, by taking a peek at ~/.gitconfig where you should now see that the following two lines have been added:

[url "https://"]
    insteadOf = git://

And that is all there is to it, everything just worked after that.

Triggers/Rowcount And NHibernate

 

The Short Story

If you have seen this error, whist using NHibernate with Triggers, this may be the right post for you

“Batch update returned unexpected row count from update; actual row count: 2; expected: 1″.

 

Long Story

So today I had to create some audit tables, ok some of you will surely go hey why didn’t you just use CQRS for that? Yes yes I know that by using CQRS and event sourcing I would indeed get full audit by way of the stored events, in fact I will be writing about that soon, but for now lets forget about that and just stick to the current situation which is :

 

  1. I have a table that I want to provide auditing for
  2. I am using SQL Server
  3. I am using Fluent NHibernate

 

Now there are numerous ways you may perform auditing in SQL server, in fact later versions of SQL Server come with inbuilt Audit functionality, or you could use a general all purpose audit table which records very generic information such as

 

  • The table name
  • The action performed (insert, update, delete)
  • The old value
  • The new value
  • Some narrative
  • Some date information

 

This is fine, but for my requirements, what I wanted was a full row copy from the original table, plus some extra columns such as

 

  • AuditId (Primary key auto generated by DB (Identity))
  • OperationType : I for Insert, D for delete, U for update

 

So lets have a look at some of this using some code example

 

SQL Server Table(s)

Let say I have the following table called “Deposit” in SQL Server

 

Deposit Table (source for Audit)

 

CREATE TABLE [dbo].[Deposit](
      [Id] [int] IDENTITY(1,1) NOT NULL,
      ….
      ….
      ….
      [Version] [timestamp] NOT NULL
CONSTRAINT [PK_Deposit] 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]

GO

 

And I also have the following Audit table

Deposit_Audit table

 

CREATE TABLE [dbo].[Deposit_Audit](
      [AuditId] [int] IDENTITY(1,1) NOT NULL,
      [OperationType] [nvarchar](1) NOT NULL,
      [Id] [int] NOT NULL,
      ….
      ….
      ….
      ….
CONSTRAINT [PK_Deposit_Audit] PRIMARY KEY CLUSTERED
(
      [AuditId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

 

The Fluent NHibernate Entities

So lets say I have a simple class called “Deposit” which looks like this. Note that for Fluent NHibernate/NHiberate to do their magic properties MUST be virtual

 

using System;
namespace Entities
{
    public class Deposit : Entity<int>
    {
        //NOTE : Do not remove this, as NHibernate needs default ctor to allow proxying
        public Deposit() { }
        public virtual int Id { get; set; }
        ….
        ….
        ….
        ….
        public virtual byte[] Version { get; set; }
    }
}

 

The Fluent NHibernate Mapping Files

Where I then have a Fluent NHibernate mapping file that looks like this

 

namespace Entities
{
    public class DepositMap : ClassMap<Deposit>
    {
        public DepositMap()
        {
            this.Schema("[dbo]");
            OptimisticLock.Version();
            this.Table("[Deposit]");
            this.Id(x => x.Id).Column("Id");
            ….
            ….
            ….
            Version(x => x.Version).Generated.Always();
        }
    }
}

 

 

The Trigger To Do The Audit

Then I have this trigger in place in SQL server to actually do the inserting of the data into the audit table

 

CREATE TRIGGER [dbo].[triDeposit_Audit]
   ON [dbo].[Deposit]
   AFTER INSERT, DELETE, UPDATE
AS

BEGIN

      DECLARE @rc AS INT;
      DECLARE @Id INT
      DECLARE @OperationType NVARCHAR(1)
      DECLARE @rcDel AS INT;
      DECLARE @rcInserted AS INT;

      SET @rc = (SELECT COUNT(*) FROM inserted);
      IF @rc = 0 RETURN;

      DECLARE @keycol AS INT;

      SELECT

            @keycol = ISNULL(inserted.Id, deleted.Id),
            @OperationType  =
            CASE

                              WHEN inserted.Id IS NULL THEN 'D' - we don't use this for now
                              WHEN deleted.Id IS NULL THEN 'I'
                              ELSE 'U'
            END
            FROM inserted
            FULL OUTER JOIN deleted
            ON inserted.Id = deleted.Id

     

      - single row
      IF @rc = 1

            BEGIN

                  INSERT INTO [Options].[dbo].[Deposit_Audit]

                  (    [OperationType]
                        ,[Id]
            		…..
            		…..
            		…..
            		…..
                  )             

                  SELECT     
                        @OperationType         
                	….
                	….
                	….
                	….
                  FROM [Options].[dbo].[Deposit] WHERE Id = @keycol
            END 
     

      - multiple rows
      ELSE
            BEGIN
                  SELECT DISTINCT * INTO #I FROM inserted;

                  BEGIN

                        INSERT INTO [Options].[dbo].[Deposit_Audit]
                        (
                           [OperationType]
                          ,[Id]
                            ……
                            ……
                            ……
                        )

                        SELECT     

                           'U'
                           ,[Id]
                            ……
                            ……
                            ……
                        FROM #I
                  END
            END  
END
GO

 

 

All good so far, so I then used my handy NHibernate ISession / Repository to do an INSERT, and then I got something that I was not expecting, I got this:

 

In NHibernate I got this error: “Batch update returned unexpected row count from update; actual row count: 2; expected: 1″. 

 

Yikes.

 

Turns out there is a simple fix for this, which to my mind was not obvious (even though I seem to recall seeing this before, and mindfully forgetting about it), you just need to include the following line at the start of your SQL Server trigger

 

SET NOCOUNT ON

 

By doing that you are saying that the code that runs inside the trigger will not effect the overall row count of the transaction. After adding this one line to my trigger everything worked as expected.

VS2013 Setup Project

I am fortunate enough to have been working on a big app for a while now, which means we have our deployment pretty sorted out, using a manner of different tools/scripts.

Then the other day I was asked to help out another team with a small bit of help, where they needed a small app written to allow them to analyse some data. The other team in question are not DEVS, so they need an installer really.

As I say I have not had to create an installer for quite a while now, I was obviously aware of the lack of “Setup Project” in VS2012/VS2013, but since I have not had a need for it lately I was like “meph”.

Until today.

Luckily help is at hand, there is a Visual Studio 2013 extension to get the ability to create Installer Projects in VS2013 again. God knows why Microsoft took that out in the first place, all that would have done is moved people to use other things such as

Anyway for those that want to use the old (probably familiar) VS Installer style project you can grab it from here:

https://visualstudiogallery.msdn.microsoft.com/9abe329c-9bba-44a1-be59-0fbf6151054d

Hopefully some of you will find that useful

 

NetMQ : Documentation is there….Phew

I have been beavering away over the past 2 weeks, creating the NetMQ documentation. I am pleased to announce that the docs have come along quite nicely and you can read them all here :

http://netmq.readthedocs.org/en/latest/

 

You can also read them directly at GitHub too :

https://github.com/zeromq/netmq/tree/master/docs

 

I actually prefer the formatting on GitHub, but “ReadTheDocs” is what we have. But at least you have choices.

I hope that helps you in some way in your journeys with NetMQ. Oh it is worth mentioning that there are a couple of pages still to do, which Doron himself will be doing. These pages are

  • Stream
  • Devices
  • Beacon
  • Scheduler

I think the docs I wrote should cover the most common cases though.

There was also one user who has offered to translate the docs into French, so you can expect some French version some time in the future too

Enjoy

 

 

 

NetMQ : Documentation II

I don’t know how many of you read my last post, but I have somehow managed to talk myself into becoming the official documentation writer for NetMQ. If you have not used NetMQ, it is a C# native port of ZeroMQ the socket library from outer space. I have really enjoyed learning about ZeroMQ (which I did by reading “The Guide”,  several times over) and playing around with NetMQ, where I even did a joint article about with NetMQs author Doron (who is a very smart guy indeed). Basically its a great library, and very interesting and lots of fun, and very light weight, with no dependencies at all.

Anway enough of the advertising, how is the documentation coming along? Well, over the past week I have made some good progress on the NetMQ documentation.

The following pages are now semi-ready (pretty much there truth be told)

Over the next week I hope to finish some more. I will notify you all when I have done some more, and again when it all gets released to become the final “official” docs.

If you have not used NetMQ I urge you to have a look, experiment, that is how I started, and now I love it, and can honestly see many places where it is a excellent fit

Anyway enjoy, over and out for now