Use a POE DBI handler so that queries to SQLite are asynchronous.
authorAndrew Ruthven <puck@catalyst.net.nz>
Fri, 19 Sep 2008 01:54:14 +0000 (13:54 +1200)
committerAndrew Ruthven <puck@dirk.wgtn.cat-it.co.nz>
Fri, 19 Sep 2008 01:54:14 +0000 (13:54 +1200)
lib/Display/Plugins/FSpot.pm

index 766a9d6..f74e419 100644 (file)
@@ -1,7 +1,9 @@
 package Display::Plugins::FSpot;
 
-use Clutter;
 use base ('Display::Plugin');
+use Clutter;
+use POE;
+use POE::Component::EasyDBI;
 
 my $f_spot_db = "/home/andrew/.gnome2/f-spot/photos.db";
 
@@ -18,14 +20,16 @@ sub new {
   return $self;
 }
 
-sub display {
-  my $self = shift;
-  my $file;
+sub display_photo {
+  my ($self, $kernel, $args) = @_[OBJECT, KERNEL, ARG0];
+  my $file = $args->{'result'};
+  $file =~ s|^file://||;
 
   # Keep on looking until we find a file that exists.
-  do {
-    $file = $self->find_photo();
-  } until (-f $file && $file ne $self->{'last_file'});
+  if (! -f $file || $file eq $self->{'last_file'}) {
+    $kernel->post('fspot_display');
+    return;
+  } 
   
   $self->{'new'}->set_from_file($file);
 
@@ -55,33 +59,28 @@ sub fade_in {
   $new->start();
 }
 
-sub find_photo {
+sub display {
   my $self = shift;
-  
-  my $uri;
-  $self->{'sth'}->bind_columns(\$uri);
-  my $rc = $self->{'sth'}->execute()
-    || die "Failed to execute statement: $DBI::errstr\n";
-
-  $self->{'sth'}->fetch;
-
-  $self->{'sth'}->finish()
-    || die "Failed to finish statement: $DBI::errstr\n";;
 
-  $uri =~ s|^file://||;
-
-  return $uri;
+  $self->{'kernel'}->post('FSpotDB',
+    single => { sql => $self->{'sql'}, event => fspot_display_photo }
+  );
 }
 
 sub init {
   my $self = shift;
 
   $self->{'kernel'}->state('fspot_display', $self, 'display');
+  $self->{'kernel'}->state('fspot_display_photo', $self, 'display_photo');
 
-  $self->{'dbh'} = DBI->connect("dbi:SQLite:dbname=$f_spot_db","","")
-    || die "Failed to connect to $f_spot_db: $DBI::errstr\n";
+  POE::Component::EasyDBI->spawn(
+    alias => 'FSpotDB',
+    dsn   => "dbi:SQLite:dbname=$f_spot_db",
+    username => '',
+    password => '',
+  );
 
-  my $sql = "
+  $self->{'sql'} = "
 SELECT uri
 FROM photos, photo_tags, tags
   WHERE photos.id = photo_tags.photo_id
@@ -91,9 +90,6 @@ ORDER BY random()
 LIMIT 1
 ";
 
-  $self->{'sth'} = $self->{'dbh'}->prepare($sql)
-    || die "Failed to prepare statement: $DBI::errstr\n";
-
   for my $age ('new', 'old') {
     $self->{$age} = Clutter::Texture->new();
     $self->{$age}->set_size($self->{'stage'}->get_size());