Git Product home page Git Product logo

dbix-class-resultset-recursiveupdate's People

Contributors

abraxxa avatar gerhardj avatar gshank avatar ilmari avatar jjn1056 avatar zby avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

dbix-class-resultset-recursiveupdate's Issues

Tests fail when run in parallel

Running HARNESS_OPTIONS=j make test will result in test failures because multiple tests try to access the same database file.

It does not work as a document for has_many

Hello.

I tried the example of has_many read POD.
http://search.cpan.org/~gshank/DBIx-Class-ResultSet-RecursiveUpdate-0.34/lib/DBIx/Class/ResultSet/RecursiveUpdate.pm#Treatment_of_has_many_relations

Example of "Passing hashrefs:" worked.
But cases of "Passing ids:" did not work.

It was confirmed by adding code to t/01_basic.t.

% git diff
diff --git a/t/01_basic.t b/t/01_basic.t
index 8f31dde..db89bfd 100644
--- a/t/01_basic.t
+++ b/t/01_basic.t
@@ -282,6 +282,16 @@ is( $schema->resultset('Address')->search( { user_id => $user->id } )->count,
 $dvd = $dvd_rs->find(1);
 is( $dvd->get_column('owner'), $user->id, 'foreign key set' );

+$user_rs->recursive_update({
+    id      => $user->id,
+    address => {
+        street => "101 Main Street",
+        city   => "Podunk",
+        state  => "New York"
+    },
+    owned_dvds => [ 1 ]
+});
+
 # has_many where foreign cols are nullable
 my $available_dvd_rs = $dvd_rs->search( { current_borrower => undef } );
 $dvd_rs->update( { current_borrower => $user->id } );

Is the output.

% prove -I lib -v t/01_basic.t
t/01_basic.t .. testing dbi:SQLite:dbname=t/var/dvdzbr.db

ok 1 - fixed_fields pre 0.21 api ok
ok 2 - fixed_fields 0.21+ api ok
...
ok 43 - the right number of addresses
ok 44 - foreign key set
DBIx::Class::ResultSet::RecursiveUpdate::recursive_update(): first parameter needs to be a hashref at t/01_basic.t line 285
# Tests were run but no plan was declared and done_testing() was not seen.
Dubious, test returned 255 (wstat 65280, 0xff00)
All 44 subtests passed

Test Summary Report
-------------------
t/01_basic.t (Wstat: 65280 Tests: 44 Failed: 0)
  Non-zero exit status: 255
  Parse errors: No plan found in TAP output
Files=1, Tests=44,  1 wallclock secs ( 0.04 usr  0.00 sys +  0.72 cusr  0.08 csys =  0.84 CPU)
Result: FAIL

Document is correct?
Or code is correct?

I would appreciate your answer.

Cheers,
Tomohiro Hosaka

Does not work with correlated columns

I have a correlated column, which appears in {_column_data}, and I am assuming the module does not check for whether the column is a real column defined in ResultSource, or if it is a correlated column. It tries to update it regardless, and results in an error "column does not exist".

RecursiveUpdate needs to check unique_constraint_names, not just PKs

There often may be cases where a table is bound to an integer id PK, but the "real" key is the name, which is uniquely constrained. And in those cases, you might not know the integer PK. For example:

owner => { name => "Thing" },

Thing already exists, so trying to INSERT this would error. However, DBIC:RS:RU isn't going to find the row, despite given a proper unique key to find it. So, you end up with an uniqueness error because it tries to INSERT it.

The $object find should look for all keys, not just PKs. I have a partial solution here:

for my $constraint (
    sort { $b eq 'primary' ? 1 : $a eq 'primary' ? -1 : $a cmp $b }  # make primary first
$source->unique_constraint_names) {
    last if defined $object; 

    # the updates hashref might contain the constraint columns
    # but with an undefined value
    my @missing =
        grep { !defined $updates->{$_} && !exists $fixed_fields{$_} }
        $source->unique_constraint_columns($constraint);

    #warn "MISSING $constraint: " . join(', ', @missing) . "\n";
    unless ( @missing ) {
        warn 'finding by: ' . Dumper( $updates ); use Data::Dumper;
        $object = $self->find( $updates, { key => $constraint } );
    }
    last if defined $object; 

    # add the resolved columns to the updates hashref
    $updates = { %$updates, %$resolved };

    # the resolved hashref might contain the constraint columns
    # but with an undefined value
    @missing = grep { !defined $resolved->{$_} } @missing;

    #warn "MISSING2 $constraint: " . join( ', ', @missing ) . "\n";
    unless ( @missing ) {
        warn 'finding by +resolved: ' . Dumper( $updates ); use Data::Dumper;
        $object = $self->find( $updates, { key => $constraint } );
    }

}

This works, but it's flawed in regards to the more complicated test cases. I think this is because the other primary_column cases haven't been converted yet. I need help with these because I don't completely understand what they do.

On the other hand, I do have a test case written for my problem above (96multi_create.t):

diag '* second create_related with same arguments';
eval {
    my $artist = $schema->resultset('Artist')->first;

    my $cd_result = $schema->resultset('CD')->recursive_update(
        {

            artist => $artist->artistid,

            title  => 'TestOneCD2',
            year   => 2007,
            tracks => [

                {   pos   => 111,
                    title => 'TrackOne',
                },
                {   pos   => 112,
                    title => 'TrackTwo',
                }
            ],

            liner_notes => { notes => 'I can haz liner notes?' },
            genre => { name => 'TestGenre' }

        }
    );

    ok( $cd_result && ref $cd_result eq 'DBICTest::CD', "Got Good CD Class" );
    ok( $cd_result->title eq "TestOneCD2",             "Got Expected Title" );
    ok( $cd_result->notes eq 'I can haz liner notes?', 'Liner notes' );

    my $tracks = $cd_result->tracks;

    ok( $tracks->isa("DBIx::Class::ResultSet"),
        "Got Expected Tracks ResultSet"
    );

    foreach my $track ( $tracks->all ) {
        ok( $track && ref $track eq 'DBICTest::Track',
            'Got Expected Track Class' );
    }
};
diag $@ if $@;

diag '* third create_related with non-primary unique key';
eval {
    my $artist = $schema->resultset('Artist')->first;

    my $cd_result = $schema->resultset('CD')->recursive_update(
        {

            artist => $artist->artistid,

            title  => 'TestOneCD2',
            year   => 2007,
            tracks => [

                {   pos   => 111,
                    title => 'TrackOne',
                },
                {   pos   => 112,
                    title => 'TrackTwo',
                }
            ],

            liner_notes => { notes => 'I can haz liner notes?' },
            genre => { name => 'TestGenre' }

        }
    );

    ok( $cd_result && ref $cd_result eq 'DBICTest::CD', "Got Good CD Class" );
    ok( $cd_result->title eq "TestOneCD2",             "Got Expected Title" );
    ok( $cd_result->notes eq 'I can haz liner notes?', 'Liner notes' );
    ok( $cd_result->genre->name eq 'TestGenre', 'Got Expected Genre' );

    my $tracks = $cd_result->tracks;

    ok( $tracks->isa("DBIx::Class::ResultSet"),
        "Got Expected Tracks ResultSet"
    );

    foreach my $track ( $tracks->all ) {
        ok( $track && ref $track eq 'DBICTest::Track',
            'Got Expected Track Class' );
    }
};
diag $@ if $@;

(The second create_related block is the same as the original with the added genre. The third create_related is a new test.)

belongs_to fails when table also defines a might_have with parent

The expected behaviour is for the row outputted from recursive_update to correctly show the nested belongs_to relationship. The actual behaviour is that it seems to lose the change in the returned row, despite correctly updating the DB.

This patch adds a test and changes a couple test schema tables:

  • liner_notes table changed to use dvd_id as it's PK
  • Add liner_notes_belongs_to table with belongs_to relationship to liner_notes

In the test, I've added comments where you can comment out a line to make the test pass. When I dug into the RecursiveUpdate code, in _update_relation when it calls set_from_related, it passes in the correct data, but the output from get_columns afterwards is unchanged, for example:

$sub_object->get_columns() = {
          'dvd_id' => 5,
          'notes' => 'test note',
          'liner_notes_belongs_to' => 1
        };
Now $object->set_from_related($name, $sub_object) is called and then:
$sub_object->get_columns() = {
          'dvd_id' => 5,
          'notes' => 'test note',
          'liner_notes_belongs_to' => undef
        };

I tried a simpler test with just the liner_notes and liner_notes_belongs_to, but they worked fine... It only stops working when I add the extra layer of the DVD.

Not working as documented since 0.40

Hello.

I'll make the question simple.

It seems that RU doesn't work unless schema is rel_name == pk naming in case of many_to_many from 0.40.

The output of the test is below.
https://github.com/bokutin/recursiveupdate-test/blob/master/out.txt
The schema is below.
https://github.com/bokutin/recursiveupdate-test/tree/master/t/lib/M2MTest

Is my usage wrong?
I think I am using it as DESIGN CHOICES - Treatment of many-to-many pseudo relations.

It would be greatly appreciated if someone could answer.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.