start of support for NOT queries
authorIan Beckwith <ianb@erislabs.net>
Mon, 11 Oct 2010 04:35:43 +0000 (05:35 +0100)
committerIan Beckwith <ianb@erislabs.net>
Mon, 11 Oct 2010 04:35:43 +0000 (05:35 +0100)
lib/ID3FS/Path.pm
lib/ID3FS/Path/Node.pm

index 46bac15..319e147 100644 (file)
@@ -338,9 +338,9 @@ sub parse
     if($self->{tagtree})
     {
        ($self->{sqlconditions},
-        $self->{andsneeded}) = $self->{tagtree}->to_sql();
+        $self->{joins}) = $self->{tagtree}->to_sql();
 #      print "TREE: ",  $self->{tagtree}->print(), "\n";
-#      print("SQL CONDITION(", $self->{andsneeded}, "): ",
+#      print("SQL CONDITION(", scalar(@{$self->{joins}}), "): ",
 #            $self->{sqlconditions}, "\n");
 #      use Data::Dumper;
 #      print Dumper $self->{tagtree};
@@ -721,21 +721,24 @@ sub tags_subselect
        $tag=$self->trailing_tag_id();
 #      print "Trailing id: $tag\n";
     }
-    my ($sqlclause, $joinsneeded)=(undef, 1);
-    ($sqlclause, $joinsneeded) = $tree->to_sql($tag) if($tree);
-#    print "SQL($joinsneeded): $sqlclause\n";
+    my ($sqlclause, @joins)=(undef, ());
+    ($sqlclause, @joins) = $tree->to_sql($tag) if($tree);
+    print "JOINS: ", join(", ", @joins), "\n";
+#    print "SQL(" . scalar(@joins) .": $sqlclause\n";
     my $sql="\tSELECT fxt1.files_id FROM tags t1";
     my @crosses=();
     my @inners=();
 #    $joinsneeded++ if($tag);
-    for(my $i=1; $i <= $joinsneeded; $i++)
+    for(my $i=0; $i <= $#joins; $i++)
     {
-       my $inner=("\tINNER JOIN files_x_tags fxt$i ON " .
-                  "t${i}.id=fxt${i}.tags_id");
-       if($i > 1)
+       my $cnt=$i+1;
+       my $join=$joins[$i];
+       my $inner=("\t$join JOIN files_x_tags fxt$cnt ON " .
+                  "t${cnt}.id=fxt${cnt}.tags_id");
+       if($i > 0)
        {
-           push(@crosses, "CROSS JOIN tags t$i");
-           $inner .= " AND fxt1.files_id=fxt${i}.files_id";
+           push(@crosses, "CROSS JOIN tags t$cnt");
+           $inner .= " AND fxt1.files_id=fxt${cnt}.files_id";
        }
        push(@inners, $inner);
     }
index 5280478..8362f34 100644 (file)
@@ -58,33 +58,31 @@ sub print_node
 
 sub to_sql
 {
-    my($self, $parent, $andlevel)=@_;
-    $andlevel=1 unless(defined($andlevel));
-    my ($leftandlevel, $rightandlevel);
+    my($self, $parent, @joins)=@_;
+    @joins=("INNER") unless(@joins);
+    my @newjoins=();
+    my (@leftjoins, @rightjoins);
     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, $parent, $andlevel);
+    return ("", @joins) unless($left || $right);
+    ($leftstr, @leftjoins) = $self->node_to_sql($left, $parent, @joins);
 #    print "LEFT: $leftstr\n";
-    $andlevel=$self->max($andlevel, $leftandlevel);
-    if($op)
+#    $andlevel=$self->max($andlevel, $leftandlevel);
+    if(defined($op))
     {
-       if(ref($op) eq "ID3FS::PathElement::Boolean")
+       if($op->{name} eq "AND")
        {
-#          print "Op: Bool: ", $op->{name}, "\n";
+           push(@newjoins, "INNER");
        }
-       else
+       elsif($op->{name} eq "NOT")
        {
-#          print "Op: $op\n";
+           push(@newjoins, "LEFT");
        }
     }
-    if(defined($op) && (($op->{name} eq "AND") || ($op->{name} eq "NOT")))
-    {
-       $andlevel++;
-    }
-    ($rightstr, $rightandlevel) = $self->node_to_sql($right, $parent, $andlevel);
+    push(@joins, @newjoins);
+    ($rightstr, @rightjoins) = $self->node_to_sql($right, $parent, @joins);
 #    print "RIGHT: $rightstr\n";
     my $str=$leftstr;
     $str .= (" " . $op->{name} . " ") if($op);
@@ -93,39 +91,34 @@ sub to_sql
     {
        $str="(" . $str . ")";
     }
+#    print "LEFTJOINS: ", join(', ', @leftjoins), "\n";
+#    print "RIGHTJOINS:", join(', ', @rightjoins), "\n";
+#    print "NEWJOINS: ",  join(', ', @newjoins), "\n";
 #    print "STR: $str\n";
-    return($str, $self->max($leftandlevel, $rightandlevel));
+#    return($str, $self->max($leftandlevel, $rightandlevel));
+    my @sidejoins=((scalar(@leftjoins) > scalar(@rightjoins)) ? @leftjoins : @rightjoins);
+    my @alljoins=(@newjoins, @sidejoins);
+    return($str, @alljoins);
 }
 
 sub node_to_sql
 {
-    my($self, $node, $parent, $andlevel)=@_;
-    return ("", $andlevel) unless(defined($node));
-    return $node->to_sql($parent, $andlevel) if(ref($node) eq "ID3FS::Path::Node");
-#    if((ref($node->op()) ne "ID3FS::Path::Element") &&
-#       $node->op() eq "
+    my($self, $node, $parent, @joins)=@_;
+    return ("", @joins) unless(defined($node));
+    return $node->to_sql($parent, @joins) if(ref($node) eq "ID3FS::Path::Node");
     my $sql;
-#    print("Hit node: " . $node->{name}. "(" .
-#        (defined($node->{parents_id}) ? $node->{parents_id} : "") .
-#        ")\n");
+    my $cnt=scalar(@joins)+1;
     if(defined($node->{parents_id}))
     {
-#      print "HIT PARENTS_ID: $node->{parents_id}\n";
-       $sql= "(t$andlevel.parents_id='$node->{parents_id}'";
-       $sql .= " AND fxt${andlevel}.tags_id='" . $node->{id} . "')";
+       $sql= "(t" . scalar(@joins) . ".parents_id='$node->{parents_id}'";
+       $sql .= " AND fxt" . scalar(@joins) . ".tags_id='" . $node->{id} . "')";
     }
-#    elsif($parent)
-#    {
-#      print "HIT \$parent\n";
-#      $sql= "(t$andlevel.parents_id='$parent')";
-#    }
     else
     {
-#      print "HIT NORMAL\n";
-       $sql= "(t$andlevel.parents_id=''";
-       $sql .= " AND fxt${andlevel}.tags_id='" . $node->{id} . "')";
+       $sql= "(t" . scalar(@joins) .".parents_id=''";
+       $sql .= " AND fxt" . scalar(@joins) . ".tags_id='" . $node->{id} . "')";
     }
-    return ($sql, $andlevel);
+    return ($sql, @joins);
 }
 
 sub used_tags