X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2FID3FS%2FPath%2FNode.pm;h=377e8dd68f53582d40ae0abceba55cc1e818e430;hb=1c7e55d34956f90d235632995acf1238878db2a3;hp=8ce259e794c6c9ce9ec78c6fe2647e5e3dbd3ff8;hpb=1e73912219547384bb259904512b8ffa49037e81;p=id3fs.git diff --git a/lib/ID3FS/Path/Node.pm b/lib/ID3FS/Path/Node.pm index 8ce259e..377e8dd 100644 --- a/lib/ID3FS/Path/Node.pm +++ b/lib/ID3FS/Path/Node.pm @@ -10,10 +10,17 @@ sub new my $self={}; bless($self,$class); - $self->left(shift); - $self->op(shift); - $self->right(shift); - + my $db=shift; + $self->{type}=shift; + $self->{name}=shift; + $self->{parents_id}=shift; + if($self->{type} ne "boolean") + { + my $table=ucfirst($self->{type}); + $table .= "s" unless($table=~/s$/); + $self->{id}=$db->lookup_id($table, $self->{name}, $self->{parents_id}); + return undef unless(defined($self->{id})); + } return $self; } @@ -27,19 +34,22 @@ sub set return $self->{$name}; } -sub left { return shift->set("left", shift); } -sub right { return shift->set("right", shift); } -sub op { return shift->set("op", shift); } +sub left { return shift->set("left", shift); } +sub right { return shift->set("right", shift); } +sub name { return shift->set("name", shift); } +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->op(); + my $op=$self->name(); my $left=$self->left(); my $right=$self->right(); return "" unless($left || $right); my $str .= $self->print_node($left); - $str .= (" " . $op->{name} . " ") if($op); + $str .= (" " . $op . " ") if($op); $str .= $self->print_node($right); if($op || ($left && $right)) { @@ -58,7 +68,7 @@ sub print_node sub to_sql { - my($self, $not, @joins)=@_; + my($self, $hasvals, $not, @joins)=@_; $not=0 unless(defined($not)); my @outjoins=(); # init @@ -69,18 +79,25 @@ sub to_sql my $left=$self->left(); my $right=$self->right(); return ("", @outjoins) unless($left || $right); - my ($leftstr, @leftjoins) = $self->node_to_sql($left, $not, @joins); + my ($leftstr, @leftjoins) = $self->node_to_sql($left, $hasvals, $not, @joins); push(@joins, @leftjoins); push(@outjoins, @leftjoins); - my $op=$self->op(); - if(defined($op)) + my $op=$self->name(); + if(defined($op) && $self->type() eq "boolean") { - if($op->{name} 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"))) { - push(@joins, "INNER"); - push(@outjoins, "INNER"); + # 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->{name} eq "NOT") + elsif($op eq "NOT") { $not=1; push(@joins, "LEFT"); @@ -89,12 +106,12 @@ sub to_sql # print("RIGHT: ", $right->print(), "\n") if($right); } } - my ($rightstr, @rightjoins) = $self->node_to_sql($right, $not, @joins); + my ($rightstr, @rightjoins) = $self->node_to_sql($right, $hasvals, $not, @joins); push(@outjoins, @rightjoins); # print "LEFT (", scalar(@leftjoins), "): $leftstr\n"; # print "RIGHT (", scalar(@rightjoins), "): $rightstr\n"; my $str=$leftstr; - $str .= (" " . $op->{name} . " ") if($op && !$not); + $str .= " $op " if($op && !$not); $str .= $rightstr; if($op || ($left && $right)) { @@ -106,22 +123,22 @@ sub to_sql sub node_to_sql { - my($self, $node, $not, @joins)=@_; + my($self, $node, $hasvals, $not, @joins)=@_; return ("", ()) unless(defined($node)); - return $node->to_sql($not, @joins) if(ref($node) eq "ID3FS::Path::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 fxt" . scalar(@joins) . ".tags_id='" . $node->{id} . "'"; + $sql .= " AND t" . scalar(@joins) . ".id='" . $node->{id} . "'"; } else { $sql= "(t" . scalar(@joins) .".parents_id=''"; - $sql .= " AND fxt" . scalar(@joins) . ".tags_id='" . $node->{id} . "'"; + $sql .= " AND t" . scalar(@joins) . ".id='" . $node->{id} . "'"; } - if($not) + if($not && !$hasvals) { $sql .= " AND fxt" . scalar(@joins) . ".files_id IS NULL"; } @@ -132,28 +149,19 @@ sub node_to_sql sub used_tags { my($self)=@_; - my @used=(grep { defined; } ($self->node_used_tags($self->left()), - $self->node_used_tags($self->right()))); - return(@used); -} - -sub node_used_tags -{ - my($self, $node)=@_; - return (undef) unless(defined($node)); - return $node->used_tags() if(ref($node) eq "ID3FS::Path::Node"); - if(defined($node->{parents_id})) + if($self->type() eq "boolean") { - return([ $node->{parents_id}, $node->{id} ]); + my @used=(); + push(@used, $self->left()->used_tags()) if($self->left()); + push(@used, $self->right()->used_tags()) if($self->right()); + print "BOOL: ", $self->name(), join(', ', grep { defined; } @used), "\n"; + return(grep { defined; } @used); } - return $node->{id}; -} - - -sub max -{ - my($self, $a, $b)=@_; - return(($a > $b) ? $a : $b); + elsif($self->parents_id()) + { + return([ $self->parents_id(), $self->id() ]); + } + return $self->id(); } 1;