Categories
Javascript Programming rants

Debugging in IE.

I did something I shouldn’t have done: from JavaScript, I appendChildNodes()-ed some text and an img to an existing img. I apologize. Firefox told me it was OK. To put it more accurately, Firefox didn’t tell me anything, and just didn’t show the text and the img, which was what I wanted it to do. IE really didn’t like it.

Finding out what IE was so upset about wasn’t fun, as I didn’t have a debugger for IE. So I started looking for one. Not wanting to install visual studio just for that, I installed(*) “Microsoft Script Debugger”, which is one old piece of software. It’s so old that its readme states that it works with IE 4. At least it works. It lacks watches and some other features you’d expect from a debugger (which Firebug has!), but it got the job done. Mostly.

I wasted about 40 minutes on that issue.

* Installing “Microsoft Script Debugger”, contrary to what some my tell you, does not require installing old office versions. I followed a download link on Microsoft’s website, and got it. It does require some voodoo if you’re running Vista, but nothing too hard to handle.

Categories
Databases Design Programming startup

Actual Data Always Needs To Be Explicit

This might seem obvious, but it wasn’t to me it first. Now I consider it a database design rule of thumb, or even a patten.
I’ll explain using an example. Consider an application where you also need automatic tagging of text. (As in generating keywords.) So you’ll have a table for objects that have textual fields (for instance, blog posts), and a table for tags.
Now, you would need a many-to-many mapping between these two tables. Various ORMs might do this automatically for you, or you might add a PostTag table yourself, with foreign keys to the other tables.

You think this might be enough, as your smart tagging algorithm can add tags and attach tags to blog posts. If you want to change it manually, then no problem, you just modify any of these tables. For example, if the algorithm makes a mistake, you just erase the mapping and/or the tag.

The problems start when you want to run the algorithm more than once.
First, the algorithm must not create duplicates on the second run. This is very easy to implement and doesn’t require any change to the DB. Now, let’s say that a taggable object (our blog post) has changed, and we want to update the tags accordingly. We might want to erase all the mappings we created for this object. No problem, also easy to do.

What about manual changes? Should these be erased as well? Probably not, at least not without alerting their creator. So we need to record the source of these mappings in an extra column of the mapping table, and use it to mark manually and algorithmically generated mappings differently.

How about deletions? What if the first time around, the algorithm made a mistake, and added a wrong tag, which was manually removed? Running the algorithm again will cause the tag to be added again. We need some way to mark “negative tags” , which are also pieces of information. The easiest way I found of doing this is adding a boolean “valid” column to the mapping table.

It’s important to note that this also applies to all mapping types and not just to many-to-many. So even when you don’t naturally need a separate table for a mapping, you should consider adding one, if the mapping is part of the actual data you keep. Also, if you need to keep extra data about the mapping itself, for example “relationship type” in a social network or “tag weight” as in our example, you would already have a separate table anyway.

I encountered this issue when I implemented my multiple source db-design. A reminder: I had data collected from various sources, and then combined together to a final merged record. The combining was done automatically.
My mistake was that I only considered the records as pieces of data, and didn’t consider that the actual grouping of raw data records is also part of the information I keep. As such, I should have represented the groupings in a separate table, with the added columns, as I outlined in this blog post.