9 'DBM::Deep' => '1.0003', # skip all if not installed
10 'DateTime::Format::MySQL' => '0.01',
16 # in case there are leftovers
17 unlink('newswriter.db') if -e 'newswriter.db';
21 unlink('newswriter.db') if -e 'newswriter.db';
27 This example creates a very basic Object Database which
28 links in the instances created with a backend store
29 (a DBM::Deep hash). It is by no means to be taken seriously
30 as a real-world ODB, but is a proof of concept of the flexibility
31 of the ::Instance protocol.
37 package MooseX::POOP::Meta::Instance;
42 extends 'Moose::Meta::Instance';
45 my %INSTANCE_COUNTERS;
47 my $db = DBM::Deep->new({
48 file => "newswriter.db",
57 $db = DBM::Deep->new({
58 file => "newswriter.db",
66 my $class = $self->associated_metaclass->name;
67 my $oid = ++$INSTANCE_COUNTERS{$class};
69 $db->{$class}->[($oid - 1)] = {};
73 instance => $db->{$class}->[($oid - 1)]
78 my ($self, $oid) = @_;
79 my $instance = $db->{$self->associated_metaclass->name}->[($oid - 1)];
83 instance => $instance,
84 }, $self->associated_metaclass->name;
88 my ($self, $instance) = @_;
90 my $class = $self->{meta}->name;
91 my $oid = ++$INSTANCE_COUNTERS{$class};
93 my $clone = tied($instance)->clone;
102 sub get_instance_oid {
103 my ($self, $instance) = @_;
108 my ($self, $instance, $slot_name) = @_;
109 return $instance->{instance}->{$slot_name};
113 my ($self, $instance, $slot_name, $value) = @_;
114 $instance->{instance}->{$slot_name} = $value;
117 sub is_slot_initialized {
118 my ($self, $instance, $slot_name, $value) = @_;
119 exists $instance->{instance}->{$slot_name} ? 1 : 0;
122 sub weaken_slot_value {
123 confess "Not sure how well DBM::Deep plays with weak refs, Rob says 'Write a test'";
126 sub inline_slot_access {
127 my ($self, $instance, $slot_name) = @_;
128 sprintf "%s->{instance}->{%s}", $instance, $slot_name;
131 package MooseX::POOP::Meta::Class;
134 extends 'Moose::Meta::Class';
136 override '_construct_instance' => sub {
138 my $params = @_ == 1 ? $_[0] : {@_};
139 return $class->get_meta_instance->find_instance($params->{oid})
146 package MooseX::POOP::Object;
147 use metaclass 'MooseX::POOP::Meta::Class' => (
148 instance_metaclass => 'MooseX::POOP::Meta::Instance'
156 ->get_instance_oid($self);
161 package Newswriter::Author;
164 extends 'MooseX::POOP::Object';
166 has 'first_name' => (is => 'rw', isa => 'Str');
167 has 'last_name' => (is => 'rw', isa => 'Str');
169 package Newswriter::Article;
171 use Moose::Util::TypeConstraints;
173 use DateTime::Format::MySQL;
175 extends 'MooseX::POOP::Object';
179 => where { length($_) < 100 };
183 => where { length($_) < 255 };
185 subtype 'DateTimeFormatString'
187 => where { DateTime::Format::MySQL->parse_datetime($_) };
189 enum 'Status' => qw(draft posted pending archive);
191 has 'headline' => (is => 'rw', isa => 'Headline');
192 has 'summary' => (is => 'rw', isa => 'Summary');
193 has 'article' => (is => 'rw', isa => 'Str');
195 has 'start_date' => (is => 'rw', isa => 'DateTimeFormatString');
196 has 'end_date' => (is => 'rw', isa => 'DateTimeFormatString');
198 has 'author' => (is => 'rw', isa => 'Newswriter::Author');
200 has 'status' => (is => 'rw', isa => 'Status');
202 around 'start_date', 'end_date' => sub {
205 $c->($self, DateTime::Format::MySQL->format_datetime($_[0])) if @_;
206 DateTime::Format::MySQL->parse_datetime($c->($self) || return undef);
210 { # check the meta stuff first
211 isa_ok(MooseX::POOP::Object->meta, 'MooseX::POOP::Meta::Class');
212 isa_ok(MooseX::POOP::Object->meta, 'Moose::Meta::Class');
213 isa_ok(MooseX::POOP::Object->meta, 'Class::MOP::Class');
215 is(MooseX::POOP::Object->meta->instance_metaclass,
216 'MooseX::POOP::Meta::Instance',
217 '... got the right instance metaclass name');
219 isa_ok(MooseX::POOP::Object->meta->get_meta_instance, 'MooseX::POOP::Meta::Instance');
221 my $base = MooseX::POOP::Object->new;
222 isa_ok($base, 'MooseX::POOP::Object');
223 isa_ok($base, 'Moose::Object');
225 isa_ok($base->meta, 'MooseX::POOP::Meta::Class');
226 isa_ok($base->meta, 'Moose::Meta::Class');
227 isa_ok($base->meta, 'Class::MOP::Class');
229 is($base->meta->instance_metaclass,
230 'MooseX::POOP::Meta::Instance',
231 '... got the right instance metaclass name');
233 isa_ok($base->meta->get_meta_instance, 'MooseX::POOP::Meta::Instance');
241 $article = Newswriter::Article->new(
242 headline => 'Home Office Redecorated',
243 summary => 'The home office was recently redecorated to match the new company colors',
246 author => Newswriter::Author->new(
247 first_name => 'Truman',
248 last_name => 'Capote'
253 }, undef, '... created my article successfully' );
254 isa_ok($article, 'Newswriter::Article');
255 isa_ok($article, 'MooseX::POOP::Object');
258 $article->start_date(DateTime->new(year => 2006, month => 6, day => 10));
259 $article->end_date(DateTime->new(year => 2006, month => 6, day => 17));
260 }, undef, '... add the article date-time stuff' );
262 ## check some meta stuff
264 isa_ok($article->meta, 'MooseX::POOP::Meta::Class');
265 isa_ok($article->meta, 'Moose::Meta::Class');
266 isa_ok($article->meta, 'Class::MOP::Class');
268 is($article->meta->instance_metaclass,
269 'MooseX::POOP::Meta::Instance',
270 '... got the right instance metaclass name');
272 isa_ok($article->meta->get_meta_instance, 'MooseX::POOP::Meta::Instance');
274 ok($article->oid, '... got a oid for the article');
276 $article_oid = $article->oid;
277 $article_ref = "$article";
279 is($article->headline,
280 'Home Office Redecorated',
281 '... got the right headline');
282 is($article->summary,
283 'The home office was recently redecorated to match the new company colors',
284 '... got the right summary');
285 is($article->article, '...', '... got the right article');
287 isa_ok($article->start_date, 'DateTime');
288 isa_ok($article->end_date, 'DateTime');
290 isa_ok($article->author, 'Newswriter::Author');
291 is($article->author->first_name, 'Truman', '... got the right author first name');
292 is($article->author->last_name, 'Capote', '... got the right author last name');
294 is($article->status, 'pending', '... got the right status');
297 MooseX::POOP::Meta::Instance->_reload_db();
304 $article2 = Newswriter::Article->new(
305 headline => 'Company wins Lottery',
306 summary => 'An email was received today that informed the company we have won the lottery',
309 author => Newswriter::Author->new(
310 first_name => 'Katie',
311 last_name => 'Couric'
316 }, undef, '... created my article successfully' );
317 isa_ok($article2, 'Newswriter::Article');
318 isa_ok($article2, 'MooseX::POOP::Object');
320 $article2_oid = $article2->oid;
321 $article2_ref = "$article2";
323 is($article2->headline,
324 'Company wins Lottery',
325 '... got the right headline');
326 is($article2->summary,
327 'An email was received today that informed the company we have won the lottery',
328 '... got the right summary');
329 is($article2->article, 'WoW', '... got the right article');
331 ok(!$article2->start_date, '... these two dates are unassigned');
332 ok(!$article2->end_date, '... these two dates are unassigned');
334 isa_ok($article2->author, 'Newswriter::Author');
335 is($article2->author->first_name, 'Katie', '... got the right author first name');
336 is($article2->author->last_name, 'Couric', '... got the right author last name');
338 is($article2->status, 'posted', '... got the right status');
344 $article = Newswriter::Article->new(oid => $article_oid);
345 }, undef, '... (re)-created my article successfully' );
346 isa_ok($article, 'Newswriter::Article');
347 isa_ok($article, 'MooseX::POOP::Object');
349 is($article->oid, $article_oid, '... got a oid for the article');
350 isnt($article_ref, "$article", '... got a new article instance');
352 is($article->headline,
353 'Home Office Redecorated',
354 '... got the right headline');
355 is($article->summary,
356 'The home office was recently redecorated to match the new company colors',
357 '... got the right summary');
358 is($article->article, '...', '... got the right article');
360 isa_ok($article->start_date, 'DateTime');
361 isa_ok($article->end_date, 'DateTime');
363 isa_ok($article->author, 'Newswriter::Author');
364 is($article->author->first_name, 'Truman', '... got the right author first name');
365 is($article->author->last_name, 'Capote', '... got the right author last name');
368 $article->author->first_name('Dan');
369 $article->author->last_name('Rather');
370 }, undef, '... changed the value ok' );
372 is($article->author->first_name, 'Dan', '... got the changed author first name');
373 is($article->author->last_name, 'Rather', '... got the changed author last name');
375 is($article->status, 'pending', '... got the right status');
378 MooseX::POOP::Meta::Instance->_reload_db();
383 $article = Newswriter::Article->new(oid => $article_oid);
384 }, undef, '... (re)-created my article successfully' );
385 isa_ok($article, 'Newswriter::Article');
386 isa_ok($article, 'MooseX::POOP::Object');
388 is($article->oid, $article_oid, '... got a oid for the article');
389 isnt($article_ref, "$article", '... got a new article instance');
391 is($article->headline,
392 'Home Office Redecorated',
393 '... got the right headline');
394 is($article->summary,
395 'The home office was recently redecorated to match the new company colors',
396 '... got the right summary');
397 is($article->article, '...', '... got the right article');
399 isa_ok($article->start_date, 'DateTime');
400 isa_ok($article->end_date, 'DateTime');
402 isa_ok($article->author, 'Newswriter::Author');
403 is($article->author->first_name, 'Dan', '... got the changed author first name');
404 is($article->author->last_name, 'Rather', '... got the changed author last name');
406 is($article->status, 'pending', '... got the right status');
410 $article2 = Newswriter::Article->new(oid => $article2_oid);
411 }, undef, '... (re)-created my article successfully' );
412 isa_ok($article2, 'Newswriter::Article');
413 isa_ok($article2, 'MooseX::POOP::Object');
415 is($article2->oid, $article2_oid, '... got a oid for the article');
416 isnt($article2_ref, "$article2", '... got a new article instance');
418 is($article2->headline,
419 'Company wins Lottery',
420 '... got the right headline');
421 is($article2->summary,
422 'An email was received today that informed the company we have won the lottery',
423 '... got the right summary');
424 is($article2->article, 'WoW', '... got the right article');
426 ok(!$article2->start_date, '... these two dates are unassigned');
427 ok(!$article2->end_date, '... these two dates are unassigned');
429 isa_ok($article2->author, 'Newswriter::Author');
430 is($article2->author->first_name, 'Katie', '... got the right author first name');
431 is($article2->author->last_name, 'Couric', '... got the right author last name');
433 is($article2->status, 'posted', '... got the right status');