File Coverage

blib/lib/DBIx/QuickORM/Role/Row.pm
Criterion Covered Total %
statement 80 91 87.9
branch 14 24 58.3
condition 6 9 66.6
subroutine 22 27 81.4
pod 0 21 0.0
total 122 172 70.9


line stmt bran cond sub pod time code
1             package DBIx::QuickORM::Role::Row;
2 22     22   35020 use strict;
  22         60  
  22         981  
3 22     22   138 use warnings;
  22         53  
  22         2186  
4              
5             our $VERSION = '0.000019';
6              
7 22     22   1115 use Carp qw/croak/;
  22         74  
  22         1901  
8 22     22   161 use List::Util qw/zip/;
  22         65  
  22         5043  
9 22     22   169 use Scalar::Util qw/blessed/;
  22         56  
  22         5556  
10              
11 22     22   166 use Role::Tiny;
  22         80  
  22         210  
12              
13             requires qw{
14             source
15             connection
16             is_invalid
17             is_valid
18             in_storage
19             is_desynced
20             has_pending
21             };
22              
23 0     0 0 0 sub track_desync { 0 }
24 0     0 0 0 sub is_stored { $_[0]->in_storage }
25 26     26 0 122 sub dialect { $_[0]->connection->dialect }
26              
27 193   33 193 0 809 sub has_field { $_[0]->source->has_field($_[1] // croak "Must specify a field name") }
28 13     13 0 62 sub field_affinity { $_[0]->source->field_affinity($_[1], $_[0]->dialect) }
29              
30             #<<<
31 29   100 29 0 64 sub primary_key_field_list { @{$_[0]->source->primary_key // []} }
  29         93  
32 4   50 4 0 25 sub primary_key_value_list { map { $_[0]->raw_stored_field($_) // undef } $_[0]->check_pk->primary_key_field_list }
  4         38  
33 24   100 24 0 86 sub primary_key_hash { map { $_ => $_[0]->raw_stored_field($_) // undef } $_[0]->check_pk->primary_key_field_list }
  23         112  
34 24     24 0 5671 sub primary_key_hashref { +{ $_[0]->primary_key_hash } }
35             #>>>
36              
37             sub handle {
38 6     6 0 15 my $self = shift;
39 6         21 $self->connection->handle(source => $self->source, row => $self)->handle(@_);
40             }
41              
42             sub display {
43 0     0 0 0 my $self = shift;
44 0         0 my $source = $self->source;
45 0         0 return $source->source_orm_name . "(" . join(', ' => $self->primary_key_value_list) . ")";
46             }
47              
48             sub conflate_args {
49 13     13 0 44 my $self = shift;
50 13         33 my ($field, $val) = @_;
51              
52 13         49 return (field => $field, value => $val, source => $self->source, dialect => $self->dialect, affinity => $self->field_affinity($field));
53             }
54              
55             #####################
56             # {{{ Sanity Checks #
57             #####################
58              
59             requires qw{
60             check_sync
61             };
62              
63             sub check_pk {
64 61 100   61 0 242 return $_[0] if $_[0]->source->primary_key;
65              
66 5         6981 croak "Operation not allowed: the table this row is from does not have a primary key";
67             }
68              
69             #####################
70             # }}} Sanity Checks #
71             #####################
72              
73             ############################
74             # {{{ Manipulation Methods #
75             ############################
76              
77             requires qw{
78             force_sync
79             refresh
80             discard
81             update
82             };
83              
84             sub insert_or_save {
85 0     0 0 0 my $self = shift;
86              
87 0 0       0 return $self->save(@_) if $self->is_stored;
88 0 0       0 return $self->insert(@_) if $self->has_pending;
89             }
90              
91             sub insert {
92 2     2 0 8 my $self = shift;
93              
94 2 50       11 croak "This row is already in the database" if $self->is_stored;
95 2 50       10 croak "This row has no data to write" unless $self->has_pending;
96              
97 2         11 $self->connection->insert($self->source, $self);
98              
99 2         19 return $self;
100             }
101              
102             sub save {
103 13     13 0 1752 my $self = shift;
104              
105 13         46 $self->check_pk;
106 12         59 $self->check_sync;
107              
108 10 50       46 croak "This row is not in the database yet" unless $self->is_stored;
109              
110 10 50       70 my $pk = $self->source->primary_key or croak "Cannot use 'save()' on a row with a source that has no primary key";
111              
112 10 50       46 return $self unless $self->has_pending;
113              
114 10         41 $self->connection->update($self->source, $self);
115              
116 10         96 return $self;
117             }
118              
119             sub delete {
120 0     0 0 0 my $self = shift;
121              
122 0         0 $self->check_pk;
123              
124 0         0 $self->connection->delete($self->source, $self);
125             }
126              
127             ############################
128             # }}} Manipulation Methods #
129             ############################
130              
131             #####################
132             # {{{ Field methods #
133             #####################
134              
135             requires qw{
136             field
137             raw_field
138             fields
139             raw_fields
140             stored_field
141             pending_field
142             raw_stored_field
143             raw_pending_field
144             stored_fields
145             pending_fields
146             raw_stored_fields
147             raw_pending_fields
148             field_is_desynced
149             };
150              
151              
152             #####################
153             # }}} Field methods #
154             #####################
155              
156             ####################
157             # {{{ Link methods #
158             ####################
159              
160             sub follow {
161 5     5 0 27 my $self = shift;
162 5         20 my ($link) = @_;
163              
164 5         23 $link = $self->source->resolve_link($link);
165              
166 5         14 my $where = {};
167 5         107 for my $set (zip($link->local_columns, $link->other_columns)) {
168 5         19 my ($local, $other) = @$set;
169 5         31 $where->{$other} = $self->field($local);
170             }
171              
172 5         34 return $self->connection->handle($link->other_table, where => $where);
173             }
174              
175             sub obtain {
176 3     3 0 38 my $self = shift;
177 3         11 my ($link) = @_;
178              
179 3         24 $link = $self->source->resolve_link($link);
180 3 100       899 croak "The specified link does not point to a unique row" unless $link->unique;
181              
182 2         13 $self->follow($link)->one;
183             }
184              
185             sub insert_related {
186 3     3 0 6105 my $self = shift;
187 3         12 my ($link, $row_data) = @_;
188              
189 3         18 $link = $self->source->resolve_link($link);
190              
191 3         50 for my $set (zip($link->local_columns, $link->other_columns)) {
192 3         13 my ($local, $other) = @$set;
193 3 100       839 croak "field '$other' already exists in provided row data" if exists $row_data->{$other};
194 2         10 $row_data->{$other} = $self->field($local);
195             }
196              
197 2         12 $self->connection->insert($link->other_table() => $row_data);
198             }
199              
200             sub siblings { # This includes the original
201 4     4 0 7885 my $self = shift;
202 4         12 my ($link_or_fields) = @_;
203              
204 4 50       32 croak "You must specify a link or arrayref of fields to search on" unless $link_or_fields;
205              
206 4         8 my $fields;
207 4 100       16 if (ref($link_or_fields) eq 'ARRAY') {
208 3         7 $fields = $link_or_fields;
209             }
210             else {
211 1         6 my $link = $self->source->resolve_link($link_or_fields);
212 1         9 $fields = $link->local_columns;
213             }
214              
215 4         13 my $where = +{ map { $_ => $self->field($_) } @$fields };
  4         20  
216 4         19 return $self->handle(where => $where);
217             }
218              
219             ####################
220             # }}} Link methods #
221             ####################
222              
223             1;