fix NOT with tagvals
[id3fs.git] / lib / ID3FS / Path.pm
index 4898aeb..dcfe0b7 100644 (file)
@@ -16,6 +16,10 @@ our ($STATE_INVALID, $STATE_ROOT, $STATE_TAG, $STATE_TAGVAL,
 
 our %priorities=( "OR" => 0, "AND" => 1, "NOT" => 2 );
 
+our $PATH_ALLTRACKS="TRACKS";
+our $PATH_NOARTIST="NOARTIST";
+our $PATH_NOALBUM="NOALBUM";
+
 sub new
 {
     my $proto=shift;
@@ -69,12 +73,13 @@ sub dirents
 {
     my($self)=@_;
     my @dents=();
+    my @fents=();
     my $state=$self->state();
 #    print "DIRENTS: STATE: $state\n";
 #    print "DIRENTS: FILE: $self->{path}\n";
     if($state==$STATE_ALL)
     {
-       push(@dents, qw(TRACKS NOARTIST), $self->artists());
+       push(@dents, $PATH_ALLTRACKS, $PATH_NOARTIST, $self->artists());
     }
     elsif($state==$STATE_TAG || $state==$STATE_TAGVAL)
     {
@@ -88,7 +93,7 @@ sub dirents
        }
        else
        {
-           push(@dents, qw(AND OR TRACKS NOARTIST), $self->artists());
+           push(@dents, qw(AND OR), $PATH_ALLTRACKS, $PATH_NOARTIST, $self->artists());
        }
     }
     elsif($state==$STATE_BOOLEAN)
@@ -108,17 +113,17 @@ sub dirents
     }
     elsif($state==$STATE_ALBUMS)
     {
-       @dents=(qw(TRACKS NOALBUM),$self->albums());
+       @dents=($PATH_ALLTRACKS, $PATH_NOALBUM, $self->albums());
     }
     elsif($state==$STATE_TRACKLIST)
     {
-       @dents=$self->tracks();
+       @fents=$self->tracks();
     }
     else
     {
        print "DIRENTS: UNHANDLED STATE: $state\n";
     }
-    return(@dents);
+    return(\@dents, \@fents);
 }
 
 sub parse
@@ -196,11 +201,11 @@ sub parse
                    $self->state($STATE_INVALID);
                }
            }
-           elsif($name eq "TRACKS")
+           elsif($name eq $PATH_ALLTRACKS)
            {
                $self->state($STATE_TRACKLIST);
            }
-           elsif($name eq "NOARTIST")
+           elsif($name eq $PATH_NOARTIST)
            {
                $self->state($STATE_TRACKLIST);
            }
@@ -262,11 +267,11 @@ sub parse
        elsif($state==$STATE_ALBUMS)
        {
 #          print "SM: ALBUM: $name\n";
-           if($name eq "TRACKS")
+           if($name eq $PATH_ALLTRACKS)
            {
                $self->state($STATE_TRACKLIST);
            }
-           elsif($name eq "NOALBUM")
+           elsif($name eq $PATH_NOALBUM)
            {
                $self->state($STATE_TRACKLIST);
            }
@@ -306,12 +311,13 @@ sub parse
        }
        elsif($state==$STATE_ALL)
        {
-           if($name eq "TRACKS")
+           if($name eq $PATH_ALLTRACKS)
            {
                $self->state($STATE_TRACKLIST);
            }
-           elsif($name eq "NOARTIST")
+           elsif($name eq $PATH_NOARTIST)
            {
+               # FIXME
                $self->state($STATE_TRACKLIST);
            }
            else
@@ -335,7 +341,6 @@ sub parse
        }
     }
 
-    print "ROOT_NOT: $root_not TAGS_SEEN: $tags_seen\n";
     if($root_not && ($tags_seen < 2))
     {
        $self->{bare_not}=1;
@@ -485,7 +490,7 @@ sub tail_parent
 sub tags
 {
     my($self)=@_;
-    if(!$self->{tagtree}) # / or /NOT
+    if(!$self->{tagtree}) # / or /NOT  # FIXME: /ALL too?
     {
        my $sql="SELECT DISTINCT name FROM tags WHERE parents_id='';";
        return($self->{db}->cmd_firstcol($sql));
@@ -721,7 +726,7 @@ sub tracks
                 "INNER JOIN files ON files.id=subselect.files_id\n");
     }
     $sql .= "INNER JOIN artists ON files.artists_id=artists.id\n";
-    if($self->{components}->[$#{$self->{components}}] eq "NOARTIST")
+    if($self->{components}->[$#{$self->{components}}] eq $PATH_NOARTIST)
     {
        $sql .= "WHERE artists.name =''\n";
     }
@@ -754,6 +759,7 @@ sub filename
 sub tags_subselect
 {
     my($self)=@_;
+    my $hasvals=$self->tag_has_values();
     # we need to specially handle a bare /NOT/tag with no other clauses,
     # using a simple WHERE id !='tagid' instead of a LEFT JOIN
     if($self->{bare_not})
@@ -765,7 +771,6 @@ sub tags_subselect
        return "\tSELECT id FROM files AS files_id\n";
     }
     my $tree=$self->{tagtree};
-    my $hasvals=$self->tag_has_values();
     my $parent=$self->trailing_tag_parent();
 
 #    print "ELEMENTS: ", join('/', map { $_->{name}; } @{$self->{elements}}), "\n";
@@ -777,7 +782,7 @@ sub tags_subselect
 #      print "Trailing id: $tag\n";
     }
     my ($sqlclause, @joins)=(undef, ());
-    ($sqlclause, @joins) = $tree->to_sql() if($tree);
+    ($sqlclause, @joins) = $tree->to_sql($hasvals) if($tree);
 #    print "SQL(" . scalar(@joins) .": $sqlclause\n";
     my $sql="\tSELECT fxt1.files_id FROM tags t1";
     my @crosses=();