# print "DIRENTS: FILE: $self->{path}\n";
if($state==$STATE_TAG || $state==$STATE_TAGVAL)
{
- my $tag=$self->{elements}->[$#{$self->{elements}}];
+ my $tag=$self->tail();
if($state==$STATE_TAG &&
defined($tag) &&
ref($tag) eq "ID3FS::PathElement::Tag" &&
}
elsif($state==$STATE_BOOLEAN)
{
- my $parent=$self->{elements}->[$#{$self->{elements}}];
+ my $parent=$self->tail();
unless(defined($parent) &&
ref($parent) eq "ID3FS::PathElement::Boolean" &&
$parent->{name} eq "NOT")
elsif($state==$STATE_TAG || $state==$STATE_TAGVAL)
{
# print "SM: TAG/TAGVAL($state): $name\n";
- my $tag=$self->{elements}->[$#{$self->{elements}}];
+ my $tag=$self->tail();
if($state==$STATE_TAG &&
defined($tag) &&
ref($tag) eq "ID3FS::PathElement::Tag" &&
elsif($state==$STATE_BOOLEAN)
{
# print "SM: BOOLEAN: $name\n";
- my $parent=$self->{elements}->[$#{$self->{elements}}];
+ my $parent=$self->tail();
my $allownot=1;
if(defined($parent) &&
ref($parent) eq "ID3FS::PathElement::Boolean" &&
}
# remove trailing boolean
my @elements=@{$self->{elements}};
- pop @elements if(@elements && ref($elements[$#elements]) eq "ID3FS::PathElement::Boolean");
+ while(@elements && ref($elements[$#elements]) eq "ID3FS::PathElement::Boolean")
+ {
+ pop @elements;
+ }
# sort elements by precedence
@elements=$self->sort_elements(@elements);
- $self->{tagtree}=$self->elements_to_tree(@elements);
+ $self->{tagtree}=$self->elements_to_tree(\@elements);
if($self->{tagtree})
{
($self->{sqlconditions},
sub elements_to_tree
{
- my($self, @elements)=@_;
- return undef unless(@elements);
+ my($self, $elements)=@_;
+ return undef unless(@$elements);
my ($left, $right, $op)=(undef, undef, undef);
- my $thing=pop @elements;
+ my $thing=pop @$elements;
if(ref($thing) eq "ID3FS::PathElement::Boolean")
{
my $op=$thing;
- $right=$self->elements_to_tree(@elements);
+ $right=$self->elements_to_tree($elements);
if($op->{name} ne "NOT")
{
- $left=$self->elements_to_tree(@elements);
+ $left=$self->elements_to_tree($elements);
}
return ID3FS::Path::Node->new($left, $op, $right);
}
{
if(ref($thing) eq "ID3FS::PathElement::Tag")
{
-# print "Pushing $thing->{name} to output\n";
push(@output, $thing);
-# print "OPSTACK: ", join(', ', map { $_->{name}; } @opstack), "\n";
-# print "OUTPUT: ", join(', ', map { $_->{name}; } @output), "\n";
}
elsif(ref($thing) eq "ID3FS::PathElement::Boolean")
{
-# print "BOOL: $thing->{name}\n";
# bool
-# print "thing: $thing->{name}: $priorities{$thing->{name}} ";
- if(@opstack)
- {
-# print("topop: ", $opstack[$#opstack]->{name},
-# ": ", $priorities{$opstack[$#opstack]->{name}}, "\n");
- }
while(@opstack &&
($priorities{$thing->{name}} <= $priorities{$opstack[$#opstack]->{name}}))
{
-# print "Pushing ", $opstack[$#opstack]->{name}, " from opstack to output\n";
push(@output, pop(@opstack));
-# print "OPSTACK: ", join(', ', map { $_->{name}; } @opstack), "\n";
-# print "OUTPUT: ", join(', ', map { $_->{name}; } @output), "\n";
}
-# print "Pushing $thing->{name} to opstack\n";
push(@opstack, $thing);
-# print "OPSTACK: ", join(', ', map { $_->{name}; } @opstack), "\n";
-# print "OUTPUT: ", join(', ', map { $_->{name}; } @output), "\n";
}
}
while(@opstack)
sub tag_has_values
{
my($self)=@_;
- my $tail=$self->{elements}->[$#{$self->{elements}}];
- print "TAIL: ", ref($tail), "\n";
+ my $tail=$self->tail();
if($tail && ref($tail) eq "ID3FS::PathElement::Tag")
{
return($self->{db}->tag_has_values($tail->{id}));
sub trailing_tag_id
{
my($self)=@_;
- my $tail=$self->{elements}->[$#{$self->{elements}}];
+ my $tail=$self->tail();
if($tail && ref($tail) eq "ID3FS::PathElement::Tag")
{
return($tail->{id});
sub trailing_tag_parent
{
my($self)=@_;
- my $tail=$self->{elements}->[$#{$self->{elements}}];
+ my $tail=$self->tail();
if($tail && ref($tail) eq "ID3FS::PathElement::Tag")
{
return($tail->{parents_id});
return undef;
}
+sub tail
+{
+ my($self)=@_;
+ return($self->{elements}->[$#{$self->{elements}}]);
+}
+
+# the one before last
+sub tail_parent
+{
+ my($self)=@_;
+ return($self->{elements}->[($#{$self->{elements}}) - 1]);
+}
+
######################################################################
sub tags
{
my($self)=@_;
- my @constraints=@{$self->{elements}};
- if(!@constraints) # /
+ if(!@{$self->{elements}}) # /
{
my $sql="SELECT DISTINCT name FROM tags WHERE parents_id='';";
return($self->{db}->cmd_firstcol($sql));
sub artists
{
my($self)=@_;
- my @constraints=@{$self->{elements}};
- if(!@constraints) # /ALL
+ if(!@{$self->{elements}}) # /ALL
{
my $sql="SELECT DISTINCT name FROM artists;";
return($self->{db}->cmd_firstcol($sql));
sub albums
{
my($self)=@_;
- my @constraints=@{$self->{elements}};
my @ids=();
+ my $tail=$self->tail();
# FIXME: rework PathElements
- if(ref($constraints[$#constraints]) eq "ID3FS::PathElement::Artist")
+ if(ref($tail) eq "ID3FS::PathElement::Artist")
{
- return $self->artist_albums($constraints[$#constraints]->{id});
+ return $self->artist_albums($tail->{id});
}
my $sql=("SELECT albums.name\n" .
"\tFROM (\n" .
sub artist_albums
{
my($self, $artist_id)=@_;
- my @constraints=@{$self->{elements}};
my $sql=("SELECT albums.name FROM (\n" .
$self->tags_subselect() .
"\t) AS subselect\n" .
sub tracks
{
my($self)=@_;
- my @constraints=@{$self->{elements}};
# FIXME: rework PathElements
- if(ref($constraints[$#constraints]) eq "ID3FS::PathElement::Artist")
+ my $tail=$self->tail();
+ if(ref($tail) eq "ID3FS::PathElement::Artist")
{
- my $artist_id=0;
- my $artist=$constraints[$#constraints];
- if(defined($artist) && (ref($artist) eq "ID3FS::PathElement::Artist"))
- {
- # should always happen
- $artist_id=$artist->{id};
- }
- return $self->artist_tracks($artist_id);
+ return $self->artist_tracks($tail->{id});
}
- elsif(ref($constraints[$#constraints]) eq "ID3FS::PathElement::Album")
+ elsif(ref($tail) eq "ID3FS::PathElement::Album")
{
my $artist_id=0;
- my $artist=$constraints[($#constraints)-1];
+ my $artist=$self->tail_parent();
if(defined($artist) && (ref($artist) eq "ID3FS::PathElement::Artist"))
{
# should always happen
$artist_id=$artist->{id};
}
- return $self->album_tracks($artist_id, $constraints[$#constraints]->{id});
+ return $self->album_tracks($artist_id, $tail->{id});
}
my $sql=("SELECT files.name\n" .
sub filename
{
my($self, $mountpoint)=@_;
- my @constraints=@{$self->{elements}};
- if(ref($constraints[$#constraints]) eq "ID3FS::PathElement::File")
+ my $tail=$self->tail();
+ if(ref($tail) eq "ID3FS::PathElement::File")
{
- my $id=$constraints[$#constraints]->{id};
+ my $id=$tail->{id};
my $sql=("SELECT paths.name, files.name FROM files\n" .
"INNER JOIN paths ON files.paths_id=paths.id\n" .
"WHERE files.id=?\n" .
"GROUP BY paths.name, files.name");
print "FILENAME SQL: $sql\n";
my ($path, $name)=$self->{db}->cmd_onerow($sql, $id);
- my $id3fs_path=join('/', map { $_->{name}; } @constraints);
+ my $id3fs_path=join('/', map { $_->{name}; } @{$self->{elements}});
return($self->{db}->relativise($path, $name, $mountpoint, $id3fs_path));
}
die("DB::filename: unhandled case\n"); #FIXME
my $hasvals=$self->tag_has_values();
my $parent=$self->trailing_tag_parent();
+# print "ELEMENTS: ", join('/', map { $_->{name}; } @{$self->{elements}}), "\n";
+# print "TREE: ", $tree->print(), "\n";
my $tag=undef;
if($hasvals)
{
}
my ($sqlclause, $joinsneeded)=(undef, 1);
($sqlclause, $joinsneeded) = $tree->to_sql($tag) if($tree);
- print "SQL($joinsneeded): $sqlclause\n";
+# print "SQL($joinsneeded): $sqlclause\n";
my $sql="\tSELECT fxt1.files_id FROM tags t1";
my @crosses=();
my @inners=();
# $joinsneeded++ if($tag);
for(my $i=1; $i <= $joinsneeded; $i++)
{
- if($i > 1)
- {
- push(@crosses, "CROSS JOIN tags t$i");
- }
my $inner=("\tINNER JOIN files_x_tags fxt$i ON " .
"t${i}.id=fxt${i}.tags_id");
- if($i>2)
+ if($i > 1)
{
+ push(@crosses, "CROSS JOIN tags t$i");
$inner .= " AND fxt1.files_id=fxt${i}.files_id";
}
push(@inners, $inner);