Tuesday, July 21, 2015

Visual Studio tip: Hide selected text

Today I noticed the menu item Edit > Outlining > Stop Hiding Current (CTRL+M CTRL+U), and wondered to myself what it does. Well, turns out you can hide selected areas of text and then later unhide them. But how do you hide them in the first place??
"The option to hide a selection only shows in the Outlining menu once you've selected text" - Captain Obvious
Thank you Captain Obvious!
So as an example, lets say we have one of the controllers for a sample ASP.NET MVC project, and just want to inspect it to see what it does, we see the below action with a long bunch of lines:
404 - Image Not Found
We go through the first few lines and realise that's all just code related to validation, followed by loading up an item and some more validation. We're not really interested in the validation just yet so we can just collapse it by selecting those lines, and going Edit > Outlining > Hide Selection (or if like me you like keyboard shortcuts, CTRL+M followed by CTRL+H). We now can see what the method's actually trying to do, and can easily ignore the validation code for now:
404 - Image Not Found
404 - Image Not Found
If later you do want to see the folded stuff, it's as easy as expanding the code again. It seems that VS remembers this custom code folding section for later on when I close and open the file, and even after closing VS itself (though I wouldn't rely on it to be there forever... I'm guessing it's stored in some local user settings file).
I've seen people use the #region directive a lot for this kind of thing - making the code easier to read - but then someone else who doesn't like #regions will delete it later, or someone will restructure it. The advantage of doing this is that it doesn't affect anyone else on your team.
To remove the custom code folded section, just do the opposite, Edit > Outlining > Stop Hiding Current (CTRL+M CTRL+U) ... H for hide, U for unhide.
Another use case for this would be doing code reviews, or maybe if you're presenting pieces of code that you don't want the audience to read and get too far ahead of the presentation.

Tuesday, May 26, 2015

DIFFERENCE in MS SQL

So, if I had two sets, A and B, and wanted to get all items that are in A but not B, as well as items in B but not A (i.e. the opposite of an intersection), I would have thought I could just do:

1
SELECT * FROM A
2
DIFFERENCE
3
SELECT * FROM B
Maybe my memory is failing me, but I thought there was a standard SQL difference operator, but after briefly looking around it seems there isn't.
It is possible though, using:
  1. EXCEPT
  2. FULL OUTER JOIN
I just tried it with table variables, set up as below (seems we get the same result with actual tables, but table variables are easier for demo purposes :B)
1
DECLARE @A TABLE (
2
    Number INT NOT NULL PRIMARY KEY
3
);
4
 
5
DECLARE @B TABLE (
6
    Number INT NOT NULL PRIMARY KEY
7
);
8
 
9
INSERT INTO @A (Number) VALUES (2), (4), (6), (8);
10
INSERT INTO @B (Number) VALUES (1), (2), (3), (5), (8);
EXCEPT way:
1
(
2
    (SELECT * FROM @A)
3
    EXCEPT
4
    (SELECT * FROM @B)
5
)
6
UNION
7
(
8
    (SELECT * FROM @B)
9
    EXCEPT
10
    (SELECT * FROM @A)
11
);
Quite verbose, but pretty easy to follow.
The FULL OUTER JOIN way is also pretty easy to follow:
1
SELECT
2
    CASE
3
        WHEN a.Number IS NULL THEN b.Number
4
        ELSE a.Number
5
    END
6
FROM
7
    @A a
8
FULL OUTER JOIN
9
    @B b
10
    ON a.Number = b.Number
11
WHERE
12
    (A.Number IS NULL AND B.Number IS NOT NULL)
13
    OR
14
    (A.Number IS NOT NULL AND B.Number IS NULL);
This is probably less easy to maintain, because you have to specifically reference the columns to match on, as well as choose which set to select values from, as is being done in the case statement. This could probably become a bit unwieldly for a table with lots of columns, and hopefully you don't mess up the NULL checks.
I did try this out on a query on a customers database though, and found that the full outer join method can be faster. Below are the execution plans for the two queries:
404 - Image Not Found
404 - Image Not Found
So, if I'm reading that right, it's having to go through each table more than once in the EXCEPT case, and only once in the FULL OUTER JOIN, which can make quite the... DIFFERENCE... (sorry couldn't help but make that pun :D).

Friday, January 9, 2015

Removing NodeJS folder on Windows

When playing around with demo projects on NodeJS, and then later trying to throw them away and delete the folders, you've most likely encountered the error: The file name is too long. We'll ignore the question of if it's too long, how it got created in the first place...
To illustrate it, create a folder that will cause a long file path. I've had this problem with grunt-contrib-imagemin, so lets install that package too:
1
cd \tmp
2
mkdir this-is-probably-a-really-long-folder-name
3
cd this-is-probably-a-really-long-folder-name
4
mkdir yeah-it-probably-is
5
cd yeah-it-probably-is
6
npm init
7
npm install grunt-contrib-imagemin -D
Now, if you try and delete this folder, you will get the pesky The file name is too long error:
1
cd \tmp
2
rmdir /s /q this-is-probably-a-really-long-folder-name
3
this-is-probably-a-really-long-folder-name\YEAH-I~1\NODE_M~1\GRUNT-~1\NODE_M~1\imagemin\NODE_M~1\IMF332~1\NODE_M~1\gifsicle\NODE_M~1\BIN-BU~1\NODE_M~1\download\NODE_M~1\DECOMP~2\NODE_M~1\TAR-ST~1\NODE_M~1\END-OF~1\NODE_M~1\once\NODE_M~1\wrappy\package.json - The file name is too long.
4
...
Le sigh.
If you manually try and change into that directory, at some point you'll also get an issue where you can't even change into it because the filename is too long. But wait, if you look at the above, everything is using short file names except the first folder. Hmm, what if we try the short file name?
1
dir /x
2
rmdir /s /q THIS-I~1
It works! Well, it did for me at least.

Tuesday, December 30, 2014

Finding the hostname for an IP address on Windows

When trying to investigate networking issues, most people know about ping and nslookup. I discovered today that there's also a utility called nbtstat to get some NetBIOS info, including the hostname and MAC address from an IP address.

nbtstat -a IPADDRESS

Friday, December 12, 2014

RequireJS and TypeScript

Here is an example of a RequireJS module:
1
define([], function() {
2
    function Calculator() {
3
    }
4
 
5
    Calculator.prototype.calculate = function (x, y) {
6
        return x + y;
7
    };
8
 
9
    return Calculator;
10
});
To make sure this is compiling through the TypeScript compiler, the first step is to convert it to use modules from TypeScript. The simplest way is:
1
function Calculator() {
2
}
3
 
4
Calculator.prototype.calculate = function (x, y) {
5
  return x + y;
6
};
7
 
8
export = Calculator;
To compile this, you then call the compiler with the right module flag, which is AMD for RequireJS:
1
tsc Calculator.ts --module amd
This will then generate the equivalent JavaScript. You'll notice it adds some extra code that's probably unneccesary, but hey, I'll take that for compile time safety:
1
define(["require", "exports"], function(require, exports) {
2
    function Calculator() {
3
    }
4
 
5
    Calculator.prototype.calculate = function (x, y) {
6
        return x + y;
7
    };
8
 
9
    return Calculator;
10
});
If you're working in Visual Studio, you might get an error about it not using the module flag. If you're working with an existing codebase, you might find you'll need to add TypeScript support first - adding a new TypeScript file in VS2013 does this by adding some stuff to the CSPROJ file, namely the XML element TypeScriptToolsVersion, and will need to reload the project. Afterwards, there should be a new tab for TypeScript Build options in the project properties dialog where you can choose the module style:
404 - Image Not Found