File Coverage

blib/lib/PGObject/Simple/Role.pm
Criterion Covered Total %
statement 26 40 65.0
branch 3 12 25.0
condition n/a
subroutine 12 17 70.5
pod 3 3 100.0
total 44 72 61.1


line stmt bran cond sub pod time code
1             package PGObject::Simple::Role;
2              
3 3     3   89568 use 5.010;
  3         13  
4              
5 3     3   1045 use Carp::Clan qr/^PGObject\b/;
  3         6030  
  3         39  
6 3     3   1392 use Log::Any qw($log);
  3         17660  
  3         22  
7              
8 3     3   5571 use Moo::Role;
  3         22806  
  3         27  
9             # Anything imported after `use Moo::Role;` will be composed into consuming packages.
10 3     3   2515 use PGObject::Simple ':full', '!dbh';
  3         53109  
  3         2681  
11              
12              
13             =head1 NAME
14              
15             PGObject::Simple::Role - Moo/Moose mappers for minimalist PGObject framework
16              
17             =head1 VERSION
18              
19             Version 2.1.1
20              
21             =cut
22              
23             our $VERSION = '2.1.1';
24              
25             =head1 SYNOPSIS
26              
27             Take the following (Moo) class:
28              
29             package MyAPP::Foo;
30             use PGObject::Util::DBMethod;
31             use Moo;
32             with 'PGObject::Simple::Role';
33              
34             has id => (is => 'ro', isa => 'Int', required => 0);
35             has foo => (is => 'ro', isa => 'Str', required => 0);
36             has bar => (is => 'ro', isa => 'Str', required => 0);
37             has baz => (is => 'ro', isa => 'Int', required => 0);
38              
39             sub _get_dbh {
40             return DBI->connect('dbi:Pg:dbname=foobar');
41             }
42             # PGObject::Util::DBMethod exports this
43             dbmethod int => (funcname => 'foo_to_int');
44              
45             And a stored procedure:
46              
47             CREATE OR REPLACE FUNCTION foo_to_int
48             (in_id int, in_foo text, in_bar text, in_baz int)
49             RETURNS INT LANGUAGE SQL AS
50             $$
51             select char_length($2) + char_length($3) + $1 * $4;
52             $$;
53              
54             Then the following Perl code would work to invoke it:
55              
56             my $foobar = MyApp->foo(id => 3, foo => 'foo', bar => 'baz', baz => 33);
57             $foobar->call_dbmethod(funcname => 'foo_to_int');
58              
59             The following will also work since you have the dbmethod call above:
60              
61             my $int = $foobar->int;
62              
63             The full interface of call_dbmethod and call_procedure from PGObject::Simple are
64             supported, and call_dbmethod is effectively wrapped by dbmethod(), allowing a
65             declarative mapping.
66              
67             =head1 DESCRIPTION
68              
69              
70              
71             =head1 ATTRIBUTES AND LAZY GETTERS
72              
73              
74             =cut
75              
76              
77             has _dbh => ( # use dbh() to get and set_dbh() to set
78             is => 'lazy',
79             isa => sub {
80             croak $log->error( "Expected a database handle. Got $_[0] instead" )
81             unless eval {$_[0]->isa('DBI::db')};
82             },
83             );
84              
85             has _DBH => ( # backwards compatible for 1.x.
86             is => 'lazy',
87             isa => sub {
88             warn $log->warn( 'deprecated _DBH used. rename to _dbh when you can' );
89             croak $log->error( "Expected a database handle. Got $_[0] instead" )
90             unless eval {$_[0]->isa('DBI::db')};
91             },
92             );
93              
94             sub _build__dbh {
95 2     2   733 my ($self) = @_;
96 2 50       17 return $self->{_DBH} if $self->{_DBH};
97 2         11 return $self->_get_dbh;
98             }
99              
100             sub _build__DBH {
101 0     0   0 my ($self) = @_;
102 0 0       0 return $self->{_dbh} if $self->{_dbh};
103 0         0 return $self->_dbh;
104             }
105              
106             sub _get_dbh {
107 1     1   6 croak 'Invoked _get_dbh from role improperly. Subclasses MUST set this method';
108             }
109              
110             has _registry => (is => 'lazy');
111              
112             sub _build__registry {
113 1     1   14 my ($self) = @_;
114 1 50       11 return $self->_get_registry() if $self->can('_get_registry');
115 0         0 _get_registry();
116             }
117              
118             =head2 _get_registry
119              
120             This is a method the consuming classes can override in order to set the
121             registry of the calls for type mapping purposes.
122              
123             =cut
124              
125             sub _get_registry{
126 1     1   7 return undef;
127             }
128              
129             has _funcschema => (is => 'lazy');
130              
131             =head2 _get_schema
132              
133             Returns the default schema associated with the object.
134              
135             =cut
136              
137             sub _build__funcschema {
138 0     0   0 return $_[0]->_get_schema;
139             }
140              
141             sub _get_schema {
142 0     0   0 return undef;
143             }
144              
145             has _funcprefix => (is => 'lazy');
146              
147             =head2 _get_prefix
148              
149             Returns string, default is an empty string, used to set a prefix for mapping
150             stored prcedures to an object class.
151              
152             =cut
153              
154             sub _build__funcprefix {
155 2     2   27 my ($self) = @_;
156 2         8 return $self->_get_prefix;
157             }
158              
159             sub _get_prefix {
160 1     1   7 return '';
161             }
162              
163             =head1 READ ONLY ACCESSORS (PUBLIC)
164              
165             =head2 dbh
166              
167             Wraps the PGObject::Simple method
168              
169             =cut
170              
171             sub dbh {
172 0     0 1 0 my ($self) = @_;
173 0 0       0 if (ref $self){
174 0         0 return $self->_dbh;
175             }
176 0         0 return "$self"->_get_dbh;
177             }
178              
179             =head2 funcschema
180              
181             Returns the schema bound to the object
182              
183             =cut
184              
185             sub funcschema {
186 0     0 1 0 my ($self) = @_;
187 0 0       0 return $self->_funcschema if ref $self;
188 0         0 return "$self"->_get_schema();
189             }
190              
191             =head2 funcprefix
192              
193             Prefix for functions
194              
195             =cut
196              
197             sub funcprefix {
198 2     2 1 16763 my ($self) = @_;
199            
200 2 50       64 return $self->_funcprefix if ref $self;
201 0           return "$self"->_get_prefix();
202             }
203              
204             =head1 REMOVED METHODS
205              
206             These methods were once part of this package but have been removed due to
207             the philosophy of not adding framework dependencies when an application
208             dependency can work just as well.
209              
210             =head2 dbmethod
211              
212             Included in versions 0.50 - 0.71.
213              
214             Instead of using this directly, use:
215              
216             use PGObject::Util::DBMethod;
217              
218             instead. Ideally this should be done in your actual class since that will
219             allow you to dispense with the extra parentheses. However, if you need a
220             backwards-compatible and central solution, since PGObject::Simple::Role
221             generally assumes sub-roles will be created for managing db connections etc.
222             you can put the use statement there and it will have the same impact as it did
223             here when it was removed with the benefit of better testing.
224              
225             =head1 AUTHOR
226              
227             Chris Travers,, C<< >>
228              
229             =head1 BUGS
230              
231             Please report any bugs or feature requests to C, or through
232             the web interface at L. I will be notified, and then you'll
233             Chris Travers,, C<< >>
234              
235             =head1 BUGS
236              
237             Please report any bugs or feature requests to C, or through
238             the web interface at L. I will be notified, and then you'll
239             automatically be notified of progress on your bug as I make changes.
240              
241              
242              
243              
244             =head1 SUPPORT
245              
246             You can find documentation for this module with the perldoc command.
247              
248             perldoc PGObject::Simple::Role
249              
250              
251             You can also look for information at:
252              
253             =over 4
254              
255             =item * RT: CPAN's request tracker (report bugs here)
256              
257             L
258              
259             =item * MetaCPAN
260              
261             L
262              
263             =back
264              
265              
266             =head1 ACKNOWLEDGEMENTS
267              
268              
269             =head1 LICENSE AND COPYRIGHT
270              
271             Copyright 2013-2017 Chris Travers
272             Copyright 2016-2021 The LedgerSMB Core team
273              
274             Redistribution and use in source and compiled forms with or without
275             modification, are permitted provided that the following conditions are met:
276              
277             =over
278              
279             =item
280              
281             Redistributions of source code must retain the above
282             copyright notice, this list of conditions and the following disclaimer as the
283             first lines of this file unmodified.
284              
285             =item
286              
287             Redistributions in compiled form must reproduce the above copyright
288             notice, this list of conditions and the following disclaimer in the
289             source code, documentation, and/or other materials provided with the
290             distribution.
291              
292             =back
293              
294             THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND
295             ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
296             WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
297             DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR
298             ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
299             (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
300             LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
301             ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
302             (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
303             SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
304              
305             =cut
306              
307             1; # End of PGObject::Simple::Role