November 2005 Blog Posts

Flat Tire Tuesday; AK Rocker Found

Yesterday was pretty eventful from a "lots of crap happening" standpoint.

I started off the day with a routine eye exam, which meant I did a little bit of work from home prior to the appointment. I also found the AK Rocker I was looking for at Circuit City. Ordered with a web special, it's $8 less than it was at Costco and I can pick it up from the store to save on shipping. Ordered and done; planned on picking that up after work.

Went to the eye exam. My glasses prescription has changed in such a minor fashion that I don't even have to worry about getting an update unless my glasses break (which just happened about four weeks ago) or get lost, so I'm good there. Also, no signs of iritis, so I'm good there, too. Two years to my next checkup.

Of course, they dilated my eyes so coming in and working was kind of a pain. Polarized sunglasses on polarized LCD monitor makes for some interesting contortions to be able to see the screen.

After work - haircut. Once every four weeks, baby.

On the way to the haircut, Jenn calls me. Guess who has a flat tire.

Okay, so the thing is, on Sunday I looked and told her that her front tires looked a little low. The bottoms were bulging out pretty bad and indicated some air could be had. She, of course, ignored it.

Sigh.

I was already halfway across town by the time I heard about it, so I told her to go back inside her work and stay warm (it's been pretty cold out) and I'd come over right after my haircut and bail her out.

Finished up my haircut and stopped by Fred Meyer on the way to help Jenn and picked up some gloves. No need to get all dirty, right? My hairdresser even donated some old towels to the cause.

Got up to where Jenn was and she was cold because she had stayed in the car rather than going back into work and sitting in the warmth. Sorry, babe, got nothin' for you. Got the tire iron out, stuck it on one of the bolts and...

Nothing. That sonofabitch wasn't moving. I stood - full weight - on the handle of the wrench to try to get those things to move, but it just wasn't happening. You have to love the impact wrenches tire stores use to put those things back on. Set the torque, guys, seriously.

Cranked on that for quite some time when a lady who was parked nearby provided a much larger cross-shaped lug wrench. That one gave me enough leverage to get the nuts unscrewed and get the wheel off. My arms were sort of shaking with the effort expended, and I'm not sure whether that's a sign of my lame physique or something more legitimate. (Each nut made a loud cracking noise as I broke it free - that's how tight they were. I wonder if maybe some WD-40 would have helped...)

Anyway, got the tire changed and sent Jenn on her way.

Made it back across town to Circuit City to pick up the chair I had ordered online that morning. Turns out the "pick it up from the store" process works pretty smoothly; I had anticipated problems. I may have to try that again.

Got everything back home and put my new chair together while watching TV. It's really cool, and much more comfortable than the other two video rockers I have, so I think that's my new favorite game chair.

All in all, not a bad day, but a lot more effort than I was hoping for. Jenn's heading over to Les Schwab this morning to see what can be done with her tires, and I'm wallowing in the bajillion things I have to get done today. It's kind of like when you have a big report to write - starting is the hardest part.

AK Rocker Gone From Costco

I finally caved in and decided I want one of those AK Rocker game chairs, so when Jenn went to Costco yesterday I told her to pick me one up. They've been there for months and I figured it was time.

Guess what they don't carry anymore. That figures.

Thanksgiving 2005

The training I was in transitioned nicely into Thanksgiving. It was almost like having a whole week of vacation... but not.

Thursday (Thanksgiving) we went to the Hometown Buffet for dinner. My parents, my sister Tori, Jenn, my grandfather, Stu, and Tif all went. This proved to be an excellent answer to all of the issues that usually arise with Thanksgiving dinner. For example, what if someone (like me) doesn't like turkey? No problem - you can have pretty much anything you want. What about the cleanup? There is none. Preparation? Nope. Everyone gets what they want, and as much of it as they want. It couldn't be any better. I even had a cheeseburger. Right on! Plus, Granddad paid. Thanks, Granddad!

After dinner, Jenn went off to visit her family (and would later rejoin us), Granddad went to visit some other friends, and the rest of us returned to my parents' place for some games. We played Lord of the Rings Risk, Apples to Apples, and even got some Donkey Konga in there. (Bongos on Thanksgiving is cool.) That went reasonably late into the evening, then we called it a night and departed for our respective residences.

Black Friday came and I had no intention of going anywhere, nor did I. Instead, Stu and Tif came over. Stu and I played some of The Warriors (like, 8 hours' worth) while the ladies entertained themselves. The night ran late, but it was awesome - the first time in a while I've gotten a decent gaming session in.

(As far as The Warriors is concerned... it's a lot of fun, but the camera could use some work. It's a pain to control. That, and in a two-player game the screen is split vertically and it would have been better to split it horizontally because there is very little vertical movement. But it's fun, and a good two-player game.)

Saturday Jenn and I ran around to stores looking to reap the benefits of the remaining sales on a few items but came out empty-handed. That evening, though, we went to the Winter Hawks hockey game to see the Teddy Bear Toss. When the Hawks score their first goal, the crowd throws stuffed animals onto the ice which then get collected and distributed to local childrens' hospitals. Good fun for a good cause. Each year they try to break the record set by the year before. This year we beat last year's record (and set the new league record) with 21,067 bears donated. That's pretty good.

Oh, Saturday I discovered I'm allergic to my deodorant, too (causes a nice rash - thanks, Speed Stick Gel), so I'm going without for a couple of days (sorry, co-workers) to let the rash go away and I'm going to have to shop for a new one. (They stopped making the one I had been using for years, so I had to switch - unfortunately, I chose poorly.) Awesome.

Sunday was sort of a "catch up on all the stuff you've neglected" day. From morning until around 1:00p Jenn and I were outside cleaning up the yard. Had a hell of a time getting the lawnmower to start and just about kicked the crap out of it when I found the secret - you have to tip it back slightly while you're starting it. That's not documented anywhere and I don't remember having to do that before, but that's the trick. Weird.

After the lawn, having played The Warriors with Stu on Friday, I went to the video store and rented the 1979 movie the game is based on. It wasn't too bad, and the game is totally dead on with its reproduction. I also rented Logan's Run (I wanted to see it for the pop culture reference, but the movie itself is horrible) and The Jacket (which was pretty decent, plus Keira Knightley is hot).

And now it's Monday and I'm catching up on email and so on. Somehow I think it's going to be a looooong week.

Where's iTunes SQL Support?

I'm working on setting up various Smart Playlists in iTunes and every time I'm working with them I totally run into all these shortcomings with the way they work. Like, what if I want all of the pop songs by Depeche Mode and Erasure that show up between 1980 and 1990? You have your choice of AND or OR, right? So it's "Genre is Pop" and "Year is in the range 1980 to 1990" and... what? "Artist is Depeche Mode" and "Artist is Erasure" won't work. I need an OR.

Why can't I just do this:
SELECT * FROM Library WHERE Year BETWEEN 1980 AND 1990 AND Genre = 'Pop' AND Artist IN ('Erasure', 'Depeche Mode')

No reason, that's why. Come on, guys, get with the program.

2734B: Updating Your Database Development Skills to Microsoft SQL Server 2005, Part 2

I'm going to combine days two and three into one big entry because I don't think I'll get a chance to do a full day-three review at the end of today.

Yesterday was day two and we looked at SQL Server 2005 service broker stuff, its native HTTP support, and Notification Services.

The service broker facilities they've added are pretty cool. The ability to set up messages and queues and such inside the server is neat, and it folds nicely into the native HTTP support to allow for exposure of these things via web service. Cool. SQLXML has rolled into SQL Server, which we all anticipated and love.

Notification Services, though... OK, I'm just going to be brutally honest:

SQL Server 2005 Notification Services sucks big fat donkey dong.

Seriously.

Notification Services is the biggest hunk of claptrap Rube Goldberg mechanics I've been introduced to in a long time. It's not debuggable, it's super-hard to set up, and for what it offers I'm not sure it's worth the effort.

We had a lab to set up some rudimentary Notification Services. The lab involved us creating a lot of hand-cranked XML configuration, running some setup to get the services up and running, then testing it out.

Problem 1: The XML contains SQL that turns into stored procedures. Why is that bad? When they make the stored procedures, there's nothing to tell you whether you have a typo in the SQL. I mistyped a database object name and it never had a problem with it. In fact, I found that error in the Event Viewer - not even in the SQL error log - and only when it actually tried to execute the procedure. NO!

Problem 2: There's insufficient logging. After I corrected my error, I tried to use the service again and something else went wrong. What happened? I have no idea. It just swallows the errors and moves on like there's no issue. No errors, no warnings, no log. How am I supposed to debug that?

The whole thing where the XML that you have to hand-generate (and there's a LOT) has a lot of magic words in it that you just have to sort of "know" about (like you have to just "know" that when you type "Foo" in one element that it becomes a stored proc with a name like "ServiceFooSomeProcNameHere" - yeah, that's intuitive. It really does work like Rube Goldberg machines - this bit of XML kicks this block of code out that rolls down the hill and knocks this table row down and flips over and tosses a message over to that service... Come on, guys. It's like someone took a weekend, architected the thing, and clamped it on the side of SQL Server 2005 so they could have a selling point or something.

Today we'll be learning about managed code in SQL Server 2005, which looks great; working with client apps (ADO.NET), which won't be news for me; and SQL management objects, which also looks great.

Oh, and before I forget, tomorrow is Thanksgiving, so Happy Thanksgiving to all!

Using System.Web.Caching From The Console Or Windows Forms

I'm looking at different ways to provide caching from within an application so I can read in some information from a file, keep it in memory, and have cache dependencies perform a callback to update the cache whenever the file changes.

This is simple to do in an ASP.NET app using the System.Web.Caching.Cache object that you find in HttpRequest. Just add something to the cache with a cache dependency and you're set. But what about if you're working in a console or Windows Forms app?

I did an experiment and it looks like you can access the cache from any application as long as you access it through HttpRuntime directly. I haven't tested to see if this works on a machine that doesn't have IIS installed, but I don't see why it wouldn't.

Below is my experiment code. It's a console app that reads/writes the cache with a file dependency that constantly changes. Running it, you can see that the cache is doing what you expect, just like in a web app.

using System;
using System.Diagnostics;
using System.IO;
using System.Web;
using System.Web.Caching;

namespace ConsoleApplication1{
  class Class1{
    const string KEY = "mykey";
    const string FILENAME = "dependency.txt";

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args){
      WriteFile();
      InsertItem();

      for(int i = 0; i < 1000; i++){
        ReadItem();
        WriteFile();
      }
      ReadItem();

      if(Debugger.IsAttached){
        Console.ReadLine();
      }
    }

    static void InsertItem(){
      DateTime t = DateTime.Now;
      Console.WriteLine("Inserting item into cache: {0:m.s.ffffff}", t);
      HttpRuntime.Cache.Insert(
          KEY,
          t,
          new CacheDependency(Path.GetFullPath(FILENAME)),
          DateTime.MaxValue,
          TimeSpan.Zero,
          CacheItemPriority.Default,
          new CacheItemRemovedCallback(CallBack));
    }

    static void ReadItem(){
      object item = HttpRuntime.Cache[KEY];
      if(item == null){
        Console.WriteLine("Item is null.");
      }
      else if(item is DateTime){
        Console.WriteLine("Item is {0:m.s.ffffff}", item);
      }
      else{
        Console.WriteLine("Item is wrong type: {0}", item.GetType());
      }
    }

    static void WriteFile(){
      if(File.Exists(FILENAME)){
        File.Delete(FILENAME);
      }
      Console.WriteLine("Removing file.");
      FileStream stm = File.Create(FILENAME);
      stm.Close();
      Console.WriteLine("Wrote file.  File exists: {0}", File.Exists(FILENAME));
    }

    static void CallBack(string key, object value, CacheItemRemovedReason reason){
      Console.WriteLine("Callback invoked: {0}", reason);
      InsertItem();
    }
  }
}


If anyone finds a problem with it, do leave me a comment with reproduction info. Seems to work, though, which is pretty cool.

2734B: Updating Your Database Development Skills to Microsoft SQL Server 2005, Part 1

I'm taking Microsoft training course #2734B: Updating Your Database Development Skills to Microsoft SQL Server 2005. I've got my MCSD; I really just want to see what's new in SQL Server 2005 and how to use it. Rock on, right?

Day 1, we covered a general overview of SQL Server 2005 changes (enough to give you a general idea of what the course will cover, but not enough to really tell you anything), some of the T-SQL enhancements they've added, and a bit on how they've updated the handling of XML in the database.

The first module, the overview, was pretty good for the beginners but really didn't tell me much.

The second module, the T-SQL updates, was neat. They added some stuff that should have been there all along (ALTER INDEX, anyone?) and put some really cool things in for partitioning. When we got to pivot tables... well, I won't lie. I generally understand the concept of pivot tables, but I'm not a data analyst and really don't care to be, so when we got to the use of PIVOT and UNPIVOT, I took it in from an academic standpoint but I can't say I totally get it. The new ranking operators are cool, though, and I can see how they would be very useful. And how can I forget the TRY/CATCH they've added? Love that.

The third module, on handling XML, got a little more tricky. I feel pretty comfortable in my XML skin and worked with SQL Server's OPENXML and SELECT...FOR XML in the 2000 version, so that stuff wasn't new. The added ability to format the output of the XML to the level now available is very welcome, as is the ability to store XML as a native data type (either validated or not).

So what have I seen that I don't like?

When we got into the trickier parts of the XML stuff - updating values of attributes in stored XML fields, for example - the book got a bit sparse. The lab would instruct you to do something like "change the 'foo' attribute in the document stored in field 'bar' in the first row in the table to have the value 'val'" and when you went to look up the syntax for that... well, good luck with that. I ended up opening the solution and seeing how they did it (at which point it finally made sense).

The biggest issue, though, is how arbitrary some of the syntax has become. It turns out that in some cases, T-SQL requires semicolons to end statements and in other cases it doesn't. That makes it difficult, but I figured out that they don't penalize you for ending every statement in a semicolon, so maybe that's the new habit to get into. I also don't like the inconsistency of the syntax - sometimes you specify options in parentheses, sometimes you don't; sometimes the parameters for a method are in [square brackets] and sometimes 'single quotes.' The worst bit is that they seem to intermingle it all without any rhyme or reason, so you might call a function like FUNCTION_CALL MODIFIER([param1], 'param2') 'param3', [param4] even if all of the parameters refer to database objects. Consistency! Pick something and stick with it! It feels very much like all this was tacked onto the end of T-SQL and they did their best not to alienate previous T-SQL users but couldn't quite make it happen.

Today, day 2, we're looking at the native SQL Server 2005 service oriented architecture provisions. I'm liking it so far. Better than SQLXML, anyway. It occurs to me that you could potentially replace BizTalk with SQL Server 2005. I wonder if that's what they were going for.

Harry Potter and the Goblet of Fire

Saw the latest installment of Harry Potter this weekend, and it rocks. I am so pleasantly surprised to see them get back to the books rather than taking too much "creative license" or whatever and ruining the thing the way they did with the last one. In all honesty, I wasn't looking forward much to this one because I was afraid they'd butcher it like they did with the last one. Not so - this is definitely the best since the original movie.

I won't review the plot, since there's a whole book on it and you can find out about that online. The question is, "Should you go see it?" The answer is an unequivocal yes.

A lot happened in the book, and I don't want you to think that they didn't cut anything, because they did. The beginning, in particular, was chopped down. Nothing to be too disappointed about because from a plot perspective, you're not missing much - a bit of character development and background, but nothing that would translate well to the screen. That said, the things that could be shown were, and they did a fantastic job with them.

The effects continue to impress me. With each episode, they get better and better with the effect quality and the level of sheer cool they throw out there. The magic, the creatures... it all totally looks exactly the way you imagined it, and it's brilliance to see it happening.

What I'm most pleased with, though, is that the screen translation of the book retained the awkwardness of growing up that was so important to the ongoing character development. I was afraid that since it wasn't a driving plot point they would nix it, but they carried it off well - the characters' expressions and actions reflecting the whole time the changes that their lives are undertaking. It totally captures that stage of adolescence where you're discovering dating and the social difficulties that ensue. Great in the book; just as great in the movie.

All the actors did a fantastic job, as usual, and the new faces... perfect casting. Love it. I don't want to give too much away - you'll just have to see.

Long story short - check it out. You'll be glad you did.

I already can't wait for the next one.

CR_Documentor Gets Its Own Visual Studio Hacks Article

Previously the CR_Documentor plugin made its way into the Visual Studio Hacks site in an article called "Ask The Pros: Visual Studio .NET Addins." Today it makes it in with its own dedicated article. That totally rocks!

I noted in the article that one of the downsides of CR_Documentor mentioned is the lack of support for included files. Not to worry; I've been noodling on how to make this work in a performant fashion. Not forgotten, just not quite here yet. There are other things I want to add, too, like the little gray box that shows the method signature in the doc and so forth. We'll see what we can do.

Something the article doesn't mention is the context menu that gets added to the code editor with CR_Documentor. It adds a lot of helpful commands that allow you to expand/collapse the XML comment blocks in your document, convert text blocks into XML comments, XML encode selected text, and insert XML comment block templates (among other things).

If you haven't already, check out CR_Documentor.

It Might Be Time To Step Up To ASP.NET 2.0

I just got a copy of Professional ASP.NET 2.0 and now I'm thinking it's time to put some of the skills I'll be learning from it to use. Stu and I have talked about writing our own blog software because none of the packages out there really do all the things we want, so maybe this is the time to step up and learn this stuff. It's always better to learn when you have a project you're working on (otherwise it's just aimless and nothing seems to get done).

Time to start reading, eh?

CR_Documentor Appears On Powertoys Weblog

Seems CR_Documentor is making the rounds today. Got a mention on the Powertoys Weblog from Josh Ledgard, which totally rocks.

CR_Documentor Appears On Visual Studio Hacks

The Visual Studio Hacks site just published an article in their new "Ask The Pros" series called "Ask The Pros: Visual Studio .NET Addins." In that article, Scott Hanselman gave some props to CR_Documentor as his favorite DXCore plugin. Thanks, Scott!

Serenity Available on DVD

SerenitySerenity, the best sci-fi movie I've seen in a looooong time, is now available for pre-order at Amazon. December 20th it's out. That's pretty quick, but I'm not going to analyze it too much. I'm stoked to see it again, and in the comfort of my own home. Buy two copies - it's that good.

155 Trick-or-Treaters

I decided to keep a tally this year of how many trick-or-treaters showed up to the house this year. Between 6:00p (when I got home and started serving) and 8:00p (when the frequency of arrivals slowed enough to warrant shutting down) we had 155 kids.

Of course, probably 15 of those were probably old enough to be tried as adults for any crime by a jury of their peers (hint: high school means no more trick-or-treating), so let's use quotes around "kids."

One kid was pretty lippy, too. Probably nine years old or so, he shows up and I answer the door in my Wonka costume. I hand out the candy and just before leaving, he strikes up conversation:

Kid: Who are you supposed to be?
Me: Willy Wonka.
Kid: I hate that guy. He's queer. [Kid exits stage left.]

Give me back that candy, you prepubescent asshole.

Aside from that, all went well. I realize now that the tally would have been much more interesting had I charted the number of kids who showed up both by general age group and time so I could see the trends from year to year, but maybe that's just overengineering the thing.

We didn't run out of candy this year, which was good (we did last year). We did go through about six pounds, though. Jenn's going to take the remains to work so we don't pig on it at home.