X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2FID3FS%2FPath%2FNode.pm;h=6254600e5a87742970a2bb3117063c57238036e9;hb=c8571ddb3cc1f9bce16c91838de17f27242d2f32;hp=478adb33b75d97d6bff21cc36e3e3846eb59b846;hpb=edba03ce7b833ca4ad60f2e33250ec5e9d455a91;p=id3fs.git diff --git a/lib/ID3FS/Path/Node.pm b/lib/ID3FS/Path/Node.pm index 478adb3..6254600 100644 --- a/lib/ID3FS/Path/Node.pm +++ b/lib/ID3FS/Path/Node.pm @@ -19,6 +19,12 @@ package ID3FS::Path::Node; use strict; use warnings; +require Exporter; +use vars qw(@ISA @EXPORT $TYPE_BOOL $TYPE_TAG $TYPE_ARTIST $TYPE_ALBUM $TYPE_FILE); +@ISA=qw(Exporter); +@EXPORT=qw($TYPE_BOOL $TYPE_TAG $TYPE_ARTIST $TYPE_ALBUM $TYPE_FILE); +($TYPE_BOOL, $TYPE_TAG, $TYPE_ARTIST, $TYPE_ALBUM, $TYPE_FILE)=(1..5); + sub new { my $proto=shift; @@ -30,10 +36,13 @@ sub new $self->{type}=shift; $self->{name}=shift; $self->{parents_id}=shift; - if($self->{type} ne "boolean") + if($self->{type} != $TYPE_BOOL) { - my $table=ucfirst($self->{type}); - $table .= "s" unless($table=~/s$/); + my $table=''; + if ($self->{type} == $TYPE_TAG) { $table="tags"; } + elsif($self->{type} == $TYPE_ARTIST) { $table="artists"; } + elsif($self->{type} == $TYPE_ALBUM) { $table="albums"; } + elsif($self->{type} == $TYPE_FILE) { $table="files"; } $self->{id}=$db->lookup_id($table, $self->{name}, $self->{parents_id}); return undef unless(defined($self->{id})); } @@ -57,115 +66,104 @@ sub type { return shift->set("type", shift); } sub id { return shift->set("id", shift); } sub parents_id { return shift->set("parents_id", shift); } -sub print -{ - my($self)=@_; - my $op=$self->name(); - my $left=$self->left(); - my $right=$self->right(); - return "" unless($left || $right); - my $str .= $self->print_node($left); - $str .= (" " . $op . " ") if($op); - $str .= $self->print_node($right); - if($op || ($left && $right)) - { - $str="(" . $str . ")"; - } - return $str; -} - -sub print_node -{ - my($self, $node)=@_; - return "" unless(defined($node)); - return $node->print() if(ref($node) eq "ID3FS::Path::Node"); - return $node->{name}; -} - 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 $str=''; + + if($self->type() != $TYPE_BOOL) { - my $cnt=scalar(@joins)+1; $str .= "t" . scalar(@joins) . ".id='" . $self->{id} . "'"; if($not && !$hasvals) { - $str .= " AND fxt" . scalar(@joins) . ".files_id IS NULL"; + $str = "(" . $str . " AND fxt" . scalar(@joins) . ".files_id IS NULL)"; } return ($str, @outjoins); } - else + + my $left=$self->left(); + my $right=$self->right(); + return ("", @outjoins) unless($left || $right); + my ($leftstr, @leftjoins) = $left->to_sql($hasvals, $not, @joins) if($left); + push(@joins, @leftjoins); + push(@outjoins, @leftjoins); + my $op=$self->name(); + print "op: $op type: ", $self->type(), " not: $not\n"; + if(defined($op)) { - my $left=$self->left(); - my $right=$self->right(); - return ("", @outjoins) unless($left || $right); - 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") + # 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") { - # 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"))) - { - # 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") - { - push(@joins, "INNER"); - push(@outjoins, "INNER"); - } - } - elsif($op eq "NOT") + 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") { - $not=1; - push(@joins, "LEFT"); - push(@outjoins, "LEFT"); -# print("LEFT: ", $left->print(), "\n") if ($left); -# print("RIGHT: ", $right->print(), "\n") if($right); + push(@joins, "INNER"); + push(@outjoins, "INNER"); } - elsif($op eq "OR") + } + elsif($op eq "NOT") + { + print "NOT (was $not)\n"; + $not=1; + # 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 left child is a not, we need an extra (inner) join - if($left && $left->name() && $left->name() eq "NOT") + if($hasvals) { push(@joins, "INNER"); push(@outjoins, "INNER"); } + else + { + push(@joins, "LEFT"); + push(@outjoins, "LEFT"); + } } } - 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 .= " $op " if($op && !$not); - $str .= $rightstr; - if($op || ($left && $right)) + elsif($op eq "OR") { - $str="(" . $str . ")"; + 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"); + } } -# print "STR: $str\n"; -# my @all=(@joins, @rightjoins); -# print "JOINS: RETURN ", scalar(@outjoins), " ALL ", scalar(@all), "\n"; - return($str, @outjoins); } + 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"; + $str=$leftstr; + $str .= " $op " if($op && !$not); + $str .= $rightstr; + if($op && $left && $right) + { + $str="(" . $str . ")"; + } +# print "STR: $str\n"; +# my @all=(@joins, @rightjoins); +# print "JOINS: RETURN ", scalar(@outjoins), " ALL ", scalar(@all), "\n"; + return($str, @outjoins); } sub used_tags { my($self)=@_; - if($self->type() eq "boolean") + if($self->type() == $TYPE_BOOL) { my @used=(); push(@used, $self->left()->used_tags()) if($self->left());