Commit | Line | Data |
c0329273 |
1 | BEGIN { do "./t/lib/ANFANG.pm" or die ( $@ || $! ) } |
2 | |
70350518 |
3 | use strict; |
26148d36 |
4 | use warnings; |
70350518 |
5 | |
6 | use Test::More; |
7d7d6975 |
7 | use Test::Exception; |
c0329273 |
8 | |
70350518 |
9 | use DBICTest; |
26148d36 |
10 | use Storable qw(dclone freeze nfreeze thaw); |
42168332 |
11 | use Scalar::Util qw/refaddr/; |
0e08abb2 |
12 | use Carp; |
42168332 |
13 | |
14 | sub ref_ne { |
0e08abb2 |
15 | my ($refa, $refb) = map { refaddr $_ or croak "$_ is not a reference!" } @_[0,1]; |
42168332 |
16 | cmp_ok ( |
17 | $refa, |
18 | '!=', |
19 | $refb, |
20 | sprintf ('%s (0x%07x != 0x%07x)', |
21 | $_[2], |
22 | $refa, |
23 | $refb, |
24 | ), |
25 | ); |
26 | } |
69ac22ee |
27 | |
42168332 |
28 | my $schema = DBICTest->init_schema; |
69ac22ee |
29 | |
e60dc79f |
30 | my %stores = ( |
3a81f59b |
31 | dclone_method => sub { return $schema->dclone($_[0]) }, |
42168332 |
32 | dclone_func => sub { |
33 | local $DBIx::Class::ResultSourceHandle::thaw_schema = $schema; |
34 | return dclone($_[0]) |
7244b45f |
35 | }, |
42168332 |
36 | "freeze/thaw_method" => sub { |
37 | my $ice = $schema->freeze($_[0]); |
38 | return $schema->thaw($ice); |
3a81f59b |
39 | }, |
26148d36 |
40 | "nfreeze/thaw_func" => sub { |
42168332 |
41 | my $ice = freeze($_[0]); |
42 | local $DBIx::Class::ResultSourceHandle::thaw_schema = $schema; |
43 | return thaw($ice); |
26148d36 |
44 | }, |
69ac22ee |
45 | |
42168332 |
46 | "freeze/thaw_func (cdbi legacy)" => sub { |
47 | # this one is special-cased to leak the $schema all over |
48 | # the same way as cdbi-compat does |
49 | DBICTest::Artist->result_source_instance->schema($schema); |
50 | DBICTest::CD->result_source_instance->schema($schema); |
51 | |
52 | my $fire = thaw(freeze($_[0])); |
53 | |
54 | # clean up the mess |
55 | $_->result_source_instance->schema(undef) |
56 | for map { $schema->class ($_) } $schema->sources; |
57 | |
58 | return $fire; |
59 | }, |
60 | |
42168332 |
61 | ); |
69ac22ee |
62 | |
49b3a264 |
63 | if ($ENV{DBICTEST_MEMCACHED}) { |
64 | if (DBIx::Class::Optional::Dependencies->req_ok_for ('test_memcached')) { |
65 | my $memcached = Cache::Memcached->new( |
66 | { servers => [ $ENV{DBICTEST_MEMCACHED} ] } |
67 | ); |
68 | |
69 | my $key = 'tmp_dbic_84serialize_memcached_test'; |
70 | |
71 | $stores{memcached} = sub { |
0e08abb2 |
72 | $memcached->set( $key, $_[0], 60 ) |
73 | or die "Unable to insert into $ENV{DBICTEST_MEMCACHED} - is server running?"; |
49b3a264 |
74 | local $DBIx::Class::ResultSourceHandle::thaw_schema = $schema; |
75 | return $memcached->get($key); |
76 | }; |
77 | } |
78 | else { |
79 | SKIP: { |
80 | skip 'Memcached tests need ' . DBIx::Class::Optional::Dependencies->req_missing_for ('test_memcached'), 1; |
81 | } |
82 | } |
83 | } |
84 | else { |
85 | SKIP: { |
86 | skip 'Set $ENV{DBICTEST_MEMCACHED} to run the memcached serialization tests', 1; |
87 | } |
88 | } |
89 | |
90 | |
91 | |
e60dc79f |
92 | for my $name (keys %stores) { |
42168332 |
93 | |
e60dc79f |
94 | my $store = $stores{$name}; |
7d7d6975 |
95 | my $copy; |
e60dc79f |
96 | |
97 | my $artist = $schema->resultset('Artist')->find(1); |
26148d36 |
98 | |
7d7d6975 |
99 | lives_ok { $copy = $store->($artist) } "serialize row object lives: $name"; |
42168332 |
100 | ref_ne($copy, $artist, 'Simple row cloned'); |
e60dc79f |
101 | is_deeply($copy, $artist, "serialize row object works: $name"); |
102 | |
7d7d6975 |
103 | my $cd_rs = $artist->search_related("cds"); |
104 | |
0b66414b |
105 | # test that a live result source can be serialized as well |
106 | is( $cd_rs->count, 3, '3 CDs in database'); |
107 | ok( $cd_rs->next, 'Advance cursor' ); |
3a81f59b |
108 | |
7d7d6975 |
109 | lives_ok { |
110 | $copy = $store->($cd_rs); |
42168332 |
111 | |
112 | ref_ne($copy, $artist, 'Simple row cloned'); |
113 | |
7d7d6975 |
114 | is_deeply ( |
115 | [ $copy->all ], |
116 | [ $cd_rs->all ], |
117 | "serialize resultset works: $name", |
118 | ); |
119 | } "serialize resultset lives: $name"; |
120 | |
121 | # Test that an object with a related_resultset can be serialized. |
e60dc79f |
122 | ok $artist->{related_resultsets}, 'has key: related_resultsets'; |
123 | |
7d7d6975 |
124 | lives_ok { $copy = $store->($artist) } "serialize row object with related_resultset lives: $name"; |
e60dc79f |
125 | for my $key (keys %$artist) { |
126 | next if $key eq 'related_resultsets'; |
127 | next if $key eq '_inflated_column'; |
42168332 |
128 | |
129 | ref_ne($copy->{$key}, $artist->{$key}, "Simple row internals cloned '$key'") |
130 | if ref $artist->{$key}; |
131 | |
e60dc79f |
132 | is_deeply($copy->{$key}, $artist->{$key}, |
42168332 |
133 | qq[serialize with related_resultset '$key']); |
e60dc79f |
134 | } |
7d7d6975 |
135 | |
0b66414b |
136 | lives_ok( |
137 | sub { $copy->discard_changes }, "Discard changes works: $name" |
138 | ) or diag $@; |
c65da661 |
139 | is($copy->id, $artist->id, "IDs still match "); |
0b66414b |
140 | |
141 | |
142 | # Test resultsource with cached rows |
49eeb48d |
143 | $schema->is_executed_querycount( sub { |
144 | $cd_rs = $cd_rs->search ({}, { cache => 1 }); |
0b66414b |
145 | |
49eeb48d |
146 | # this will hit the database once and prime the cache |
147 | my @cds = $cd_rs->all; |
0b66414b |
148 | |
0b66414b |
149 | $copy = $store->($cd_rs); |
42168332 |
150 | ref_ne($copy, $cd_rs, 'Cached resultset cloned'); |
0b66414b |
151 | is_deeply ( |
152 | [ $copy->all ], |
153 | [ $cd_rs->all ], |
154 | "serialize cached resultset works: $name", |
155 | ); |
156 | |
157 | is ($copy->count, $cd_rs->count, 'Cached count identical'); |
49eeb48d |
158 | }, 1, 'Only one db query fired'); |
e60dc79f |
159 | } |
42168332 |
160 | |
4376a157 |
161 | # test schema-less detached thaw |
162 | { |
163 | my $artist = $schema->resultset('Artist')->find(1); |
164 | |
165 | $artist = dclone $artist; |
166 | |
167 | is( $artist->name, 'Caterwauler McCrae', 'getting column works' ); |
168 | |
169 | ok( $artist->update, 'Non-dirty update noop' ); |
170 | |
171 | ok( $artist->name( 'Beeeeeeees' ), 'setting works' ); |
172 | |
173 | ok( $artist->is_column_changed( 'name' ), 'Column dirtyness works' ); |
174 | ok( $artist->is_changed, 'object dirtyness works' ); |
175 | |
176 | my $rs = $artist->result_source->resultset; |
177 | $rs->set_cache([ $artist ]); |
178 | |
179 | is( $rs->count, 1, 'Synthetic resultset count works' ); |
180 | |
181 | my $exc = qr/Unable to perform storage-dependent operations with a detached result source.+use \$schema->thaw/; |
182 | |
183 | throws_ok { $artist->update } |
184 | $exc, |
185 | 'Correct exception on row op' |
186 | ; |
187 | |
188 | throws_ok { $artist->discard_changes } |
189 | $exc, |
190 | 'Correct exception on row op' |
191 | ; |
192 | |
193 | throws_ok { $rs->find(1) } |
194 | $exc, |
195 | 'Correct exception on rs op' |
196 | ; |
197 | } |
198 | |
42168332 |
199 | done_testing; |