chiark / gitweb /
where-vessels: subclass smasher works; need to reorg to be a grid like Show
[ypp-sc-tools.db-live.git] / yarrg / web / qtextstringcheck
index a489d8e1232940e6c603c44e05f43eed3add47b9..539abce6a550d8387c0171b845ef20b50b0d651c 100755 (executable)
@@ -44,6 +44,7 @@ $ctype => undef
 $string
 $what
 $dbh => undef
+$debug => 0
 </%args>
 
 <%flags>
@@ -55,81 +56,85 @@ use JSON;
 use Data::Dumper;
 use HTML::Entities;
 use CommodsWeb;
+use Scalar::Util qw(blessed);
 
 die if $what =~ m/[^a-z]/;
 my $chk= $m->fetch_comp("check_${what}");
+die "check_$what" unless $chk;
 
 my $mydbh;
 $dbh ||= ($mydbh= dbw_connect($ocean));
 
-#print STDERR "qtsc string=\`$string'\n";
+my $debugf= !$debug ? sub { } : sub {
+    print escapeHTML("@_")."\n";
+};
 
-my ($sth, @sqlstmt_qs);
-if ($chk->method_exists('sqlstmt')) {
-       my $sqlstmt= $chk->scall_method("sqlstmt");
-       $sth= $dbh->prepare($sqlstmt);
-       @sqlstmt_qs= $sqlstmt =~ m/\?/g;
-}
+$debugf->("QTSC STRING '$string'");
 
 my $emsg= '';
 my @results;
-my @specs;
 my $canontext;
-my $hooks = {  Emsg => \$emsg,         String => \$string,
-               Results => \@results,   Specs => \@specs,
-               Canon => \$canontext
-           };
 
-if ($chk->method_exists('preparse')) {
-       $chk->call_method('preparse', h => $hooks);
-} else {
-       @specs= $chk->attr('multiple') ? (split m#[/|,]#, $string) : ($string);
-}
+$string =~ s/^\s*//;
+$string =~ s/\s$//;
+$string =~ s/\s+/ /g;
 
-no warnings qw(exiting);
-
-foreach my $each (@specs) {
-       $each =~ s/^\s*//;  $each =~ s/\s*$//;  $each =~ s/\s+/ /g;
-       next if !length $each;
-       my $err= sub { $emsg= $_[0]; last; };
-       my %m;
-       my $results;
-       foreach my $pat ("$each", "$each\%", "\%$each\%") {
-               $sth->execute(($pat) x @sqlstmt_qs);
-               $results= $sth->fetchall_arrayref();
-               last if @$results==1;
-               map { $m{ $_->[0] }=1 } @$results;
-               $results= undef;
+if ($chk->method_exists('execute')) {
+       ($canontext, @results)= eval {
+               $chk->call_method('execute',
+                               dbh => $dbh, string => $string,
+                               debugf => $debugf);
+       };
+       if ($@) {
+               die unless blessed $@ && $@->isa('CommodsWeb::ExpectedError');
+               $emsg= $@->emsg();
        }
-       if (!$results) {
-               if (!%m) {
-                       $err->($chk->scall_method("nomatch",
-                               spec => $each));
-               } elsif (keys(%m) > $chk->attr('maxambig')) {
-                       $err->($chk->scall_method("manyambig"));
-               } else {
-                       $err->($chk->scall_method("ambiguous",
-                               spec => $each,
-                               couldbe => join(', ', sort keys %m)));
+} else {
+       my $sqlstmt= $chk->scall_method("sqlstmt");
+       my $sth= $dbh->prepare($sqlstmt);
+       my @sqlstmt_nqs= $sqlstmt =~ m/\?/g;
+       my $sqlstmt_nqs= @sqlstmt_nqs;
+
+       my @specs= $chk->attr('multiple')
+               ? (split m#\s*[/|,]\s*#, $string)
+               : ($string);
+
+       foreach my $each (@specs) {
+               next unless $each =~ m/\S/;
+               my ($temsg, @tresults) =
+                   dbw_lookup_string($each,
+                       $sth, $sqlstmt_nqs,
+                       $chk->attr_exists('abbrev_initials'),
+                       $chk->attr('maxambig'),
+                       $chk->scall_method("nomatch", specq => escerrq($each)),
+                       $chk->scall_method("manyambig"),
+                       sub {
+                               $chk->scall_method("ambiguous",
+                                       specq => escerrq($each),
+                                       couldbe => $_[1])
+                       });
+               if (defined $temsg) {
+                       $emsg= $temsg;
+                       last;
                }
-       }
-       push @results, $results->[0];
-};
+               push @results, [ @tresults ];
+       };
+}
 
 if (!defined $canontext) {
        $canontext= join ' | ', map { $_->[0] } @results;
 }
-if ($chk->method_exists('postquery')) {
-       $chk->call_method('postquery', h => $hooks);
-}
 
 $emsg='' if !defined $emsg;
 @results=() if length $emsg;
 
-#print STDERR "qtsc emsg=\`$emsg' results=\`@results'\n";
+$debugf->("QTSC EMSG='$emsg' RESULTS='@results'");
 
 if ($format =~ /json/) {
-       $r->content_type($ctype or $format);
+       $ctype ||= $format;
+       die unless grep { $_ eq $ctype }
+               qw(application/json text/plain text/xml);
+       $r->content_type($ctype);
        my $jobj= {
                success => 1*!length $emsg,
                show => (length $emsg      ? $emsg                       :
@@ -147,6 +152,6 @@ $mydbh->rollback() if $mydbh;
 
 return  $emsg,
        $canontext,
-       [ @results ];
+       @results;
 
 </%perl>