Archive for the ‘Coding’ Category

Gotta Admit, Heads-Down Coding is A Ton of Fun

Thursday, November 19th, 2009

Today I've been doing a fair share of heads-down coding on the Google Visualization DataTable in Java - to get it up to the current JavaScript API published by Google. I started with this update a few days ago, but I stopped at the filtering and sorting. Today I dug into the filtering and allowed either a Java List<Map>, or the standard JSON array of maps. To make this a little easier, I made a parser to take the JSON string and convert it into the Java List<Map> and then have the JSON version of the method call the Java version. Pretty simple, but the converter was a little tricky, but not too bad.

I was pleased with the filtering. It worked wonderfully, and while it's probably not the highest performance implementation, it's pretty good, and certainly good enough for what I'm going to be using it for initially, which is just filling out the API spec. But if there becomes a problem later, I can imagine a few ways to make it nicer, I just didn't mess with them, and so performance tests to see which is better.

But the really nice thing was just that I was able to shut the floor out, listen to some decent music instead, and focus on coding. The one thing I really enjoy. That was the treat I gave myself today - the pleasure of creating. I really don't get to do it enough.

Camino 2.0 is Out

Thursday, November 19th, 2009

Big news from the alternative browser space - Camino 2.0 has been released and is out there for all. It's not my top-flight browser choice, but you need to have a bunch of them to test all the pages you make, and this one is nicely Mac-like with the Mozilla engine behind it. It looks like it's got a new tab overview - like Safari's latest pages feature. Could be nice, sort-of like Expose for the browser. We'll see if it's really useful.

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.

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 &amp; 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.

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.

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.

Examining the Limits of the Web 2.0 Paradigm

Tuesday, November 10th, 2009

AJAX.jpg

Today I needed to get a few interesting things done on my web app - primarily all GUI-related, but there were a few things I needed on the back-end for some new functionality I was adding to the administration page. It was very simple on the back-end and on the GUI, and it got me to thinking - Are there really limits to the Web 2.0 paradigm now? I'm not convinced there are that many.

Oh sure, if I was writing a Photoshop-clone, using a web browser is a mistake. But for the vast majority of the apps that I've written in my life, I'm not sure that they could not now be written in AJAX and be just as effective as the original apps.

This web app I'm working with is a great example. Lots of graph/graphics that needs lots of data, but it's working just fine. Sure, I might wish the Google Visualization widgets were a little more full-featured, but that's an implementation issue - not a limitation of the technology.

I have been talking to an old friend about some problems they are having with their patient management system - a successor to one I wrote for them many years ago. That could certainly be re-written in the AJAX framework and probably have a significantly better user-experience. At the time, it was forms-based, and while that was fine for patient management, it's not anything like what we're doing now.

I'm getting to like this idea more and more. In the past, applications like Paradox and Filemaker were the tools that I used to make these applications, but now I could use a Mac Mini Server with Tomcat, H2, and AJAX, and be done with it for next to nothing. This is really pretty impressive. I just need to keep thinking about things a little differently. Interesting what assumptions you challenge, and how your answers change as time passes. Neat.

Finally Getting to Make Some Nice Progress Today

Monday, November 9th, 2009

Today started off very nicely. I fixed up a few more things on my web app and was able to get rid of the fixed calendar on two pages and replace it with a pop-up version of the same calendar. It allowed me to free up a nice 200x200 px area that I really needed to free up for some other GUI elements. It was really nice to get something done and make progress on something.

I was then able to keep moving and add a new feature to the web app and allow a few interesting aggregations on the client. It was interestingly easy - I took the data, had the mappings from the existing columns to the aggregating columns and then simply run through all the rows collecting the data into the aggregate columns. Simple. One nice little function in the code and a few GUI widgets and we're good to go.

It's been very nice to get real progress made today. No problems with legacy apps... no never-ending performance problems... it's nice to make progress.