On Sat, Nov 23, 2019 at 01:48:16PM -0800, Andrew Hewus Fresh wrote:
> On Sat, Nov 23, 2019 at 01:25:16PM +0100, Marc Espie wrote:
> > Woah. That code is horrible. It also spends a lot of time 
> > connecting/disconnecting.
> > 
> > - The database connection should be a singleton
> > - sqlports should always be opened ReadOnly
> > - The query should be prepared.
> > 
> > Apart from that, PortsQ will help, but the basic code should be taken out
> > and shot.


I think this is a slight improvement, building on the changes sthen@
made.   The benefit here is that the query to the sqlports database
should be able to figure out if what we're looking for exists without
looping over a bunch of possibilities.

I think there is still room for future improvement, for example, being
able to find "perltidy" from "p5-Perl-Tidy" by looking without the
prefix, removing any non-alphanumeric and continuing to convert to
lowercase.  But, that could make it find things that aren't actually
what we're looking for.

I'm a bit worried about python3 only ports, so if someone can make sure
things work the way they expect with those, I'd appreciate it.

Comments? OK?


Index: infrastructure/lib/OpenBSD/PortGen/Utils.pm
===================================================================
RCS file: /cvs/ports/infrastructure/lib/OpenBSD/PortGen/Utils.pm,v
retrieving revision 1.5
diff -u -p -r1.5 Utils.pm
--- infrastructure/lib/OpenBSD/PortGen/Utils.pm 23 Nov 2019 14:59:39 -0000      
1.5
+++ infrastructure/lib/OpenBSD/PortGen/Utils.pm 30 Nov 2019 22:56:23 -0000
@@ -18,6 +18,7 @@ package OpenBSD::PortGen::Utils;
 
 use 5.012;
 use warnings;
+use feature qw( state );
 
 use parent qw( Exporter );
 
@@ -47,12 +48,8 @@ sub ports_dir { $ENV{PORTSDIR} || '/usr/
 
 sub base_dir { ports_dir() . '/mystuff' }
 
-sub module_in_ports
+sub _module_sth
 {
-       my ( $module, $prefix ) = @_;
-
-       return unless $module and $prefix;
-
        my $dbfile = '/usr/local/share/sqlports';
        die "install databases/sqlports and databases/p5-DBD-SQLite\n"
            unless -e $dbfile;
@@ -64,22 +61,34 @@ sub module_in_ports
            RaiseError => 1,
        } ) or die "failed to connect to database: $DBI::errstr";
 
-       my @results = @{ $dbh->selectcol_arrayref(
-           "SELECT _paths.fullpkgpath FROM _paths JOIN _paths p1 ON 
p1.pkgpath=_paths.id
-               JOIN _ports ON _ports.fullpkgpath=p1.id WHERE _ports.distname 
LIKE ?",
-           {}, "$module%"
-       ) };
-
-       $dbh->disconnect();
-
-       # just returning the shortest one that's a module of the same ecosystem
-       # this should be improved
-       @results = sort { length $a <=> length $b } @results;
-
-       # this works well enough in practice, but can't rely on it
-       # see devel/perltidy
-       for (@results) {
-               return $_ if /\/$prefix/;
+       return $dbh->prepare(q{
+           SELECT _Paths.FullPkgPath FROM _Paths
+             JOIN _Ports ON _Paths.PkgPath = _Ports.FullPkgPath
+            WHERE PKGSTEM = ?
+              AND _Paths.Id = _Paths.PkgPath
+            ORDER BY LENGTH(_Paths.FullPkgPath)
+       });
+}
+
+sub module_in_ports
+{
+       my ( $module, $prefix ) = @_;
+       return unless $module and $prefix;
+
+       state $sth = _module_sth();
+       END { undef $sth }; # Bus error if destroyed during global destruction
+
+       my @stems = ( $prefix . $module );
+
+       # We commonly convert the port to lowercase
+       push @stems, $prefix . lc($module) if $module =~ /\p{Upper}/;
+
+       foreach my $stem (@stems) {
+               $sth->execute($stem);
+               my ($path, @extra) = map {@$_} @{ $sth->fetchall_arrayref };
+               warn "Found paths other than $path: @extra\n"
+                   if @extra;
+               return $path if $path;
        }
 
        # Many ports, in particular python ports, start with $prefix,
Index: infrastructure/lib/OpenBSD/PortGen/Port/PyPI.pm
===================================================================
RCS file: /cvs/ports/infrastructure/lib/OpenBSD/PortGen/Port/PyPI.pm,v
retrieving revision 1.17
diff -u -p -r1.17 PyPI.pm
--- infrastructure/lib/OpenBSD/PortGen/Port/PyPI.pm     15 Jul 2019 13:35:35 
-0000      1.17
+++ infrastructure/lib/OpenBSD/PortGen/Port/PyPI.pm     30 Nov 2019 22:56:23 
-0000
@@ -54,11 +54,20 @@ sub name_new_port
 {
        my ( $self, $di ) = @_;
 
-       my $name = ref $di ? $di->{info}{name} : $di;
-       $name =~ s/^python-/py-/;
+       my $module = ref $di ? $di->{info}{name} : $di;
+       $module =~ s/^python-/py-/;
 
-       $name = $self->SUPER::name_new_port($name);
-       $name = "pypi/$name" unless $name =~ m{/};
+       my $name = $self->SUPER::name_new_port($module);
+
+       # Try for a py3 only version if we didn't find something ported
+       unless ( $name =~ m{/} ) {
+               if ( my $p = module_in_ports( $name, 'py3-' ) ) {
+                       $name = $p;
+               }
+               else {
+                       $name = "pypi/$name"
+               }
+       }
 
        return $name;
 }
@@ -171,7 +180,8 @@ sub get_deps
 
                next if @plat and join( " ", @plat ) !~ /OpenBSD/i;
 
-               my $port = module_in_ports( $name, 'py-' );
+               my $port = module_in_ports( $name, 'py-' )
+                   || module_in_ports( $name, 'py3-' );
                my $dep_dir;
 
                if ($port) {

Reply via email to