From: Ian Beckwith Date: Sat, 23 Oct 2010 19:09:40 +0000 (+0100) Subject: make hasvals a per-node setting X-Git-Tag: debian/1.0-1~7 X-Git-Url: http://erislabs.net/gitweb/?p=id3fs.git;a=commitdiff_plain;h=a461a5fca9a1ffc9e54c978423214c2fa59431e5 make hasvals a per-node setting --- diff --git a/lib/ID3FS/Path.pm b/lib/ID3FS/Path.pm index e54c7e2..de8d63b 100644 --- a/lib/ID3FS/Path.pm +++ b/lib/ID3FS/Path.pm @@ -116,7 +116,7 @@ sub dirents elsif($state==$STATE_BOOLEAN) { my $parent=$self->tail(); - unless($self->is($TYPE_BOOL, $parent) && $parent->{name} eq "NOT") + unless($self->is($TYPE_BOOL, $parent) && $parent->name() eq "NOT") { @dents=("NOT"); } @@ -250,7 +250,7 @@ sub parse my $parent=$self->tail(); my $allownot=1; if($self->is($TYPE_BOOL, $parent) && - $parent->{name} eq "NOT") + $parent->name() eq "NOT") { $allownot=0; } @@ -375,11 +375,11 @@ sub number_joins my $nextjoin=undef; my $lastop=undef; return (@joins) unless(@elements); - while(my $thing=shift @elements) + while(my $node=shift @elements) { - if($thing->type() == $TYPE_BOOL) + if($node->type() == $TYPE_BOOL) { - my $op=$thing->name(); + my $op=$node->name(); if($op eq "AND") { $nextjoin="INNER"; @@ -400,9 +400,17 @@ sub number_joins if(@elements) { # if tag has a value, eat the tag, shifting to the value - $thing=shift(@elements) if($elements[0]->type() == $TYPE_TAG); + if($elements[0]->type() == $TYPE_TAG) + { + $node->hasvals(1); + $node=shift(@elements); + } + else + { + $node->hasvals(0); + } } - elsif($self->{db}->tag_has_values($thing->id())) + elsif($self->{db}->tag_has_values($node->id())) { # if the expression ends in a tag that has a value # (ie we have the tag and want the value) @@ -415,7 +423,7 @@ sub number_joins push(@joins, $nextjoin); $nextjoin=undef; } - $thing->table($table); + $node->table($table); } } return @joins; @@ -438,18 +446,18 @@ sub elements_to_tree my($self, $elements)=@_; return undef unless(@$elements); my ($left, $right, $op)=(undef, undef, undef); - my $thing=pop @$elements; - if($self->is($TYPE_BOOL, $thing)) + my $node=pop @$elements; + if($self->is($TYPE_BOOL, $node)) { $right=$self->elements_to_tree($elements); - if($thing->{name} ne "NOT") + if($node->name() ne "NOT") { $left=$self->elements_to_tree($elements); } - $thing->left($left); - $thing->right($right); + $node->left($left); + $node->right($right); } - return $thing; + return $node; } # Dijkstra's shunting-yard algorithm @@ -458,25 +466,25 @@ sub sort_elements my ($self, @input)=@_; my @opstack=(); my @output=(); - while(my $thing = shift @input) + while(my $node = shift @input) { - if($self->is($TYPE_TAG, $thing)) + if($self->is($TYPE_TAG, $node)) { # Handle tag values by dropping parent if(@input && $self->is($TYPE_TAG, $input[0])) { - $thing=shift @input; + $node=shift @input; } - push(@output, $thing); + push(@output, $node); } - elsif($self->is($TYPE_BOOL, $thing)) + elsif($self->is($TYPE_BOOL, $node)) { while(@opstack && - ($priorities{$thing->{name}} <= $priorities{$opstack[$#opstack]->{name}})) + ($priorities{$node->name()} <= $priorities{$opstack[$#opstack]->name()})) { push(@output, pop(@opstack)); } - push(@opstack, $thing); + push(@opstack, $node); } } while(@opstack) @@ -533,10 +541,10 @@ sub tail sub is { - my($self, $type, $thing)=@_; - return 0 unless($thing); - return 0 unless($thing->type()); - return 1 if($type == $thing->type()); + my($self, $type, $node)=@_; + return 0 unless($node); + return 0 unless($node->type()); + return 1 if($type == $node->type()); return 0; } @@ -557,7 +565,6 @@ sub tags my $sql="SELECT DISTINCT name FROM tags WHERE parents_id='';"; return($self->{db}->cmd_firstcol($sql)); } - my $hasvals=$self->expecting_values(); my $sql="SELECT tags.name FROM "; if($self->want_all_tags()) { @@ -575,7 +582,7 @@ sub tags my $id=$self->trailing_tag_id(); my $parentclause= "tags.parents_id='"; - $parentclause .= $id if($hasvals); + $parentclause .= $id if($self->expecting_values()); $parentclause .= "'"; push(@andclauses, $parentclause); @@ -728,11 +735,10 @@ sub filename sub tags_subselect { my($self)=@_; - my $hasvals=$self->expecting_values(); my $tree=$self->{tagtree}; # use Data::Dumper; # print Dumper $tree; - my ($sqlclause, @joins)=$tree->to_sql($hasvals) if($tree); + my ($sqlclause, @joins)=$tree->to_sql() if($tree); my $sql="\tSELECT fxt1.files_id FROM tags t1"; my @crosses=(); my @inners=(); diff --git a/lib/ID3FS/Path/Node.pm b/lib/ID3FS/Path/Node.pm index ee3f931..b343090 100644 --- a/lib/ID3FS/Path/Node.pm +++ b/lib/ID3FS/Path/Node.pm @@ -37,7 +37,7 @@ sub new $self->{name}=shift; $self->{parents_id}=shift; $self->{table}=1; - $self->{join}=undef; + $self->{hasvals}=undef; if($self->{type} != $TYPE_BOOL) { my $table=''; @@ -68,19 +68,18 @@ sub type { return shift->set("type", shift); } sub id { return shift->set("id", shift); } sub parents_id { return shift->set("parents_id", shift); } sub table { return shift->set("table", shift); } -sub join { return shift->set("join", shift); } +sub hasvals { return shift->set("hasvals", shift); } sub to_sql { - my($self, $hasvals, $not)=@_; + my($self, $not)=@_; $not=0 unless(defined($not)); - $hasvals=0 unless(defined($hasvals)); my $str=''; if($self->type() != $TYPE_BOOL) { $str .= "t" . $self->table() . ".id='" . $self->{id} . "'"; - if($not && !$hasvals) + if($not && !$self->hasvals()) { $str = "(" . $str . " AND fxt" . $self->table() . ".files_id IS NULL)"; } @@ -91,10 +90,10 @@ sub to_sql my $right=$self->right(); return ("") unless($left || $right); - my $leftstr = $left->to_sql($hasvals, $not) if($left); + my $leftstr = $left->to_sql($not) if($left); my $op=$self->name(); $not=1 if(defined($op) && ($op eq "NOT")); - my $rightstr = $right->to_sql($hasvals, $not) if($right); + my $rightstr = $right->to_sql($not) if($right); $str = $leftstr; $str .= " $op " if($op && !$not); $str .= $rightstr;