Backcompat tests for the dev version of DBIx::Class::Schema::Loader

7 messages Options
Embed this post
Permalink
Zbigniew Lukasiak

Backcompat tests for the dev version of DBIx::Class::Schema::Loader

Reply Threaded More More options
Print post
Permalink
Hi,

I am attaching some tests for the backcompat layer of the new Loader.
I only managed to use it as a subclass of
DBIx::Class::Schema::Loader::DBI::SQLite, I am not too familiar with
how the Loader builds it's components and how to override
DBIx::Class::Schema::Loader::Base.  So this needs to be fixed.

To put it in other words - I don't know how the existing back compat
layer is supposed to be used - i.e. how the end user could use it to
make the new loader behave as the old one.  I only managed to add the
backcompat to one of the many storage layers.

The diff is against:
http://dev.catalyst.perl.org/repos/bast/branches/DBIx-Class-Schema-Loader/back-compat

--
Zbigniew Lukasiak
http://brudnopis.blogspot.com/
http://perlalchemy.blogspot.com/

[backcompat_tests.diff]

Index: t/lib/dbixcsl_backcompat.pm
===================================================================
--- t/lib/dbixcsl_backcompat.pm (revision 0)
+++ t/lib/dbixcsl_backcompat.pm (revision 0)
@@ -0,0 +1,134 @@
+package dbixcsl_backcompat;
+
+use strict;
+use warnings;
+
+use Test::More;
+use DBIx::Class::Schema::Loader::Compat::v0_040;
+use File::Path;
+
+use parent 'dbixcsl_common_tests';
+
+my $DUMP_DIR = './t/_common_dump';
+rmtree $DUMP_DIR;
+
+sub _monikerize {
+    my $name = shift;
+    return 'LoaderTest2X' if $name =~ /^loader_test2$/i;
+    return undef;
+}
+
+sub run_tests {
+    my $self = shift;
+
+    plan tests => 3 + 7 + ($self->{extra}->{count} || 0);
+
+    $self->create();
+
+    my @connect_info = ( $self->{dsn}, $self->{user}, $self->{password} );
+
+    # First, with in-memory classes
+    my $schema_class = $self->setup_schema(@connect_info);
+    $self->test_schema($schema_class);
+    $self->drop_tables;
+}
+
+sub setup_schema {
+    my $self = shift;
+    my @connect_info = @_;
+
+    my $schema_class = 'DBIXCSL_Test::Schema';
+
+    my $debug = ($self->{verbose} > 1) ? 1 : 0;
+
+    my %loader_opts = (
+        constraint              => qr/^(?:\S+\.)?(?:$self->{vendor}_)?loader_test[0-9]+s?$/i,
+        relationships           => 1,
+        additional_classes      => 'TestAdditional',
+        additional_base_classes => 'TestAdditionalBase',
+        left_base_classes       => [ qw/TestLeftBase/ ],
+        components              => [ qw/TestComponent/ ],
+        resultset_components    => [ qw/TestRSComponent/ ],
+        inflect_plural          => { loader_test4 => 'loader_test4zes' },
+        inflect_singular        => { fkid => 'fkid_singular' },
+        moniker_map             => \&_monikerize,
+        debug                   => $debug,
+        dump_directory          => $DUMP_DIR,
+    );
+
+    $loader_opts{db_schema} = $self->{db_schema} if $self->{db_schema};
+    {
+       my @loader_warnings;
+       local $SIG{__WARN__} = sub { push(@loader_warnings, $_[0]); };
+        eval qq{
+            package $schema_class;
+            use base qw/DBIx::Class::Schema::Loader/;
+    
+            __PACKAGE__->loader_class('DBIx::Class::Schema::Loader::Compat::v0_040');
+            __PACKAGE__->loader_options(\%loader_opts);
+            __PACKAGE__->connection(\@connect_info);
+        };
+
+        ok(!$@, "Loader initialization") or diag $@;
+
+       my $warn_count = 2;
+       $warn_count++ if grep /ResultSetManager/, @loader_warnings;
+
+        if($self->{skip_rels}) {
+            SKIP: {
+                is(scalar(@loader_warnings), $warn_count, "No loader warnings")
+                    or diag @loader_warnings;
+                skip "No missing PK warnings without rels", 1;
+            }
+        }
+        else {
+    $warn_count++;
+            is(scalar(@loader_warnings), $warn_count, "Expected loader warning")
+                or diag @loader_warnings;
+            is(grep(/loader_test9 has no primary key/, @loader_warnings), 1,
+                 "Missing PK warning");
+        }
+    }
+    
+    return $schema_class;
+}
+
+sub test_schema {
+    my $self = shift;
+    my $schema_class = shift;
+
+    my $conn = $schema_class->clone;
+    my $monikers = {};
+    my $classes = {};
+    foreach my $source_name ($schema_class->sources) {
+        my $table_name = $schema_class->source($source_name)->from;
+        $monikers->{$table_name} = $source_name;
+        $classes->{$table_name} = $schema_class . q{::} . $source_name;
+    }
+
+    is($monikers->{loader_test1s}, 'LoaderTest1s', 'moniker singularisation');
+
+    SKIP: {
+        skip $self->{skip_rels}, 6 if $self->{skip_rels};
+        
+        my $obj6 = $conn->resultset($monikers->{loader_test6})->find(1);
+        isa_ok( $obj6->loader_test2_id, $classes->{loader_test2} );   # zby
+        ok($classes->{loader_test6}->column_info('loader_test2_id')->{is_foreign_key}, 'Foreign key detected'); # zby
+    
+        # test one-to-one rels
+        my $rsobj27 = $conn->resultset($monikers->{loader_test27});
+        my $obj27 = $rsobj27->find(1);
+        my $obj28 = $obj27->loader_test28s->first;
+        isa_ok($obj28, $classes->{loader_test28});
+
+        my $obj29 = $obj27->loader_test29s->first;
+        isa_ok($obj29, $classes->{loader_test29});
+
+        $obj27 = $rsobj27->find(2);
+        is($obj27->loader_test28s->first, undef, "Undef for missing one-to-one row");
+        is($obj27->loader_test29s->first, undef, "Undef for missing one-to-one row");
+    }
+}
+
+
+1;
Index: t/30backcompat.t
===================================================================
--- t/30backcompat.t (revision 0)
+++ t/30backcompat.t (revision 0)
@@ -0,0 +1,22 @@
+use strict;
+use lib qw(t/lib);
+use dbixcsl_backcompat;
+
+eval { require DBD::SQLite };
+my $class = $@ ? 'SQLite2' : 'SQLite';
+
+{
+    my $tester = dbixcsl_backcompat->new(
+        vendor          => 'SQLite',
+        auto_inc_pk     => 'INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT',
+        dsn             => "dbi:$class:dbname=./t/sqlite_test",
+        user            => '',
+        password        => '',
+    );
+
+    $tester->run_tests();
+}
+
+END {
+    unlink './t/sqlite_test';
+}
Index: lib/DBIx/Class/Schema/Loader/Compat/v0_040.pm
===================================================================
--- lib/DBIx/Class/Schema/Loader/Compat/v0_040.pm (revision 7618)
+++ lib/DBIx/Class/Schema/Loader/Compat/v0_040.pm (working copy)
@@ -4,17 +4,17 @@
 use warnings;
 use Class::C3;
 use DBIx::Class::Schema::Loader::RelBuilder::Compat::v0_040;
+use base 'DBIx::Class::Schema::Loader::DBI::SQLite';
 
 # Make a moniker from a table
 sub _default_table2moniker {
     my ($self, $table) = @_;
-
     return join '', map ucfirst, split /[\W_]+/, lc $table;
 }
 
 sub _relbuilder {
  my ($self) = @_;
-    $self->{relbuilder} ||= DBIx::Class::Schema::Loader::RelBuilder::v04Compat->new(
+    $self->{relbuilder} ||= DBIx::Class::Schema::Loader::RelBuilder::Compat::v0_040->new(
         $self->schema, $self->inflect_plural, $self->inflect_singular
     );
 }


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

Re: Backcompat tests for the dev version of DBIx::Class::Schema::Loader

Reply Threaded More More options
Print post
Permalink
After some help from #dbic-class (ribasushi and ilmari) - here is a
version using Class::C3::Componentised->inject_base to inject the
backcompat layer into the isa of DBIx::Class::Schema::Loader::DBI.
This way the backcompat can work for all the backends.

Cheers,
Z.

On Thu, Sep 10, 2009 at 1:55 PM, Zbigniew Lukasiak <[hidden email]> wrote:

> Hi,
>
> I am attaching some tests for the backcompat layer of the new Loader.
> I only managed to use it as a subclass of
> DBIx::Class::Schema::Loader::DBI::SQLite, I am not too familiar with
> how the Loader builds it's components and how to override
> DBIx::Class::Schema::Loader::Base.  So this needs to be fixed.
>
> To put it in other words - I don't know how the existing back compat
> layer is supposed to be used - i.e. how the end user could use it to
> make the new loader behave as the old one.  I only managed to add the
> backcompat to one of the many storage layers.
>
> The diff is against:
> http://dev.catalyst.perl.org/repos/bast/branches/DBIx-Class-Schema-Loader/back-compat
>
> --
> Zbigniew Lukasiak
> http://brudnopis.blogspot.com/
> http://perlalchemy.blogspot.com/
>


--
Zbigniew Lukasiak
http://brudnopis.blogspot.com/
http://perlalchemy.blogspot.com/


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

backcompat_tests.diff.1 (5K) Download Attachment
Zbigniew Lukasiak

Re: Backcompat tests for the dev version of DBIx::Class::Schema::Loader

Reply Threaded More More options
Print post
Permalink
Hi,

I am now trying again to make it work and I am really sorry but even
after all those IRC discussions I am still a bit puzzled about how the
backcompat layer is supposed to work.  So once again - I understand
that the scenario is like that:

I have an old schema
I use the new Loader to load a new one
the backcompat reads the old schema and notices that it is old and it
switches itself on
the loaded schema is compatible with the old one
then I call dump_to_dir - and it is dumped
the old schema is overwritten with the new one (but compatible)

Is that what you have in mind?

If the answer is yes - then there are two questions

1. Should there be any changes between the old schema and the new one?
 If there are any then how to decide what changes are compatible and
what are not.  And if there should not be any change - then what is
the purpose of overwriting one schema with an identical one?  Wouldn't
it be simpler to just refuse overwriting old schemas?

2. If we are overwriting with the compatibility adjustments - then we
need to mark the new schema somehow, so that subsequent re-dumping
will leave these adjustments.

Initially I imagined that the backcompat is needed for dynamic
loading, then there is no old schema, so I was not thinking about
these problems, but in the IRC conversations someone said that dynamic
loading is not important.

Cheers,
Zbigniew
http://brudnopis.blogspot.com/
http://perlalchemy.blogspot.com/

_______________________________________________
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@...
Peter Rabbitson-2

Re: Re: Backcompat tests for the dev version of DBIx::Class::Schema::Loader

Reply Threaded More More options
Print post
Permalink
On Thu, Oct 08, 2009 at 05:55:04PM +0200, Zbigniew Lukasiak wrote:

> Hi,
>
> I am now trying again to make it work and I am really sorry but even
> after all those IRC discussions I am still a bit puzzled about how the
> backcompat layer is supposed to work.  So once again - I understand
> that the scenario is like that:
>
> I have an old schema
> I use the new Loader to load a new one
> the backcompat reads the old schema and notices that it is old and it
> switches itself on
> the loaded schema is compatible with the old one
> then I call dump_to_dir - and it is dumped
> the old schema is overwritten with the new one (but compatible)
>
> Is that what you have in mind?
>
> If the answer is yes - then there are two questions
>
> 1. Should there be any changes between the old schema and the new one?
>  If there are any then how to decide what changes are compatible and
> what are not.  And if there should not be any change - then what is
> the purpose of overwriting one schema with an identical one?  Wouldn't
> it be simpler to just refuse overwriting old schemas?

You are mixing two issues here. The first is updates of non-changed
resultsources - this is something that needs fixing, and acmoore was
about to do something about it (not sure how far he went).

The second problem is backwards compatibility - the whole issue centers
around relationship naming. They are purely cosmetic, but changed between
the old and new codebase. So without changing your actual database, your
code doing artist->cd would all of a sudden stop working, as the rel is
now called 'cds'. This is what we need to guard against.

>
> 2. If we are overwriting with the compatibility adjustments - then we
> need to mark the new schema somehow, so that subsequent re-dumping
> will leave these adjustments.

This is correct and afaik has not yet been discussed. Once the user wrote
code against ->cd it needs to kep working, unless the user decides to
break things.

>
> Initially I imagined that the backcompat is needed for dynamic
> loading, then there is no old schema, so I was not thinking about
> these problems, but in the IRC conversations someone said that dynamic
> loading is not important.
>

It was me, and I didn't say that :) Dynamic loading can not possibly
know what S::L was used on prior invocation, thus it is impossible to
detect when back compat is needed. My take on this problem was:

dynamic S::L is *RETARDED*. It needs to die in the following manner:

1) A warning (which can be disabled of course) is issued when S::L
is used dynamically, stating that this is dumb, and you get to kep
the pieces when it stops working.
2) When S::L is used dynamically we *always* use backcompat mode.
Want to reap the benefits of the new relationship naming? - use on-disk
files.


This is of course just my one-sided take on the issue, I am not a heavy
S::L user (deploy ftw).

Cheers

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

Re: Re: Backcompat tests for the dev version of DBIx::Class::Schema::Loader

Reply Threaded More More options
Print post
Permalink
On Fri, Oct 9, 2009 at 6:25 AM, Peter Rabbitson <[hidden email]> wrote:

> On Thu, Oct 08, 2009 at 05:55:04PM +0200, Zbigniew Lukasiak wrote:
>> Hi,
>>
>> I am now trying again to make it work and I am really sorry but even
>> after all those IRC discussions I am still a bit puzzled about how the
>> backcompat layer is supposed to work.  So once again - I understand
>> that the scenario is like that:
>>
>> I have an old schema
>> I use the new Loader to load a new one
>> the backcompat reads the old schema and notices that it is old and it
>> switches itself on
>> the loaded schema is compatible with the old one
>> then I call dump_to_dir - and it is dumped
>> the old schema is overwritten with the new one (but compatible)
>>
>> Is that what you have in mind?
>>
>> If the answer is yes - then there are two questions
>>
>> 1. Should there be any changes between the old schema and the new one?
>>  If there are any then how to decide what changes are compatible and
>> what are not.  And if there should not be any change - then what is
>> the purpose of overwriting one schema with an identical one?  Wouldn't
>> it be simpler to just refuse overwriting old schemas?
>
> You are mixing two issues here. The first is updates of non-changed
> resultsources - this is something that needs fixing, and acmoore was
> about to do something about it (not sure how far he went).
>
> The second problem is backwards compatibility - the whole issue centers
> around relationship naming. They are purely cosmetic, but changed between
> the old and new codebase. So without changing your actual database, your
> code doing artist->cd would all of a sudden stop working, as the rel is
> now called 'cds'. This is what we need to guard against.

OK - so the question here is what other changes there are?

I am not mixing those two things without purpose - leaving the old
schema intact is just a very simple solution to backwards
compatibility :)  And if there isn't anything changed - then it would
be enough.  So once again are there any changes that are not nullified
by the backcompat layer?

>> 2. If we are overwriting with the compatibility adjustments - then we
>> need to mark the new schema somehow, so that subsequent re-dumping
>> will leave these adjustments.
>
> This is correct and afaik has not yet been discussed. Once the user wrote
> code against ->cd it needs to kep working, unless the user decides to
> break things.

OK

>
>>
>> Initially I imagined that the backcompat is needed for dynamic
>> loading, then there is no old schema, so I was not thinking about
>> these problems, but in the IRC conversations someone said that dynamic
>> loading is not important.
>>
>
> It was me, and I didn't say that :) Dynamic loading can not possibly
> know what S::L was used on prior invocation, thus it is impossible to
> detect when back compat is needed. My take on this problem was:
>
> dynamic S::L is *RETARDED*. It needs to die in the following manner:
>
> 1) A warning (which can be disabled of course) is issued when S::L
> is used dynamically, stating that this is dumb, and you get to kep
> the pieces when it stops working.
> 2) When S::L is used dynamically we *always* use backcompat mode.
> Want to reap the benefits of the new relationship naming? - use on-disk
> files.

OK

--
Zbigniew Lukasiak
http://brudnopis.blogspot.com/
http://perlalchemy.blogspot.com/

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

Re: Re: Backcompat tests for the dev version of DBIx::Class::Schema::Loader

Reply Threaded More More options
Print post
Permalink
Just to be more precise:

On Fri, Oct 9, 2009 at 6:40 AM, Zbigniew Lukasiak <[hidden email]> wrote:

> On Fri, Oct 9, 2009 at 6:25 AM, Peter Rabbitson <[hidden email]> wrote:
>> On Thu, Oct 08, 2009 at 05:55:04PM +0200, Zbigniew Lukasiak wrote:
>>> Hi,
>>>
>>> I am now trying again to make it work and I am really sorry but even
>>> after all those IRC discussions I am still a bit puzzled about how the
>>> backcompat layer is supposed to work.  So once again - I understand
>>> that the scenario is like that:
>>>
>>> I have an old schema
>>> I use the new Loader to load a new one
>>> the backcompat reads the old schema and notices that it is old and it
>>> switches itself on
>>> the loaded schema is compatible with the old one
>>> then I call dump_to_dir - and it is dumped
>>> the old schema is overwritten with the new one (but compatible)
>>>
>>> Is that what you have in mind?
>>>
>>> If the answer is yes - then there are two questions
>>>
>>> 1. Should there be any changes between the old schema and the new one?
>>>  If there are any then how to decide what changes are compatible and
>>> what are not.  And if there should not be any change - then what is
>>> the purpose of overwriting one schema with an identical one?  Wouldn't
>>> it be simpler to just refuse overwriting old schemas?
>>
>> You are mixing two issues here. The first is updates of non-changed
>> resultsources - this is something that needs fixing, and acmoore was
>> about to do something about it (not sure how far he went).
>>
>> The second problem is backwards compatibility - the whole issue centers
>> around relationship naming. They are purely cosmetic, but changed between
>> the old and new codebase. So without changing your actual database, your
>> code doing artist->cd would all of a sudden stop working, as the rel is
>> now called 'cds'. This is what we need to guard against.
>
> OK - so the question here is what other changes there are?
>

I know there are some changes, like the auto_increment flag that I
need, that are not likely to be covered by the backcompat layer.  Now
the question is how to separate those two kinds of changes - how do
you decide what change is compatible and what is not.
On the extreme interpretation adding a new flag to an existing field
will change it's behaviour - so it is not totally back compatible.

I hope that clarifies what I am talking about - and sorry if that was
already covered somewhere, I must have missed it.


--
Zbigniew Lukasiak
http://brudnopis.blogspot.com/
http://perlalchemy.blogspot.com/

_______________________________________________
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@...
Peter Rabbitson-2

Re: Re: Backcompat tests for the dev version of DBIx::Class::Schema::Loader

Reply Threaded More More options
Print post
Permalink
On Fri, Oct 09, 2009 at 06:52:32AM +0200, Zbigniew Lukasiak wrote:

> Just to be more precise:
>
> On Fri, Oct 9, 2009 at 6:40 AM, Zbigniew Lukasiak <[hidden email]> wrote:
> > On Fri, Oct 9, 2009 at 6:25 AM, Peter Rabbitson <[hidden email]> wrote:
> >> On Thu, Oct 08, 2009 at 05:55:04PM +0200, Zbigniew Lukasiak wrote:
> >>> Hi,
> >>>
> >>> I am now trying again to make it work and I am really sorry but even
> >>> after all those IRC discussions I am still a bit puzzled about how the
> >>> backcompat layer is supposed to work.  So once again - I understand
> >>> that the scenario is like that:
> >>>
> >>> I have an old schema
> >>> I use the new Loader to load a new one
> >>> the backcompat reads the old schema and notices that it is old and it
> >>> switches itself on
> >>> the loaded schema is compatible with the old one
> >>> then I call dump_to_dir - and it is dumped
> >>> the old schema is overwritten with the new one (but compatible)
> >>>
> >>> Is that what you have in mind?
> >>>
> >>> If the answer is yes - then there are two questions
> >>>
> >>> 1. Should there be any changes between the old schema and the new one?
> >>>  If there are any then how to decide what changes are compatible and
> >>> what are not.  And if there should not be any change - then what is
> >>> the purpose of overwriting one schema with an identical one?  Wouldn't
> >>> it be simpler to just refuse overwriting old schemas?
> >>
> >> You are mixing two issues here. The first is updates of non-changed
> >> resultsources - this is something that needs fixing, and acmoore was
> >> about to do something about it (not sure how far he went).
> >>
> >> The second problem is backwards compatibility - the whole issue centers
> >> around relationship naming. They are purely cosmetic, but changed between
> >> the old and new codebase. So without changing your actual database, your
> >> code doing artist->cd would all of a sudden stop working, as the rel is
> >> now called 'cds'. This is what we need to guard against.
> >
> > OK - so the question here is what other changes there are?
> >
>
> I know there are some changes, like the auto_increment flag that I
> need, that are not likely to be covered by the backcompat layer.  Now
> the question is how to separate those two kinds of changes - how do
> you decide what change is compatible and what is not.
> On the extreme interpretation adding a new flag to an existing field
> will change it's behaviour - so it is not totally back compatible.
>
> I hope that clarifies what I am talking about - and sorry if that was
> already covered somewhere, I must have missed it.
>

I might be completely in the wrong here, but afaik the backcompat layer
only deals with the relationship naming. The detection of autoinc and
stuff happens in the core, which is shared by both the new and old class
generators. However I could be talking out of my ass, you need to confirm
this with someone who actually dug in the code.

Cheers

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