Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I recently saw a neat little os x app called Delicious Library, but I have ben unable to find anything comparable for linux. So I decided that it would be a good chance to learn some perl. I immediately ran into a problem, which I've reduced to the following example:
#!/usr/bin/perl use warnings; use strict; use Storable qw(freeze thaw); use DBI; my $dbh = DBI->connect("dbi:SQLite:dbname=/root/testlib.db","",""); my @books=( { 'ISBN' => '0596004788', 'Title' => 'Learning Perl Objects, References, and Mod +ules' }, { 'ISBN' => '0596001320', 'Title' => 'Learning Perl, Third Edition' }, { 'ISBN' => '0596003137', 'Title' => 'Perl Cookbook, Second Edition' }, ); my $book_list = freeze(\@books); $dbh->do("INSERT INTO BOOKS (BOOK) values (?)",undef,$book_list); my $sth = $dbh->prepare( 'select * from BOOKS' ); $sth->execute(); my $book= $sth->fetchrow_array ; my $new_list = thaw($book); foreach(@{$new_list}){ print "$_->{'ISBN'} $_->{'Title'}\n"; }
What I'm expecting is the output of:
0596004788 Learning Perl Objects, References, and Modules 0596001320 Learning Perl, Third Edition 0596003137 Perl Cookbook, Second Edition
Instead nothing happens. At first I though the database migh be mangleing the data, so I recreated the table with: CREATE TABLE BOOKS(BOOK BLOB);. Which if my understanding, and execution is correct should allow data to be stored exactly as it was inserted? What I'm trying to do is slightly beyond my current abilites, and I'm stumped. I'll never learn if I don't try. Any help you could offer would be appreciated.

Replies are listed 'Best First'.
Re: Problems with storable and Sqlite
by antirice (Priest) on Nov 18, 2005 at 06:09 UTC

    I've faced this problem before and the only solution I found to work besides encoding the data was to prepare the statement and specifically bind the data as a blob. So now your code would look like this:

    #!/usr/bin/perl use warnings; use strict; use Storable qw(freeze thaw); use DBI "SQL_BLOB"; my $dbh = DBI->connect("dbi:SQLite:dbname=testlib.db","","",{RaiseErro +r => 1}); my @books=( { 'ISBN' => '0596004788', 'Title' => 'Learning Perl Objects, References, and Mod +ules' }, { 'ISBN' => '0596001320', 'Title' => 'Learning Perl, Third Edition' }, { 'ISBN' => '0596003137', 'Title' => 'Perl Cookbook, Second Edition' }, ); my $book_list = freeze(\@books); my $sth = $dbh->prepare("INSERT INTO BOOKS (BOOK) values (?)"); $sth->bind_param(1,$book_list,SQL_BLOB); $sth->execute; $sth->finish; $sth = $dbh->prepare( 'select * from BOOKS' ); $sth->execute(); my $book= $sth->fetchrow_array ; my $new_list = thaw($book); foreach(@{$new_list}) { print "$_->{'ISBN'} $_->{'Title'}\n"; } __END__ 0596004788 Learning Perl Objects, References, and Modules 0596001320 Learning Perl, Third Edition 0596003137 Perl Cookbook, Second Edition
      Thank you very much thats exactly what I want to do. I don't think I would have figured that out on my own, everything after the line use strict; are things that I've only learned in the past few hours.
Re: Problems with storable and Sqlite
by friedo (Prior) on Nov 18, 2005 at 05:06 UTC
    my $book= $sth->fetchrow_array ;

    I think your problem might be because you're calling fetchrow_array in scalar context, which can produce unexpected results. From the docs:

    If called in a scalar context for a statement handle that has more than one column, it is undefined whether the driver will return the value of the first column or the last. So don't do that. Also, in a scalar context, an undef is returned if there are no more rows or if an error occurred. That undef can't be distinguished from an undef returned because the first field value was NULL. For these reasons you should exercise some caution if you use fetchrow_array in a scalar context.

    To make it list context, do this:

    my ( $book ) = $sth->fetchrow_array;
      I thought of that too, but notice that the statement does only return one column. So no, I don't think that's the problem. (also I tested it and it didn't help)
Re: Problems with storable and Sqlite
by Aristotle (Chancellor) on Nov 18, 2005 at 12:20 UTC

    Errm, is there a reason you’re inserting a blob containing a list of hashes into a row – instead of having ISBN and title columns in your books table and putting each of those records in a row? Your code is treating the database as just a file (or a bunch of them). Why not capitalise on the strengths of an RDBMS?

    Makeshifts last the longest.

Re: Problems with storable and Sqlite
by DrHyde (Prior) on Nov 18, 2005 at 11:16 UTC
    I'm not going to comment on your code, just point you at an alternative application :-)

    There is a Linux (and Windows, and OS X, and everything else) equivalent of Delicious Library. You want Readerware, which is written in Java and so runs in most places. I've been using it for a couple of years now, and highly recommend it.