Tuesday, November 29, 2016

SourceTree Authenticate prompt

September 2021 note: SourceTree is a clumsy bug-ridden mess that has only marginally been improved in the four years since I made this post. The great news is that you can uninstall and delete SourceTree from your mind because Visual Studio now has all the Git source control functionality you need integrated into it.


Sometime in the last few weeks SourceTree 1.9.x for Windows started popping-up the Authenticate dialog prompt, over and over and over and over... You could you enter your password until hell froze but it just kept asking.

I noticed that Tools > Options > Authentication had an empty list of saved passwords, whereas for the last couple of years I remember seeing my user name in there.

Countless web searches on this problem revealed lots of complaints about it, but all the discussions and suggestions were utterly irrelevant or useless. Going through the tedious steps of installing SSH keys did not help.

Out of frustration and disgust I decided to uninstall and purge SourceTree completely from my PC. I noticed that there were 3 icons with different versions in the Programs and Features list and they did not uninstall cleanly. Then I searched my whole C: drive for anything with the word 'SourceTree' in the name and deleted it. I then ran regedit as Admin and similarly deleted any keys or values containing 'SourceTree'.

After reinstalling the most recent copy of SourceTree and entering my fresh credentials the problem went away and the program now seems to be running trouble free.

SourceTree issues an irritatingly frequent number of incremental updates, which I usually accept, so I'm guessing that an accumulation of these updates has corrupted something. I'm angry that I had to use such a ham-fisted fix for this, but I document it here in case it helps others who suffer this problem.

Saturday, November 19, 2016

SQLite and Dapper ORM

This morning I tried to read a SQLite database for the first time in at least 3 years. I remember the last time I tried to integrate SQLite into a C# project with Entity Framework 6 and designer support I just about went mad. It took hours and hours of searching and bumbling around to eventually get the right combination of references and config values. I even restored a backup of an old project that used SQLite, and I couldn't get it working again, probably due to missing dependent installs.

This time I went looking for a simpler way, with minimal dependencies and simpler code. Remembering a hint from someone several weeks ago in the ozdotnet forum I searched for "SQLite Dapper" and came upon StackExchange/dapper-dot-net. This lightweight ORM has a tiny footprint of a single DLL and one class that adds extension methods to IDbConnection, so it's mostly database agnostic. The readme.md on the main page contains a neat summary of how to perform basic database and query operations. The code is so terse that some of it seems "magical" and you need to read the samples carefully to see the pattern.

As a sanity check I attempted to read the Songs table in a MediaMonkey db3 database file. I made a POCO class which is a subset of the dozens of table columns.

public class Song
{
  public long ID { get; set; }
  public string Album{ get; set; }
  public string SongTitle { get; set; }
}

Add Nuget packages Dapper and System.Data.SQLite.Core to your project. The following code enumerates all the Songs table rows.

using (var connect = new SQLiteConnection(@"Data Source=M:\Monkey.db3"))
{
  connect.Open();
  foreach (var song in connect.Query<Song>("Select ID,SongTitle,Album from Songs", buffered: false))
  {
    Info($"{song.ID} {song.SongTitle} - {song.Album}");
  }
}

Dapper is a long way from being a full ORM, but you can still easily perform all of the typically needed database operations in a strongly typed way. You can even do eager loads over joins, a bit like the Include extension method used in Entity Framework queries (using a curious syntax).

Best of all, you only need two small Nuget packages, there is no need to put anything in a config file, you can learn to use it in minutes and the code is brief.