File Coverage

blib/lib/Mandel/Relationship/HasOne.pm
Criterion Covered Total %
statement 34 47 72.3
branch 6 18 33.3
condition 1 6 16.6
subroutine 9 10 90.0
pod 1 1 100.0
total 51 82 62.2


line stmt bran cond sub pod time code
1             package Mandel::Relationship::HasOne;
2 1     1   574 use Mojo::Base 'Mandel::Relationship';
  1         2  
  1         6  
3 1     1   63 use Mojo::Util;
  1         2  
  1         38  
4 1     1   8 use Mango::BSON 'bson_dbref';
  1         2  
  1         671  
5              
6             sub monkey_patch {
7 1     1 1 27 my $self = shift;
8 1         6 my $foreign_field = $self->foreign_field;
9 1         12 my $accessor = $self->accessor;
10              
11             Mojo::Util::monkey_patch(
12             $self->document_class,
13             $accessor,
14             sub {
15 1 50   1   34 my $cb = ref $_[-1] eq 'CODE' ? pop : undef;
        1      
16 1         3 my $doc = shift;
17 1         1 my $obj = shift;
18 1         8 my $related_model = $self->_related_model;
19 1         6 my $related_collection = $related_model->new_collection($doc->connection);
20              
21 1 50 0     19 if ($obj) { # set ===========================================================
    0          
22 1 50       4 if (ref $obj eq 'HASH') {
23 1         4 $obj = $related_collection->create($obj);
24             }
25              
26 1         24 $obj->data->{$foreign_field} = bson_dbref $doc->model->collection_name, $doc->id;
27              
28             # Blocking
29 1 50       86 unless ($cb) {
30 0         0 $related_collection->search({sprintf('%s.$id', $foreign_field), $doc->id})->remove();
31 0         0 $obj->save;
32 0         0 $doc->save;
33 0         0 $doc->_cache($accessor => $obj);
34 0         0 return $obj;
35             }
36              
37             # Non-blocking
38             Mojo::IOLoop->delay(
39             sub {
40 1     1   150 my ($delay) = @_;
41 1         15 $related_collection->search({sprintf('%s.$id', $foreign_field), $doc->id})->remove($delay->begin);
42             },
43             sub {
44 1     1   179 my ($delay, $err) = @_;
45 1 50       6 return $delay->begin(0)->($err) if $err;
46 0         0 $doc->save($delay->begin);
47 0         0 $obj->save($delay->begin);
48             },
49             sub {
50 1     1   81 my ($delay, $o_err, $d_err) = @_;
51 1   33     3 my $err = $o_err || $d_err;
52 1 50       4 $doc->_cache($accessor => $obj) unless $err;
53 1         12 $doc->$cb($err, $obj);
54             },
55 1         36 );
56             }
57             elsif (!delete $doc->{fresh} and my $cached = $doc->_cache($accessor)) { # get cached
58 0 0       0 return $cached unless $cb;
59 0         0 $self->$cb('', $cached);
60             }
61             else { # get =============================================================
62 0         0 my $cursor = $related_collection->search({sprintf('%s.$id', $foreign_field), $doc->id});
63 0 0       0 return $cursor->single unless $cb;
64 0     0   0 $cursor->single(sub { $doc->$cb(@_[1, 2]) });
  0         0  
65             }
66              
67 1         251 return $doc;
68             }
69 1         5 );
70              
71 1         31 return $self;
72             }
73              
74             1;
75              
76             =encoding utf8
77              
78             =head1 NAME
79              
80             Mandel::Relationship::HasOne - A field relates to another mongodb document
81              
82             =head1 DESCRIPTION
83              
84             L is a class used to describe the relationship
85             between one document that has a relationship to one other documents.
86             The connection between the documents is described in the database using
87             L.
88              
89             =head1 DATABASE STRUCTURE
90              
91             A "dinosaur" that I "cat" will look like this in the database:
92              
93             mongodb# db.dinosaurs.find({ })
94             { "_id" : ObjectId("5352b4d8c5483e4502010000") }
95              
96             mongodb# db.cats.find({ "dinosaur.$id": ObjectId("53529f28c5483e4977020000") })
97             {
98             "_id" : ObjectId("5352b4d8c5483e4502040000"),
99             "dinosaur" : DBRef("dinosaurs", ObjectId("5352b4d8c5483e4502010000"))
100             }
101              
102             =head1 SYNOPSIS
103              
104             =head2 Using DSL
105              
106             package MyModel::Dinosaur;
107             use Mandel::Document;
108             has_one cat => 'MyModel::Cat';
109              
110             =head2 Using object oriented interface
111              
112             MyModel::Dinosaur->model->relationship(
113             "has_one",
114             "cat",
115             "MyModel::Cat",
116             );
117              
118             =head2 Methods generated
119              
120             $cat = MyModel::Dinosaur->new->cat(\%args, $cb);
121             $cat = MyModel::Dinosaur->new->cat($person_obj, $cb);
122              
123             $person_obj = MyModel::Dinosaur->new->cat(\%args);
124             $person_obj = MyModel::Dinosaur->new->cat($person_obj);
125              
126             $person = MyModel::Dinosaur->new->cat;
127             $self = MyModel::Dinosaur->new->cat(sub { my($self, $err, $person) = @_; });
128              
129             See also L.
130              
131             =head1 METHODS
132              
133             =head2 monkey_patch
134              
135             Add methods to L.
136              
137             =head1 SEE ALSO
138              
139             L, L, L
140              
141             =head1 AUTHOR
142              
143             Jan Henning Thorsen - C
144              
145             =cut