Re: [Dbix-class] additional condition in LEFT JOIN in DBIx::Class

2009-09-18 Thread Paweł Pabian
On Thursday, 17 of September 2009 18:18:44 Emanuele Zeppieri wrote:
 Peter Rabbitson wrote:
  Eden Cardim wrote:
  On Thu, Sep 17, 2009 at 9:40 AM, Paweł Pabian pawel.pab...@implix.com 
wrote:
  Hi
 
  I have some users
 
  package Schema::User;
  __PACKAGE__-table('users');
  __PACKAGE__-add_columns('id', 'login');
  __PACKAGE__-set_primary_key('id');
  __PACKAGE__-has_many('attributes' = 'Schema::Attribute', 'users_id');
 
  and they have many attributes
 
  package Schema::Atrribute;
  __PACKAGE__-table('attributes');
  __PACKAGE__-add_columns('users_id', 'name', 'value');
  __PACKAGE__-set_primary_key('users_id', 'name');
  __PACKAGE__-belongs_to('user' = 'Schema::User', 'users_id');
 
  Now i want to find Users that don't have Attribute of given name.
  In raw SQL it needs name condition to be placed in LEFT JOIN:
 
  SELECT *
  FROM users AS u
  LEFT JOIN attributes AS a
 ON u.id=a.users_id
 AND a.name=car
  WHERE a.users_id IS NULL
 
  How to force DBIx::Class to add this
  
  AND a.name=car
  
  part to join condition?
 
  DBIC doesn't support variable join conditions, but you can add the AND
  a.name = 'car' condition to your where clause to the same effect.
 
  He can not. A left with right-side condition join is not the same as
  left join + where condition.
 
  The only way to do this currently is with a virtual view:
  http://search.cpan.org/~ribasushi/DBIx-Class-0.08111/lib/DBIx/Class/Resul
 tSource/View.pm

 Wouldn't a subquery like this work with the latest DBIC?

 my $users_wo_car = $schema-resultset('User')-search({
  id = {
  'not in' = $schema-resultset('Attribute')-search({
  name = 'car'
  })-get_column('users_id')-as_query
  }
 });

 (Untested, just noted that there are similar subqueries in from_subquery.t)

Yes.

It gives correct result but In my case it's ~900 times slower than JOIN due to 
DEPENDENT SUBQUERY optimizer bug in MySQL 5.x. That's why i asked question 
about JOIN version.

Thanks.

___
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk


[Dbix-class] Filtering with Many-to-Many relationship

2009-09-18 Thread Shawn Marincas
Alright, it seemed to me that what I wanted to do was straightforward, but
it doesn't seem like I can find any resources on how to do it... so maybe
I'm just going about it the wrong way.

I have a table Products and a table Tags with a many_to_many relationship
setup, the purpose of which would be to easily generate a resultset of
products with the given tag(s).  However, I'm running in to problems when I
want to generate a resultset of product records filtered with multiple
tags.  I was thinking that one of the following would work:

my $tag1 = 'A';
my $tag2 = 'B';

$c-model('MyApp:Tag')-single({ tag_id = $tag1 })-products-search({ tags
= { tag_id = $tag2 }});

OR

$c-model('MyApp:Tag')-single({ tag_id = $tag1
})-products-search_related('product_tags', { tag_id  = $tag2 });

But apparently the many_to_many relationship accessor only returns a list of
row_objects rather than a resultset itself, so I can't perform resultset
searches on that.  So I tried the following to chain together two searches:

$c-model('MyApp:Product')-search_related('product_tags',{ tag_id = $tag1
})-search_related('product_tags', { tag_id = $tag2 });

I tried the same chaining using search and joins to link to the
ProductTagsLink table, they combined the searches so that it was joining on
the related table searching for tag_id = $tag1 AND tag_id = $tag2 so that it
wasn't returning anything.  I was looking in to creating a subquery for
this, but my attempts have failed and the documentation mentions that
subqueries are experimental.  I'm thinking if I had an accessor to access
the many_to_many resultset as an actual resultset rather than a list of
row_objects I could probably get it working, but I didn't see any
documentation on actually doing that.  I managed to get the actual concept
working using this code here, but would prefer a straight SQL/DBIX solution
since this doesn't seem very efficient:

my $tag1 = 'A';
my $tag2 = 'B';
my $tag_rs = $c-model('ReaneyDesignDB::Tag')-single({ tag_id = $tag });

my @products = $tag_rs-products;

$c-stash-{products} = [grep { ($_-search_related('product_tags', { tag_id
= $tag2 })-single) } @products];

Anyone have experience trying to accomplish what I'm doing here?  Let me
know if I'm missing something here.  Thanks.

- Shawn Marincas
___
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk

Re: [Dbix-class] Filtering with Many-to-Many relationship

2009-09-18 Thread Wallace Reis
On Fri, Sep 18, 2009 at 3:06 PM, Shawn Marincas
shawngmarin...@gmail.com wrote:
 I have a table Products and a table Tags with a many_to_many relationship
 setup, the purpose of which would be to easily generate a resultset of
 products with the given tag(s).  However, I'm running in to problems when I
 want to generate a resultset of product records filtered with multiple
 tags.  I was thinking that one of the following would work:

 my $tag1 = 'A';
 my $tag2 = 'B';

my $product_rs = $schema-resultset('Product')-search_rs({
'tag.tag_id' = { -in = [qw/A B/] }
}, {
join = { 'product_tags' = 'tag' }
});

 But apparently the many_to_many relationship accessor only returns a list of
 row_objects rather than a resultset itself, so I can't perform resultset
 searches on that.  So I tried the following to chain together two searches:

You've used the -search method in your code in list context, so it
calls -all over the resultset and returns a list of row objects.

-- 
 wallace reis/wreis Catalyst and DBIx::Class consultancy with a clue
 Software Engineer  and a commit bit: 
http://shadowcat.co.uk/catalyst/
 Shadowcat Systems Limited
 http://www.shadowcat.co.uk http://www.linkedin.com/in/wallacereis

___
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk