Skip Menu |

This queue is for tickets about the DBIx-Class-Schema-Loader CPAN distribution.

Report information
The Basics
Id: 74175
Status: resolved
Priority: 0/
Queue: DBIx-Class-Schema-Loader

People
Owner: Nobody in particular
Requestors: MARKLE [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in:
  • 0.07011
  • 0.07012
  • 0.07013
  • 0.07014
  • 0.07015
Fixed in: (no value)



Subject: confusion with schema_base_class loader option when it overrides connection()
Hi. I tried using schema_base_class with make_schema_at() loader_options. Except that base class overrides connection(). When Loader calls connection(), it calls it as a class method instead of an object method. When DBIx::Class::Schema's connect() calls connection(), it has already instantiated an object and calls connection() as an object method. This caused some confusion for me because my overloaded connection() method uses object attributes to keep track of what it does the connection is first established. Other schema objects may use the same base class and will need to use their object attributes to keep that state for each one. I worked around this by checking (ref $self) when I do stuff in the overloaded connection() method in my schema base class. That seems a little awkward. Would it make sense for make_schema_at() to call connect() instead of connection()? Thanks. HTH. -Mark
On Thu Jan 19 22:29:25 2012, MARKLE wrote: Show quoted text
> Hi. I tried using schema_base_class with make_schema_at() > loader_options. Except that base class overrides connection(). When > Loader calls connection(), it calls it as a class method instead of an > object method. When DBIx::Class::Schema's connect() calls
connection(), Show quoted text
> it has already instantiated an object and calls connection() as an > object method. > > This caused some confusion for me because my overloaded connection() > method uses object attributes to keep track of what it does the > connection is first established. Other schema objects may use the
same Show quoted text
> base class and will need to use their object attributes to keep that > state for each one. > > I worked around this by checking (ref $self) when I do stuff in the > overloaded connection() method in my schema base class. That seems a > little awkward. Would it make sense for make_schema_at() to call > connect() instead of connection()? > > Thanks. HTH. -Mark
Hi, just getting to this ticket. To answer your question, probably not. Could you write me a test that illustrates what breaks for you, and what behavior you expect? Write it against git master preferably. In the meanwhile I'll try to come up with one myself based on what you wrote here.
Ok, I see the problem you're running into now. It is perfectly reasonable for the loader to call ->connection as a class method because DBIx::Class::Schema holds 'storage' as class data, more precisely as the 'inherited' Class::Accessor::Grouped type, and - Show quoted text
>connection initializes 'storage'.
More on the 'inherited' group in Class::Accessor::Grouped: it does not simply mean class data, if it is invoked on an instance it will be stored on the instance, and the instance will override the class data version. For this reason, make_schema_at cannot simply call ->connect instead of ->connection and throw away the $schema instance, the 'storage' would then be initialized on this instance and not on the class, and the class would have no storage initialized. ->connect is simply: sub connect { shift->clone->connection(@_) } I'm not sure how important this is, or not, since the important part is invoking the loader in the overloaded connection method, but some dynamic schema users may expect the storage to be set on the schema class, so that they can simply do SchemaClass->clone and have all the connection information already populated. So the problem seems to be in your code, that is expecting ->connection to be called only on an instance, rather than on a class which is valid usage. The correct solution is to make your instance data be of type 'inherited' accessors using Class::Accessor::Grouped. It is possible others will run into this same mistaken assumption, so I will add a workaround to make_schema_at, something like the following: my $temp_schema = $target->connect(@info); $target->storage($temp_schema->storage); I will do this later today and do a new release and update this ticket.
Fixed in 0.07021, was a bit more involved then I originally thought. Reopen the ticket if this release doesn't fix your issue with instance state in connection.