File Coverage

blib/lib/Mandel/Relationship/BelongsTo.pm
Criterion Covered Total %
statement 23 49 46.9
branch 3 22 13.6
condition 0 6 0.0
subroutine 6 9 66.6
pod 1 1 100.0
total 33 87 37.9


line stmt bran cond sub pod time code
1             package Mandel::Relationship::BelongsTo;
2 1     1   559 use Mojo::Base 'Mandel::Relationship';
  1         3  
  1         6  
3 1     1   130 use Mojo::Util;
  1         3  
  1         75  
4 1     1   6 use Mango::BSON 'bson_dbref';
  1         2  
  1         736  
5              
6             has foreign_field => sub { shift->accessor };
7              
8             sub monkey_patch {
9 1     1 1 25 my $self = shift;
10 1         3 my $foreign_field = $self->foreign_field;
11 1         7 my $accessor = $self->accessor;
12              
13             Mojo::Util::monkey_patch(
14             $self->document_class,
15             $accessor,
16             sub {
17 1 50   1   30 my $cb = ref $_[-1] eq 'CODE' ? pop : undef;
        1      
18 1         2 my $doc = shift;
19 1         2 my $obj = shift;
20 1         5 my $related_model = $self->_related_model;
21 1         6 my $related_collection = $related_model->new_collection($doc->connection);
22              
23 1 50 0     61 if ($obj) { # set
    0          
24 1 50       11 if (UNIVERSAL::isa($obj, 'Mango::BSON::ObjectID')) {
25 1         4 $doc->data->{$foreign_field} = bson_dbref $related_model->collection_name, $obj;
26 1         9 return $obj;
27             }
28 0 0       0 if (ref $obj eq 'HASH') {
29 0         0 $obj = $related_collection->create($obj);
30             }
31              
32 0         0 $doc->data->{$foreign_field} = bson_dbref $related_model->collection_name, $obj->id;
33 0 0       0 $doc->dirty->{$foreign_field} = 1 if $doc->dirty;
34              
35             # Blocking
36 0 0       0 unless ($cb) {
37 0         0 $obj->save;
38 0         0 $doc->save;
39 0         0 $doc->_cache($accessor => $obj);
40 0         0 return $obj;
41             }
42              
43             # Non-blocking
44             Mojo::IOLoop->delay(
45             sub {
46 0     0   0 my ($delay) = @_;
47 0         0 $obj->save($delay->begin);
48 0         0 $doc->save($delay->begin);
49             },
50             sub {
51 0     0   0 my ($delay, $o_err, $d_err) = @_;
52 0   0     0 my $err = $o_err || $d_err;
53 0 0       0 $doc->_cache($accessor => $obj) unless $err;
54 0         0 $doc->$cb($err, $obj);
55             },
56 0         0 );
57             }
58             elsif (!delete $doc->{fresh} and my $cached = $doc->_cache($accessor)) { # get cached
59 0 0       0 return $cached unless $cb;
60 0         0 $self->$cb('', $cached);
61             }
62             else { # get
63 0         0 my $cursor = $related_collection->search({_id => $doc->data->{$foreign_field}{'$id'}});
64 0 0       0 return $doc->_cache($accessor => $cursor->single) unless $cb;
65             $cursor->single(
66             sub {
67 0     0   0 my ($cursor, $err, $obj) = @_;
68 0 0       0 $doc->_cache($accessor => $obj) unless $err;
69 0         0 $doc->$cb($err, $obj);
70             }
71 0         0 );
72             }
73              
74 0         0 $doc;
75             }
76 1         7 );
77              
78 1         46 return $self;
79             }
80              
81             1;
82              
83             =encoding utf8
84              
85             =head1 NAME
86              
87             Mandel::Relationship::BelongsTo - A document is owned by another mongodb document
88              
89             =head1 DESCRIPTION
90              
91             L is a class used to describe the relationship
92             between one document that belongs to another document. The connection
93             between the documents is described in the database using
94             L.
95              
96             =head1 DATABASE STRUCTURE
97              
98             A "cat" that I a "person" will look like this in the database:
99              
100             mongodb# db.persons.find();
101             { "_id" : ObjectId("5352abb0c5483e591a010000") }
102              
103             mongodb# db.cats.find({ "person.$id": ObjectId("5352abb0c5483e591a010000") })
104             {
105             "_id" : ObjectId("5352abb0c5483e591a020000"),
106             "person" : DBRef("persons", ObjectId("5352abb0c5483e591a010000"))
107             }
108              
109             =head1 SYNOPSIS
110              
111             =head2 Using DSL
112              
113             package MyModel::Cat;
114             use Mandel::Document;
115             belongs_to owner => 'MyModel::Person';
116              
117             =head2 Using object oriented interface
118              
119             MyModel::Cat
120             ->model
121             ->relationship(belongs_to => owner => 'MyModel::Person');
122              
123             See also L.
124              
125             =head2 Methods generated
126              
127             # non-blocking set
128             $cat = MyModel::Cat->new->owner(\%args, sub {
129             my($cat, $err, $person_obj) = @_;
130             # ...
131             });
132              
133             $cat = MyModel::Cat->new->owner($person_obj, sub {
134             my($cat, $err, $person_obj) = @_;
135             # ...
136             });
137              
138             # non-blocking get
139             $cat = MyModel::Cat->new->owner(sub {
140             my($cat, $err, $person_obj) = @_;
141             # ...
142             });
143              
144              
145             # blocking set
146             $person_obj = MyModel::Cat->new->owner(\%args);
147             $person_obj = MyModel::Cat->new->owner($person_obj);
148             $person_obj = MyModel::Cat->new->owner($bson_oid);
149              
150             # blocking get
151             $person = MyModel::Cat->new->owner;
152              
153             =head1 ATTRIBUTES
154              
155             L inherits all attributes from
156             L and implements the following new ones.
157              
158             =head2 foreign_field
159              
160             The name of the field in this class which hold the "_id" to the related doc.
161              
162             =head1 METHODS
163              
164             L inherits all methods from
165             L and implements the following new ones.
166              
167             =head2 monkey_patch
168              
169             Add methods to L.
170              
171             =head1 SEE ALSO
172              
173             L, L, L
174              
175             =head1 AUTHOR
176              
177             Jan Henning Thorsen - C
178              
179             =cut