$self->{path} =~ s/\/\//\//g; # drop doubled slashes
$self->parse();
-# print "STATE: ", $self->state(), "\n";
return $self;
}
my @dents=();
my @fents=();
my $state=$self->state();
-# print "DIRENTS: STATE: $state\n";
-# print "DIRENTS: FILE: $self->{path}\n";
if($state==$STATE_ALL)
{
@dents=($self->filter($PATH_ALLTRACKS, $PATH_NOARTIST), $self->artists());
return if($self->{path} eq "/");
@{$self->{components}}=split(/\//, $self->{path});
shift @{$self->{components}}; # drop empty field before leading /
-# print "PATH: $self->{path}\n";
my @parts=@{$self->{components}};
my($tag, $tagval);
$self->{elements}=[];
my $tags_seen=0;
while(defined(my $name=shift @parts))
{
-# print "NAME: $name\n";
my $state=$self->state();
if($state==$STATE_INVALID)
{
-# print "SM: INVALID: $name\n";
return;
}
elsif($state==$STATE_ROOT)
{
-# print "SM: ROOT: $name\n";
if($name eq "ALL")
{
$self->{in_all}=1;
elsif($state==$STATE_TAG)
{
my $tag=$self->tail();
-# print "SM: TAG/TAGVAL($state): $name\n";
if($self->is($TYPE_TAG, $tag) && $self->{db}->tag_has_values($tag->id()))
{
-# print "Parsing: parent: $tag->id()\n";
my $tagval=ID3FS::Path::Node->new($self->{db}, $TYPE_TAG, $name, $tag->id());
if(defined($tagval))
{
}
elsif($state==$STATE_BOOLEAN)
{
-# print "SM: BOOLEAN: $name\n";
my $parent=$self->tail();
my $allownot=1;
if($self->is($TYPE_BOOL, $parent) &&
}
elsif($state==$STATE_ALBUMS)
{
-# print "SM: ALBUM: $name\n";
if($name eq $PATH_ALLTRACKS)
{
$self->state($STATE_TRACKLIST);
}
elsif($state==$STATE_TRACKLIST)
{
-# print "SM: TRACKLIST: $name\n";
my $track=ID3FS::Path::Node->new($self->{db}, $TYPE_FILE, $name);
if($track)
{
}
elsif($state==$STATE_FILE)
{
-# print "SM: FILE: $name\n";
# Can't have anything after a filename
$self->state($STATE_INVALID);
}
{
pop @elements;
}
-# print "\nELEMENTS: ", join(' ', map { $_->name(); } @elements), "\n";
- my @joins=$self->number_joins(@elements);
- @joins=qw(INNER) unless(@joins);
- $self->{joins}=\@joins;
-# print "AFTER: ", join(' ', map { $_->name() . "(" . $_->{table} . ")"; } @elements), "\n";
-# print "JOINS: ", join(', ', @joins), "\n";
+
+ # calculate joins and assign table numbers to nodes
+ $self->{joins}=[$self->number_joins(@elements)];
+
+ # always need at least one join
+ $self->{joins}=[qw(INNER)] unless(@{$self->{joins}});
+
# sort elements by precedence
@elements=$self->sort_elements(@elements);
+
+ # convert to binary tree
$self->{tagtree}=$self->elements_to_tree(\@elements);
}
}
else
{
+ $node->hasvals(0);
if(@elements)
{
# if tag has a value, eat the tag, shifting to the value
$node->hasvals(1);
$node=shift(@elements);
}
- else
- {
- $node->hasvals(0);
- }
}
elsif($self->{db}->tag_has_values($node->id()))
{
{
my($self)=@_;
my $tree=$self->{tagtree};
-# use Data::Dumper;
-# print Dumper $tree;
my ($sqlclause, @joins)=$tree->to_sql() if($tree);
my $sql="\tSELECT fxt1.files_id FROM tags t1";
my @crosses=();