Saturday, April 29, 2006

Automated Firefox install

Firefox is terrible to install for administrators, or just people who install it often.

You cannot give arguments to the installer, so you are forced to click your way through the dialogs. The worst of these dialogs is obviously the braindead browse for folder dialog. No way to just type in the path where you want FF installed.

Then it creates a user profile, and there is no way to have that profile take some predefined settings from an .ini file, some existing profile folder or whatever. Profiles cannot be copied either, because they have these stupid paths like "C:\Documents and Settings\john\Application Data\Mozilla\Firefox\Profiles\uwayeoxn.default\" hardcoded into several of their files. (Why don't they use variables like %APPDATA% on Windows, $HOME, etc.?)

While the about:config page would probably allow entering all the needed settings, there is no way to automate or even simplify that. click click click...

The Bookmarks are pretty easy to configure, and the file can be copied. And userChrome.css can be copied too, but it should be possible to define defaults for these.

The real trouble starts with plugins and extensions...

The fact that the ShockWave installer is now bundled with some spy/ad/whatever-shit-ware (the Yahoo toolbar) is no fault of Firefox. But if it were possible to just copy an FF install where Shockwave was successfully installed while carefully avoiding the Yahoo trap, that would be nice.

Update: In fact, it is apparently possible to just copy the FF folder from one machine to another. That is very good. And the Flash player keeps working (not Shockwave, though).
But this doesn't take care of all the settings and configuration, and still leaves problems with extensions.

Update2: For Flash, it seems pretty easy after all. I have yet to test it on an install on a new machine, but it seems that all is needed are the files Firefox-dir\plugins\NPSWF32.dll
and Firefox-dir\plugins\NPSWF32_FlashUtil.exe. I used to have files in %SystemRoot%\System32\Macromed\Flash, but it seems to work without them.

Tuesday, April 11, 2006

cannot cast type money

In PostgreSQL, there used to be a type money which is now deprecated. It is suggested to replace it with numeric(p,s), but how do you convert your existing money columns?

Someone complained that no migration path is provided, but that conversation ended up in some useless nitpicking about whether it had ever been possible in some previous version.

There is a MONEY Conversion Module patch, but that requires you to recompile PostgreSQL and will only work with some specific versions of Postgres.

Well, if you inadvertently used that stupid money type and need to convert, maybe the simple solution below will work for you. It takes advantage of the fact that you can use Perl in PostgreSQL functions.

The following steps have worked for me:

  1. Connect to your database
    #psql -U postgres my_database

  2. Add the plperl language
    CREATE TRUSTED PROCEDURAL LANGUAGE 'plperl' HANDLER plperl_call_handler;

  3. Create the function
    CREATE OR REPLACE FUNCTION money2numeric(money)
    RETURNS "numeric" AS
    '$_=shift; s/[^0-9\.\-]//g; return 1 * $_;'
    LANGUAGE 'plperl' IMMUTABLE STRICT;
    (in case you are not familiar with Perl, here is what it does: assign the argument to the $_ variable; remove any characters which are not a digit, a dot or a minus sign; return the result multiplied by 1 to ensure it is numeric)

  4. Add a numeric column
    ALTER TABLE my_table ADD COLUMN my_new_col numeric(15,2);

  5. Update your data
    UPDATE my_table SET my_new_col = money2numeric(my_old_col);

  6. Drop the old column
    ALTER TABLE my_table DROP COLUMN my_old_col;

  7. Rename the new column to the old name
    ALTER TABLE my_table RENAME COLUMN my_old_col TO my_new_col;

That's it...

Labels:

Thursday, April 06, 2006

en_CH locale

English may not be one of the official Swiss languages (yet?), but it is certainly useful in a computer system. I don't want server logs and error messages in French or German or Italian (or Romantsch?). These things are easiest to understand and get help about in English. But I don't want dates in the confusing US "MM/DD/YY" format either, or times in AM/PM. Most importantly: I want sorting to work correctly with accented letters, and I want Perl to understand accented letters for \w, the uc(), lc() functions, etc.

So I made my own en_CH locale. Tested it in Debian stable (3.1 "Sarge"), and it seems to do what I expected. If you want to try it out, the steps are below. And it is quite easy to edit language_COUNTRY files to suit your needs.
# cp /usr/share/i18n/SUPPORTED /usr/share/i18n/SUPPORTED.orig
# echo -e "en_CH ISO-8859-1\nen_CH.UTF-8 UTF-8" | sort - /usr/share/i18n/SUPPORTED.orig >/usr/share/i18n/SUPPORTED
# wget -O /usr/share/i18n/locales/en_CH http://alma.ch/linux/en_CH
# echo "en_CH ISO-8859-1" >>/etc/locale.gen
# echo "en_CH.UTF-8 UTF-8" >>/etc/locale.gen
# dpkg-reconfigure locales
You may also need to edit your /etc/environment file and/or /etc/default/locale if they have a left-over LANGUAGE= line.
At your next login, your locale should be set to en_CH, and these little tests should work:
$ echo -e "é\ne\nA\nà\nE" |sort
$ perl -Mlocale -e 'print "Uppercase accented é and à: ", uc("éà\n")'
$ echo -e "é\ne\nA\nà\nE" |perl -Mlocale -ne 'while (/(\w+)/g) {print "$1\n"}'
(Note that for Perl, you need use locale;).

Update: For Ubuntu 6.10 ("Edgy"), see also this post in this ubuntu forum thread!

Labels: , , , , , ,

Monday, April 03, 2006

The Access ODBC PostgreSQL boolean mess

I like using PostgreSQL with an MS Access frontend for various little database applications, but always had trouble with boolean fields. Finally, after all sorts of tests, I think I nailed down what is needed to make it work, and avoid all these errors like "operator does not exist: boolean = integer", "Data Type mismatch in criteria expression", "invalid input syntax for type boolean: "-" (#7)", and another one which I can't remember. What we want is simple:
  • Booleans should be usable in Access queries with simple statements like SELECT x FROM y WHERE z; (and no silly stuff like where z=true, z='t', z=-1 or the insane where cbool(z)=true)
  • Booleans should appear as check boxes in Access forms and tables
I still don't quite understand why this is not hanlded transparently by the ODBC driver, but anyway here is what seems to be needed with PostgreSQL 7.4:
  • In PostgreSQL, make sure your boolean fields have a default value. Access cannot handle NULLs in booleans.
  • Configure the ODBC driver for "Bools as Char": no, "True is -1": yes.
  • Create these functions and operators in your database and/or in template1 for new databases:
    CREATE FUNCTION plpgsql_call_handler() RETURNS language_handler
    AS '$libdir/plpgsql', 'plpgsql_call_handler'
    LANGUAGE c;
    
    CREATE TRUSTED PROCEDURAL LANGUAGE plpgsql HANDLER plpgsql_call_handler;
    
    CREATE FUNCTION inttobool(integer, boolean) RETURNS boolean
    AS '
    begin
      if $1=0 and not $2 then
      return true;
      elsif $1<>0 and $2 then
      return true;
      else
              return false;
      end if;
    end;
    '
    LANGUAGE plpgsql;
    
    CREATE FUNCTION inttobool(boolean, integer) RETURNS boolean
    AS '
    begin
      return inttobool($2, $1);
    end;
    '
    LANGUAGE plpgsql;
    
    CREATE FUNCTION notinttobool(boolean, integer) RETURNS boolean
    AS '
    begin
      return not inttobool($2,$1);
    end;
    '
    LANGUAGE plpgsql;
    
    CREATE FUNCTION notinttobool(integer, boolean) RETURNS boolean
    AS '
    begin
    return not inttobool($1,$2);
    end;
    '
    LANGUAGE plpgsql;
    
    CREATE OPERATOR = (
    PROCEDURE = inttobool,
    LEFTARG = boolean,
    RIGHTARG = integer,
    COMMUTATOR = =,
    NEGATOR = <>
    );
    
    CREATE OPERATOR <> (
    PROCEDURE = notinttobool,
    LEFTARG = integer,
    RIGHTARG = boolean,
    COMMUTATOR = <>,
    NEGATOR = =
    );
    
    CREATE OPERATOR = (
    PROCEDURE = inttobool,
    LEFTARG = integer,
    RIGHTARG = boolean,
    COMMUTATOR = =,
    NEGATOR = <>
    );
    
    CREATE OPERATOR <> (
    PROCEDURE = notinttobool,
    LEFTARG = boolean,
    RIGHTARG = integer,
    COMMUTATOR = <>,
    NEGATOR = =
    );
    After linking the tables in Access, if you want check boxes in table view, you need to go into table design mode. It will show an error because it's a linked table; just ignore it. Select your boolean field(s) and set their Lookup -> Display Control to Check Box.
Update: See also this page.

Labels: , , , , ,

The Access ODBC PostgreSQL boolean mess

I like using PostgreSQL with an MS Access frontend for various little database applications, but always had trouble with boolean fields. Finally, after all sorts of tests, I think I nailed down what is needed to make it work, and avoid all these errors like "operator does not exist: boolean = integer", "Data Type mismatch in criteria expression", "invalid input syntax for type boolean: "-" (#7)", and another one which I can't remember. What we want is simple:
  • Booleans should be usable in Access queries with simple statements like SELECT x FROM y WHERE z; (and no silly stuff like where z=true, z='t', z=-1 or the insane where cbool(z)=true)
  • Booleans should appear as check boxes in Access forms and tables
I still don't quite understand why this is not hanlded transparently by the ODBC driver, but anyway here is what seems to be needed with PostgreSQL 7.4:
  • In PostgreSQL, make sure your boolean fields have a default value. Access cannot handle NULLs in booleans.
  • Configure the ODBC driver for "Bools as Char": no, "True is -1": yes.
  • Create these functions and operators in your database and/or in template1 for new databases:
    CREATE FUNCTION plpgsql_call_handler() RETURNS language_handler
    AS '$libdir/plpgsql', 'plpgsql_call_handler'
    LANGUAGE c;
    
    CREATE TRUSTED PROCEDURAL LANGUAGE plpgsql HANDLER plpgsql_call_handler;
    
    CREATE FUNCTION inttobool(integer, boolean) RETURNS boolean
    AS '
    begin
      if $1=0 and not $2 then
      return true;
      elsif $1<>0 and $2 then
      return true;
      else
              return false;
      end if;
    end;
    '
    LANGUAGE plpgsql;
    
    CREATE FUNCTION inttobool(boolean, integer) RETURNS boolean
    AS '
    begin
      return inttobool($2, $1);
    end;
    '
    LANGUAGE plpgsql;
    
    CREATE FUNCTION notinttobool(boolean, integer) RETURNS boolean
    AS '
    begin
      return not inttobool($2,$1);
    end;
    '
    LANGUAGE plpgsql;
    
    CREATE FUNCTION notinttobool(integer, boolean) RETURNS boolean
    AS '
    begin
    return not inttobool($1,$2);
    end;
    '
    LANGUAGE plpgsql;
    
    CREATE OPERATOR = (
    PROCEDURE = inttobool,
    LEFTARG = boolean,
    RIGHTARG = integer,
    COMMUTATOR = =,
    NEGATOR = <>
    );
    
    CREATE OPERATOR <> (
    PROCEDURE = notinttobool,
    LEFTARG = integer,
    RIGHTARG = boolean,
    COMMUTATOR = <>,
    NEGATOR = =
    );
    
    CREATE OPERATOR = (
    PROCEDURE = inttobool,
    LEFTARG = integer,
    RIGHTARG = boolean,
    COMMUTATOR = =,
    NEGATOR = <>
    );
    
    CREATE OPERATOR <> (
    PROCEDURE = notinttobool,
    LEFTARG = boolean,
    RIGHTARG = integer,
    COMMUTATOR = <>,
    NEGATOR = =
    );
    After linking the tables in Access, if you want check boxes in table view, you need to go into table design mode. It will show an error because it's a linked table; just ignore it. Select your boolean field(s) and set their Lookup -> Display Control to Check Box.
Update: See also this page.

Labels: , , , , ,

Saturday, April 01, 2006

Information Overload: la solution?

Si vous lisez des blogs, il vous faut absolument lire ça:
The Cure for Information Overload

C'est quand même plus intéressant que la solution de Microsoft, non?