no filter and inflate column
[dbsrgits/DBIx-Class.git] / t / row / filter_column.t
1 use strict;
2 use warnings;
3
4 use Test::More;
5 use Test::Exception;
6 use lib qw(t/lib);
7 use DBICTest;
8
9 my $from_storage_ran = 0;
10 my $to_storage_ran = 0;
11 my $schema = DBICTest->init_schema();
12 DBICTest::Schema::Artist->load_components(qw(FilterColumn InflateColumn));
13 DBICTest::Schema::Artist->filter_column(rank => {
14   filter_from_storage => sub { $from_storage_ran++; $_[1] * 2 },
15   filter_to_storage   => sub { $to_storage_ran++; $_[1] / 2 },
16 });
17 Class::C3->reinitialize();
18
19 my $artist = $schema->resultset('Artist')->create( { rank => 20 } );
20
21 # this should be using the cursor directly, no inflation/processing of any sort
22 my ($raw_db_rank) = $schema->resultset('Artist')
23                              ->search ($artist->ident_condition)
24                                ->get_column('rank')
25                                 ->_resultset
26                                  ->cursor
27                                   ->next;
28
29 is ($raw_db_rank, 10, 'INSERT: correctly unfiltered on insertion');
30
31 for my $reloaded (0, 1) {
32   my $test = $reloaded ? 'reloaded' : 'stored';
33   $artist->discard_changes if $reloaded;
34
35   is( $artist->rank , 20, "got $test filtered rank" );
36 }
37
38 $artist->update;
39 $artist->discard_changes;
40 is( $artist->rank , 20, "got filtered rank" );
41
42 $artist->update ({ rank => 40 });
43 ($raw_db_rank) = $schema->resultset('Artist')
44                              ->search ($artist->ident_condition)
45                                ->get_column('rank')
46                                 ->_resultset
47                                  ->cursor
48                                   ->next;
49 is ($raw_db_rank, 20, 'UPDATE: correctly unflitered on update');
50
51 $artist->discard_changes;
52 $artist->rank(40);
53 ok( !$artist->is_column_changed('rank'), 'column is not dirty after setting the same value' );
54
55 MC: {
56    my $cd = $schema->resultset('CD')->create({
57       artist => { rank => 20 },
58       title => 'fun time city!',
59       year => 'forevertime',
60    });
61    ($raw_db_rank) = $schema->resultset('Artist')
62                                 ->search ($cd->artist->ident_condition)
63                                   ->get_column('rank')
64                                    ->_resultset
65                                     ->cursor
66                                      ->next;
67
68    is $raw_db_rank, 10, 'artist rank gets correctly unfiltered w/ MC';
69    is $cd->artist->rank, 20, 'artist rank gets correctly filtered w/ MC';
70 }
71
72 CACHE_TEST: {
73   my $expected_from = $from_storage_ran;
74   my $expected_to   = $to_storage_ran;
75
76   # ensure we are creating a fresh obj
77   $artist = $schema->resultset('Artist')->single($artist->ident_condition);
78
79   is $from_storage_ran, $expected_from, 'from has not run yet';
80   is $to_storage_ran, $expected_to, 'to has not run yet';
81
82   $artist->rank;
83   cmp_ok (
84     $artist->get_filtered_column('rank'),
85       '!=',
86     $artist->get_column('rank'),
87     'filter/unfilter differ'
88   );
89   is $from_storage_ran, ++$expected_from, 'from ran once, therefor caches';
90   is $to_storage_ran, $expected_to,  'to did not run';
91
92   $artist->rank(6);
93   is $from_storage_ran, $expected_from, 'from did not run';
94   is $to_storage_ran, ++$expected_to,  'to ran once';
95
96   ok ($artist->is_column_changed ('rank'), 'Column marked as dirty');
97
98   $artist->rank;
99   is $from_storage_ran, ++$expected_from, 'from ran once';
100   is $to_storage_ran, $expected_to,  'to did not run';
101
102   $artist->rank;
103   is $from_storage_ran, $expected_from, 'from did not run';
104   is $to_storage_ran, $expected_to,  'to did not run';
105
106   $artist->update;
107
108   $artist->set_column(rank => 3);
109   ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on same set_column value');
110   is ($artist->rank, '6', 'Column set properly (cache blown)');
111   is $from_storage_ran, ++$expected_from, 'from ran once (set_column blew cache)';
112   is $to_storage_ran, $expected_to,  'to did not run';
113
114   $artist->rank(6);
115   ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on same accessor-set value');
116   is ($artist->rank, '6', 'Column set properly');
117   is $from_storage_ran, $expected_from, 'from did not run';
118   is $to_storage_ran, $expected_to,  'to did not run';
119
120   $artist->store_column(rank => 4);
121   ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on differing store_column value');
122   is ($artist->rank, '6', 'Filtered column still contains old value (cache not blown)');
123   is $from_storage_ran, $expected_from, 'from did not run';
124   is $to_storage_ran, $expected_to,  'to did not run';
125
126   $artist->set_column(rank => 4);
127   TODO: {
128     local $TODO = 'There seems to be no way around that much wizardry... which is ok';
129     ok ($artist->is_column_changed ('rank'), 'Column marked as dirty on out-of-sync set_column value');
130   }
131   is ($artist->rank, '8', 'Column set properly (cache blown)');
132   is $from_storage_ran, ++$expected_from, 'from ran once (set_column blew cache)';
133   is $to_storage_ran, $expected_to,  'to did not run';
134 }
135
136 IC_DIE: {
137   dies_ok {
138      DBICTest::Schema::Artist->inflate_column(rank =>
139         { inflate => sub {}, deflate => sub {} }
140      );
141   } q(Can't inflate column after filter column);
142
143   DBICTest::Schema::Artist->inflate_column(name =>
144      { inflate => sub {}, deflate => sub {} }
145   );
146
147   dies_ok {
148      DBICTest::Schema::Artist->filter_column(name => {
149         filter_to_storage => sub {},
150         filter_from_storage => sub {}
151      });
152   } q(Can't filter column after inflate column);
153 }
154
155 done_testing;