Is it possible to use "dumb" result classes with DBIx::Class?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Is it possible to use "dumb" result classes with DBIx::Class?

Lasse Makholm
I'm using DBIx::Class::ResultClass::HashRefInflator in some places where full row object inflation is too slow. That's fine.

What I'd really like to do though, is bless the resulting hashrefs into a "light weight" result class that provides a few convenience methods but knows little to nothing about DBIx::Class.

Trying something like:

my $rs = $schema->resultset('MyTable')->search(...);
$rs->result_class('MyApp::Schema::DumbResult::MyTable');
while (my $thingy = $rs->next) {
# do, do, do
}

with something like:

package MyApp::Schema::DumbResult::MyTable;

use strict;
use warnings;

use DBIx::Class::ResultClass::HashRefInflator;

sub inflate_result
{
my $class = shift;
my $result = DBIx::Class::ResultClass::HashRefInflator->inflate_result(@_);
return bless $result, $class;
}

sub TO_JSON
{
my $self = shift;
return { %$self };
}

1;

...breaks for a variety of reasons it seems, because DBIx::Class wants to do things like setting a result source instance on the result object, etc...

Is there an (easy) make this work? Or is it just in general a horrible idea?

Of course I can just do:

$rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
my @stuff = map { bless $_, MyApp::Schema::DumbResult::MyTable } $rs->all;

...but the other way is more convenient...

Or is it more sane to subclass the ResultSet and override first(), all() and next() to set the result_class and bless the resulting hashrefs?

Any input appreciated?

/L



_______________________________________________
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@...
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Is it possible to use "dumb" result classes with DBIx::Class?

Will Crawford
You _should_ just be able to subclass the HRI class and add those methods (and pass { result_class => 'My::HRI::Subclass' } in for the RS attributes). I haven't tested this, will do in a moment :)

On 9 April 2015 at 14:58, Lasse Makholm <[hidden email]> wrote:
I'm using DBIx::Class::ResultClass::HashRefInflator in some places where full row object inflation is too slow. That's fine.

What I'd really like to do though, is bless the resulting hashrefs into a "light weight" result class that provides a few convenience methods but knows little to nothing about DBIx::Class.

Trying something like:

my $rs = $schema->resultset('MyTable')->search(...);
$rs->result_class('MyApp::Schema::DumbResult::MyTable');
while (my $thingy = $rs->next) {
# do, do, do
}

with something like:

package MyApp::Schema::DumbResult::MyTable;

use strict;
use warnings;

use DBIx::Class::ResultClass::HashRefInflator;

sub inflate_result
{
my $class = shift;
my $result = DBIx::Class::ResultClass::HashRefInflator->inflate_result(@_);
return bless $result, $class;
}

sub TO_JSON
{
my $self = shift;
return { %$self };
}

1;

...breaks for a variety of reasons it seems, because DBIx::Class wants to do things like setting a result source instance on the result object, etc...

Is there an (easy) make this work? Or is it just in general a horrible idea?

Of course I can just do:

$rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
my @stuff = map { bless $_, MyApp::Schema::DumbResult::MyTable } $rs->all;

...but the other way is more convenient...

Or is it more sane to subclass the ResultSet and override first(), all() and next() to set the result_class and bless the resulting hashrefs?

Any input appreciated?

/L



_______________________________________________
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@...


_______________________________________________
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@...
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Is it possible to use "dumb" result classes with DBIx::Class?

Lasse Makholm


On Thu, Apr 9, 2015 at 4:57 PM, Will Crawford <[hidden email]> wrote:
You _should_ just be able to subclass the HRI class and add those methods (and pass { result_class => 'My::HRI::Subclass' } in for the RS attributes). I haven't tested this, will do in a moment :)

Yeah, the problem seems to returning a blessed object from inflate_result, because then DBIx::Class thinks "Ooh! A real row object! I can do all sort of things with this!" Which it can't, so BOOM! :-)

/L

On 9 April 2015 at 14:58, Lasse Makholm <[hidden email]> wrote:
I'm using DBIx::Class::ResultClass::HashRefInflator in some places where full row object inflation is too slow. That's fine.

What I'd really like to do though, is bless the resulting hashrefs into a "light weight" result class that provides a few convenience methods but knows little to nothing about DBIx::Class.

Trying something like:

my $rs = $schema->resultset('MyTable')->search(...);
$rs->result_class('MyApp::Schema::DumbResult::MyTable');
while (my $thingy = $rs->next) {
# do, do, do
}

with something like:

package MyApp::Schema::DumbResult::MyTable;

use strict;
use warnings;

use DBIx::Class::ResultClass::HashRefInflator;

sub inflate_result
{
my $class = shift;
my $result = DBIx::Class::ResultClass::HashRefInflator->inflate_result(@_);
return bless $result, $class;
}

sub TO_JSON
{
my $self = shift;
return { %$self };
}

1;

...breaks for a variety of reasons it seems, because DBIx::Class wants to do things like setting a result source instance on the result object, etc...

Is there an (easy) make this work? Or is it just in general a horrible idea?

Of course I can just do:

$rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
my @stuff = map { bless $_, MyApp::Schema::DumbResult::MyTable } $rs->all;

...but the other way is more convenient...

Or is it more sane to subclass the ResultSet and override first(), all() and next() to set the result_class and bless the resulting hashrefs?

Any input appreciated?

/L



_______________________________________________
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@...


_______________________________________________
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@...


_______________________________________________
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@...
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Is it possible to use "dumb" result classes with DBIx::Class?

Will Crawford
In reply to this post by Will Crawford
Ignore me, -EINSUFFICIENTCAFFEINE. Of course you need to class the returned objects ...


On 9 April 2015 at 15:57, Will Crawford <[hidden email]> wrote:
You _should_ just be able to subclass the HRI class and add those methods (and pass { result_class => 'My::HRI::Subclass' } in for the RS attributes). I haven't tested this, will do in a moment :)

On 9 April 2015 at 14:58, Lasse Makholm <[hidden email]> wrote:
I'm using DBIx::Class::ResultClass::HashRefInflator in some places where full row object inflation is too slow. That's fine.

What I'd really like to do though, is bless the resulting hashrefs into a "light weight" result class that provides a few convenience methods but knows little to nothing about DBIx::Class.

Trying something like:

my $rs = $schema->resultset('MyTable')->search(...);
$rs->result_class('MyApp::Schema::DumbResult::MyTable');
while (my $thingy = $rs->next) {
# do, do, do
}

with something like:

package MyApp::Schema::DumbResult::MyTable;

use strict;
use warnings;

use DBIx::Class::ResultClass::HashRefInflator;

sub inflate_result
{
my $class = shift;
my $result = DBIx::Class::ResultClass::HashRefInflator->inflate_result(@_);
return bless $result, $class;
}

sub TO_JSON
{
my $self = shift;
return { %$self };
}

1;

...breaks for a variety of reasons it seems, because DBIx::Class wants to do things like setting a result source instance on the result object, etc...

Is there an (easy) make this work? Or is it just in general a horrible idea?

Of course I can just do:

$rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
my @stuff = map { bless $_, MyApp::Schema::DumbResult::MyTable } $rs->all;

...but the other way is more convenient...

Or is it more sane to subclass the ResultSet and override first(), all() and next() to set the result_class and bless the resulting hashrefs?

Any input appreciated?

/L



_______________________________________________
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@...



_______________________________________________
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@...
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Is it possible to use "dumb" result classes with DBIx::Class?

Will Crawford
In reply to this post by Lasse Makholm
It's easy enough to override inflate_result, like so:

{
    package My::HRI::Subclass;
    use Moose;
    BEGIN { extends 'DBIx::Class::ResultClass::HashRefInflator'; }
    sub inflate_result { bless shift->maybe::next::method(@_); }
    sub TO_JSON
    {
            my $self = shift;
            return { %$self };
    }
}

my $users = $schema->resultset('User');
my $me = $users->find( $my_user_id, { 
    result_class => 'My::HRI::Subclass' 
} );

Dwarn $me->TO_JSON;


On 9 April 2015 at 16:00, Lasse Makholm <[hidden email]> wrote:


On Thu, Apr 9, 2015 at 4:57 PM, Will Crawford <[hidden email]> wrote:
You _should_ just be able to subclass the HRI class and add those methods (and pass { result_class => 'My::HRI::Subclass' } in for the RS attributes). I haven't tested this, will do in a moment :)

Yeah, the problem seems to returning a blessed object from inflate_result, because then DBIx::Class thinks "Ooh! A real row object! I can do all sort of things with this!" Which it can't, so BOOM! :-)

/L

On 9 April 2015 at 14:58, Lasse Makholm <[hidden email]> wrote:
I'm using DBIx::Class::ResultClass::HashRefInflator in some places where full row object inflation is too slow. That's fine.

What I'd really like to do though, is bless the resulting hashrefs into a "light weight" result class that provides a few convenience methods but knows little to nothing about DBIx::Class.

Trying something like:

my $rs = $schema->resultset('MyTable')->search(...);
$rs->result_class('MyApp::Schema::DumbResult::MyTable');
while (my $thingy = $rs->next) {
# do, do, do
}

with something like:

package MyApp::Schema::DumbResult::MyTable;

use strict;
use warnings;

use DBIx::Class::ResultClass::HashRefInflator;

sub inflate_result
{
my $class = shift;
my $result = DBIx::Class::ResultClass::HashRefInflator->inflate_result(@_);
return bless $result, $class;
}

sub TO_JSON
{
my $self = shift;
return { %$self };
}

1;

...breaks for a variety of reasons it seems, because DBIx::Class wants to do things like setting a result source instance on the result object, etc...

Is there an (easy) make this work? Or is it just in general a horrible idea?

Of course I can just do:

$rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
my @stuff = map { bless $_, MyApp::Schema::DumbResult::MyTable } $rs->all;

...but the other way is more convenient...

Or is it more sane to subclass the ResultSet and override first(), all() and next() to set the result_class and bless the resulting hashrefs?

Any input appreciated?

/L



_______________________________________________
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@...


_______________________________________________
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@...


_______________________________________________
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@...


_______________________________________________
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@...
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Is it possible to use "dumb" result classes with DBIx::Class?

Dmitry Latin
In reply to this post by Lasse Makholm
Strange. Your example just works for me.
I tried it with DBIC example ( DBIx::Class::Manual::Example ) without
any changes, just copy-paste.

And yes, I use the latest DBIC.

On 9 April 2015 at 16:58, Lasse Makholm <[hidden email]> wrote:

> I'm using DBIx::Class::ResultClass::HashRefInflator in some places where
> full row object inflation is too slow. That's fine.
>
> What I'd really like to do though, is bless the resulting hashrefs into a
> "light weight" result class that provides a few convenience methods but
> knows little to nothing about DBIx::Class.
>
> Trying something like:
>
> my $rs = $schema->resultset('MyTable')->search(...);
> $rs->result_class('MyApp::Schema::DumbResult::MyTable');
> while (my $thingy = $rs->next) {
>
> # do, do, do
>
> }
>
>
> with something like:
>
> package MyApp::Schema::DumbResult::MyTable;
>
> use strict;
> use warnings;
>
> use DBIx::Class::ResultClass::HashRefInflator;
>
> sub inflate_result
> {
> my $class = shift;
> my $result = DBIx::Class::ResultClass::HashRefInflator->inflate_result(@_);
> return bless $result, $class;
> }
>
> sub TO_JSON
> {
> my $self = shift;
> return { %$self };
> }
>
> 1;
>
>
> ...breaks for a variety of reasons it seems, because DBIx::Class wants to do
> things like setting a result source instance on the result object, etc...
>
> Is there an (easy) make this work? Or is it just in general a horrible idea?
>
> Of course I can just do:
>
> $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
> my @stuff = map { bless $_, MyApp::Schema::DumbResult::MyTable } $rs->all;
>
> ...but the other way is more convenient...
>
> Or is it more sane to subclass the ResultSet and override first(), all() and
> next() to set the result_class and bless the resulting hashrefs?
>
> Any input appreciated?
>
> /L
>
>
>
> _______________________________________________
> 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@...



--
//wbr, Dmitry L.

_______________________________________________
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@...
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Is it possible to use "dumb" result classes with DBIx::Class?

Lasse Makholm
Hah! You're right! It does work.

It was just me failing to realize that the errors were actually thrown at load time, not inflate time. The problem is putting a "dumb" under MyApp::Schema::Result:: because DBIx::Class will try to load and initialize it as a normal result class during DBIx::Class::Schema->load_namespaces().

Putting the dumb result class outside the MyApp::Schema::Result:: namespace works just fine.

Thanks for your help both of you.

/L

On Thu, Apr 9, 2015 at 5:34 PM, Dmitry L. <[hidden email]> wrote:
Strange. Your example just works for me.
I tried it with DBIC example ( DBIx::Class::Manual::Example ) without
any changes, just copy-paste.

And yes, I use the latest DBIC.

On 9 April 2015 at 16:58, Lasse Makholm <[hidden email]> wrote:
> I'm using DBIx::Class::ResultClass::HashRefInflator in some places where
> full row object inflation is too slow. That's fine.
>
> What I'd really like to do though, is bless the resulting hashrefs into a
> "light weight" result class that provides a few convenience methods but
> knows little to nothing about DBIx::Class.
>
> Trying something like:
>
> my $rs = $schema->resultset('MyTable')->search(...);
> $rs->result_class('MyApp::Schema::DumbResult::MyTable');
> while (my $thingy = $rs->next) {
>
> # do, do, do
>
> }
>
>
> with something like:
>
> package MyApp::Schema::DumbResult::MyTable;
>
> use strict;
> use warnings;
>
> use DBIx::Class::ResultClass::HashRefInflator;
>
> sub inflate_result
> {
> my $class = shift;
> my $result = DBIx::Class::ResultClass::HashRefInflator->inflate_result(@_);
> return bless $result, $class;
> }
>
> sub TO_JSON
> {
> my $self = shift;
> return { %$self };
> }
>
> 1;
>
>
> ...breaks for a variety of reasons it seems, because DBIx::Class wants to do
> things like setting a result source instance on the result object, etc...
>
> Is there an (easy) make this work? Or is it just in general a horrible idea?
>
> Of course I can just do:
>
> $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
> my @stuff = map { bless $_, MyApp::Schema::DumbResult::MyTable } $rs->all;
>
> ...but the other way is more convenient...
>
> Or is it more sane to subclass the ResultSet and override first(), all() and
> next() to set the result_class and bless the resulting hashrefs?
>
> Any input appreciated?
>
> /L
>
>
>
> _______________________________________________
> 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@...



--
//wbr, Dmitry L.


_______________________________________________
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@...
Loading...