File Coverage

blib/lib/Pinwheel/Model/Base.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Pinwheel::Model::Base;
2              
3             =head1 NAME
4              
5             Pinwheel::Model::Base - Base class for PinWheel models
6              
7             =head1 SYNOPSIS
8              
9             # Given $obj which is some PinWheel model...
10              
11             $obj->has_key($column_name);
12             $column_names = $obj->keys; # unordered array ref
13             $value = $obj->get($key);
14              
15             $sql_param = $obj->sql_param;
16             @route_params = $obj->route_param;
17              
18             =head1 DESCRIPTION
19              
20             =over 4
21              
22             =cut
23              
24 2     2   13 use Carp qw(confess);
  2         4  
  2         110  
25 2     2   8677 use Class::ISA;
  0            
  0            
26              
27             use Pinwheel::Database qw(prepare);
28              
29              
30             sub new
31             {
32             my ($class, $model, $data) = @_;
33             my ($ctx, $key, $obj);
34              
35             $ctx = Pinwheel::Context::get('Model--' . $model->{table});
36             $obj = $ctx->{$key} if ($key = $data->{id});
37              
38             if ($obj) {
39             $obj->{data} = {%{$obj->{data}}, %$data};
40             } else {
41             $obj = bless {model => $model, data => $data}, $class;
42             $ctx->{$key} = $obj if ($key);
43             }
44             return $obj;
45             }
46              
47             sub STORABLE_freeze
48             {
49             my ($obj, $cloning) = @_;
50             return Storable::freeze($obj->{data});
51             }
52              
53             sub STORABLE_attach
54             {
55             my ($class, $cloning, $data) = @_;
56             return new($class, \%{"$class\::model"}, Storable::thaw($data));
57             }
58              
59             =item $bool = $obj-Ehas_key($key)
60              
61             Returns true iff C<$obj> has a key named C<$key>. If the column hasn't been
62             fetched yet, C returns false.
63              
64             =cut
65              
66             sub has_key { exists($_[0]->{data}{$_[1]}) }
67              
68             =item $keys = $obj-Ekeys
69              
70             Return an (unordered) list of the current data keys in the model object. This
71             only includes the columns where data has been fetched.
72              
73             =cut
74              
75             sub keys { return [ keys(%{$_[0]->{data}}) ] }
76              
77             =item $value = $obj-Eget($key)
78              
79             TODO, document me.
80              
81             =cut
82              
83             sub get
84             {
85             my ($self, $key) = @_;
86             my ($getter);
87              
88             $getter = $self->{model}{getters}{$key};
89             return $getter ? $self->$getter() : $self->{data}{$key};
90             }
91              
92             sub _prefetched_link
93             {
94             my ($self, $key, $data) = @_;
95             my ($pkg, $model, $obj);
96              
97             $pkg = $self->{model}{associations}{$key};
98             $pkg = $self->_inherit_association($key) if !defined($pkg);
99             confess "Unknown relation $key" if !defined($pkg);
100             $model = $pkg->{model};
101             confess "Unable to resolve relation $key" if !defined($model);
102              
103             if (defined($data->{id})) {
104             $model = Pinwheel::Model::_find_inherited_model($model, $data);
105             $obj = Pinwheel::Model::Base::new($model->{model_class}, $model, $data);
106             }
107             $self->{data}{$key} = $obj;
108             }
109              
110             sub _inherit_association
111             {
112             my ($self, $key) = @_;
113             my ($classname, $pkg);
114              
115             foreach $classname (Class::ISA::super_path(ref($self))) {
116             $pkg = \%::;
117             $pkg = $pkg->{"$_\::"} foreach split(/::/, $classname);
118             if (defined($pkg->{model})) {
119             $pkg = $pkg->{model}{associations}{$key};
120             } else {
121             $pkg = undef;
122             }
123             last if defined($pkg);
124             }
125             $self->{model}{associations}{$key} = $pkg;
126             return $pkg;
127             }
128              
129             sub _fill_out
130             {
131             my $self = shift;
132             my ($data, $sth, $row, $key);
133              
134             $data = $self->{data};
135             $sth = prepare("SELECT * FROM `$self->{model}{table}` WHERE id = ?");
136             $sth->execute($data->{id});
137             $row = $sth->fetchrow_hashref();
138             foreach $key (CORE::keys %{$self->{model}{fields}}) {
139             $data->{$key} = $row->{$key} unless exists($data->{$key});
140             }
141             }
142              
143             =item $sql_param = $obj-Esql_param
144              
145             Turns C<$obj> into a SQL query parameter; see L.
146              
147             Default: C<$obj-Eid>.
148              
149             =cut
150              
151             sub sql_param { $_[0]->id }
152              
153             =item @route_params = $obj-Eroute_param
154              
155             Turns C<$obj> into route parameter(s); see L.
156              
157             Default: C<$obj-Eid>.
158              
159             =cut
160              
161             sub route_param { $_[0]->id }
162              
163             sub DESTROY { }
164              
165             =back
166              
167             =head1 AUTHOR
168              
169             A&M Network Publishing
170              
171             =cut
172              
173             1;