NHibernate 4.0.3 Released

NHibernate 4.0.3 General Availability is now available for download from Sourceforge and Nuget.

This includes fixes for regressions in NH 4.0.2 and some minor fixes. Please see the full release notes for more information: releasenotes.txt

Full list of changes:

Bug

  • [NH-2504] - Can't use Cacheable with Group By
  • [NH-3457] - TemplatedViolatedConstraintNameExtracter.​ExtractUsingTemplate calls Substring with wrong arguments
  • [NH-3468] - InvalidCastException when deleting entities containing uninitialized lazy components
  • [NH-3573] - Query cache statistics not updated when using MultiCriteria
  • [NH-3731] - Unable to serialize session after modifying the index of entities in a list

Source: http://nhibernate.info/blog/2015/01/20/nhibernate-4-0-3-released.html

NHibernate 4.0.2 Released

NHibernate 4.0.2 General Availability is now available for download from Sourceforge and Nuget.

This includes fixes for regressions in NH 4.0.1, and some fixes for mapping-by-code and Firebird issues. Please see the full release notes for more information: releasenotes.txt

Full list of changes:

Bug

  • [NH-2779] - Session.Get() can throw InvalidCastException when log-level is set to DEBUG
  • [NH-2782] - Linq: selecting into a new array doesn't work
  • [NH-2831] - NH cannot load mapping assembly from GAC
  • [NH-3049] - Mapping by code to Field not working
  • [NH-3222] - NHibernate Futures passes empty tuples to ResultSetTransformer
  • [NH-3650] - ComponentAsId used more than once, cache first mapping and produces subsequently a sql select wrong
  • [NH-3709] - Fix Reference to One Shot Delete and Inverse Collections
  • [NH-3710] - Use of SetLockMode with DetachedCriteria causes null reference exception

Task

  • [NH-3697] - Ignore Firebird in NHSpecificTest.NH1981
  • [NH-3698] - NHSpecificTest.NH1989 fails for some drivers

Source: http://nhibernate.info/2014/11/15/nhibernate-4-0-2-released.html

Playing with Google Apps Scripts

Google has an Apps Script platform which allows you yo write scripts for most of Google products, such as Gmail, Drive, Spreadsheets, etc. The google script (extension .gs) is an JavaScript language subset. Google provides online editor for scripts, which is available at script.google.com. The editor is an online IDE with basic autocompletion support, which is really nice. But I prefer to write Google Scripts in some mature desctop editors such as Visual Studio or at least Sublime Text.

I came across need of writing Google Script, when I wanted to sort my GitHub notification and remove some subscription emails.

Ok, lets start. First, open the script.google.com page in your favourite browser. The page will ask you to choose an project type, or open recent project.

Step 1

I'm going to select the "Blank Project" option.

Step 2

If you click on "Untitled project" you'll be able to give a sensible name for your project.

Step 3

Step 4

Then you can write a code. As manipulating emails means a lot of work with collection, so it would be nice to have something like underscore.js or lodash.js in place. I'll go with Lo-Dash. Just go to lodash.com and dowload minified modern build.

When you have Lo-Dash downloaded you need to import it to your Google Apps Script project. Press File->New->Script File

Step 5

Enter the name of the file: LoDash

Step 6

Then copy and paste content of lodash.min.js to LoDash.gs and save the file.

And finally there is my code to sort Github label in the Gmail.

function split() {
  // I have a filter in Gmail, which will put all emails from notifications@github.com 
  // to "GitHub" label and skip inbox for them
  // Get the 'GitHub' label
  var label = GmailApp.getUserLabelByName('GitHub');

  // Group all threads by Project Name. All notification emails have Project Name 
  // in square brackets in the email title. 
  var groups = _.groupBy(label.getThreads(), function(t) {
    var subject = t.getFirstMessageSubject();

    var tag = /\[([^\]]+)\]/.exec(subject);
    if (tag) {
      return label.getName() + '/' + tag[1];
    }
    return label.getName();
  });

  _.forEach(groups, function(threads, l) {
    if (label.getName() != l) {

      // Get or create a label for a project 
      var new_label = GmailApp.getUserLabelByName(l) || GmailApp.createLabel(l);

      // Label.addToThreads / Label.removeFromThreads has an restriction of
      // 100 threads per call, so we need to page our threads.
      var pages = _.groupBy(threads, function(t, i) { return (i / 100) >> 0; });

      _.forEach(pages, function(page) {
        new_label.addToThreads(page);
        label.removeFromThreads(page);  

        // If you call API to often you can reach call limit and script will stop execution
        Utilities.sleep(100);
      });
    }
  });
}

When we have code in place we want to add a trigger to run the script regularly. Click Resources->Current project's triggers

Step 9

Then click on "No triggers set up. Click here to add new now."

Step 10

Select the frequence you want your trigger to run. I've chosen to run this script every five minutes. Click Save. The script will ask you for Authorisation.

Step 11

Press "Continue". And then in the pop-up window review and Accept permissions for your script.

Step 12

Happy scripting!

Git Filter to Convert Spaces to Tabs and Vice Versa

Usually people have different preferences on tabs vs spaces. Here is a git filter to convert tabs to spaces, and spaces to tabs. Git allows you to write filters - a small commands which will be run after checkout (smudge) or before add (clean). As usual all settings are stored in git config files.

To make a work I use two GNU tools expand (converts tabs to spaces) and unexpand (converts spaces to tabs). If you are using Windows, then you'll need these tools to be reachable from your PATH environment varible. You can get this tools as part of GnuWin32 or any other port of GNU tools to Windows.

DISCLAMER: Be really careful before commiting, as these filters can produce a huge changesets.

Tabify - spaces to tabs on add

  1. Open your ~/.gitconfig (%SystemDrive%\Users\<username>\.gitconfig in case of Windows)
  2. Add following lines
[filter "tabify"]
    clean = unexpand --tabs=4 --first-only

It says that we want to convert each 4 space characters at the beginning of a line to one tab.

  1. To make the filter active add following lines to your .gitconfig (or to .git\info\attributes)
*.cs filter=tabify

It says that for files with ".cs" extension we want to use this filter.

Spacify - spaces to tabs on add

  1. Open your ~/.gitconfig (%SystemDrive%\Users<username>.gitconfig in case of Windows)
  2. Add following lines
[filter "spacify"]
    clean = expand --tabs=4 --initial

It says that we want to convert each tab character at the beginning of line to 4 space characters.

  1. To make the filter active add following lines to your .gitconfig (or to .git\info\attributes)
*.cs filter=spacify

It says that for files with ".cs" extension we want to use this filter.

Spaces2Tabs - spaces to tabs on add, and tabs to spaces on checkout.

This filter is just a combination of previous two filters. This filter is usefull if your repository requires you to use tabs for indents, but you prefer spaces. The code

[filter "spaces2tabs"]
    clean = unexpand --tabs=4 --first-only
    smudge = expand --tabs=4 --initial  

Tabs2Spaces - tabs to spaces on add, and spaces to tabs on checkout.

This filter is just a combination of first two filters. This filter is usefull if your repository requires you to use spaces for indents, but you prefer tabs. The code

[filter "tabs2spaces"]
    clean = expand --tabs=4 --initial
    smudge = unexpand --tabs=4 --first-only

Happy filtering!

Git aliases to apply patches from url

Git has two commands to apply patches: git am and git apply, but none of them are able to apply patches from an url. So here are my aliases to do so.

git apply-url - Apply a patch to files and/or to the index from url

$git config --global alias.apply-url "!f() { curl -s $1 2>nul | git apply ${@:2}; }; f"

The alias itself is pretty simple. First it declares callable function f and then calls it. The function itself calls curl in silent mode with first argument passed to alias as url. Then it pipes curls output to git apply with remaing arguments. This alias applies the patch but does not create a commit.

Usage

$git apply-url http://example.org/sample.patch args

The first argument MUST be an url for a patch, other arguments will be passed to git apply.

git apply-url - Apply a series of patches from an url (git am-url):

$git config --global alias.am-url "!f() { curl -s $1 2>nul | git am ${@:2}; }; f"

This alias works exactly the same as previous.

Usage

$git am-url http://example.org/sample.patch args

The first argument MUST be an url for a patch, other arguments will be passed to git am. You can apply a pull request from github by performing following:

$git am-url https://github.com/user/repo/pull/777.patch

Happy aliasing!