Monday, August 6th, 2007
Interesting PHP MySQL tips.
Some comments:
2. Always prepend the table name to the field. E.g. ProductName, SupplierPostCode.
This refers to field name aliasing, not to actual field names. He doesn’t suggest that you actually name your fields like that in the table, but only when you select them: SELECT product.name AS product_name instead of SELECT product.product_name. The only real reason I can think of why you’d want to do this is for easier selecting the values in the calling code. I don’t see why it would make joins easier, as it’s just as easy to type JOIN order ON order.product_id = product.id, IMHO.
3. Always create a primary id field with the name of the table followed by the id. e.g. ProductID
Two things I don’t agree with. First, it’s not always necessary to create a primary id field. You should only add an ID field if there’s no unique key for that table. Second, I don’t think prepending the tablename to the ID field is a good idea for primary id fields. It’s not really bad either, but I like a plain ‘product.id’ field better, because you can instantly recognise the unique identifier field for that table. Foreign key fields, on the other hand, do feel better with their tablename prepended: order.product_id refers to product.id.
5. Use a separate logging table or transactions for logs of table updates, deletes etc.
We usually create a duplicate table for every table in the database, and name it ‘tableHistory’ or something like that. Then we add some metadata fields to the history table (time, user, mutationtype, etc) and place triggers on each table so that any mutation will insert the old row into the history table for that table, along with some metadata. That way, you always have a complete history of every mutation in your database. Great for auditing, plus you can create generic ‘Last changed by foo on bar’ functionality very easily.
Sunday, August 5th, 2007
I don’t buy music CDs. They’re more expensive than they should be, and the prices never drop, even if the CDs are old. I don’t buy music online either, since it’s usually even more expensive than a CD, it has stupid DRM (Digital Restriction Management) restrictions, and you don’t even get the nice booklet. How can something that has no costs for physical production, worse quality than the real product and less value for your money cost more than the real thing? I don’t buy movies (DVDs) either, because there’s all kinds of restrictive stuff on them such as regions and DRM copy restrictions.
DRM that’s meant to keep you from copying media is illegal in the Netherlands. We’ve got a law that says you can make backup copies of media you buy. Fair-use probably also allows me to convert media I’ve bought so that I can listen to it in my car (if I had one), or on whatever device I happen to have. It’s also legal in the Netherlands to make copies of music and movies for your friends. Since DRM prevents these things, it’s illegal. Why would I buy a product that is too expensive, restricts my rights and is also illegal?
Instead of buying content, I download it. I download massive amounts of music and movies, and I never pay for any of it. And I don’t have to feel guilty about it, because it’s legal in the Netherlands. I can download as much as I want, but distributing contents is illegal (unless it’s to some close friends).
In the Netherlands, we pay a tax on empty CDs and DVDs. Legislators assume everybody buying empty, writeable media is a criminal. It’s not even a case of “Guilty until proven innocent”, because there’s no way to escape the tax, short of illegally importing empty media from across the border. What if I just want to make backups of my personal files? The money’s supposed to go to the record companies. It doesn’t always get there apparently, but it’s the idea that counts. I don’t want my money to go to the record companies, because they’re greedy bastards that keep breaking the law and violating my rights. So I don’t buy empty media either. I’ve got a big fat Internet connection and harddisk space is cheap, so why would I keep my stuff on CDs or DVDs?
I don’t have to feel sorry for the artists either. They get their money from the tax on empty media. Except from me of course. But if the law can be ambiguous, so can I. Besides, those poor artists should stand up to their record companies and distributors and demand fairly priced CDs and DVDs and renounce DRM.
I’ve got 8000 pieces of music on my computer. Let’s say the average CD contains eight songs. That’s a thousand CDs. I’d consider €10,- for a CD that’s just been released a fair price. An older CD, say, a year old, should cost a maximum of €5,- to €7,- euro’s. So let’s say €6,-. Most of my music was older than a year by the time I downloaded it. Perhaps 2% was just released. That would be twenty CDs.
20 x €10,- = €200,-
980 x €6,- = €5880,-
Total: €6080,-
So, the record industry could have had approximately €6000,- of my money in their pocket instead of €0,-, all because they’re greedy bastards. Too bad folks, but I don’t really feel sorry for you.
Here’s what the government should do:
- Remove the tax on empty media.
- Break the Record Industry’s cartel
- Demand fair prices on CDs
- Outlaw Digital Restriction Management when it breaks the law.
Saturday, August 4th, 2007
There are some myths out there which are just blatantly false, but that are really pervasive:
- Water in a sink on one hemisphere does not flow from the sink the other way than on the other hemisphere. There is such a thing as the Coriolis force, which (basically) describes the deflection in the path of an object moving on a rotating sphere due to its inertia. The Coriolis force does explain why cyclones rotate in the opposite direction on the northern hemisphere than on the southern hemisphere. But the force is simply way too small to have any effect on the rotation of water draining from a sink.
- Hair is not alive, it’s dead. The only thing alive is the hair-sack beneath the skin, from which the hair grows. Same goes for nails, as both consist of keratin
- Split hair-ends cannot be mended. Once split, they stay split. Apparently, some products out there will glue them back together temporary, but after it wears off, the ends split again.
- Hair does not grow back thicker when you shave it. It just appears that way because the hair-stems are thicker than the ends.
- Your hair cannot turn gray all at once if something scares you.
- Going swimming after having eaten something will not give you cramps and make you drown.
I thought about citing references, but that would be useless. People who believe (and keep perpetuating) these myths are apparently hellbent on keeping those beliefs, no matter how much evidence you show them that it’s false. For the others out there, google around a bit. You’ll find enough information dispelling these myths.
Thursday, August 2nd, 2007
I never really liked Gnome because I couldn’t make Metacity act the way I like it.
I’m used to WindowMaker, and it has very configurable keybindings for managing windows. For instance, it’s quite easy to map a keybinding like <Control><Alt>-;
to an action that maximizes the currently focussed window horizontally. Another keybinding maximizes the window vertically. These are very useful options for me, since I use terminal windows a lot.
Another annoying thing about Gnome/Metacity was that you could have a keybinding which maximized the currently focussed window, but pressing that keybinding again wouldn’t bring the window back to the original size. This is another feature is use all the time, because I often need to have more screen real estate for my terminal window for a short while (so that I can see more of the terminal output buffer).
Something else I missed from WindowMaker is binding keybindings to programs in the menu so that, say, <Win>-e
opened my editor. This didn’t seem possible in Gnome/Metacity, and I didn’t want to use a third-party application for it, because that doesn’t integrate nicely with Gnome (and will therefore cause strange behaviour, such as conflicting keybindings in applications).
In the past, I’ve given Gnome a couple of tries, but everytime I switched back to WindowMaker after a little while because of the lack of proper keybindings. A couple of days ago I decided to give Gnome another try, because I’m planning on installing Ubuntu (currently running Debian GNU/Linux) somewhere in the near future. Quite by accident, I stumbled upon the fact that Gnome/Metacity does support all the keybindings I’m used to. All you have to do is dive into the GConf registry a bit.
Window manipulations
Here are the various locations for Window manipulations in the Gnome registry and their purposes. To edit these, you’ll have to have the gconf-editor
installed.
/apps/metacity/window_keybindings/maximize
Maximize the window. Disable this setting because it doesn’t “toggle” the maximization state, it only maximizes the window. Just edit the value and enter ‘disabled
‘ as the value.
/apps/metacity/window_keybindings/maximize_horizontally
Maximize the window horizontally. (make it as wide as the screen while keeping the same height)
/apps/metacity/window_keybindings/maximize_vertically
Maximize the window vertically. (make it as high as the screen while keeping the same width)
/apps/metacity/window_keybindings/toggle_maximized
Maximize the window on the first keypress. Unmaximize it on the next keypress.
/apps/metacity/window_keybindings/toggle_shaded
Roll up the window so that only the title bar is visible. This is handy for quickly peaking under the currently focussed window.
You can edit these bindings by right-clicking on the key and selecting ‘Edit key’. For the value, you’ll have to type out the full keybinding name. For instance: “<Control><Alt>r” (without the quotes). Take a look at the already defined keybindings for hints.
Global command-running keybindings
After finding out about the above configuration options for Metacity, I took a closer look at other options, and it turns out you can also bind global keybindings to programs so you can have shortcuts. Just press the keybinding and the program starts. I’m using this mostly for the top-10 applications I use: browser, editor, terminal emulator and some other stuff. Here’s how to add keybindings to programs:
- In gconf-editor, find the key
/apps/metacity/keybinding_commands/
. Here, you’ll see a list of ‘command_NR’ key/value pairs.
- Edit the value for one of the
command_NR
keys, and enter the name of the program you want to run when pressing some keybinding. For instance: /usr/bin/gvim
- Now, go to
/apps/metacity/global_keybindings/
. Here, you’ll see a list of keys with names similar to run_command_NR
.
- Edit the value for the key with the name corresponding to the key you edited in step 2. Enter your keybinding in the same way as mentioned above.
Using the Windows key for bindings
Perhaps it’s not the same on every system, but I couldn’t use the Windows key (left of the left Alt key) for keybindings. When I tried binding commands to it in Gnome’s Keyboard Shortcuts manager, all I got was an ‘Super_L’ entry, and I couldn’t enter any extra modifiers (such as <Super>e, to run my Editor). Turns out you have to change the behaviour of the Win key so that it registers as a normal modifier key (similar to Shift, Control, etc) in X.org. Here’s how to do that:
- Open the Keyboard manager. On my system, it’s the
System → Preferences → Keyboard
menu-option.
- Open the
Layout options
tab.
- Open the
Alt/Win key behavior fold-out.
- Choose the
Meta is mapped to the left Win-key
option.
- Now,
Meta
is a code-name for one of the modifier-keys. Each modifier key (Shift, Alt, Control, etc) has a codename. But internally, X.org doesn't use these codenames. Instead, it used different names: Mod1
through Mod5
. And apparently it differs from system to system to which Mod-X
internal name the Meta
modifier is mapped. So in order to find out which Mod-X
you'll need to use when specifying keybindings, you can use the Gnome Keyboard Shortcuts manager.
- Open the Gnome Keyboard Shortcuts manager. (
System → Preferences → Keyboard shortcuts
)
- Click on of the options, and press the
Win
key with some other key. This will appear in the manager as: l
, for instance. You now know that you need to use Mod4
if you want to bind commands or other things to the Win key when using the GConf-editor tool.
Move/resize Windows with a modifier key
WindowMaker's got this option that allows you to move and resize windows by simply holding the Alt
key and then drag-and-drop anywhere in the window to resize or move it. So, if I hold the Alt key, and press and drag anywhere in the window with the left mouse-button, I can move the window. If I hold the Alt key and press and drag with the right button, I can resize the window. This is so much more comfortable than having to go al the way to the edge of the window in order to drag it.
I don't know how long Gnome/Metacity's been supporting this, but as far as I know, it didn't the last time I tried it. It does now. I'm not sure if you need to turn it on explicitly, but here's how it's set up on my system:
In the menu, choose System → Preferences → Windows
. Here, under 'Movement key', choose the 'Alt' key. You can now move windows by holding Alt
and then use the left mouse-button to move the window. Holding Alt
and dragging with the middle mouse-button in the window resizes the window. It's a little annoying that you can't resize windows when it's maximized (either fully, horizontally or vertically), but I guess I'll get used to that. Or maybe I overlooked an option in the GConf-editor again... lemme check.. Nope, doesn't look like it.
Standard window options
Something that's completely unsupported by Metacity is automatically setting window options on windows when they start. WindowMaker has a facility that allows you to set options for windows as soon as they are opened. This way, you can force a window to be maximized or minimized as soon as it opens, even if the program itself doesn't support this. Metacity can't do that, but there's a third-party application that takes care of that: Devil's Pie.
Application run dialog
By default, Gnome has an Application Run dialog, but it's not very good. It doesn't do a good job at completing the name of programs I want to run. I want tab-completion. Fortunately, I wrote GExec a while ago. I've hooked it up to the <Win>r
keybinding as described in the 'Global command-running keybindings' section in this post.
Result
I now have the following keybindings set for Gnome/Metacity:
Control-Alt-h |
Switch to the workspace on the left. Vim-style. |
Control-Alt-l |
Switch to the workspace on the right. Vim-style. |
Control-Alt-j |
Minimize the current window. |
Control-Alt-k |
Maximize/Unmaximize the current window. |
Control-Alt-- |
Shade/Unshade the current window. |
Control-Alt-; |
Horizontally maximize/unmaximize the current window. |
Control-Alt-' |
Vertically maximize/unmaximize the current window. |
Control-Alt-1 |
Jump to workspace 1. |
Control-Alt-9 |
Jump to workspace 9. |
Win-e |
Start my editor (gvim). |
Win-b |
Start my browser (Iceweasel / Firefox). |
Win-x |
Start my terminal emulator. (gnome-terminal) |
Win-r |
Start my application launcher (gexec). |
With the customizations described above, I feel Gnome is probably much more usable for me. I hope to switch to Ubuntu shortly. For the curious among you, this is how my desktop looks now:
.
And this is what it used to look like:

Update: I forgot to mention. If you want to bind keybindings to stuff like <Control><Alt>-; , you need to enter <Control><Alt>Semicolon. Use the Gnome keyboard shortcut manager to find out the proper keybinding to enter in gconf.
Update II: These customizations work for Metacity 2.14.5. Your mileage may vary for other versions.
Update III: Also check out the Emacs keybindings 'theme'. It lets you use Emacs-like keybindings in Gnome so that you can press Ctrl-u
to erase everything in front of the cursor on the current line and/or use Ctrl-y
to insert back what you just erased ('yanking'). Edit the GConf key /desktop/gnome/interface/gtk_key_theme
and set it to the 'Emacs
' value. If you're only using GTK and not Gnome, you can add a line with:
gtk-key-theme-name = "Emacs"
to a .gtkrc-2.0
file in your home directory to get the same effect.
Saturday, July 28th, 2007
Here’s an interesting use of SQL: SQLChess – A tutorial on thinking in sets.
Saturday, July 28th, 2007
I write a lot of documentation for various articles and projects. Usually, I’ll use DocBook for writing that documentation. DocBook is an SGML/XML dialect for writing articles, books and other writings. It’s pretty extensive, and it can do a lot. It can export to LaTeX, HTML, PDF and a variety of other formats. But it’s also somewhat tedious to write, with the many and long tag names.
Some time ago I searched for an alternative to DocBook. Something more simple. My wish was for something as simple to write as, say, Wikipedia’s Wiki syntax.
During my quest for the ultimate document markup tool, I came across reStructuredText; a simple text-based format used by (amongst others) Python programs to put document markup in Python source code. Though reStructuredText is pretty good, I found it a bit limiting. It doesn’t seem to support exporting to PDF (unless you want to pass the generated HTML through a HTML2PDF converter) and its syntax is kind of limited. Another problem is the fact that it’s not easy to distinguish different headings because they all use a bunch of ‘=’s, ‘-‘s, ‘~’, etc surrounding the headings.
Just the other day I found AsciiDoc. AsciiDoc is very similar to reStructuredText, but it supports more formats. It can convert to HTML, PDF en DocBook (which in turn can be converted to many other formats). It also supports Wikipedia-like ‘== heading ==’ headings. It’s very readable. It’s also a lot faster than DocBook.
Here’s a little example of a document marked up with AsciiDoc:
PHLite User Guide
=================
Ferry Boender
v0.1, Jul 2007
About
-----
This document serves as the User Guide for PHLite v0.1.
Introduction
------------
PHLite is a lightweight, no-nonse, easy to use web
development framework for PHP. Most of the currently big
frameworks focus on Web2.0, design patterns, REST-fullness,
MVC and other 'hip' paradigms. Often, they are too strict in
enforcing these methods and therefor restrict the developer.
Getting Started
---------------
This chapter should help you get started using PHLite.
=== Requirements ===
PHLite requires:
* PHP 5.1.0 or higher
=== Basics ===
Very clear, isn’t it? The example above produces this HTML document. And, yes, it can also generate automatic Table of Contents for documents (including HTML), something that seems to be missing from many documentation generators.
Wednesday, July 25th, 2007
Here are some true facts about Microsoft Vista:
- Vista is the forefather of the Matrix AND Skynet
- Vista installations contain two full dumps of both Bill Gates and Steve Balmers DNA so they can be cloned in the future.
- Your installation of Vista is very safe. The FBI, NSA and Homeland Security keep a close eye on it for you.
- Every time you click on something in Vista, a kitten is killed (slowly, like everything else in Vista)
- Vista is possessed by the devil. Vista CDs glow eerily in the night and produce spooky sounds, even when not in your computer
- Vista was an experiment of Microsoft’s research department to see what would REALLY happen if you’d let twenty-thousand monkeys bash on a ‘typewriter’ (keyboard, in this case).
- 2,189,000 and a half trees where destroyed due to printing out Vista’s source code and manuals at Microsoft.
- Vista’s so ugly… it’s uglier than yo momma!
- People die every minute out of frustration with Vista
- Vista wouldn’t be so bad (but still pretty bad) if it didn’t cras)!#@_!!!!E_NOCARRIER
Tuesday, July 24th, 2007
Amazingly enough, I’ve never had the need to find duplicate rows in a table before. But in this case, I somehow forgot to add a key to a particular table in a database and, naturally, duplicates where accidentally inserted. Of course you’ll want to put a key on the table, but first you’ll have to remove the duplicate rows. As is usually the case, it’s pretty easy using SQL.
Suppose you have the following data in a table:
firstname lastname Age
----------------------------
Jane Doe 21
John Doe 25
John Smith 43
Jane Doe 55
Jane Smith 22
John Doe 19
Jane Doe 21
The superkey in the above table is (for example) <firstname, lastname>. To find duplicates for this superkey, you can use the following query:
SELECT
COUNT(*),
firstname,
lastname
FROM Address
GROUP BY firstname, lastname
HAVING COUNT(*) > 1
This will give the following results:
COUNT(*) firstname lastname
---------------------------------
2 John Doe
3 Jane Doe
This means the combination ‘John’ + ‘Doe’ appears two times and ‘Jane’ + ‘Doe’ appears thrice. People with a little SQL experience will find this straightforward, but I’ll explain anyway:
We select a “COUNT(*)” in order to count all the rows, plus we select firstname and lastname fields so we can see which are actually the duplicates. We use the fields firstname and lastname on the GROUP BY clause because that’s our superkey. GROUP BY will tell aggregate functions (COUNT(), SUM(), etc) in the SELECT clause that it should count grouped by certain fields, not just all the results returned. Basically, it counts all the unique values of a concatenation of firstname + lastname. The HAVING COUNT(*) > 1 is purely to weed out stuff that’s not duplicate.
I’m not quite sure how to automatically delete duplicates while leaving one in place though ;-)
Update: I do now! Here’s how to delete duplicates in place: SQL: Remove duplicte rows
Saturday, July 21st, 2007

The little blue-yellow fish (a Spanish Hogfish) in the picture on the right looks like it doesn’t have long to live, doesn’t it?
But nothing’s farther from the truth. This fish is hard at work. The fish surrounding it (called Grunts, apparently) are inviting, or rather begging, the Spanish Hogfish to clean them. This is happening at a so called ‘Cleaning station’. A cleaning station is where fish go when they need a good scrubbing. Kind of a car-wash for fish, where they’ll get cleaned of bacteria, dead skin and parasites. Even fish that are normally enemies of the cleaning fish go to the cleaning stations to get themselves cleaned by their, otherwise, enemies.
These cleaning stations are beneficial for both the cleaner and the fish being cleaned. One gets parasites and other stuff cleaned and the other gets free food and some rest at the ‘neutral zone’.
Apparently, they even provide services to humans.
More information:
Wednesday, July 18th, 2007
When writing a document, you’ll probably want to refer to another section in the document. For instance: “See chapter 5 for more information”. However, when you insert a new chapter before chapter 5, you’ll have to read through your entire document and update every mentioning of “Chapter 5” to “Chapter 6”. Tedious and prone to error. But you don’t have to do it by hand! There’s a way in OpenOffice Writer to refer to another chapter so that when the document changes, you can easily update all references:
- Insert a bookmark in the document by using Insert → Bookmark at the position in the document you want to refer too. Enter a name for the bookmark and press Ok.
- Now, to refer to the position where you created the bookmark from another part of your document, go to that part and choose Insert → Cross-reference. Choose ‘Bookmarks‘ under Title and the name of the recently created bookmark under Selection. Under Format, you can choose how you’d like the reference to look. ‘Page’ will insert the page number of the bookmark at the current position, ‘Chapter’ will show the chapter number, etc.
- Press ‘Insert‘ and then ‘Close‘
A reference to the bookmark will now be inserted at the current location. The text that will be displayed depends on what you chose under Format.
If changes in your document occur that have an impact on what’s displayed at the reference, you can update all references by choosing Tools → Update → Update All.
The text of all posts on this blog, unless specificly mentioned otherwise, are licensed under this license.