That's Neat, Changes.app!

One of the best things about having a laptop as my primary machine is that I generally don’t have to worry about synchronising issues any longer. For instance, I used to have a USB Drive that was my “transfer device”, and I was endlessly copying data to and from it. This meant I had three or more copies of my data, but I sometimes wasn’t sure which was the most recent.

I bought Changes.app to use with my Source Control system(s), as it is nicer than FileMerge.app. And it meant I could support an independent MacOS X Developer. And I’ve been using it, sometimes “in anger” where some data has been corrupted.

Today, I wasn’t able to get onto the Wireless network properly, and had my data on my Laptop, but needed to run some SQL queries on a database on a Uni machine. I copied the files across (in a location where the WiFi worked), and then ran the queries on the Uni Machine, but made some changes to both sets of files at the same time.

When I sat down to merge them all, I happened to think to use Changes. I dragged both folders onto Changes, and it gave me a list of files that differed.

I was able to choose which parts of each I wanted to keep, and save them, and it made both files the same as the merged version.

I wasn’t really expecting this – I naïvely thought that it was a read-only process, but Changes made it pleasant.

120 Feeds and no New News?

I subscribe to 120+ feeds, from mostly MacOS X related sites, but a few others.

From 9am onwards today, I don’t think I got a single new news item.

This is just so that people who subscribe to my feed actually get at least one new item :).

(Update: Apparently something was wrong with NetNewsWire – It just wasn’t downloading anything. A restart of the application fixed it. 70 items – that’s much more like it ).

(One reason) why J2EE sucks dog balls.

I really don’t respect or like Java as a language. I’m not going to go into reasons why here, but I am going to bitch about J2EE and Enterprise Java app development under NetBeans.

Now, I’m not just a clueless student annoyed with stuff that doesn’t work because I’m a gumby. I write enterprise applications in python, apache and SQL Alchemy for my day job. It shouldn’t be as hard as it is to develop in NetBeans.

For starters, if I deploy my code and it fails, I shouldn’t be able to redeploy it again and it works. Same goes for building. I have found instances where I can build and it fails, and then an immediate re-build succeeds. And I’m not talking “Clean Build”, just a regular ordinary build.

More to the point, if I do an “Undeploy and Deploy”, and I get a whole load of exceptions, I kind of expect that the deployment has failed. But if I then do a build, it works.

And, it appears that if I build without a fresh redeployment, it fails.

This is just build and deployment issues. I’ve also had instances where code has failed, when I was pretty fucking sure it should have worked. I was throwing exceptions all over the joint (or, more correctly, the JVM or some other bit of technology was), and they were meaningless. A redeployment and the associated re-build, and it worked.

Developing a similar application in python+SQL Alchemy is faster, doesn’t appear to run much slower, and is much, much easier to read later. Yet, it is not taken seriously, because it isn’t Java.

Ugh.

Getting the largest ID in a database

I ♥ SQL Alchemy.

I’m currently rewriting a database so that the schema definition is in SQL Alchemy, allowing for us to deploy it across a range of platforms with a bit more ease.

We had been using some sequence types to automatically set the primary key to a new unique integer. Think Autoincrement in Access, if that’s where you’ve done some database stuff, or in MySQL I believe it’s AUTO_INCREMENT.

In SQL Alchemy, you get to define Tables in python, like this:

log_table = Table(‘log’, metadata,
Column(‘IP’, String(15), primary_key=True),
Column(‘timestamp’, DateTime, primary_key=True),
Column(‘reqSize’, Integer),
Column(‘resSize’, Integer),
Column(‘time’, Float),
Column(‘reqName’, String(256)),
Column(‘reqData’, String(4096)),
Column(‘resData’, String(4096)),
Column(‘reqObj’, String(4096)),
Column(‘resObj’, String(4096)))

Now, if you need a sequence type, then you can use a Sequence() object. But what if you have existing data, which may or may not have holes, and you need to ensure you don’t have any collisions?

db.query(Person).order_by('id').all()[-1].id + 1

This will query and get the Person object with the highest id, and add one to it.

You can then use this as an argument to the Sequence() object, and it will only generate the sequence from that value onwards.

Done a Runner

(While I wait for something to compile…)

Had to fill the car up with petrol this morning. Petrol prices are a touch under AU$1.60/litre, which is higher than it has ever been in Australia. It costs me about 3 hours of work to fill my car up.

Anyway, there was a bit of a line up at the servo, and another guy came out to serve. The woman in front of me did the shit that she wasn’t being served first (people behind me rushed over to his till), and swore at everyone and stormed out, leaving a newspaper and some chocolate bars on the counter. Did I mention she was a bit fat? And feral?

So, she stormed out, straight into her car, which she had apparently also filled up with petrol, and drove off.

The chick behind the counter didn’t really get her number properly, so I corrected her.

And scored myself a free coffee for it.

But it was worth if for the show alone.

You called it what?

Shopping today – had to buy some Nutella (Hazelnut Spread).

Noticed a couple of cheaper imitations. One was Foodland or Black and Gold brand. The other, well, was:

20052008.jpg

Nutkao new Cream.

Guess which one I didn’t buy.

Daring Fireball Linked List: May 2008

John Gruber is well worth keeping in your feed list. Not only is the stuff he writes generally entertaining, on the ball and well written, but he finds other good stuff too.

Take, for example, his recent comment on How Apple is Changing DRM. Which, let’s face it, I wouldn’t have come across otherwise.

The flip side, though, is that DRM rules the day for paid video content.

From Daring Fireball Linked List: May 2008

I think that (tech-savvy) people are more accepting to have DRM applied to video content for a couple of reasons. First, you are less likely to keep watching the same movie over and over again. You are likely to listen to a piece of music over and over again. People will rent movies, either on DVD or from an online source, for this exact reason. By definition, rented movies must have DRM, else you have effectively bought them.

The second, and I think more important reason is to do with viewing modes of video. Most video is watched on a single device – at this stage still the device it was bought with. If you purchase a video on your computer, it’s probably to watch it there. Or, you have purchased/rented something as part of a system and plan to watch it on, say, an Apple TV, which uses the same DRM system as iTunes on your computer.

Perhaps in the future, as people have more video devices that can view the data they buy or rent, we will find less of an acceptance of DRM.

A third reason that just struck me is that traditionally, music was sold without DRM, even whilst in a digital format. Digital video has never really been sold without DRM. Even if it’s trivial to disable the DRM in DVDs and make copies, say to use on a device that doesn’t have a DVD drive.

Java 6 Breaks JComboBox Events

It took some figuring out, but I came across what appears to be a deliberate bug in Java 6 SE.

Under Java 1.5, you can rely on a JComboBox to generate ActionEvent actions whenever an item is selected from the list – even if that item is already selected.

Java 6 SE does not do this. You only receive an ActionEvent when you select a different item from the list than is currently selected.

For most cases, this will be fine. If selecting something should update other objects or properties, then this might not be the case.

There are a couple of workarounds. The one I chose uses .setSelectedItem(null) when another event is generated that would need to be ‘overridden’ by the JComboBox choice. Another is to create a subclass of JComboBox that performs the desired behaviour. But this is too hard.

It comes about from using ComboBoxes where they aren’t really designed. The shouldn’t really be used for actions to begin with, but in some cases they are.

This is yet another example of Java breaking previous code.

WiFi ate my RSS bookmarks

I have around about 120 feeds in my NetNewsWire subscription list. And I love reading all of them.

Just recently, I had noticed I seemed to be getting less and less news than before. This was odd, but I just put it down to everyone else being as busy as me.

Then, tonight I noticed when I refreshed my feeds manually, most of them had generic icons, instead of the usual favicons that appear.

When viewing the properties, all of these feeds had the default address that pages get redirected to when using one of the various Wireless networks I use daily is accessed without authenticating.

Thus, some of them pointed at www.vpn.infoeng.flinders.edu.au, and some had the IP address of the authentication router that one of the other APs points me at.

So, I spent the first half hour of my free time this evening double-clicking each item in the feeds list, and re-subscribing to the feed, and then deleting the original feed entry, which is pointed to the wrong site.

I then spent the next few hours catching up on the feeds that had obviously been modified by the lovely WiFi router over the past few months. 455 unread articles.

I’m not quite sure how the feeds addresses got changed, whether it is a NNW issue, or something that is idiosyncratic of the way that HTTP redirects work. I’m thinking it’s just a side effect of the way the router redirects all pages. But it is a pretty crappy one. I have looked at a method of trying to automatically authenticate on an unsecured wireless network that uses web-based authentication, but it failed last time.