my @constraints=@{$path->{elements}};
if(!@constraints) # /
{
- # FIXME: add ALL?
my $sql="SELECT DISTINCT name FROM tags WHERE parents_id='';";
my $tags=$self->cmd_rows($sql);
return(map { $_->[0]; } @$tags);
}
+ my $hasvals=$path->tag_has_values();
+ my $parent=$path->trailing_tag_parent();
+ print "THASVALS: $hasvals\n";
+ print "TPARENT: ", (defined($parent)? $parent : "NO"), "\n";
my @ids=();
my $sql=("SELECT tags.name FROM (\n" .
$self->tags_subselect($path) .
print "tags(): USED: ", join(", ", @used), "\n";
print "tags(): USED_WITH_VALS: ", join(", ", map { "[".$_->[0]. ", ".$_->[1]."]";} @used_with_vals), "\n";
my @orclauses=();
- if($path->tag_has_values())
+ my @andclauses=();
+ my $id=$path->trailing_tag_id();
+ if($hasvals)
{
print "HAS_VALUES\n";
- my $parent=$path->trailing_tag_id();
- print "parent: $parent\n";
- my @values=map { "'".$_->[1]."'"; } grep { $_->[0] == $parent; } @used_with_vals;
- my $clause="(tags.parents_id='$parent'";
+ my @values=map { "'".$_->[1]."'"; } grep { $_->[0] == $id; } @used_with_vals;
+ my $clause="(tags.parents_id='$id'";
if(@values)
{
$clause .= " AND tags.id NOT IN (" . join(', ', @values) . ")";
print "HASNT VALUES\n";;
if(@used)
{
- push(@orclauses, "(tags.parents_id='' AND tags.id NOT IN (" . join(', ', @used) . "))");
+ push(@orclauses, "(NOT (tags.parents_id='' AND tags.id IN (" . join(', ', @used) . ")))");
}
for my $pair (@used_with_vals)
{
- push(@orclauses, "(tags.parents_id='" . $pair->[0] . "' AND tags.id!='" . $pair->[1] . "')");
+ push(@orclauses, "(NOT (tags.parents_id='" . $pair->[0] . "' AND tags.id='" . $pair->[1] . "'))");
}
}
+
+ my $parentclause= "(tags.parents_id='";
+ if($hasvals)
+ {
+ $parentclause .= $id;
+ }
+ elsif($parent)
+ {
+ $parentclause .= $parent;
+ }
+ $parentclause .= "')";
+ push(@andclauses, $parentclause);
+
if(@orclauses)
{
- $sql .= "WHERE " . join(' OR ', @orclauses) . "\n";
+ push(@andclauses, join(' OR ', @orclauses));
+ }
+ if(@andclauses)
+ {
+ $sql .= "WHERE " . join(' AND ', @andclauses) . "\n";
}
$sql .= "GROUP BY tags.name;";
print "SQL: $sql\n";
sub artist_tracks
{
my($self, $artist_id, $path)=@_;
- my @constraints=@{$path->{elements}};
my $sql=("SELECT files.name FROM (\n" .
$self->tags_subselect($path) .
"\t) AS subselect\n" .
# FIXME: rework PathElements
if(ref($constraints[$#constraints]) eq "ID3FS::PathElement::Artist")
{
- return $self->artist_tracks($constraints[$#constraints]->{id}, @constraints);
+ 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, $path);
}
elsif(ref($constraints[$#constraints]) eq "ID3FS::PathElement::Album")
{
{
my($self, $path)=@_;
my $tree=$path->{tagtree};
+ my $hasvals=$path->tag_has_values();
+ my $parent=$path->trailing_tag_parent();
+
my $tag=undef;
- if($path->tag_has_values())
+ if($hasvals)
{
$tag=$path->trailing_tag_id();
print "Trailing id: $tag\n";
}
- my ($sqlclause, $joinsneeded)=$tree->to_sql($tag);
+ my ($sqlclause, $joinsneeded)=(undef, 1);
+ ($sqlclause, $joinsneeded) = $tree->to_sql($tag) if($tree);
print "SQL($joinsneeded): $sqlclause\n";
my $sql="\tSELECT fxt1.files_id FROM tags t1";
my @crosses=();
}
$sql .= ("\n\t" . join(" ", @crosses)) if(@crosses);
$sql .= ("\n" . join("\n", @inners)) if(@inners);
- $sql .= "\n\tWHERE $sqlclause";
+ $sql .= "\n\tWHERE $sqlclause" if($sqlclause);
# if($tag)
# {
# $sql .= " AND t${joinsneeded}.parents_id='$tag'";
}
}
# remove trailing boolean
- if(@{$self->{elements}} &&
- ref($self->{elements}->[$#{$self->{elements}}]) eq "ID3FS::PathElement::Boolean")
- {
- $self->{lastop}=pop @{$self->{elements}};
- }
+ my @elements=@{$self->{elements}};
+ pop @elements if(@elements && ref($elements[$#elements]) eq "ID3FS::PathElement::Boolean");
# sort elements by precedence
- @{$self->{elements}}=$self->sort_elements(@{$self->{elements}});
- $self->{tagtree}=$self->elements_to_tree([ @{$self->{elements}} ]);
+ @elements=$self->sort_elements(@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);
}
{
my($self)=@_;
my $tail=$self->{elements}->[$#{$self->{elements}}];
+ print "TAIL: ", ref($tail), "\n";
if($tail && ref($tail) eq "ID3FS::PathElement::Tag")
{
return($self->{db}->tag_has_values($tail->{id}));
return undef;
}
+sub trailing_tag_parent
+{
+ my($self)=@_;
+ my $tail=$self->{elements}->[$#{$self->{elements}}];
+ if($tail && ref($tail) eq "ID3FS::PathElement::Tag")
+ {
+ return($tail->{parents_id});
+ }
+ return undef;
+}
+
+
1;