Constructor fails politely (warns and returns undef) if the registry
[irspy-moved-to-github.git] / lib / ZOOM / IRSpy / Connection.pm
index 0ad9c2b..0d68df2 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Connection.pm,v 1.6 2006-10-25 15:43:43 mike Exp $
+# $Id: Connection.pm,v 1.20 2007-12-20 12:31:09 mike Exp $
 
 package ZOOM::IRSpy::Connection;
 
@@ -9,6 +9,9 @@ use warnings;
 use ZOOM;
 our @ISA = qw(ZOOM::Connection);
 
+use ZOOM::IRSpy::Record;
+use ZOOM::IRSpy::Utils qw(cql_target render_record irspy_identifier2target);
+
 use ZOOM::IRSpy::Task::Connect;
 use ZOOM::IRSpy::Task::Search;
 use ZOOM::IRSpy::Task::Retrieve;
@@ -26,24 +29,54 @@ Keeping the private data in these objects removes the need for ugly
 mappings in the IRSpy object itself; adding the methods makes the
 application code cleaner.
 
-The constructor takes an additional first argument, a reference to the
-IRSpy object that it is associated with.
+The constructor takes an two additional leading arguments: a reference
+to the IRSpy object that it is associated with, and the target ID of
+the connection.
 
 =cut
 
 sub create {
     my $class = shift();
     my $irspy = shift();
+    my $id = shift();
 
     my $this = $class->SUPER::create(@_);
+    my $target = irspy_identifier2target($id);
+    $this->option(host => $target);
     $this->{irspy} = $irspy;
-    $this->{record} = undef;
     $this->{tasks} = [];
 
+    my $query = cql_target($id);
+    my $rs;
+    eval {
+       $rs = $irspy->{conn}->search(new ZOOM::Query::CQL($query));
+    }; if ($@) {
+       # This should be a "can't happen", but junk entries such as
+       #       //lucasportal.info/blogs/payday-usa">'</a>night:G<a href="http://lucasportal.info/blogs/payday-usa">'</a>night/Illepeliz
+       # (yes, really) yield BIB-1 diagnostic 108 "Malformed query"
+       warn "registry search for record '$id' had error: '$@'";
+       return undef;
+    }
+    my $n = $rs->size();
+    $this->log("irspy", "query '$query' found $n record", $n==1 ? "" : "s");
+    ### More than 1 hit is always an error and indicates duplicate
+    #   records in the database; no hits is fine for a new target
+    #   being probed for the first time, but not if the connection is
+    #   being created as part of an "all known targets" scan.
+    my $zeerex;
+    $zeerex = render_record($rs, 0, "zeerex") if $n > 0;
+    $this->{record} = new ZOOM::IRSpy::Record($this, $target, $zeerex);
+
     return $this;
 }
 
 
+sub destroy {
+    my $this = shift();
+    $this->SUPER::destroy(@_);
+}
+
+
 sub irspy {
     my $this = shift();
     return $this->{irspy};
@@ -107,18 +140,25 @@ sub irspy_connect {
     my $this = shift();
     my($udata, $options, %cb) = @_;
 
-    my $task = new ZOOM::IRSpy::Task::Connect($this, $udata, $options, %cb);
-    $this->add_task($task);
+    $this->add_task(new ZOOM::IRSpy::Task::Connect
+                   ($this, $udata, $options, %cb));
 }
 
 
-sub irspy_search_pqf {
+sub irspy_search {
     my $this = shift();
-    my($query, $udata, $options, %cb) = @_;
+    my($qtype, $qstr, $udata, $options, %cb) = @_;
+
+    #warn "calling $this->irspy_search(", join(", ", @_), ")\n";
+    $this->add_task(new ZOOM::IRSpy::Task::Search
+                   ($qtype, $qstr, $this, $udata, $options, %cb));
+}
+
 
-    my $task = new ZOOM::IRSpy::Task::Search($query,
-                                            $this, $udata, $options, %cb);
-    $this->add_task($task);
+# Wrapper for backwards compatibility
+sub irspy_search_pqf {
+    my $this = shift();
+    return $this->irspy_search("pqf", @_);
 }
 
 
@@ -126,9 +166,8 @@ sub irspy_rs_record {
     my $this = shift();
     my($rs, $index0, $udata, $options, %cb) = @_;
 
-    my $task = new ZOOM::IRSpy::Task::Retrieve($rs, $index0,
-                                              $this, $udata, $options, %cb);
-    $this->add_task($task);
+    $this->add_task(new ZOOM::IRSpy::Task::Retrieve
+                   ($rs, $index0, $this, $udata, $options, %cb));
 }
 
 
@@ -143,6 +182,14 @@ sub add_task {
 }
 
 
+sub render {
+    my $this = shift();
+    return ref($this) . "(" . $this->option("host") . ")";
+}
+
+use overload '""' => \&render;
+
+
 =head1 SEE ALSO
 
 ZOOM::IRSpy