inicio mail me! sindicaci;ón

hstore magic

A lot of nice things can be done with postgresql’s hstore type.

They are a nice way to store flags, for example, and by providing an aggregate function to sum them up, one can easily compute complex unions of properties.

First we define an aggregate function to sum postgresql hstores, straightforward as this:

CREATE AGGREGATE sum(
  sfunc     = hs_concat,
  basetype  = hstore,
  stype     = hstore,
  initcond  = ''
);

Allows for beautiful constructs as

CREATE OR REPLACE FUNCTION array_to_hstore(text[]) RETURNS hstore AS $$
  DECLARE
    arr     text[];
    result  hstore;
  BEGIN
    SELECT INTO arr $1;

    SELECT INTO result sum(key=>1) FROM (
      select
        btrim(arr[idx.i]) as key
      from
        generate_series(1, array_upper(arr,1)) as idx(i)
    ) as dummy;

    RETURN result;

  END
$$ LANGUAGE plpgsql;

Now what can be done with that? For example we can turn comma separated lists into hstores:

mydb=> SELECT array_to_hstore(string_to_array('a, b, c, a', ','));
              array_to_hstore
-------------------------------------------
 "a"=>"1", "b"=>"1", "c"=>"1"
(1 Zeile)

Using Finks svk on MacOSX with zsh

Some days ago I tried installing svk on MacOSX using fink. Everything worked fine except when I finally tried to use it:
aljoscha% svk
Can't locate Class/Autouse.pm in @INC 
(@INC contains: /System/Library/Perl/5... [snip] ...5.8.1 .) at /Library/Perl/5.8.6/SVK.pm line 6.
BEGIN failed--compilation aborted at /Library/Perl/5.8.6/SVK.pm line 6.
Compilation failed in require at /usr/bin/svk line 6.
BEGIN failed--compilation aborted at /usr/bin/svk line 6.
The solution was not so obvious to me: Fink sets its paths in /sw/bin/init.sh (/sw/bin/init.csh for csh users respectively) Putting a
source /sw/bin/init.sh
into your ~/.zshrc makes svk happy.

Testcase I

These tests check that, with the prototype fix in place
$H({fruit:"apple", vegetable:"cucumber"}).reject(
  function(el) { return (el[1] == 'cucumber');}
) == $H({fruit:"apple"})
and
$H({fruit:"apple", vegetable:"cucumber"}).findAll(
  function(el) { return (el[1] == 'apple'); }
) == $H({fruit:"apple"}) 

Fixing the Prototype Enumeration Mixin

The following article describes ticket #3592 in the RoR Trac and explains a proposed solution.

Prototypes Enumerable mixin class does not properly respect the mixees internal format. For example the reject and findAll methods, operating on Hashes, return Arrays instead of Hashes.

var a = $H({a:1, b:2, c:1, d:3});
document.writeln(a.inspect().escapeHTML());

=>#

var b = a.reject(function(val){ return (val[1]==1) });
document.writeln(b.inspect().escapeHTML());

=> [['b', 2], ['d', 3]]   // !!! should be hash

var c = b.findAll(function(val){ return (val[0]=='d') });
document.writeln(c.inspect().escapeHTML());

=> [['b', 2], ['d', 3]]   // !!! should be hash

In Ruby (from which the inspiration for the Enumerable Mixin stems), the reject method does return a hash, not an array, when operating on an hash:

irb(main):001:0> a={:a => 1, :b => 2, :c => 1, :d => 3}  

=> {:b=>2, :c=>1, :a=>1, :d=>3}  

irb(main):002:0> b=a.reject{|k,v| v==1}

=> {:b=>2, :d=>3}

The patch requires all classes that want to mixin Enumerable to define two more methods similar to _each:
_new, which returns an empty object of that class and
_add, that adds an element. Enumerable mixin thus needs to make no more assumptions about the internal structure of its mixee class.

After the fix the methods return correctly:

=> #
« Previous entries