X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2FID3FS%2FPath%2FNode.pm;h=bdc403fda57f238972315a9b5ba1c5ae33beb73a;hb=fc30364efa6a07b2065f0f54e6792f17970535b8;hp=681a66cfc911eb965eaf7eaf384a721d7346bfc4;hpb=fb37f8cca3d20be63e245717448a1d2ce1e3b5fb;p=id3fs.git diff --git a/lib/ID3FS/Path/Node.pm b/lib/ID3FS/Path/Node.pm index 681a66c..bdc403f 100644 --- a/lib/ID3FS/Path/Node.pm +++ b/lib/ID3FS/Path/Node.pm @@ -1,3 +1,19 @@ +# id3fs - a FUSE-based filesystem for browsing audio metadata +# Copyright (C) 2010 Ian Beckwith +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + package ID3FS::Path::Node; use strict; @@ -71,24 +87,39 @@ sub to_sql my($self, $hasvals, $not, @joins)=@_; $not=0 unless(defined($not)); my @outjoins=(); + my $str=''; # init unless(@joins) { @outjoins = @joins = ("INNER"); } + + if($self->type() ne "boolean") + { + my $cnt=scalar(@joins)+1; + $str .= "t" . scalar(@joins) . ".id='" . $self->{id} . "'"; + if($not && !$hasvals) + { + $str .= " AND fxt" . scalar(@joins) . ".files_id IS NULL"; + } + return ($str, @outjoins); + } + my $left=$self->left(); my $right=$self->right(); return ("", @outjoins) unless($left || $right); - my ($leftstr, @leftjoins) = $self->node_to_sql($left, $hasvals, $not, @joins); + my ($leftstr, @leftjoins) = $left->to_sql($hasvals, $not, @joins) if($left); push(@joins, @leftjoins); push(@outjoins, @leftjoins); my $op=$self->name(); - if(defined($op) && $self->type() eq "boolean") + print "op: $op type: ", $self->type(), " not: $not\n"; + if(defined($op)) { # if we are ANDing, add an inner join # also if we are NOTing, but we are looking for a tag *value* - if( ($op eq "AND") || ($hasvals && ($op eq "NOT"))) + if($op eq "AND") { + print "AND\n"; # hack - if right child is a NOT, we don't need extra join/brackets # NOT will do the same and we will end up with an extra one unless($right && $right->name() && $right->name() eq "NOT") @@ -99,18 +130,44 @@ sub to_sql } elsif($op eq "NOT") { + print "NOT (was $not)\n"; $not=1; - push(@joins, "LEFT"); - push(@outjoins, "LEFT"); + # as above - if right child is a NOT, we don't need extra join/brackets + # NOT will do the same and we will end up with an extra one + unless($right && $right->name() && $right->name() eq "NOT") + { + if($hasvals) + { + push(@joins, "INNER"); + push(@outjoins, "INNER"); + } + else + { + push(@joins, "LEFT"); + push(@outjoins, "LEFT"); + } + } # print("LEFT: ", $left->print(), "\n") if ($left); # print("RIGHT: ", $right->print(), "\n") if($right); } + elsif($op eq "OR") + { + print "OR\n"; + # if left child is a NOT, we need an extra (inner) join + # unless right child is also a NOT + if(($left && $left->name() && $left->name() eq "NOT") && + !($right && $right->name() && $right->name() eq "NOT")) + { + push(@joins, "INNER"); + push(@outjoins, "INNER"); + } + } } - my ($rightstr, @rightjoins) = $self->node_to_sql($right, $hasvals, $not, @joins); + my ($rightstr, @rightjoins) = $right->to_sql($hasvals, $not, @joins) if($right); push(@outjoins, @rightjoins); # print "LEFT (", scalar(@leftjoins), "): $leftstr\n"; # print "RIGHT (", scalar(@rightjoins), "): $rightstr\n"; - my $str=$leftstr; + $str=$leftstr; $str .= " $op " if($op && !$not); $str .= $rightstr; if($op || ($left && $right)) @@ -118,34 +175,11 @@ sub to_sql $str="(" . $str . ")"; } # print "STR: $str\n"; +# my @all=(@joins, @rightjoins); +# print "JOINS: RETURN ", scalar(@outjoins), " ALL ", scalar(@all), "\n"; return($str, @outjoins); } -sub node_to_sql -{ - my($self, $node, $hasvals, $not, @joins)=@_; - return ("", ()) unless(defined($node)); - return $node->to_sql($hasvals, $not, @joins) if($node->type() eq "boolean"); - my $sql; - my $cnt=scalar(@joins)+1; - if(defined($node->{parents_id})) - { - $sql= "(t" . scalar(@joins) . ".parents_id='$node->{parents_id}'"; - $sql .= " AND t" . scalar(@joins) . ".id='" . $node->{id} . "'"; - } - else - { - $sql= "(t" . scalar(@joins) .".parents_id=''"; - $sql .= " AND t" . scalar(@joins) . ".id='" . $node->{id} . "'"; - } - if($not && !$hasvals) - { - $sql .= " AND fxt" . scalar(@joins) . ".files_id IS NULL"; - } - $sql .= ")"; - return ($sql, ()); -} - sub used_tags { my($self)=@_; @@ -156,10 +190,6 @@ sub used_tags push(@used, $self->right()->used_tags()) if($self->right()); return(grep { defined; } @used); } - elsif($self->parents_id()) - { - return([ $self->parents_id(), $self->id() ]); - } return $self->id(); }