in reply to mapping complex structures to mysql tables

This should show you how to store any complex structure into an SQL table (I used SQLite in the example). I chose a hash as the top structure:
#!/usr/bin/perl use warnings; use strict; use DBI; use Data::Dumper; use constant { KEY => 0, VALUE => 1, WHERE => 2, NEW => 3, }; sub store { my ($db, $struct) = @_; $db->do('DROP TABLE IF EXISTS t'); $db->do('CREATE TABLE t (key VARCHAR, value VARCHAR, ref INT)'); my $store = $db->prepare('INSERT INTO t VALUES (?, ?, ?)'); while (my ($key, $value) = each %$struct) { _store($db, $store, $key, $value); } } sub _store { my ($db, $store, $key, $value, $where) = @_; if (my $ref = ref $value) { $store->execute($key, $ref, $where); my $new = $db->last_insert_id((q()) x 4); if ('HASH' eq $ref) { while (my ($k, $v) = each %$value) { _store($db, $store, $k, $v, $new); } } elsif ('ARRAY' eq $ref) { _store($db, $store, $_, $value->[$_], $new) for 0 .. $#{$v +alue}; } } else { $store->execute($key, $value, $where); } } sub retrieve { my ($db) = @_; my %hash; my $select = $db->prepare('SELECT ROWID, key, value, ref FROM t OR +DER BY ROWID'); $select->execute; while (my @row = $select->fetchrow_array) { $hash{ $row[0] } = [ @row[1 .. 3] ]; } my %return; for my $key (sort { $b <=> $a } keys %hash) { my $new = defined $hash{$key}[NEW] ? $hash{$key}[NEW] : $hash{ +$key}[VALUE]; if (defined $hash{$key}[WHERE]) { my $where = $hash{ $hash{$key}[WHERE] }; if ('ARRAY' eq $where->[VALUE]) { unshift @{ $where->[NEW] }, $new; } else { $where->[NEW]{ $hash{$key}[KEY] } = $new; } } else { $return{$hash{$key}[KEY]} = $new; } } return %return; } my %struct = ( sv0 => 100, sv1 => 'string', hv => { l1sv => 'deeper', l1hv => { x => 10, y => 20 }, l1av => [qw/1 2 3 A B C/] }, av => [ 5, 'e', { k0 => 'v0', k1 => 'v1' }, [qw/Mercury Venus Mars/] ], ); my $db = 'DBI'->connect('dbi:SQLite:dbname=1.db', q(), q()); store($db, \%struct); %struct = retrieve($db); print Dumper \%struct;
لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

Replies are listed 'Best First'.
Re^2: mapping complex structures to mysql tables
by niubi (Initiate) on May 09, 2013 at 16:44 UTC
    Thanks, this is a very nice piece of code that will be certainly useful as a starting point. I've also been pointed at DBIx class to implement this, I will look into this as well.
Re^2: mapping complex structures to mysql tables
by Anonymous Monk on Jan 14, 2014 at 01:39 UTC

    Fantastic, that was just what I was looking for!

    I might suggest testing to see if the table exists first before creating it:

    if (do('SELECT 1 FROM t LIMIT 1')){ $db->do('CREATE TABLE t (key VARCHAR, value VARCHAR, ref INT)') }

    Also, some people may like comment out the "DROP TABLE" statement.

    Thanks for sharing your code.