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 },
17 Class::C3->reinitialize() if DBIx::Class::_ENV_::OLD_MRO;
19 my $artist = $schema->resultset('Artist')->create( { rank => 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)
29 is ($raw_db_rank, 10, 'INSERT: correctly unfiltered on insertion');
31 for my $reloaded (0, 1) {
32 my $test = $reloaded ? 'reloaded' : 'stored';
33 $artist->discard_changes if $reloaded;
35 is( $artist->rank , 20, "got $test filtered rank" );
39 $artist->discard_changes;
40 is( $artist->rank , 20, "got filtered rank" );
42 $artist->update ({ rank => 40 });
43 ($raw_db_rank) = $schema->resultset('Artist')
44 ->search ($artist->ident_condition)
49 is ($raw_db_rank, 20, 'UPDATE: correctly unflitered on update');
51 $artist->discard_changes;
53 ok( !$artist->is_column_changed('rank'), 'column is not dirty after setting the same value' );
56 my $cd = $schema->resultset('CD')->create({
57 artist => { rank => 20 },
58 title => 'fun time city!',
59 year => 'forevertime',
61 ($raw_db_rank) = $schema->resultset('Artist')
62 ->search ($cd->artist->ident_condition)
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';
73 my $expected_from = $from_storage_ran;
74 my $expected_to = $to_storage_ran;
76 # ensure we are creating a fresh obj
77 $artist = $schema->resultset('Artist')->single($artist->ident_condition);
79 is $from_storage_ran, $expected_from, 'from has not run yet';
80 is $to_storage_ran, $expected_to, 'to has not run yet';
84 $artist->get_filtered_column('rank'),
86 $artist->get_column('rank'),
87 'filter/unfilter differ'
89 is $from_storage_ran, ++$expected_from, 'from ran once, therefor caches';
90 is $to_storage_ran, $expected_to, 'to did not run';
93 is $from_storage_ran, $expected_from, 'from did not run';
94 is $to_storage_ran, ++$expected_to, 'to ran once';
96 ok ($artist->is_column_changed ('rank'), 'Column marked as dirty');
99 is $from_storage_ran, $expected_from, 'from did not run';
100 is $to_storage_ran, $expected_to, 'to did not run';
104 $artist->set_column(rank => 3);
105 ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on same set_column value');
106 is ($artist->rank, '6', 'Column set properly (cache blown)');
107 is $from_storage_ran, ++$expected_from, 'from ran once (set_column blew cache)';
108 is $to_storage_ran, $expected_to, 'to did not run';
111 ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on same accessor-set value');
112 is ($artist->rank, '6', 'Column set properly');
113 is $from_storage_ran, $expected_from, 'from did not run';
114 is $to_storage_ran, ++$expected_to, 'to did run once (call in to set_column)';
116 $artist->store_column(rank => 4);
117 ok (! $artist->is_column_changed ('rank'), 'Column not marked as dirty on differing store_column value');
118 is ($artist->rank, '8', 'Cache properly blown');
119 is $from_storage_ran, ++$expected_from, 'from did not run';
120 is $to_storage_ran, $expected_to, 'to did not run';
123 # test in-memory operations
124 for my $artist_maker (
125 sub { $schema->resultset('Artist')->new({ rank => 42 }) },
126 sub { my $art = $schema->resultset('Artist')->new({}); $art->rank(42); $art },
129 my $expected_from = $from_storage_ran;
130 my $expected_to = $to_storage_ran;
132 my $artist = $artist_maker->();
134 is $from_storage_ran, $expected_from, 'from has not run yet';
135 is $to_storage_ran, $expected_to, 'to has not run yet';
137 ok( ! $artist->has_column_loaded('artistid'), 'pk not loaded' );
138 ok( $artist->has_column_loaded('rank'), 'Filtered column marked as loaded under new' );
139 is( $artist->rank, 42, 'Proper unfiltered value' );
140 is( $artist->get_column('rank'), 21, 'Proper filtered value' );
144 for my $v ( \ '16', \[ '?', '16' ] ) {
145 my $art = $schema->resultset('Artist')->new({ rank => 10 });
148 is_deeply( $art->rank, $v);
149 is_deeply( $art->get_filtered_column("rank"), $v);
150 is_deeply( $art->get_column("rank"), $v);
153 $art->discard_changes;
155 is ($art->get_column("rank"), 16, "Literal inserted into database properly");
156 is ($art->rank, 32, "filtering still works");
158 $art->update({ rank => $v });
160 is_deeply( $art->rank, $v);
161 is_deeply( $art->get_filtered_column("rank"), $v);
162 is_deeply( $art->get_column("rank"), $v);
164 $art->discard_changes;
166 is ($art->get_column("rank"), 16, "Literal inserted into database properly");
167 is ($art->rank, 32, "filtering still works");
172 DBICTest::Schema::Artist->inflate_column(rank =>
173 { inflate => sub {}, deflate => sub {} }
175 } qr/InflateColumn can not be used on a column with a declared FilterColumn filter/, q(Can't inflate column after filter column);
177 DBICTest::Schema::Artist->inflate_column(name =>
178 { inflate => sub {}, deflate => sub {} }
182 DBICTest::Schema::Artist->filter_column(name => {
183 filter_to_storage => sub {},
184 filter_from_storage => sub {}
186 } qr/FilterColumn can not be used on a column with a declared InflateColumn inflator/, q(Can't filter column after inflate column);
189 # test when we do not set both filter_from_storage/filter_to_storage
190 DBICTest::Schema::Artist->filter_column(rank => {
191 filter_to_storage => sub { $to_storage_ran++; $_[1] },
193 Class::C3->reinitialize() if DBIx::Class::_ENV_::OLD_MRO;
195 ASYMMETRIC_TO_TEST: {
200 my $expected_from = $from_storage_ran;
201 my $expected_to = $to_storage_ran;
204 ok ($artist->is_column_changed ('rank'), 'Column marked as dirty on accessor-set value');
205 is ($artist->rank, '10', 'Column set properly');
206 is $from_storage_ran, $expected_from, 'from did not run';
207 is $to_storage_ran, ++$expected_to, 'to did run';
209 $artist->discard_changes;
211 is ($artist->rank, '20', 'Column set properly');
212 is $from_storage_ran, $expected_from, 'from did not run';
213 is $to_storage_ran, $expected_to, 'to did not run';
216 DBICTest::Schema::Artist->filter_column(rank => {
217 filter_from_storage => sub { $from_storage_ran++; $_[1] },
219 Class::C3->reinitialize() if DBIx::Class::_ENV_::OLD_MRO;
221 ASYMMETRIC_FROM_TEST: {
226 my $expected_from = $from_storage_ran;
227 my $expected_to = $to_storage_ran;
230 ok ($artist->is_column_changed ('rank'), 'Column marked as dirty on accessor-set value');
231 is ($artist->rank, '13', 'Column set properly');
232 is $from_storage_ran, $expected_from, 'from did not run';
233 is $to_storage_ran, $expected_to, 'to did not run';
235 $artist->discard_changes;
237 is ($artist->rank, '23', 'Column set properly');
238 is $from_storage_ran, ++$expected_from, 'from did run';
239 is $to_storage_ran, $expected_to, 'to did not run';
242 throws_ok { DBICTest::Schema::Artist->filter_column( rank => {} ) }
243 qr/\QAn invocation of filter_column() must specify either a filter_from_storage or filter_to_storage/,
244 'Correctly throws exception for empty attributes'