From 1c7e55d34956f90d235632995acf1238878db2a3 Mon Sep 17 00:00:00 2001 From: Ian Beckwith Date: Mon, 18 Oct 2010 08:30:17 +0100 Subject: [PATCH] merge PathElement::* into Path::Node --- lib/ID3FS/Path.pm | 53 +++++++++++++++-------------------- lib/ID3FS/Path/Node.pm | 76 ++++++++++++++++++++++++-------------------------- 2 files changed, 59 insertions(+), 70 deletions(-) diff --git a/lib/ID3FS/Path.pm b/lib/ID3FS/Path.pm index 919d28a..4947256 100644 --- a/lib/ID3FS/Path.pm +++ b/lib/ID3FS/Path.pm @@ -2,12 +2,6 @@ package ID3FS::Path; use strict; use warnings; -use ID3FS::PathElement::Artist; -use ID3FS::PathElement::Album; -use ID3FS::PathElement::Boolean; -use ID3FS::PathElement::File; -use ID3FS::PathElement::Tag; -use ID3FS::PathElement::Tagval; use ID3FS::Path::Node; our ($STATE_INVALID, $STATE_ROOT, $STATE_TAG, $STATE_TAGVAL, @@ -166,12 +160,12 @@ sub parse elsif($name eq "NOT") { $root_not=1; - push(@{$self->{elements}}, ID3FS::PathElement::Boolean->new($self->{db}, $name)); + push(@{$self->{elements}}, ID3FS::Path::Node->new($self->{db}, "boolean", $name)); $self->state($STATE_BOOLEAN); } else { - $tag=ID3FS::PathElement::Tag->new($self->{db}, $name); + $tag=ID3FS::Path::Node->new($self->{db},"tag", $name); if($tag) { push(@{$self->{elements}}, $tag); @@ -192,7 +186,7 @@ sub parse $self->{db}->tag_has_values($tag->id())) { # print "Parsing: parent: $tag->id()\n"; - my $tagval=ID3FS::PathElement::Tag->new($self->{db}, $name, $tag->id()); + my $tagval=ID3FS::Path::Node->new($self->{db}, "tag", $name, $tag->id()); if(defined($tagval)) { $self->state($STATE_TAGVAL); @@ -215,16 +209,16 @@ sub parse elsif($name eq "AND") { $self->state($STATE_BOOLEAN); - push(@{$self->{elements}}, ID3FS::PathElement::Boolean->new($self->{db}, $name)); + push(@{$self->{elements}}, ID3FS::Path::Node->new($self->{db}, "boolean", $name)); } elsif($name eq "OR") { $self->state($STATE_BOOLEAN); - push(@{$self->{elements}}, ID3FS::PathElement::Boolean->new($self->{db}, $name)); + push(@{$self->{elements}}, ID3FS::Path::Node->new($self->{db}, "boolean", $name)); } else { - my $artist=ID3FS::PathElement::Artist->new($self->{db}, $name); + my $artist=ID3FS::Path::Node->new($self->{db}, "artist", $name); if($artist) { push(@{$self->{elements}}, $artist); @@ -249,11 +243,11 @@ sub parse if($allownot && $name eq "NOT") { $self->state($STATE_BOOLEAN); - push(@{$self->{elements}}, ID3FS::PathElement::Boolean->new($self->{db}, $name)); + push(@{$self->{elements}}, ID3FS::Path::Node->new($self->{db}, "boolean", $name)); } else { - my $tag=ID3FS::PathElement::Tag->new($self->{db}, $name); + my $tag=ID3FS::Path::Node->new($self->{db}, "tag", $name); if($tag) { push(@{$self->{elements}}, $tag); @@ -279,7 +273,7 @@ sub parse } else { - my $album=ID3FS::PathElement::Album->new($self->{db}, $name); + my $album=ID3FS::Path::Node->new($self->{db}, "album", $name); if($album) { push(@{$self->{elements}}, $album); @@ -294,7 +288,7 @@ sub parse elsif($state==$STATE_TRACKLIST) { # print "SM: TRACKLIST: $name\n"; - my $track=ID3FS::PathElement::File->new($self->{db}, $name); + my $track=ID3FS::Path::Node->new($self->{db}, "file", $name); if($track) { push(@{$self->{elements}}, $track); @@ -323,7 +317,7 @@ sub parse } else { - my $artist=ID3FS::PathElement::Artist->new($self->{db}, $name); + my $artist=ID3FS::Path::Node->new($self->{db}, "artist", $name); if($artist) { push(@{$self->{elements}}, $artist); @@ -358,8 +352,8 @@ sub parse $self->{tagtree}=$self->elements_to_tree(\@elements); if($self->{tagtree}) { - ($self->{sqlconditions}, - $self->{joins}) = $self->{tagtree}->to_sql(); + my ($conditions, @joins)=$self->{tagtree}->to_sql(); +# print "CONDITIONS(", scalar(@joins), "): ", $conditions, "\n"; # print "TREE: ", $self->{tagtree}->print(), "\n"; # print("SQL CONDITION(", scalar(@{$self->{joins}}), "): ", # $self->{sqlconditions}, "\n"); @@ -387,18 +381,15 @@ sub elements_to_tree my $thing=pop @$elements; if($self->is("boolean", $thing)) { - my $op=$thing; $right=$self->elements_to_tree($elements); - if($op->{name} ne "NOT") + if($thing->{name} ne "NOT") { $left=$self->elements_to_tree($elements); } - return ID3FS::Path::Node->new($left, $op, $right); - } - else - { - return ID3FS::Path::Node->new($thing); + $thing->left($left); + $thing->right($right); } + return $thing; } # Dijkstra's shunting-yard algorithm @@ -493,9 +484,8 @@ sub is { my($self, $type, $thing)=@_; return 0 unless($thing); - my $ref=ref($thing); - my $typestr="ID3FS::PathElement::" . ucfirst($type); - return 1 if($ref eq $typestr); + return 0 unless($thing->type()); + return 1 if($type eq $thing->type()); return 0; } @@ -610,7 +600,6 @@ sub albums my($self)=@_; my @ids=(); my $tail=$self->tail(); - # FIXME: rework PathElements if($self->is("artist", $tail)) { return $self->artist_albums($tail->id()); @@ -670,7 +659,6 @@ sub album_tracks sub tracks { my($self)=@_; - # FIXME: rework PathElements my $tail=$self->tail(); if($self->is("artist", $tail)) { @@ -735,6 +723,9 @@ sub tags_subselect return "\tSELECT id FROM files AS files_id\n"; } my $tree=$self->{tagtree}; + print "UNDEF!!\n" unless($self->{tagtree}); + use Data::Dumper; + print Dumper $tree; my $parent=$self->trailing_tag_parent(); # print "ELEMENTS: ", join('/', map { $_->{name}; } @{$self->{elements}}), "\n"; diff --git a/lib/ID3FS/Path/Node.pm b/lib/ID3FS/Path/Node.pm index fe74252..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)) { @@ -72,25 +82,22 @@ sub to_sql 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 we are ANDing, add an inner join # also if we are NOTing, but we are looking for a tag *value* - if( ($op->{name} eq "AND") || - ($hasvals && ($op->{name} eq "NOT"))) + 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->{op} - && $right->{op}->{name} - && $right->{op}->{name} eq "NOT") + 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"); @@ -104,7 +111,7 @@ sub to_sql # 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)) { @@ -118,7 +125,7 @@ sub node_to_sql { my($self, $node, $hasvals, $not, @joins)=@_; return ("", ()) unless(defined($node)); - return $node->to_sql($hasvals, $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})) @@ -142,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; -- 2.11.0