MySQL : so advanced that it forgot the simplest things

Out of two next snippets, the first one will throw a UNIQUE KEY constraint error and the second will pass.

CREATE table test(name varchar(60)) DEFAULT CHARSET=utf8;
ALTER TABLE test ADD UNIQUE KEY name (name);
SET NAMES utf8 COLLATE utf8_bin;
CREATE table test(name varchar(60)) DEFAULT CHARSET=utf8;
ALTER TABLE test ADD UNIQUE KEY name (name);

All this because some wise folks decided that the default collation for utf-8 be utf8_general_ci, the one that does not make a difference between upper- and lowercase, and also considers that CYRILLIC CAPITAL LETTER IE, CYRILLIC CAPITAL LETTER IO, CYRILLIC SMALL LETTER IE, CYRILLIC SMALL LETTER IO to be equal.

Лучшие фото фотосайта на рабочем столе

Фотосайт раздаёт программу под винду, которая ротирует фотообои с лучшими фото. Программа -- маленький, глючный до невозможности экзешник. А ведь её можно заменить всего одной строчкой, которая будет скачивать последнее лучшее фото в том случае, если оно ещё не скачано.

ID=`wget -q -O -`; \
  wget -q -N$ID

А ещё в три коротенькие строчки можно поставить это фото на рабочий стол Gnome Desktop

cd /var/tmp; ID=`wget -q -O -`; \
  wget -q -N$ID
mv $ID $ID.jpg
gconftool-2 -t str --set /desktop/gnome/background/picture_filename \
gconftool-2 -t str --set /desktop/gnome/background/picture_options \

[Poor man's langmap] using vim key bindings while typing non-latin1 texts

When I am typing in cyrillic, I can not access any of the vim key bindings, unless I switch the keyboard layout to a latin-based one.

There existed a solution for 1-byte locales, the famous langmap command. Putting the following in the ~/.vimrc solved the problem for those who worked in e.g. a koi8-r or cp1251-based locale.

set langmap=ж;;
set langmap=ё`,йq,цw,уe,кr,еt,нy,гu,шi,щo,зp,х[,ъ],фa,ыs,\

Unfortunately, this did not work in a multibyte locale. Instead, one has to map every key independently with the map command:

   map ё `
   map й q
   map ц w
   map у e
   map к r
   map е t
   map н y
   map г u
   map ш i
   map щ o
   map з p
   map х [
   map ъ ]

   map ф a
   map ы s
   map в d
   map а f
   map п g
   map р h
   map о j
   map л k
   map д l
   map ж ;
   map э '

   map я z
   map ч x
   map с c
   map м v
   map и b
   map т n
   map ь m
   map б ,
   map ю .

   map Ё ~
   map Й Q
   map Ц W
   map У E
   map К R
   map Е T
   map Н Y
   map Г U
   map Ш I
   map Щ O
   map З P
   map Х {
   map Ъ }

   map Ф A
   map Ы S
   map В D
   map А F
   map П G
   map Р H
   map О J
   map Л K
   map Д L
   map Ж :
   map Э "

   map Я Z
   map Ч X
   map С C
   map М V
   map И B
   map Т N
   map Ь M
   map Б 

see also at

yet another backup script

After reading the excellent Easy Automated Snapshot-Style Backups with Linux and Rsync, I deicided to make a new backup script for my home directory that would keep the last 9 incremental snapshots.

Here is the resulting script:

if [ -n "$1" ] ; then

if [ -n "$2" ] ; then

LINKTO=--link-dest=$TO/`basename $FROM`.1
OPTS="-Ca --delete --exclude-from=$FROM/bin/rsync-excluded -delete-excluded"

find $TO -maxdepth 1 -type d -name '*.[0-9]'| sort -rn| while read dir
	this=`expr match "$dir" '.*\([0-9]\)'`; 
	let next=($this+1)%$NUMBER_OF_BACKUPS;
	if [ $next -eq 0 ] ; then
		 rm -rf $dir
		 mv $dir $basedirname.$next
rsync $OPTS $LINKTO $FROM/ $TO/`basename $FROM.0`

It would be nice to extend it to add the possibility to create an unlimited number of incremental backups.

P.S. In the plans: a detailed explanation of the payslip calculation in Belgium

Java enums suck (as if everyone disagreed)

Java enums are translated by the compiler into a class that contains the enum elements as public static final fields.

If we put specific code into the enum elements, these fields become inner classes. (So that they can store code for each element)

One non-obvious consequence of this approach is that

Myenum.MyElement.getClass().getName() may return either Myenum or Myenum$n where n is an ordinal number of the element, depending on whether the element has associated code or not.

Software shapes life

Just another story I presented on a few occasions already.

Belgium has a very developed temporary job market. One particular feature of temporary contracts, also called interim contracts is that they are made for the period of 1 week and then renewed as needed. The 1-week length is perceived as a tradtion not a requirement, as the only legal limit to interim contracts is 6 months. Only few people know that this tradition comes from the limitation of the interim mangement software called ISI wich is still used by ~90% of all interim offices in Belgium. The original ISI software allowed to make contracts and invoices for 1 week at most, this forcing all the interim market to live by 1-week cycles.