Andy Crouch - Code, Technology & Obfuscation ...

Setting Up PostgreSQL On Arch

Man Looking At Monitor

Photo: Austin Distel - Unsplash

Today I installed PostgreSQL on my local machine to work through some tutorials for a new language. (More on that soon). It wasn’t the most straightforward install and set up ever. Some of the steps appear to be missing or different from the Arch wiki and so I thought I would document it here.

First up install PostgreSQL in pacman with

$ sudo pacman -S postgresql

Next, you need to initialise your database storage cluster on disk. This will be the directory which stores all the data. There is no default location but most people stick with the convention of mapping it to /var/lib/postgres/data. You can initialise this with

$ sudo mkdir /var/lib/postgres/data

You then need to set the owner of that directory to be the PostgreSQL user with

$ sudo chown -c -R postgres:postgres /var/lib/postgres

Next we need to switch to the PostgreSQL user and initialise a database cluster which we do with

$ sudo -i -u postgres
$ initdb -D '/var/lib/postgres/data'

Once completed you can log out and start PostgreSQL with

$ logout && sudo systemctl start postgresql

If you want PostgreSQL to start each time you launch your machine then run

$ sudo systemctl enable postgresql

The final thing to do is to grant your usual user access to save you having to keep switching to the PostgreSQL user to access the PostgreSQL shell which you can do with

$ createuser -s -U postgres --interactive
  Enter name of role to add: YourUsualLoginUserName

At this point, you should have a functioning PostgreSQL install.

I’m now looking for a good GUI for PostgreSQL. Please share your recommendations with me via twitter or email.

Debugging Object Lists

Man Sitting At Deak Looking At Monitor

Photo: Austin Distel - Unsplash

Something that I wish I had written for Visual Studio over the years was an object list debugger. Data Tables in ADO.Net had the DataSet visualizer which allowed you to see the contents. You were able to copy those contents out to Excel if need be and it was genuinely useful.

Something that I coded up some time ago was a class that takes a list of Entity objects and creates a Data Table from it. I developed it to use within a Table Gateway implementation that I created to improve bulk database insert times. As a side note, you really can not beat the speed of the SQlBulkCopy utility class for inserts on large datasets. Perhaps I will write a post on those topics soon.

I was recently tracking down an intermittent bug. The issue was obviously down to some data passed to a processing routine. The idea came to me to use my EntityDataTableFactory class to dump out objects at debug time. I didn’t really have time to create a polished solution. But, my theory worked and by plugging in my factory, I was able to inspect the data in the DataSet visualiser.

See the optional visualiser option when debugging and results below. The visualiser is available when you hover over a Data Table variable.

Visual Studio Debugging Code


Visual Studio Dataset Visualisation

The EntityDataTableFactory class will work on any strongly typed object List<T> type. You need to declare a table to store the resulting Entity table to and then you can use the DataSet visualiser. Using this to inspect the object list takes a couple of lines to set up. But, I find it is easier to use than Watch values and the property viewer.

I have condensed the code into a single namespace below in case you find it useful yourself.

using EntityListViewer.ExtensionMethods;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
using System.Linq;
using System.Reflection;

namespace DataUtilities
{
    public interface IEntityDataTableFactory
    {
        DataTable CreateDataTableFrom<T>(List<T> entityList) where T : class;
    }

    public class EntityDataTableFactory : IEntityDataTableFactory
    {
        public DataTable CreateDataTableFrom<T>(List<T> entityList) where T : class
        {
            if (entityList.IsNullOrEmpty())
                return new DataTable();

            DataTable entityDataTable = CreateDataTableFor(entityList);

            const int MinimumExpectedColumns = 1;
            if (entityDataTable.Columns.Count.IsLessThan( MinimumExpectedColumns))
                return new DataTable();

            foreach (var entity in entityList)
            {
                GenerateDataRowFrom(entity, ref entityDataTable);
            }

            return entityDataTable;
        }

       private DataTable CreateDataTableFor<T>(List<T> entityList) where T : class
        {
            Type classType = entityList.First().GetType();

            List<PropertyInfo> propertyList 
                = classType
                     .GetProperties()
                     .Where(p => p.GetCustomAttributes(typeof(NotMappedAttribute)).Any() == false && 
                                 p.GetCustomAttributes(typeof(DatabaseGeneratedAttribute)).Any() == false)
                     .ToList();

            const int MinimumPropertyCount = 1;
            if (propertyList.Count < MinimumPropertyCount)
                return new DataTable();

            string entityName = classType.UnderlyingSystemType.Name;
            DataTable entityDataTable = new DataTable(entityName);

            foreach (PropertyInfo property in propertyList)
            {
                DataColumn column = new DataColumn();
                column.ColumnName = property.Name;

                Type dataType = property.PropertyType;

                if (IsNullable(dataType))
                {
                    if (dataType.IsGenericType)
                    {
                        dataType = dataType.GenericTypeArguments.FirstOrDefault();
                    }
                }
                else
                {   
                    column.AllowDBNull = false;
                }

                column.DataType = dataType;

                entityDataTable.Columns.Add(column);
            }

            return entityDataTable;
        }


        private void GenerateDataRowFrom<T>(T entity, ref DataTable entityDataTable) where T : class
        {
            Type classType = entity.GetType();

            DataRow row = entityDataTable.NewRow();
            List<PropertyInfo> entityPropertyInfoList = classType.GetProperties().ToList();

            foreach (PropertyInfo propertyInfo in entityPropertyInfoList)
            {
                if (entityDataTable.Columns.Contains(propertyInfo.Name))
                {
                    if (entityDataTable.Columns[propertyInfo.Name].IsNotNull())
                    {
                        row[propertyInfo.Name] = propertyInfo.GetValue(entity, null) ?? DBNull.Value;
                    }
                }
            }

            entityDataTable.Rows.Add(row);
        }

        private bool IsNullable(Type type)
        {
            if (type.IsValueType.IsFalse()) 
                return true; 

            if (Nullable.GetUnderlyingType(type).IsNotNull()) 
                return true; 

            return false; 
        }
    }

    public static class ExtensionMethods
    {
        public static bool IsNull(this object obj)
        {
            return obj == null;
        }

        public static bool IsNotNull(this object obj)
        {
            return obj != null;
        }

        public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
        {
            return enumerable.IsNull() || !enumerable.Any();
        }

        public static bool IsLessThan(this int number, int value)
        {
            return number < value;
        }

        public static bool IsFalse(this bool bln)
        {
            return bln == false;
        }
    }

}

I’d be interested to hear your thoughts on better ways to debug within Visual Studio. Please share them with me via twitter or email.

The i-Stay Fineline Laptop Bag

i-Stay Fineline Laptop Bags

Photo: Andy Crouch

I work remotely a lot of the time. But, as my role has developed I travel more and carry my office with me. I am always trying new laptop bags in an effort to find the balance between space and weight.

For many years I have used STM bags. Before that Pakuma which, unfortunately, have ceased trading. I have tried all kind of messenger bags, briefcases and backpacks.

For a long time, especially while I rode a motorbike, I settled on backpacks. They are functional but at a cost. I find that using them damages clothing, especially wool based clothing.

I decided to try a messenger type bag again recently and after much research, I have opted for an i-Stay Fineline. This is a fairly standard laptop and tablet bag. Given its slim nature, it has a number of compartments and pockets. It takes a laptop to 15.6” and a tablet up to 12”. I can easily get a power brick in along with pens, moleskin and various charging cables. The outer flap has a large zipped pocket and the rear has a velcro fastened flap for magazines or paperwork. All in all a slim, neat and waterproof bag.

The standout point on the bag though is the strap. If you have used a messenger bag with a material strap you will know they are no good at staying on your shoulder. As you walk, it moves and slips and you are forever pulling the bag back onto your shoulder. The i-Stay has a rubber shoulder strap which goes nowhere. If you run with a full bag, it doesn’t move. It is the bags USP and it works.

This isn’t meant to be any kind of endorsement for the bag but it is one of the better slim laptop bags I have used. If you don’t need to carry the kitchen sink with you on your daily commute, you should check it out.

I’d love to hear your recommendations on laptop bags and which you use. Please share them with me via twitter or email.

Microsoft Has Purchased Github

Microsoft PC Showing Getting Ready Message

Photo: Johny vino - Unsplash

So the news has been confirmed that Microsoft has brought GitHub for $7.5 billion. Rumours first started to circulate late last week. The deal was officially disclosed yesterday.

I have been around both the Open Source and Microsoft communities for over 20 years. The reactions are predictable, in some cases quite funny but also unfair. Obviously, from the Microsoft side, there is nothing but general praise and excitement. From the OSS side there seem’s to be two main camps:

  • Those who were around for the Steve Ballmer driven onslaught on Linux. They remember the “cancer” comment. They remember the sponsorship of SCO while they tried to sue various Linux companies and developers. Worse yet are the younger generation who have been fed the war stories of old greybeards during which the details have been elaborated over time.

  • Those who totally get that Github is a rare unicorn. They built a great product at the right time for the right user base that had a need. Users of Github who have used it to power fantastic projects and power great products.

I for one think that the deal is good. Github, while suffering numerous (and normal) growing pains have been rewarded for their hard work. Microsoft picks up some amazing talent and the projects hosted on Github get continuity and the resources to power it for years to come. The also get an experienced and highly influential leader in Nat Friedman.

Fun times ahead.

What are your thoughts on Microsoft buying Github? Please share them with me via twitter or email.

Pixel 2

Picel 2

Photo: Andy Crouch

After 2 solid years of use my Nexus 5x finally died. No warning, no signs, it just died. I would argue that 2 years for a phone is not that long. I appreciate I am on it a lot and am an above average use type user. Then again, I am getting older and my expectations are perhaps excessive.

So I upgraded to a Pixel 2. This was a phone that I was actually excited to get rather than just an upgrade. But, I have to be honest and say that after some initial use I am disappointed.

First the good. The thing I love about the Google phones is stock Android. You get the latest version of Android almost as soon as it is released. Their launcher is far better than any others I have tried. The phone itself is very well built and the lack of physical buttons on the front makes it very slick. On the side, you just have power and volume. The performance I have found to be excellent and it comes with 64gb of storage. On the rear is a 12.2-megapixel camera and flash.

Now the not so good. First up, only one USB C connection. I am sure that USB C is going to dominate at some point but it doesn’t yet. No headphone jack. This is a massive issue and a pain I know felt by iPhone users. But, they have Airpods. Google released Buds but they have flopped and flopped hard. This seems to be one of the less harsh reviews. The next issue is the USB C to phono converter they supply. It’s about 1.5 inches which makes the phone about 7 inches long when plugged in. You need deep pockets to accommodate that. It makes it really uncomfortable when you are sitting down so you are forced into buying a good pair of Bluetooth headphones.

Charging is very quick but only if you use the official charger. If you use a converter to make USB C fit in any standard USB port then it charges so slowly you might as well not bother.

Finally, due to its size, the phone is hard to use one-handed. If you try to type single-handed you find you mishit keys and write gibberish.

On the whole, the phone is good but it’s not great. It had the potential to really show how great an Android device can be. Unfortunately, they allowed Samsung to do that instead and given their horrendous UI that is a shame.

I’d love to hear your thoughts on the Pixel and on alternatives worthy of looking at. Please share them with me via twitter or email.