9 eval "use DBM::Deep 1.0003;";
10 plan skip_all => "DBM::Deep 1.0003 (or greater) is required for this test" if $@;
11 eval "use DateTime::Format::MySQL;";
12 plan skip_all => "DateTime::Format::MySQL is required for this test" if $@;
18 # in case there are leftovers
19 unlink('newswriter.db') if -e 'newswriter.db';
23 unlink('newswriter.db') if -e 'newswriter.db';
29 This example creates a very basic Object Database which
30 links in the instances created with a backend store
31 (a DBM::Deep hash). It is by no means to be taken seriously
32 as a real-world ODB, but is a proof of concept of the flexibility
33 of the ::Instance protocol.
39 package Moose::POOP::Meta::Instance;
44 extends 'Moose::Meta::Instance';
47 my %INSTANCE_COUNTERS;
49 my $db = DBM::Deep->new({
50 file => "newswriter.db",
59 $db = DBM::Deep->new({
60 file => "newswriter.db",
68 my $class = $self->associated_metaclass->name;
69 my $oid = ++$INSTANCE_COUNTERS{$class};
71 $db->{$class}->[($oid - 1)] = {};
75 instance => $db->{$class}->[($oid - 1)]
80 my ($self, $oid) = @_;
81 my $instance = $db->{$self->associated_metaclass->name}->[($oid - 1)];
85 instance => $instance,
86 }, $self->associated_metaclass->name;
90 my ($self, $instance) = @_;
92 my $class = $self->{meta}->name;
93 my $oid = ++$INSTANCE_COUNTERS{$class};
95 my $clone = tied($instance)->clone;
104 sub get_instance_oid {
105 my ($self, $instance) = @_;
110 my ($self, $instance, $slot_name) = @_;
111 return $instance->{instance}->{$slot_name};
115 my ($self, $instance, $slot_name, $value) = @_;
116 $instance->{instance}->{$slot_name} = $value;
119 sub is_slot_initialized {
120 my ($self, $instance, $slot_name, $value) = @_;
121 exists $instance->{instance}->{$slot_name} ? 1 : 0;
124 sub weaken_slot_value {
125 confess "Not sure how well DBM::Deep plays with weak refs, Rob says 'Write a test'";
128 sub inline_slot_access {
129 my ($self, $instance, $slot_name) = @_;
130 sprintf "%s->{instance}->{%s}", $instance, $slot_name;
133 package Moose::POOP::Meta::Class;
136 extends 'Moose::Meta::Class';
138 override '_construct_instance' => sub {
140 my $params = @_ == 1 ? $_[0] : {@_};
141 return $class->get_meta_instance->find_instance($params->{oid})
148 package Moose::POOP::Object;
149 use metaclass 'Moose::POOP::Meta::Class' => (
150 instance_metaclass => 'Moose::POOP::Meta::Instance'
158 ->get_instance_oid($self);
163 package Newswriter::Author;
166 extends 'Moose::POOP::Object';
168 has 'first_name' => (is => 'rw', isa => 'Str');
169 has 'last_name' => (is => 'rw', isa => 'Str');
171 package Newswriter::Article;
173 use Moose::Util::TypeConstraints;
175 use DateTime::Format::MySQL;
177 extends 'Moose::POOP::Object';
181 => where { length($_) < 100 };
185 => where { length($_) < 255 };
187 subtype 'DateTimeFormatString'
189 => where { DateTime::Format::MySQL->parse_datetime($_) };
191 enum 'Status' => qw(draft posted pending archive);
193 has 'headline' => (is => 'rw', isa => 'Headline');
194 has 'summary' => (is => 'rw', isa => 'Summary');
195 has 'article' => (is => 'rw', isa => 'Str');
197 has 'start_date' => (is => 'rw', isa => 'DateTimeFormatString');
198 has 'end_date' => (is => 'rw', isa => 'DateTimeFormatString');
200 has 'author' => (is => 'rw', isa => 'Newswriter::Author');
202 has 'status' => (is => 'rw', isa => 'Status');
204 around 'start_date', 'end_date' => sub {
207 $c->($self, DateTime::Format::MySQL->format_datetime($_[0])) if @_;
208 DateTime::Format::MySQL->parse_datetime($c->($self) || return undef);
212 { # check the meta stuff first
213 isa_ok(Moose::POOP::Object->meta, 'Moose::POOP::Meta::Class');
214 isa_ok(Moose::POOP::Object->meta, 'Moose::Meta::Class');
215 isa_ok(Moose::POOP::Object->meta, 'Class::MOP::Class');
217 is(Moose::POOP::Object->meta->instance_metaclass,
218 'Moose::POOP::Meta::Instance',
219 '... got the right instance metaclass name');
221 isa_ok(Moose::POOP::Object->meta->get_meta_instance, 'Moose::POOP::Meta::Instance');
223 my $base = Moose::POOP::Object->new;
224 isa_ok($base, 'Moose::POOP::Object');
225 isa_ok($base, 'Moose::Object');
227 isa_ok($base->meta, 'Moose::POOP::Meta::Class');
228 isa_ok($base->meta, 'Moose::Meta::Class');
229 isa_ok($base->meta, 'Class::MOP::Class');
231 is($base->meta->instance_metaclass,
232 'Moose::POOP::Meta::Instance',
233 '... got the right instance metaclass name');
235 isa_ok($base->meta->get_meta_instance, 'Moose::POOP::Meta::Instance');
243 $article = Newswriter::Article->new(
244 headline => 'Home Office Redecorated',
245 summary => 'The home office was recently redecorated to match the new company colors',
248 author => Newswriter::Author->new(
249 first_name => 'Truman',
250 last_name => 'Capote'
255 } '... created my article successfully';
256 isa_ok($article, 'Newswriter::Article');
257 isa_ok($article, 'Moose::POOP::Object');
260 $article->start_date(DateTime->new(year => 2006, month => 6, day => 10));
261 $article->end_date(DateTime->new(year => 2006, month => 6, day => 17));
262 } '... add the article date-time stuff';
264 ## check some meta stuff
266 isa_ok($article->meta, 'Moose::POOP::Meta::Class');
267 isa_ok($article->meta, 'Moose::Meta::Class');
268 isa_ok($article->meta, 'Class::MOP::Class');
270 is($article->meta->instance_metaclass,
271 'Moose::POOP::Meta::Instance',
272 '... got the right instance metaclass name');
274 isa_ok($article->meta->get_meta_instance, 'Moose::POOP::Meta::Instance');
276 ok($article->oid, '... got a oid for the article');
278 $article_oid = $article->oid;
279 $article_ref = "$article";
281 is($article->headline,
282 'Home Office Redecorated',
283 '... got the right headline');
284 is($article->summary,
285 'The home office was recently redecorated to match the new company colors',
286 '... got the right summary');
287 is($article->article, '...', '... got the right article');
289 isa_ok($article->start_date, 'DateTime');
290 isa_ok($article->end_date, 'DateTime');
292 isa_ok($article->author, 'Newswriter::Author');
293 is($article->author->first_name, 'Truman', '... got the right author first name');
294 is($article->author->last_name, 'Capote', '... got the right author last name');
296 is($article->status, 'pending', '... got the right status');
299 Moose::POOP::Meta::Instance->_reload_db();
306 $article2 = Newswriter::Article->new(
307 headline => 'Company wins Lottery',
308 summary => 'An email was received today that informed the company we have won the lottery',
311 author => Newswriter::Author->new(
312 first_name => 'Katie',
313 last_name => 'Couric'
318 } '... created my article successfully';
319 isa_ok($article2, 'Newswriter::Article');
320 isa_ok($article2, 'Moose::POOP::Object');
322 $article2_oid = $article2->oid;
323 $article2_ref = "$article2";
325 is($article2->headline,
326 'Company wins Lottery',
327 '... got the right headline');
328 is($article2->summary,
329 'An email was received today that informed the company we have won the lottery',
330 '... got the right summary');
331 is($article2->article, 'WoW', '... got the right article');
333 ok(!$article2->start_date, '... these two dates are unassigned');
334 ok(!$article2->end_date, '... these two dates are unassigned');
336 isa_ok($article2->author, 'Newswriter::Author');
337 is($article2->author->first_name, 'Katie', '... got the right author first name');
338 is($article2->author->last_name, 'Couric', '... got the right author last name');
340 is($article2->status, 'posted', '... got the right status');
346 $article = Newswriter::Article->new(oid => $article_oid);
347 } '... (re)-created my article successfully';
348 isa_ok($article, 'Newswriter::Article');
349 isa_ok($article, 'Moose::POOP::Object');
351 is($article->oid, $article_oid, '... got a oid for the article');
352 isnt($article_ref, "$article", '... got a new article instance');
354 is($article->headline,
355 'Home Office Redecorated',
356 '... got the right headline');
357 is($article->summary,
358 'The home office was recently redecorated to match the new company colors',
359 '... got the right summary');
360 is($article->article, '...', '... got the right article');
362 isa_ok($article->start_date, 'DateTime');
363 isa_ok($article->end_date, 'DateTime');
365 isa_ok($article->author, 'Newswriter::Author');
366 is($article->author->first_name, 'Truman', '... got the right author first name');
367 is($article->author->last_name, 'Capote', '... got the right author last name');
370 $article->author->first_name('Dan');
371 $article->author->last_name('Rather');
372 } '... changed the value ok';
374 is($article->author->first_name, 'Dan', '... got the changed author first name');
375 is($article->author->last_name, 'Rather', '... got the changed author last name');
377 is($article->status, 'pending', '... got the right status');
380 Moose::POOP::Meta::Instance->_reload_db();
385 $article = Newswriter::Article->new(oid => $article_oid);
386 } '... (re)-created my article successfully';
387 isa_ok($article, 'Newswriter::Article');
388 isa_ok($article, 'Moose::POOP::Object');
390 is($article->oid, $article_oid, '... got a oid for the article');
391 isnt($article_ref, "$article", '... got a new article instance');
393 is($article->headline,
394 'Home Office Redecorated',
395 '... got the right headline');
396 is($article->summary,
397 'The home office was recently redecorated to match the new company colors',
398 '... got the right summary');
399 is($article->article, '...', '... got the right article');
401 isa_ok($article->start_date, 'DateTime');
402 isa_ok($article->end_date, 'DateTime');
404 isa_ok($article->author, 'Newswriter::Author');
405 is($article->author->first_name, 'Dan', '... got the changed author first name');
406 is($article->author->last_name, 'Rather', '... got the changed author last name');
408 is($article->status, 'pending', '... got the right status');
412 $article2 = Newswriter::Article->new(oid => $article2_oid);
413 } '... (re)-created my article successfully';
414 isa_ok($article2, 'Newswriter::Article');
415 isa_ok($article2, 'Moose::POOP::Object');
417 is($article2->oid, $article2_oid, '... got a oid for the article');
418 isnt($article2_ref, "$article2", '... got a new article instance');
420 is($article2->headline,
421 'Company wins Lottery',
422 '... got the right headline');
423 is($article2->summary,
424 'An email was received today that informed the company we have won the lottery',
425 '... got the right summary');
426 is($article2->article, 'WoW', '... got the right article');
428 ok(!$article2->start_date, '... these two dates are unassigned');
429 ok(!$article2->end_date, '... these two dates are unassigned');
431 isa_ok($article2->author, 'Newswriter::Author');
432 is($article2->author->first_name, 'Katie', '... got the right author first name');
433 is($article2->author->last_name, 'Couric', '... got the right author last name');
435 is($article2->status, 'posted', '... got the right status');