Joe Doyle : Blog

Coding and Brewing beer

And the winner is… Git

In 2010 I made the choice to use Mercurial instead of Git.  That was mostly due to Mercurial having much better Windows support.  It had strong tooling for the command line, Windows Explorer, and Visual Studio.  It was a simple choice.  Ahh, but the times they are a changing…

Here we are, a quarter of the way through 2012.  The world has moved forward as it tends to do.  GitHub has dominated the open source world and elevated Git to be the de facto winner of the DVCS battle.  The final victory for Git was the announcement from CodePlex that they too will support Git.  It seems Git is really all you hear about now-a-days in the DVCS world.

So now that it’s clear that Git is the tool to know, I guess it’s time to make the switch for my personal projects.  I can get by cloning a repo with my rudimentary Git skills, now is the time to get familiar enough with it to use it in my normal workflow.  I’m not planning on converting existing repos, just starting new ones on Git.

Another good sign for us Windows Git users is that Phil Haack has moved over to GitHub.  I have much faith in Phil as he and the GitHub gang works towards improving the Git experience on Windows.

And I, for one, welcome our new DVCS overlords.

New Year, New Job, New Stuff!

Motivation can be a funny thing. Sometimes you have it when you don’t have time for it. Other times it’s nowhere to be found when you are desperately seeking it. My motivation for blogging has waxed and waned other the last year, as probably is apparent by all three of my posts. This year will be better. Hard to be much worse!

I am motivated by moving my blog over to WordPress. I think my layout is cleaner, and my mobile layout is awesome! (Try it!)

New Year!

Happy New Year! Gregorian and Chinese.

New Job!

In November I started a new job as a developer at Pinnacle of Indiana. They found me through Careers 2.0 at Stackoverflow.com. I had created a profile when it was still 1.0, but I never really expected to get contacted, let alone a job.

I get to work with a great group of people who have a focus on the craftsmanship of programming.  I’m excited to learn and hopefully begin to master the Agile methodologies. Most of our projects are .NET, but I’m getting exposure to other Microsoft products like SharePoint, Dynamics GP, and CRM. And of course, lots of web apps.  The JavaScript I write today is so much better than just 2 months ago.

So far it’s been a great opportunity for me and I’m super lucky to be working here. Depending on what I come up with, I might even do some blogging on our developer blog at www.pinnacleofindiana.com/blog/developers

New Stuff!

In addition to learning more work skills, I have started brewing my own beer!  I’m currently in process of fermenting my second batch. I started out with a Porter which turned out great! My Amber should be ready in about 2 weeks. I would love to blog about it, but I’m not sure what I would say yet.

I’ve played with quite a few of the “cool kid” technologies over the last year and I have a bunch of things I want to cover in future posts. Some of the topics are:

  • Node.js
  • MongoDB
  • JavaScript
  • Git

More posts are on the way!

CoffeeScript gently reminds me that tabs are not spaces

I recently picked up Trevor Burnham’s CoffeeScript book.  So far it’s a great introduction into CoffeeScript and also Node.js, two topics which I wanted to learn more about.  I started running through the first examples to see them run.  I downloaded the latest node.exe, and found a way to add the CoffeeScript module without NPM.  I wrote up a simple test just to make sure it worked:

console.log "Hello World!"

I ran this command to run it:

node %coffee% test.coffee

That worked.  Node gladly printed my string, passed through CoffeeScript.  Of course there isn’t much that CoffeeScript is doing, but there were no errors.

My next step was to try the first full sample in the book.  It’s a buildup of the larger app which the book is building up to.  I use Notepad++ for most of my plain text editing.  I typed in the code, saved it and ran it.

Error: In prompt.coffee, Parse error on line 14: Unexpected ‘POST_IF’

The function at line 14 looks like this:

promptForTile2 = ->
  console.log "Please enter coordinates for the second tile."
inputCallback = (input) ->
  if strToCoordinates input
  console.log "Swapping tiles...done!"
promptForTile1()

Everything looked correct. I just didn’t get it.  Googling for the ‘Unexpected POST_IF’ brings up that it’s a parsing error and most posts have to do with multi-line if statements.  I didn’t think that was what I was running into here.

Or was I?

I read through the multi-line if posts and it dawned on me that maybe it was being more helpful then I thought.  I went back though my code and re-counted the spaces just to make sure I was consistent.  Turns out I wasn’t exactly.  Notepad++ was helping me out my automatically starting the next line at the same indention level as the last line.  The I ran into was that Notepad++ was inserting a tab instead of 4 spaces when the indention was 4 spaces or more.  CoffeeScript didn’t like the tab to start the line after the if statement.  It wants spaces, not tabs.

The fix was easy enough.  Like all great apps, Notepad++ is flexible.  I just had to turn off the option to automatically align the next line.  After cleaning out the tabs and changing them to spaces, we were good to go.

Since I didn’t really find anything on Google I thought it might help someone else that runs into this.  I’m pretty sure it the kind of thing that only us Windows users will run into, with all of our overly helpful tools.

Cutting the Cable – Life after Comcast

Like most American’s, our family had cable TV, Comcast in our area. And it was good, just expensive. Having 2 TVs, HD service, and a DVR really adds up.  Throw in the sports package to be able to watch NFL Network in the fall and we’re talking a healthy sum of money each month.  Now we’re doing fine financially, but we have a house, a toddler, and are planning for another one in the future.  The more we can save, the better, right?

Channels, Channels, Channels

Our most common complaint is one you can read about whenever someone talks about cable (or U-verse, or satellite).  We had more channels than anyone can watch. We had just about each channel twice, one in standard def, and one in HD.  I never did count them, but I would guess we had about 250 HD channels.  Of which, I think we watched about 15 on a regular basis.  And most of those weren’t watched live, but through the DVR after we recorded the show.

When you compare the total number of channels available per your monthly bill, you’re probably close to $0.25 a channel.  Not too bad.  But when you compare that bill to our actual usage… Now it’s more like $10 a channel.  Throw in that 4 of those channels are the major networks, and that makes you think if there is a better way.

I know that the “À La Carte” channel model will never happen even though that is the trend most technologies are headed. If that were an option on Comcast, we would have stayed a cable TV customer.  We are still an Internet customer, but on the business side.

To the Cloud! – Kind of

So what’s the alternative?  We do like to watch some TV.  Just not as much any more.

Netflix – Of course!  Hulu Plus also helps fill in the gaps.  But we have a nice HD TV which is a monster compared to our laptop screens!

Roku to the rescue!

IPTV – The future is here

I don’t remember exactly where I first heard about Roku boxes.  I think it was a podcast or maybe Slashdot.  Either way, this device is pretty slick.  You can connect it to your Netflix, Hulu Plus, and Amazon Instant accounts to get started.  Then there are a bunch of free and premium channels available as well.  Roku also has an SDK which allows developers to create their own channels from content they may already have available in the web.  You can even connect into your Pandora account to listen to music through it.  A little Googling, and you can even find a channel to watch YouTube.

Roku has 3 different models available ranging from $60 to $100.  This is a one time fee.  You just have to pay for the other services you use, like Netflix or the premium channels.  Honestly, there is no reason not to just get the XD|S version and call it a day.  Full HD, wireless N, optical output, AND a USB port which can be used to view pictures or play movies.  All of that is worth the extra $40 in my opinion.

Overall, the quality is really good.  Granted, having a 20MB downstream internet connection sure helps that, but overall, we haven’t had any issues with the Roku box itself.  It holds the wireless connection well and picture quality is really good for streaming.  We even picked up a second Roku for the other TV.

Just about perfect

Overall, Netflix & Hulu Plus cover about 80% of everything I want to watch.  We don’t have Amazon Instant right now.  Hulu Plus is good, but the commercials have to go.  I’d pay another $5 a month to be totally commercial free.  Saturday Night Live is pretty much skit, commercial, skit, commercial.  Plus, I like Big Bang Theory, so no CBS on Hulu also hurts a bit.  The CBS website does cover that though.

The transition was pretty smooth.  Our TV bill is now about 1/10th what it was before.  We miss the DVR and select shows that aren’t on Hulu Plus, but everything else is on demand anyways. There’s also plenty of children’s programming for our little guy.  I have thought of getting an antenna and seeing what local channels get can get in HD.  We haven’t quite gotten to that point yet, but maybe someday.

Getting Started With MongoDB and the 10gen C# Driver

My main goals are to setup MongoDB for small scale applications that aren’t going to scale up to lots of users and multiple servers. I’ve installed MongoDB as a service and I’ve started to play around with the 10gen C# driver. There are a couple of C# drivers already out there (NoRM and the mongodb-csharp ones being the most popular) and people report varying levels of success. 10gen has also released a driver which has caught up feature-wise to the others. I decided to use this one because it’s easy to use and I do get a warm and fuzzy feeling knowing that it is from the 10gen folks. You can find the repository at https://github.com/mongodb/mongo-csharp-driver

Into the code!

The best place to get started is the 10gen C# driver tutorial at http://www.mongodb.org/display/DOCS/CSharp+Driver+Tutorial.  It covers what you need to get started and sometimes a bit more.

The app I’m writing is a simple one that stores usernames and passwords along with some other information like the URL of the website to use the password and any notes that we might want to add. It’s just going to be on our internal network and won’t have any interface to the internet. That means I’m not focusing on things like encrypting the passwords, or other security measures if this were to be used anywhere else in the public.

Connecting to your database is pretty straight forward. There are many other options available, but just to get started, you just need the server name.

    MongoServer server = MongoServer.Create("mongodb://myserver");
    MongoDatabase db = server.GetDatabase("TheDatabase");

One of the things I like about MongoDB is that just asking for the database will create it.

So now that we have a reference to our new database, what are we going to do with it? Most of the time, we already have a model ready to be stored. Here’s my class that hold a password set.

    public class CredentialSet
    {
        public ObjectId _id { get; set; }
        public string Title { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public string WebSite { get; set; }
        public string Notes { get; set; }
        public int Owner { get; set; }
        public DateTime LastUpdate { get; set; }
    }

It’s a pretty basic class. The only addition from standard C# is the ObjectId class. This class represents the default MongoDB identifier. You can choose to use your own unique identifier, but for now, I’m just going to use the default.

Our next step is to create an instance of our class and save it to the database. But first, we need a place to store it. In the relational world, we would use tables inside our database to store the data. In the MongoDB world, we use the Collection. Just like the database, the act of getting the reference to it will create it if it doesn’t exist.

    MongoCollection passwords = db.GetCollection("passwords");

As you can see, we can specify our CredentialSet class when we get our collection. Even though MongoDB is a schema-less document store, it does make life easier to have a standard, static type to work with. When we specify a class like this, we are telling the driver to use our CredentialSet as the default when pulling our documents from the database. You can still insert any type of document you want, but this style saves us some key strokes later on.

So now let’s save our document.

    var password = new CredentialSet();

    // set the property values.
    passwords.Save(password);

We can now use a tool like MongoVUE to see our record in MongoDB. When we take a look at it, we see something a little unexpected. Our _id is all zeros!

    /* 0 */
    {
      "_id": "000000000000000000000000",
      "Title": "A password",
      "Username": "username",
      "Password": "password",
      "WebSite": "www.google.com",
      "Notes": "This is a password!",
      "Owner": "1",
      "LastUpdate": "Tue, 1 Feb 2011 10:47:20 GMT -05:00"
    }

Doing some research, I found some references to a known issue with the 10gen client, and a simple fix.  We just need to add an attribute to our model’s _id property.  Here’s the updated CredentialSet.

public class CredentialSet
{
    [BsonId]
    public ObjectId _id { get; set; }
    public string Title { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
    public string WebSite { get; set; }
    public string Notes { get; set; }
    public int Owner { get; set; }
    public DateTime LastUpdate { get; set; }
}

This tells the driver that we want to use the _id property as the internal MongoDB identifier.  After delete our exiting item using MongoVUE, we can run our sample again and examine the record.

/* 0 */
{
"_id": "4d38833880844214f0a8c60b",
"Title": "A password",
"Username": "username",
"Password": "password",
"WebSite": "www.google.com",
"Notes": "This is a password!",
"Owner": "1",
"LastUpdate": "Tue, 1 Feb 2011 10:47:20 GMT -05:00"
}

Much better.  Now we can try to pull that document out.  There are lots of queries you might want to do.  Way more than I can go through.  I’m just going to show two simple examples.  The first is pulling out all documents, and the second is finding a specific record based on a single field.

Let’s start with all records.

var allPasswords = passwords.FindAll();

It doesn’t get much easier than this!  Again, we can use this simple method because we’ve specified a default document class.  From here, we have a collection of CredentialSet objects that we can work with using standard methods such as foreach or Linq to Objects.  So now let’s get a specific document.

To get a specific document, we need to build up a Query object to tell the driver how to create the JSON that MongoDB will use to find our document.  From there, we use the FindOne method on the collection.

var query = Query.EQ("Title", "A password");
var oneDocument = passwords.FindOne(query);

There are lots of options when creating a Query.  The one we used here, EQ, does a simple Equality comparison.  It finds all documents where the Title field exactly matches ‘A password’. Since this was the Title we put in above, that’s the one we get back.  Just about all of the options for querying are available. The 10gen C# driver page does a good job covering them.

Wrapping up

This was my first use of MongoDB.  With the basics of saving and retrieval down, I can move forward on getting an app up and running. I know that this is really simple and it doesn’t cover any of the features MongoDB is known for such as master/slave replication or sharding.  I also don’t do any error checking.

Something as simple as this can be done with any relational database. But in order to do this, I’d need to hook in an ORM such as nHibernate or EF4. That means extra code. The MongoDB driver handles all of the class to JSON mapping automatically. That’s what I’m looking for with this.

Standard tutorial disclaimer: None of this code is what I consider Production Ready. It did give me a starting point to move forward from. Hopefully it helps someone else as well.