9 eval "use DBM::Deep 0.983; use DateTime::Format::MySQL;";
10 plan skip_all => "DBM::Deep and DateTime::Format::MySQL required for this test" if $@;
22 This example creates a very basic Object Database which
23 links in the instances created with a backend store
24 (a DBM::Deep hash). It is by no means to be taken seriously
25 as a real-world ODB (see Presto for that), but is a proof
26 of concept of the flexibility of the ::Instance protocol.
32 package Moose::POOP::Meta::Instance;
37 extends 'Moose::Meta::Instance';
40 my %INSTANCE_COUNTERS;
42 my $db = DBM::Deep->new({
43 file => "newswriter.db",
52 $db = DBM::Deep->new({
53 file => "newswriter.db",
61 my $class = $self->{meta}->name;
62 my $oid = ++$INSTANCE_COUNTERS{$class};
64 $db->{$class}->[($oid - 1)] = {};
66 $self->bless_instance_structure({
68 instance => $db->{$class}->[($oid - 1)]
73 my ($self, $oid) = @_;
74 my $instance = $db->{$self->{meta}->name}->[($oid - 1)];
75 $self->bless_instance_structure({
82 my ($self, $instance) = @_;
84 my $class = $self->{meta}->name;
85 my $oid = ++$INSTANCE_COUNTERS{$class};
87 my $clone = tied($instance)->clone;
89 $self->bless_instance_structure({
96 sub get_instance_oid {
97 my ($self, $instance) = @_;
102 my ($self, $instance, $slot_name) = @_;
103 return $instance->{instance}->{$slot_name};
107 my ($self, $instance, $slot_name, $value) = @_;
108 $instance->{instance}->{$slot_name} = $value;
111 sub is_slot_initialized {
112 my ($self, $instance, $slot_name, $value) = @_;
113 exists $instance->{instance}->{$slot_name} ? 1 : 0;
116 sub weaken_slot_value {
117 confess "Not sure how well DBM::Deep plays with weak refs, Rob says 'Write a test'";
120 sub inline_slot_access {
121 my ($self, $instance, $slot_name) = @_;
122 sprintf "%s->{instance}->{%s}", $instance, $slot_name;
125 package Moose::POOP::Meta::Class;
128 extends 'Moose::Meta::Class';
130 override 'construct_instance' => sub {
131 my ($class, %params) = @_;
132 return $class->get_meta_instance->find_instance($params{oid})
139 package Moose::POOP::Object;
140 use metaclass 'Moose::POOP::Meta::Class' => (
141 ':instance_metaclass' => 'Moose::POOP::Meta::Instance'
149 ->get_instance_oid($self);
154 package Newswriter::Author;
157 extends 'Moose::POOP::Object';
159 has 'first_name' => (is => 'rw', isa => 'Str');
160 has 'last_name' => (is => 'rw', isa => 'Str');
162 package Newswriter::Article;
164 use Moose::Util::TypeConstraints;
166 use DateTime::Format::MySQL;
168 extends 'Moose::POOP::Object';
172 => where { length($_) < 100 };
176 => where { length($_) < 255 };
178 subtype 'DateTimeFormatString'
180 => where { DateTime::Format::MySQL->parse_datetime($_) };
182 enum 'Status' => qw(draft posted pending archive);
184 has 'headline' => (is => 'rw', isa => 'Headline');
185 has 'summary' => (is => 'rw', isa => 'Summary');
186 has 'article' => (is => 'rw', isa => 'Str');
188 has 'start_date' => (is => 'rw', isa => 'DateTimeFormatString');
189 has 'end_date' => (is => 'rw', isa => 'DateTimeFormatString');
191 has 'author' => (is => 'rw', isa => 'Newswriter::Author');
193 has 'status' => (is => 'rw', isa => 'Status');
195 around 'start_date', 'end_date' => sub {
198 $c->($self, DateTime::Format::MySQL->format_datetime($_[0])) if @_;
199 DateTime::Format::MySQL->parse_datetime($c->($self) || return undef);
203 { # check the meta stuff first
204 isa_ok(Moose::POOP::Object->meta, 'Moose::POOP::Meta::Class');
205 isa_ok(Moose::POOP::Object->meta, 'Moose::Meta::Class');
206 isa_ok(Moose::POOP::Object->meta, 'Class::MOP::Class');
208 is(Moose::POOP::Object->meta->instance_metaclass,
209 'Moose::POOP::Meta::Instance',
210 '... got the right instance metaclass name');
212 isa_ok(Moose::POOP::Object->meta->get_meta_instance, 'Moose::POOP::Meta::Instance');
214 my $base = Moose::POOP::Object->new;
215 isa_ok($base, 'Moose::POOP::Object');
216 isa_ok($base, 'Moose::Object');
218 isa_ok($base->meta, 'Moose::POOP::Meta::Class');
219 isa_ok($base->meta, 'Moose::Meta::Class');
220 isa_ok($base->meta, 'Class::MOP::Class');
222 is($base->meta->instance_metaclass,
223 'Moose::POOP::Meta::Instance',
224 '... got the right instance metaclass name');
226 isa_ok($base->meta->get_meta_instance, 'Moose::POOP::Meta::Instance');
234 $article = Newswriter::Article->new(
235 headline => 'Home Office Redecorated',
236 summary => 'The home office was recently redecorated to match the new company colors',
239 author => Newswriter::Author->new(
240 first_name => 'Truman',
241 last_name => 'Capote'
246 } '... created my article successfully';
247 isa_ok($article, 'Newswriter::Article');
248 isa_ok($article, 'Moose::POOP::Object');
251 $article->start_date(DateTime->new(year => 2006, month => 6, day => 10));
252 $article->end_date(DateTime->new(year => 2006, month => 6, day => 17));
253 } '... add the article date-time stuff';
255 ## check some meta stuff
257 isa_ok($article->meta, 'Moose::POOP::Meta::Class');
258 isa_ok($article->meta, 'Moose::Meta::Class');
259 isa_ok($article->meta, 'Class::MOP::Class');
261 is($article->meta->instance_metaclass,
262 'Moose::POOP::Meta::Instance',
263 '... got the right instance metaclass name');
265 isa_ok($article->meta->get_meta_instance, 'Moose::POOP::Meta::Instance');
267 ok($article->oid, '... got a oid for the article');
269 $article_oid = $article->oid;
270 $article_ref = "$article";
272 is($article->headline,
273 'Home Office Redecorated',
274 '... got the right headline');
275 is($article->summary,
276 'The home office was recently redecorated to match the new company colors',
277 '... got the right summary');
278 is($article->article, '...', '... got the right article');
280 isa_ok($article->start_date, 'DateTime');
281 isa_ok($article->end_date, 'DateTime');
283 isa_ok($article->author, 'Newswriter::Author');
284 is($article->author->first_name, 'Truman', '... got the right author first name');
285 is($article->author->last_name, 'Capote', '... got the right author last name');
287 is($article->status, 'pending', '... got the right status');
290 Moose::POOP::Meta::Instance->_reload_db();
297 $article2 = Newswriter::Article->new(
298 headline => 'Company wins Lottery',
299 summary => 'An email was received today that informed the company we have won the lottery',
302 author => Newswriter::Author->new(
303 first_name => 'Katie',
304 last_name => 'Couric'
309 } '... created my article successfully';
310 isa_ok($article2, 'Newswriter::Article');
311 isa_ok($article2, 'Moose::POOP::Object');
313 $article2_oid = $article2->oid;
314 $article2_ref = "$article2";
316 is($article2->headline,
317 'Company wins Lottery',
318 '... got the right headline');
319 is($article2->summary,
320 'An email was received today that informed the company we have won the lottery',
321 '... got the right summary');
322 is($article2->article, 'WoW', '... got the right article');
324 ok(!$article2->start_date, '... these two dates are unassigned');
325 ok(!$article2->end_date, '... these two dates are unassigned');
327 isa_ok($article2->author, 'Newswriter::Author');
328 is($article2->author->first_name, 'Katie', '... got the right author first name');
329 is($article2->author->last_name, 'Couric', '... got the right author last name');
331 is($article2->status, 'posted', '... got the right status');
337 $article = Newswriter::Article->new(oid => $article_oid);
338 } '... (re)-created my article successfully';
339 isa_ok($article, 'Newswriter::Article');
340 isa_ok($article, 'Moose::POOP::Object');
342 is($article->oid, $article_oid, '... got a oid for the article');
343 isnt($article_ref, "$article", '... got a new article instance');
345 is($article->headline,
346 'Home Office Redecorated',
347 '... got the right headline');
348 is($article->summary,
349 'The home office was recently redecorated to match the new company colors',
350 '... got the right summary');
351 is($article->article, '...', '... got the right article');
353 isa_ok($article->start_date, 'DateTime');
354 isa_ok($article->end_date, 'DateTime');
356 isa_ok($article->author, 'Newswriter::Author');
357 is($article->author->first_name, 'Truman', '... got the right author first name');
358 is($article->author->last_name, 'Capote', '... got the right author last name');
361 $article->author->first_name('Dan');
362 $article->author->last_name('Rather');
363 } '... changed the value ok';
365 is($article->author->first_name, 'Dan', '... got the changed author first name');
366 is($article->author->last_name, 'Rather', '... got the changed author last name');
368 is($article->status, 'pending', '... got the right status');
371 Moose::POOP::Meta::Instance->_reload_db();
376 $article = Newswriter::Article->new(oid => $article_oid);
377 } '... (re)-created my article successfully';
378 isa_ok($article, 'Newswriter::Article');
379 isa_ok($article, 'Moose::POOP::Object');
381 is($article->oid, $article_oid, '... got a oid for the article');
382 isnt($article_ref, "$article", '... got a new article instance');
384 is($article->headline,
385 'Home Office Redecorated',
386 '... got the right headline');
387 is($article->summary,
388 'The home office was recently redecorated to match the new company colors',
389 '... got the right summary');
390 is($article->article, '...', '... got the right article');
392 isa_ok($article->start_date, 'DateTime');
393 isa_ok($article->end_date, 'DateTime');
395 isa_ok($article->author, 'Newswriter::Author');
396 is($article->author->first_name, 'Dan', '... got the changed author first name');
397 is($article->author->last_name, 'Rather', '... got the changed author last name');
399 is($article->status, 'pending', '... got the right status');
403 $article2 = Newswriter::Article->new(oid => $article2_oid);
404 } '... (re)-created my article successfully';
405 isa_ok($article2, 'Newswriter::Article');
406 isa_ok($article2, 'Moose::POOP::Object');
408 is($article2->oid, $article2_oid, '... got a oid for the article');
409 isnt($article2_ref, "$article2", '... got a new article instance');
411 is($article2->headline,
412 'Company wins Lottery',
413 '... got the right headline');
414 is($article2->summary,
415 'An email was received today that informed the company we have won the lottery',
416 '... got the right summary');
417 is($article2->article, 'WoW', '... got the right article');
419 ok(!$article2->start_date, '... these two dates are unassigned');
420 ok(!$article2->end_date, '... these two dates are unassigned');
422 isa_ok($article2->author, 'Newswriter::Author');
423 is($article2->author->first_name, 'Katie', '... got the right author first name');
424 is($article2->author->last_name, 'Couric', '... got the right author last name');
426 is($article2->status, 'posted', '... got the right status');
430 unlink('newswriter.db') if -e 'newswriter.db';