[Dbix-class] table-per-subclass - how it works?

Alexander Hartmaier alexander.hartmaier at t-systems.at
Mon Jun 18 08:04:39 GMT 2012


If I understand you correctly, you want to define a Perl object that
doesn't directly relate to one table but to column from multiple tables?
DBIC result objects always represent exactly one table with all its
columns, primary and unique keys and relationships.
What you want is a 'business' layer on top of that which you can define
however you like, for example with Moose, that uses the DBIC objects so
you don't have to deal with SQL.

Am 2012-06-15 15:06, schrieb Alex Erzin:
> Hm...You revert idea of ORM ;)
>
> "extend one table class (called resultsource/resultset in DBIC) to form another table class" - I not need a _table_class_ at all. 
> I need just a Host object with related properties regardless of one or two or three tables I need to represent my object in RDBMS.
> In reality i need more extended hierarhy of classes, but here i try to find elegant solution only for two objects where one is inherited from another.
> And one of the ways is to use two tables where one table is represent common fields for both classes and another table represents fields only 
> specific for inherited class. And when i need to create one more inherited class i need simple to add new fields in new table - that's all.
> This in theory (or in Java ;)
>
> In other words, is it possible in Perl do something like in Hibernate in Java or no?
> And if possible - how to do this?
>
> PS. I already have mentioned that have developed such subsystem some years ago, but it was commercial project and i cannot use that solution in my current projects.
> I think that exists some free solution... seems to me i'm wrong with it.
>
>
>
> 15.06.2012, 15:53, "Alexander Hartmaier" <alexander.hartmaier at t-systems.at>:
>> Hi Alex,
>> there is no such thing as inheritance in an RDBMS, so why whould an ORM
>> extend one table class (called resultsource/resultset in DBIC) to form
>> another table class?
>> To get you started it's usually the easiest to let dbicdump [1] create
>> all the DBIC classes and look at what it generated.
>> Also the glossary [2] is a great thing to read before the rest of the
>> docs to know which terms the docs use for the various components.
>>
>> [1] https://metacpan.org/module/dbicdump
>> [2] https://metacpan.org/module/DBIx::Class::Manual::Glossary
>>
>> BR Alex
>>
>> Am 2012-06-15 10:30, schrieb Alex Erzin:
>>
>>>  I'm confused with "package Host; extends 'Base';"
>>>  I expect "extends 'Target'", not 'Base'. Is it correct?
>>>
>>>  15.06.2012, 12:06, "Hailin Hu" <i at h2l.name>:
>>>>  I have no idea about "standard" solution, but another idea for reference :)
>>>>
>>>>  Package Base;
>>>>  use base 'DBIx::Class::Core';
>>>>
>>>>  # parents' name should be a defined has_one or belong_to relationship
>>>>  has 'parents' => (
>>>>    is => 'rw',
>>>>    isa => 'ArrayRef[Str]',
>>>>    builder => _build_parents,
>>>>  );
>>>>
>>>>  sub inflate_result {
>>>>    my $self = shift;
>>>>    my $ret = $self->next::method( @_ );
>>>>    foreach my $relationship ( @{ $ret->parents } ) {
>>>>      my $parent = $ret->$relationship;
>>>>      my @columns = ... # @columns_in_$parent - @column_in_$ret
>>>>      foreach my $column ( @columns ) {
>>>>        # stolen from DBIx::Class's source
>>>>        no strict 'refs';
>>>>        no warnings 'redefine';
>>>>        my $method = join '::', ref $ret, $column;
>>>>        *$method = Sub::Name::subname( $method, sub {
>>>>          return $ret->$parent->$column;
>>>>        });
>>>>      }
>>>>    }
>>>>  }
>>>>  ...
>>>>
>>>>  package Target;
>>>>  extends 'Base';
>>>>  ...
>>>>
>>>>  package Host;
>>>>  extends 'Base';
>>>>  __PACKAGE__->belong_to('target' => 'Target', 'target_id');
>>>>  sub _build_parents {[qw/target/]}
>>>>  ...
>>>>
>>>>  so just declare the attribute 'parents' in subclass is ok.
>>>>  the task is not typical for me, but interesting.
>>>>
>>>>  On Fri, Jun 15, 2012 at 3:59 PM, Alex Erzin <eaa-home at yandex.ru> wrote:
>>>>>   Yes, in some cases you are right, but you are saying about "long inheritance chains" and other cases where inheritance is not enought flexible,
>>>>>   but i say about just one case in one place where inheritance is preferred for me, and i try to find solution _how_ to implement inheritance, but not about _why_not_ :)
>>>>>
>>>>>   15.06.2012, 10:43, "Ben Tilly" <btilly at gmail.com>:
>>>>>>   The benefits of OOP are mostly in information hiding.
>>>>>>
>>>>>>   If you're creating a bunch of long inheritance chains, you're probably
>>>>>>   doing OOP poorly.  Composition is preferred.  And maps *much* more
>>>>>>   naturally onto a relational database.
>>>>>>
>>>>>>   On Thu, Jun 14, 2012 at 11:37 PM, Alex Erzin <eaa-home at yandex.ru> wrote:
>>>>>>>    Hm... it really works, but where are benefits of OOP? ;)
>>>>>>>    There is no inheritance at all, and to access parent's properties I should call parent directly, so inheritance just replaced with incapsulation, and it's no one what i try to find.
>>>>>>>
>>>>>>>    Some years ago we have implemented inheritance in ORM in some commercial project in Perl, later I have swithed to java and have found Hibernate it really cool with ORM.
>>>>>>>    But now I have returned to Perl and I think that DBIx::Class can help me with ORM, but right now i'm confused that cannot find "standard" solution for typical task.
>>>>>>>
>>>>>>>    15.06.2012, 10:25, "Hailin Hu" <i at h2l.name>:
>>>>>>>>    Is it acceptable like something below
>>>>>>>>
>>>>>>>>    package Target;
>>>>>>>>    ...
>>>>>>>>    package Host;
>>>>>>>>    ...
>>>>>>>>    __PACKAGE__->belong_to('target' => 'Target', 'target_id');
>>>>>>>>    sub column_only_exists_in_target {
>>>>>>>>      my $self = shift;
>>>>>>>>      return $self->target->column_only_exists_in_target;
>>>>>>>>    }
>>>>>>>>
>>>>>>>>    well, it is not a good solution, but it could work, I think :)
>>>>>>>>
>>>>>>>>    On Fri, Jun 15, 2012 at 3:04 PM, Alex Erzin <eaa-home at yandex.ru> wrote:
>>>>>>>>>     Hello,
>>>>>>>>>
>>>>>>>>>     I need to implement table-per-class inheritance, as it simple made in Hibernate in Java (more details can be found here http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html/ch10.html#inheritance-tablepersubclass),
>>>>>>>>>     but cannot find right way how to do it in DBIx::Class.
>>>>>>>>>
>>>>>>>>>     For example, I have two objects: Target (with properties ID, Description) and Host (ID, Hostname, IP), Host inherited from Target, and on table-level there are two tables Host and Target, joined by ID field.
>>>>>>>>>
>>>>>>>>>     CREATE  TABLE  `mydb`.`target` (
>>>>>>>>>      `target_id` INT NOT NULL ,
>>>>>>>>>      `description` VARCHAR(45) NULL ,
>>>>>>>>>      PRIMARY KEY (`target_id`) )
>>>>>>>>>
>>>>>>>>>     CREATE  TABLE `mydb`.`host` (
>>>>>>>>>      `target_id` INT NOT NULL ,
>>>>>>>>>      `hostname` VARCHAR(45) NULL ,
>>>>>>>>>      `ip` VARCHAR(45) NULL ,
>>>>>>>>>      PRIMARY KEY (`target_id`) ,
>>>>>>>>>      CONSTRAINT `fk_host_target`
>>>>>>>>>        FOREIGN KEY (`target_id` )
>>>>>>>>>        REFERENCES `mydb`.`target` (`target_id` )
>>>>>>>>>     )
>>>>>>>>>
>>>>>>>>>     How to implemeng there classes Target and Host, so it possible to write
>>>>>>>>>
>>>>>>>>>     print $target->id(), $targer->description()
>>>>>>>>>     print $host->id(), $host->description(), $host->hostname(), $host->ip()
>>>>>>>>>
>>>>>>>>>     ?
>>>>>>>>>
>>>>>>>>>     I have no ideas how to implement inheritance, and all my experiments are failed - from Host i cannot get access to parent properties like description.
>>>>>>>>>     Could you help me please (with examples)?
>>>>>>>>>
>>>>>>>>>     Thanks.
>>>>>>>>>
>>>>>>>>>     --
>>>>>>>>>     eaa@
>>>>>>>>>
>>>>>>>>>     _______________________________________________
>>>>>>>>>     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
>>>>>>>>    _______________________________________________
>>>>>>>>    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
>>>>>>>    --
>>>>>>>    eaa@
>>>>>>>
>>>>>>>    _______________________________________________
>>>>>>>    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
>>>>>>   _______________________________________________
>>>>>>   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
>>>>>   --
>>>>>   eaa@
>>>>>
>>>>>   _______________________________________________
>>>>>   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
>>>>  _______________________________________________
>>>>  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
>> *"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*
>> T-Systems Austria GesmbH Rennweg 97-99, 1030 Wien
>> Handelsgericht Wien, FN 79340b
>> *"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*
>> Notice: This e-mail contains information that is confidential and may be privileged.
>> If you are not the intended recipient, please notify the sender and then
>> delete this e-mail immediately.
>> *"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*
>>
>> _______________________________________________
>> 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
> -- 
> Cheers, Alex



More information about the DBIx-Class mailing list