Archive for November, 2009

Google Chrome dev 4.0.249.0 Fixes AnnotatedTimeLine Bug

Thursday, November 19th, 2009

I noticed this morning that Google Chrome dev 4.0.249.0 was out for the Mac, and it fixes the nasty JavaScript bug that I submitted to Google a while back. I'm really excited to see this fixed, not for the Mac, per se, but the fact that this was the reason the Google Chrome Frame stopped working.

When I got to work and restarted IE 8, I was able to see that the auto-updating of the Google Chrome component in the Google Chrome Frame was working and my pages were working once again. Fantastic! I really love it when good software is written by great engineers.

Cyberduck 3.3 is Finally Out

Thursday, November 19th, 2009

This morning I noticed that they finally had an official release of Cyberduck 3.3. This new release is Snow Leopard compatible, and 64-bit all the way. Not that I use an FTP client a lot, but this is one of the cleanest I've ever seen. It does it all.

How Bad Can it Be, Really? Plenty…

Wednesday, November 18th, 2009

This morning I came in to a horrible problem brought on by a new business focus, and folks not asking the right people what the possible impact would be of a seemingly simple change. Both of the apps I'm responsible for suffered this morning - one was a disaster until I could get a fix in the code for the problem, and another was simply not showing the right data. Arguably, not a lot better, but at least it was up and running.

The problem started long before I joined the Shop with the decision by someone to make all the databases case-insensitive sorting. This means that the data: "Steve" and "STEVE" are different in the database, but if you try to do a SELECT on the data, you'll get both values on any variation of "Steve" in the WHERE clause.

Let's assume we had a table in this database where people's names were held.

ID First Last Age
412 Steve Jobs 44
21 Tom Swift 44
332 Bill Gates 44
12 Tom Slick 44

then it would be possible to do the query:

  SELECT * FROM people WHERE FIRST='steve'

and get:

ID First Last Age
412 Steve Jobs 44

but you'd get the exact same results if you did:

  SELECT * FROM people WHERE FIRST='STEVE'

or:

  SELECT * FROM people WHERE FIRST='sTeVe'

It doesn't matter to the query processor. I can't see a possible reason for this - why not just force all the data in a table's column to be uppercase? It would make it case-insensitive, but not open you up to the following disaster.

Last evening something was added to this mythical table - a new "Steve Jobs". Let's say the table originally looked like this:

ID First Last Age
412 STEVE JOBS 44
21 Tom Swift 44
332 Bill Gates 44
12 Tom Slick 44

and they wanted to correct the mistake in the case of the name. Well... the obvious change to me is to run the SQL:

  UPDATE people
    SET FIRST='Steve', LAST='Jobs'
    WHERE ID=412

But that's not what was done. No, they created a new person so that the database looked like this:

ID First Last Age
412 STEVE JOBS 44
21 Tom Swift 44
332 Bill Gates 44
12 Tom Slick 44
601 Steve Jobs 44

now we're in a pickle. When we try to find Steve with the SQL:

  SELECT * FROM people WHERE FIRST='Steve'

we're going to get both of the rows:

ID First Last Age
412 STEVE JOBS 44
601 Steve Jobs 44

and where we were expecting one row to be returned, we now have two. Different systems will handle this differently, but there's no way the database will be able to differentiate them by their names. In reality, the ID is all that you have, and that's typically not visible to the users of a complex system.

This is what hit me this morning - two rows, and the new row was the first one returned, and it wasn't completely set up properly, so a lot of the supporting data wasn't there. Disaster.

Since there's nothing you can do to the SELECT statement, you have to filter the output, so my code went from:

  String    sql = "select ID from people where First='" + name + "'";
  ResultSet rs = stmt.executeQuery(sql);
  if (rs != null) {
    if (rs.next()) {
      id = rs.getInt("ID");
    }
  }

to:

  String    sql = "select First, ID from people where First='" + name + "'";
  ResultSet rs = stmt.executeQuery(sql);
  if (rs != null) {
    while (rs.next()) {
      if (name.equals(rs.getString("First"))) {
        id = rs.getInt("ID");
        break;
      }
    }
  }

and then later in the code, of course, I need to check and see that I actually got something.

While it's not horrible, it's something that's totally avoidable by either setting the case on the fields in the table, or allowing correct case determination in the SELECT statements so that this would easily have been found out early in the process.

As it was, I spent several hours on this - fixing code, and planning for other similar problems as they migrated datasets in the database. It's just not necessary.

Web Sites aren’t Made for Ampersands

Tuesday, November 17th, 2009

Today I've had a little fun with ampersands. Those little buggers are nasty to get right in the URLs and the HTML pages and XML config files of a typical Tomcat web site. But after having done it enough today, I think the rules are pretty simple, but need to be followed to the letter.

In URLs - Escape, Escape, Escape!

If you're in a JSP, or Java, in general, then the easiest thing for a URL is to use the URLEncoder that's in the standard JDK. It's possible to do the manual replacement, but it's so easy to use the URLEncoder that there's really no reason to do it the hard way.

  StringBuilder  vars = new StringBuilder();
 
  var.append("report=").append(URLEncoder.encode(report));
  var.append("&page=").append(URLEncoder.encode(page));
  var.append("&name=").append(URLEncoder.encode(name));

it's so easy, that there's no reason not to. However, a surprising number of developers forget to do this simple act.

In HTML Pages Go Verbose

It's been said that the escape sequence & is one of the most verbose HTML escape sequences, and I have to agree. It's a mess, but it needs to exist for the reason that the ampersand is the escape sequence initiator. So it goes. In HTML, use it. It's just what you have to do.

In XML Config Go Verbose Again

It makes a little bit of sense to have the HTML and XML escape sequences for ampersand the same, but as with other things, I would not have been surprised if it had worked out that things were different in the two markups. What I am surprised at is that the URL escape code (%26) is not allowed in the XML config files, but then again, I guess it's exclusively for the URLs.

There's what I learned today. Doesn't sound like much, but it was a pain to pin down.

Getting Back in the Game

Monday, November 16th, 2009

I had a pretty rough weekend, and Liza still isn't feeling very well, so today has been a short (8 hr) day at work because I needed to be home to help her out. It's no fun having a migraine, and with all she's been through, it seemed to be the least I could do. So I left a little early.

Before I did, it was a day of messing with the configuration of one of my inherited apps to make it more granular for the business. Their plans for next year include paying closer attention to things in slightly different portfolios, so the took a very large one and made it several small ones. Nothing really earth-shaking about it, but there's a lot of little configuration details to make sure that things are ready to go. Nothing earth-shaking, but time-consuming.

I sure hope Liza is feeling better tonight.

UPDATE: we took her to the doctor near the house and got her a migraine 'shot' to clear up the migraine. It's a horrible thing. I wish she felt better.

Skitch 1.0b8.4 is Out with Snow Leopard Fixes

Monday, November 16th, 2009

This morning I noticed that they have released an update to Skitch, the incredible networked image tool, to 1.0b8.4 with a few improvements for Snow Leopard and extending the 'beta timeout' in the application. I'm guessing that someday they aren't going to extend the beta period, and that's when I'll need to cough up the money to purchase it. It's just that valuable to me.

One Heck of a Weekend

Sunday, November 15th, 2009

This weekend has been a pretty stressful weekend. Liza hasn't been feeling well, she had to spend the night in the hospital for tests... it was really stressful. I heard someone say that being in a hospital is like entering a time warp, and I totally agree. There's nothing that happens quickly in a hospital - unless you're in real trouble, and that is a good sign, I suppose.

The Lead-Up

It started last Tuesday (11/10) when Liza told me she couldn't open her right eye all the way. It didn't sound good, but she's not one to run to medical help if there's not broken bones or bleeding. In this case, it wasn't warranted, and since there was no blurred vision, no outward signs of a stroke, no dizziness, she thought "I'm getting old". So she let it go.

Wednesday (11/11) it was getting better, she could open it more, still had a headache from the day before, and now things didn't taste right. The ice cream she had in the evening didn't taste right. I told her that tomorrow (Thurs) she was going to the doctor to get it checked out. And she did.

Thursday (11/12) her right eye could open up almost all the way. It was very hard for me to even tell there was a problem, but she could tell that the right eyelid wasn't opening up as quickly as the left. When she called the doctor and explained her symptoms, they wanted her in right away. She, of course, had a few things to do, and went in around 3:30-ish in the afternoon.

The doctor saw that the right pupil wasn't responding to light like the left one, and tried to get her into the opthamologist that afternoon. No luck there, but the next morning (Friday) was going to have to do. She tells me that he didn't look very lad back and happy after seeing the pupil dilatation difference. He even gave her a list of "bad things" to check on overnight. The worst of which was a ruptured carotid artery. Nice.

I knew I needed to go with her on Friday as it was going to mean pupil dilation, and that's no fun to drive home with. So we went. The doctor was very nice, and checked her out from top to bottom. He couldn't see any evidence of the differing pupil dilation, and in general, couldn't see anything wrong with here in the complete exam. So we left with no idea what was causing the problem.

When we got home, I started doing a little taste-testing with her. What was it in her taste that was really effected? Turns out, it was sweet and sour. They are connected, so that makes sense, but her sense of smell was totally unaffected. That was odd. We both remembered that your sense of smell is tightly coupled to your sense of taste, but I guess the reverse is not necessarily true. She could smell lemon juice, but it wasn't sour in her mouth. She could smell sweet cookies, but she couldn't even taste raw sugar on her tongue. Very odd.

The next morning, Saturday, we decided to go to the emergency room as waiting another two days for a chance to she her primary care physician didn't seem like a good idea any more.

The Weekend

Saturday morning we had a volleyball game to coach, and after the game we got a little lunch and then headed out to the emergency room at the local hospital. We had expected to spend the rest of the day there, but little did we know Liza wouldn't see the light of day for more than 30 hours.

We got into the emergency room, explained the story once to the nurse. She got the vitals and we started to wait. That afternoon, she got a CAT scan, and explained her story now fewer than four more times to doctors. I told her we needed to write it down before we came and then just hand out photocopies. In the end, by 4:00 pm we hadn't seen a doctor for more more than an hour, and we were convinced by their stunned silence that they had no idea what was happening.

Hey, that's OK. As long as they don't know, then it's not something like a stroke, tumor, etc. All those they'd recognize and we'd be in a lot worse shape than if we didn't know. So I took this as a good sign, and about the only thing they could do yet was an MRI. We figured, OK, that'll take an hour, let's get cookin' and get it done.

Silly me.

They had to 'admit' her, but they really didn't, we later found out. They had her as an Out Patient in-house. Very odd, but that's what they wanted to do. Still, we didn't learn this until long after, but it's interesting that they believe all these little details are "beyond" the typical patient. I say, tell me the facts, and let me decide.

Rather than get her up and going, it took several more hours of waiting, and then about 7:00 pm, she was in her room. When I returned from checking on the kids and making sure they had dinner, we found out that she wasn't going to have the MRI until the next morning. Now while some people might not mind this "mini-vacation", she and I wanted to be back at home and not sitting in some hospital room. It's not restful, no matter what you hear.

I left at 8:30 pm on Saturday to be with the kids for the night. Telling her I'd be back in the morning as early as I could.

On Sunday I arrived at about 6:45 am and she was awake and waiting on the MRI.

Finally, at 8:30, they took her to the MRI. Good. Maybe we can be out of here by noon. Sounds very reasonable. After all, this is a simple "covering the bases" test as they have no reason to believe it'll uncover anything, but OK... we go.

By 9:40 am, she's back in the room and we sit and wait for the neurologist to come in and tell us the results, and then we can leave. So we say "Noon. We'll give him to noon, and then we'll ask them to contact him."

Good plan.

So we wait.

At noon I get up and go talk to the nurses and ask if they have the ability to call the doctor and ask when he's going to come in and give us the results. Here's where my wonderful experiences with the nurses up to this point sours. They say that they can't get ahold of the doctor, and there's nothing they can do. In fact, they can't even be sure he's coming in today.

OK, I'm not an idiot, but what about some healthcare professionals thinks they can treat me like one. Do they think I'm dumb enough to think that if she goes into a seizure they will not be able to get ahold of him? Wrong. Simply silly. Of course, they can contact him... they just won't.

If it's honest, then I can deal with it. Tell me you won't, not that you can't. Then, I can say "Give me the number, and I'll call" - to which they can again say they won't (or not), and we can go from there. But the lies to save them from having to look bad or incompetent are really quite annoying when it's your health on the line.

Finally, I got a nurse that told me that if they called, the doctor would hang up on them. To which, I said "Give me the phone number", and I called him. Amazing how a little personal presence can get things moving.

He wasn't up to speed on the case, even at a different hospital (possibly), but he felt uncomfortable enough that I felt we'd gotten his attention and at 4:00 he walked in the door.

Of course, his answers were the same as we'd heard all weekend: "No idea". But the MRI was clear, and finally we got to leave. Liza finally got the prescriptions for something to kill the migraine, and that was good, but it was days late, and my poor wife had to sit in a horrible hospital bed for more than a day for an hour-long procedure and be told the same thing as the emergency room doc said.

I'm exhausted. I know she is. It's been one heck of a weekend.

Keeping Up with The Googles

Thursday, November 12th, 2009

GoogleVisualization.jpg

When I started using the Google Visualization widgets, like the AnnotatedTimeLine, I didn't have any Java-based tools and had to make my own to fit into the Tomcat backend of the web app. Not too bad, Google had an API for the server component, and a pretty complete spec for the DataTable, I just had to build it. So I did.

In the meantime, they have built a Java back-end, and while it's possible to use theirs, it's no better than what I have in mine, so I'm sticking with that, and yet they have significantly expanded the spec for the DataTable. I needed to play "catch-up". So that's exactly what I did this afternoon.

Most of the things weren't too hard, but I'll admit I've postponed the filtering and sorting as I just didn't have time for it today, and I didn't think it was going to be something I needed this week. I'll get around to finishing it, I just didn't get to it today.

The rest is pretty well implemented. I've put in some unit tests (where appropriate), and they are working well. I also ended up making a lot of the objects Cloneable so that it was easy to copy these guys. Details, yeah, but that's where stuff like this lives - all in the details. We now have the ability to get limits on columns, distinct values, etc. It's much more full-featured.

But if Google keeps moving, I'll need to have another afternoon like this. I don't see them making a Java version of this, but if they did, I'd certainly look at it. I'd love to find something that's well-built and completely free of my involvement. But until they do, this is what I'm going to stay on top of.

Safari 4.0.4 on Software Update

Thursday, November 12th, 2009

This morning I knew that I needed to get Safari 4.0.4 with a few security fixes and a few nice improvements - like faster JavaScript execution, which always helps. Safari is still my favorite browser on any platform, and on the Mac, it's just beautiful. I just wish they allowed me to have the "tabs in the title bar" that was a feature of the beta several months ago. I really liked that, but can see that there were a bunch of folks that didn't. Hence the option. In any case, it's the thing to do this morning, and then the reboot... ugh... but a necessity.

JSON is Faster than XML – This is No Surprise

Wednesday, November 11th, 2009

I was reading the wires today and came across another article talking about the speed advantage of JSON over XML in the serialization/transfer/de-serialization. Certainly, that's no surprise to anyone that's used both of these formats. XML, as it's defined is just not meant to move large amounts of data, and while it's possible to use it for config files, I think it's still a miss there as plists or SQLite is a far better solution.

But what got my interest this morning is the existence of a Google Groups project called touchcode. In this one project, there is a sub-project called TouchJSON that implements the JSON format in Obj-C code. This is cool stuff.

I've done plenty of JSON stuff in Java for the Google Visualization API, but this means that I don't have to mess around with writing an API for all the work on the Mac I might like to use JSON. Again, I can't see it as a valid tool for config files, but for serving up JSON data, this, along with a nice embedded HTTP server in Obj-C would be a great pairing. That way, I could stay in Obj-C and provide JSON data to AJAX clients. Neat.

Not sure why WebObjects got the can, but it did. Sure would be nice to see what (if anything) Apple is looking at for a possible replacement.