1 package ID3FS::Path::Node;
9 my $class=ref($proto) || $proto;
22 my($self, $name, $val)=@_;
27 return $self->{$name};
30 sub left { return shift->set("left", shift); }
31 sub right { return shift->set("right", shift); }
32 sub op { return shift->set("op", shift); }
38 my $left=$self->left();
39 my $right=$self->right();
40 return "" unless($left || $right);
41 my $str .= $self->print_node($left);
42 $str .= (" " . $op->{name} . " ") if($op);
43 $str .= $self->print_node($right);
44 if($op || ($left && $right))
46 $str="(" . $str . ")";
54 return "" unless(defined($node));
55 return $node->print() if(ref($node) eq "ID3FS::Path::Node");
61 my($self, $hasvals, $not, @joins)=@_;
62 $not=0 unless(defined($not));
67 @outjoins = @joins = ("INNER");
69 my $left=$self->left();
70 my $right=$self->right();
71 return ("", @outjoins) unless($left || $right);
72 my ($leftstr, @leftjoins) = $self->node_to_sql($left, $hasvals, $not, @joins);
73 push(@joins, @leftjoins);
74 push(@outjoins, @leftjoins);
78 # if we are ANDing, add an inner join
79 # also if we are NOTing, but we are looking for a tag *value*
80 if( ($op->{name} eq "AND") ||
81 ($hasvals && ($op->{name} eq "NOT")))
83 # hack - if right child is a NOT, we don't need extra join/brackets
84 # NOT will do the same and we will end up with an extra one
85 unless($right && $right->{op}
86 && $right->{op}->{name}
87 && $right->{op}->{name} eq "NOT")
89 push(@joins, "INNER");
90 push(@outjoins, "INNER");
93 elsif($op->{name} eq "NOT")
97 push(@outjoins, "LEFT");
98 # print("LEFT: ", $left->print(), "\n") if ($left);
99 # print("RIGHT: ", $right->print(), "\n") if($right);
102 my ($rightstr, @rightjoins) = $self->node_to_sql($right, $hasvals, $not, @joins);
103 push(@outjoins, @rightjoins);
104 # print "LEFT (", scalar(@leftjoins), "): $leftstr\n";
105 # print "RIGHT (", scalar(@rightjoins), "): $rightstr\n";
107 $str .= (" " . $op->{name} . " ") if($op && !$not);
109 if($op || ($left && $right))
111 $str="(" . $str . ")";
113 # print "STR: $str\n";
114 return($str, @outjoins);
119 my($self, $node, $hasvals, $not, @joins)=@_;
120 return ("", ()) unless(defined($node));
121 return $node->to_sql($hasvals, $not, @joins) if(ref($node) eq "ID3FS::Path::Node");
123 my $cnt=scalar(@joins)+1;
124 if(defined($node->{parents_id}))
126 $sql= "(t" . scalar(@joins) . ".parents_id='$node->{parents_id}'";
127 $sql .= " AND t" . scalar(@joins) . ".id='" . $node->{id} . "'";
131 $sql= "(t" . scalar(@joins) .".parents_id=''";
132 $sql .= " AND t" . scalar(@joins) . ".id='" . $node->{id} . "'";
134 if($not && !$hasvals)
136 $sql .= " AND fxt" . scalar(@joins) . ".files_id IS NULL";
145 my @used=(grep { defined; } ($self->node_used_tags($self->left()),
146 $self->node_used_tags($self->right())));
153 return (undef) unless(defined($node));
154 return $node->used_tags() if(ref($node) eq "ID3FS::Path::Node");
155 if(defined($node->{parents_id}))
157 return([ $node->{parents_id}, $node->{id} ]);
165 my($self, $a, $b)=@_;
166 return(($a > $b) ? $a : $b);