X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2FID3FS%2FPath%2FNode.pm;h=52888a6b03e068ef0308056dcc85e5cee00398ad;hb=125aa69f2632c386f65b413ae0cb095ff0afd886;hp=771a15a48e766a7013fce9e1b5c1ce5307a2bc36;hpb=6dabdf427ad2980410665482e096c5ab3fc24a0e;p=id3fs.git diff --git a/lib/ID3FS/Path/Node.pm b/lib/ID3FS/Path/Node.pm index 771a15a..52888a6 100644 --- a/lib/ID3FS/Path/Node.pm +++ b/lib/ID3FS/Path/Node.pm @@ -1,8 +1,30 @@ +# id3fs - a FUSE-based filesystem for browsing audio metadata +# Copyright (C) 2010 Ian Beckwith +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + 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; @@ -10,10 +32,22 @@ 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; + $self->{table}=1; + $self->{hasvals}=undef; + if($self->{type} != $TYPE_BOOL) + { + 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})); + } return $self; } @@ -27,77 +61,57 @@ 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 table { return shift->set("table", shift); } +sub hasvals { return shift->set("hasvals", shift); } -sub print +sub to_sql { - my($self)=@_; - my $op=$self->op(); - my $left=$self->left(); - my $right=$self->right(); - return "" unless($left || $right); - my $str .= $self->print_node($left); - $str .= (" " . $op->{name} . " ") if($op); - $str .= $self->print_node($right); - if($op || ($left && $right)) + my($self, $not)=@_; + $not=0 unless(defined($not)); + my $str=''; + + if($self->type() != $TYPE_BOOL) { - $str="(" . $str . ")"; + $str .= "t" . $self->table() . ".id='" . $self->{id} . "'"; + if($not && !$self->hasvals()) + { + $str = "(" . $str . " AND fxt" . $self->table() . ".files_id IS NULL)"; + } + return ($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, $andlevel, $parent_is_tag)=@_; - $andlevel=1 unless(defined($andlevel)); - $parent_is_tag=0 unless(defined($parent_is_tag)); - my ($leftandlevel, $rightandlevel); - my ($leftstr, $rightstr); - my $op=$self->op(); my $left=$self->left(); my $right=$self->right(); - return ("", $andlevel) unless($left || $right); - ($leftstr, $leftandlevel) = $self->node_to_sql($left, $andlevel); - $andlevel=$self->max($andlevel, $leftandlevel); - if(defined($op) && (($op->{name} eq "AND") || ($op->{name} eq "NOT"))) - { - $andlevel++; - } - ($rightstr, $rightandlevel) = $self->node_to_sql($right, $andlevel); - my $str=$leftstr; - $str .= (" " . $op->{name} . " ") if($op); - $str .= $rightstr; - if($op || ($left && $right)) - { - $str="(" . $str . ")"; - } - return($str, $self->max($leftandlevel, $rightandlevel)); -} + return ("") unless($left || $right); -sub node_to_sql -{ - my($self, $node, $andlevel)=@_; - return ("", $andlevel) unless(defined($node)); - return $node->to_sql($andlevel) if(ref($node) eq "ID3FS::Path::Node"); - # FIXME: switch to id when debugged -# return( ( "fxt" . $andlevel . "=\"" . $node->{id} . "\""), $andlevel); - return( ( "fxt" . $andlevel . "=\"" . $node->{name} . "\""), $andlevel); + 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($not) if($right); + $str = $leftstr; + $str .= " $op " if($op && !$not); + $str .= $rightstr; + $str=("(" . $str . ")") if($op && $left && $right); + return($str); } -sub max +sub used_tags { - my($self, $a, $b)=@_; - return(($a > $b) ? $a : $b); + my($self)=@_; + if($self->type() == $TYPE_BOOL) + { + my @used=(); + push(@used, $self->left()->used_tags()) if($self->left()); + push(@used, $self->right()->used_tags()) if($self->right()); + return(grep { defined; } @used); + } + return $self->id(); } 1;