in reply to data historization with DBIx::Class

I think that DBIx::Class::Journal might be what you need. Specifically, take a look at the TABLES section.
  • Comment on Re: data historization with DBIx::Class

Replies are listed 'Best First'.
Re^2: data historization with DBIx::Class
by morgon (Priest) on Dec 26, 2010 at 13:23 UTC
    Thanks for your reply - this really looks very promisising.

    For my current needs however I may not be able to use it as I am supposed to use only those CPAN-modules that can be found in the ubuntu-repositories.

    But be it as it may - is there an easy way in DBIx::Class to create a row belonging to another resultset based on a given resultset that would copy over all shared attributes?

    In pseudo-code something like:

    my $rs1 = $schema->resultset("table1"); my $rs2 = $schema->resultset("table2"); my $o1 = $rs1->find({ id => $id }); my $o2 = $rs2->create_copy($o1); # does something like this exist?
    As a related question I know I can get plain hashes from a resultset with DBIx::Class::ResultClass::HashRefInflator but only when I use it as a setting on the resultset-class.

    But how would I convert a row that I have already retrieved, i.e. something like

    my $o = $rs1->find({ id => $id }); my $hash_ref = $o->as_hashref; # does this exist?
    Many thanks!

      As for the last part, check out DBIx::Class::ResultSet::HashRef. You use it as a parent class and then you get a handful of methods like hashref_rs which you can use as the end point of a chain.

      For a similar but heavier (object inflation is more to much more expensive depending on your columns and inflation types) solution you can also rewrite this–

      my $hash_ref = $o->as_hashref; # does this exist?

      –as–

      my $hash_ref = { $o->get_columns };
        Thanks a lot for your reply.

        "get_columns" is what I have been looking for - however I cannot find it in the documentation.

        Is that an offical interface that had not yet been documented or something that could break with the next version?

Re^2: data historization with DBIx::Class
by CountZero (Bishop) on Dec 26, 2010 at 19:58 UTC
    It is not exactly what the OP asked for. The journaling system documents the changes, whereas the OP asked for the data that was changed.

    Of course it is possible to reconstruct the previous contents by running the journal to just before the SQL that changed the data, but that would be quite cumbersome.

    Of course the OP's request is also very naive, as (s)he assumes that all changes will be atomic on a single record. By simply "saving" the previous content into a history table, you are open to all kinds of race conditions, such as two connections editing different fields in the same record, which will make it dificult, if not imossible to determine what the "previous content" was.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      Of course the OP's request is also very naive, as (s)he assumes that all changes will be atomic on a single record.
      I am not sure I understand your point...

      To clarify:

      What I want is a way to save an object (representing a row) BEFORE I call any updating methods on it into another table (adding a few extra attibutes e.g user-information).

      This will be done in the same transaction that will eventually commit the updates to the original row.

      After that I have a "before-image" (the row at transaction start) and an "after-image" (the row after commit) in the database.

      Which of my assumption here is naive?

        There may be other connections working on the same row, updating or deleting it. Of course the transaction manager of the database will take care (or so we hope) that the database remains in a consistent state, but it may be difficult, or even impossible, to maintain a table of historical data in such a way that you can always reconstruct the status of the database at any given moment. It is surely for good reason that these internal transaction managers work on a journalling basis too!

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James