File Coverage

blib/lib/ORLite/Pod.pm
Criterion Covered Total %
statement 154 173 89.0
branch 17 38 44.7
condition 2 6 33.3
subroutine 27 28 96.4
pod 0 17 0.0
total 200 262 76.3


line stmt bran cond sub pod time code
1             package ORLite::Pod;
2              
3             =pod
4              
5             =head1 NAME
6              
7             ORLite::Pod - Documentation generator for ORLite
8              
9             =head1 SYNOPSIS
10              
11             my $generator = ORLite::Pod->new(
12             from => 'My::Project::DB',
13             to => 'My-Project/lib',
14             author => 'Adam Kennedy',
15             email => 'adamk@cpan.org',
16             );
17            
18             $generator->run;
19              
20             =head1 DESCRIPTION
21              
22             The biggest downside of L is that because it can generate you
23             an entire ORM in one line of code, you can have a large an extensive
24             API without anywhere for documentation for the API to exist.
25              
26             The result is quick efficient creation of APIs that nobody can
27             understand or use :)
28              
29             B was created to fix this problem by allowing you to keep
30             your slimline Perl module as is, but generating a tree of .pod files
31             alongside the regular modules containing the documentation for the API.
32              
33             B connects directly to a loaded ORLite instance,
34             interrogating it to find the database it connects to, and discovering
35             which tables have or don't have classes generated for them.
36              
37             TO BE COMPLETED
38              
39             =head1 METHODS
40              
41             =cut
42              
43 3     3   315665 use 5.008;
  3         12  
  3         135  
44 3     3   17 use strict;
  3         6  
  3         106  
45 3     3   28 use Carp ();
  3         8  
  3         59  
46 3     3   16 use File::Spec 3.2701 ();
  3         72  
  3         77  
47 3     3   15 use File::Path 2.07 ();
  3         200  
  3         79  
48 3     3   17 use File::Basename 0 ();
  3         70  
  3         63  
49 3     3   2637 use Params::Util 1.00 ();
  3         13916  
  3         136  
50 3     3   3937 use Class::Inspector 1.23 ();
  3         20084  
  3         104  
51 3     3   2709 use ORLite 1.23 ();
  3         169749  
  3         145  
52 3     3   46029 use Template 2.20 ();
  3         179843  
  3         14881  
53              
54             our $VERSION = '0.11';
55              
56             my $year = (localtime(time))[5] + 1900;
57              
58              
59              
60              
61              
62             #####################################################################
63             # Constructor and Accessors
64              
65             sub new {
66 1     1 0 5320635 my $class = shift;
67 1         14 my $self = bless { @_ }, $class;
68              
69             # Normalise flags
70 1 50       8 unless ( defined $self->trace ) {
71 0         0 $self->{trace} = 1;
72             }
73 1         6 $self->{trace} = !! $self->{trace};
74              
75             # Check params
76 1 50 33     7 unless (
77             Params::Util::_CLASS($self->from)
78             and
79             $self->from->can('orlite')
80             ) {
81 0         0 die("Did not provide a 'from' ORLite root class to generate from");
82             }
83 1         7 my $to = $self->to;
84 1 50       5 unless ( $self->to ) {
85 0         0 die("Did not provide a 'to' lib directory to write into");
86             }
87 1 50       5 unless ( -d $self->to ) {
88 0         0 die("The 'to' lib directory '$to' does not exist");
89             }
90 1 50       5 unless ( -w $self->to ) {
91 0         0 die("No permission to write to directory '$to'");
92             }
93 1 50       7 unless ( defined $self->author ) {
94 0         0 $self->{author} = '';
95             }
96 1 50       12 unless ( defined $self->email ) {
97 0         0 $self->{email} = '';
98             }
99 1 50       6 unless ( $self->year ) {
100 1         4 $self->{year} = $year;
101             }
102              
103             # Create the copyright year
104 1 50       6 if ( $self->{year} == $year ) {
105 1         4 $self->{copyyear} = $self->{year};
106             } else {
107 0         0 $self->{copyyear} = "$self->{year} - $year";
108             }
109              
110             # Create the Template Toolkit context
111 1         23 $self->{template} = Template->new( {
112             PRE_CHOMP => 1,
113             } );
114              
115 1         307792 return $self;
116             }
117              
118             sub from {
119 5     5 0 142 $_[0]->{from};
120             }
121              
122             sub dist {
123 0     0 0 0 my $dist = $_[0]->from;
124 0         0 $dist =~ s/::/-/g;
125 0         0 return $dist;
126             }
127              
128             sub to {
129 6     6 0 115 $_[0]->{to};
130             }
131              
132             sub author {
133 11     11 0 139 $_[0]->{author};
134             }
135              
136             sub author_pod {
137 4     4 0 201332 my $self = shift;
138 4 50 33     14 if ( $self->author and $self->email ) {
    0          
139 4         12 return $self->author . ' E' . $self->email . 'E';
140             } elsif ( $self->author ) {
141 0         0 return $self->author;
142             } else {
143 0         0 return '';
144             }
145             }
146              
147             sub email {
148 9     9 0 54 $_[0]->{email};
149             }
150              
151             sub year {
152 1     1 0 7 $_[0]->{year};
153             }
154              
155             sub template {
156 2     2 0 10 $_[0]->{template};
157             }
158              
159              
160              
161              
162              
163             #####################################################################
164             # POD Generation
165              
166             sub run {
167 1     1 0 28 my $self = shift;
168 1         6 my $pkg = $self->from;
169              
170             # Capture the raw schema information
171 1         46 $self->trace("Analyzing " . $pkg->dsn . "...\n");
172 1         31 my $dbh = $pkg->dbh;
173 1         607 my $tables = $dbh->selectall_arrayref(
174             'select * from sqlite_master where type = ?',
175             { Slice => {} }, 'table',
176             );
177 1         614 foreach my $table ( @$tables ) {
178 1         12 $table->{columns} = $dbh->selectall_arrayref(
179             "pragma table_info('$table->{name}')",
180             { Slice => {} },
181             );
182             }
183              
184             # Generate the main additional table level metadata
185 1         254 my %tindex = map { $_->{name} => $_ } @$tables;
  1         6  
186 1         3 foreach my $table ( @$tables ) {
187 1         3 my @columns = @{ $table->{columns} };
  1         3  
188 1         2 my @names = map { $_->{name} } @columns;
  2         6  
189 1         2 $table->{cindex} = map { $_->{name} => $_ } @columns;
  2         6  
190              
191             # Discover the primary key
192 1     1   15 $table->{pk} = List::Util::first { $_->{pk} } @columns;
  1         5  
193 1 50       39 $table->{pk} = $table->{pk}->{name} if $table->{pk};
194              
195             # What will be the class for this table
196 1         5 $table->{class} = ucfirst lc $table->{name};
197 1         8 $table->{class} =~ s/_([a-z])/uc($1)/ge;
  1         5  
198 1         4 $table->{class} = "${pkg}::$table->{class}";
199              
200             # Generate various SQL fragments
201 1         4 my $sql = $table->{sql} = { create => $table->{sql} };
202 1         2 $sql->{cols} = join ', ', map { '"' . $_ . '"' } @names;
  2         8  
203 1         5 $sql->{vals} = join ', ', ('?') x scalar @columns;
204 1         5 $sql->{select} = "select $table->{sql}->{cols} from $table->{name}";
205 1         4 $sql->{count} = "select count(*) from $table->{name}";
206 1         13 $sql->{insert} = join ' ',
207             "insert into $table->{name}" .
208             "( $table->{sql}->{cols} )" .
209             " values ( $table->{sql}->{vals} )";
210             }
211              
212             # Generate the foreign key metadata
213 1         4 foreach my $table ( @$tables ) {
214             # Locate the foreign keys
215 1         2 my %fk = ();
216 1         4 my @fk_sql = $table->{sql}->{create} =~ /[(,]\s*(.+?REFERENCES.+?)\s*[,)]/g;
217              
218             # Extract the details
219 1         3 foreach ( @fk_sql ) {
220 0 0       0 unless ( /^(\w+).+?REFERENCES\s+(\w+)\s*\(\s*(\w+)/ ) {
221 0         0 die "Invalid foreign key $_";
222             }
223 0         0 $fk{"$1"} = [ "$2", $tindex{"$2"}, "$3" ];
224             }
225 1         2 foreach ( @{ $table->{columns} } ) {
  1         3  
226 2         8 $_->{fk} = $fk{$_->{name}};
227             }
228             }
229              
230             # Generate the root module .pod file
231 1         5 $self->write_db( $tables );
232              
233             # Generate the table .pod files
234 1         16 foreach my $table ( @$tables ) {
235             # Beautify the create fragment
236 1         11 $table->{create} = $self->beautify(
237             $table->{sql}->{create}
238             );
239              
240             # Skip tables we aren't modelling
241 1 50       27 next unless $table->{class}->can('select');
242              
243             # Generate the table-specific file
244 1         5 $self->write_table( $tables, $table );
245             }
246              
247 1         159 return 1;
248             }
249              
250             sub beautify {
251 2     2 0 17 my $sql = $_[1];
252 2         5 my $copy = $sql;
253              
254             # Normalise and trim whitespace
255 2         32 $copy =~ s/\s+/ /sg;
256 2         13 $copy =~ s/\(\s+/(/sg;
257 2         16 $copy =~ s/\s+\)/)/sg;
258 2         17 $copy =~ s/\s*,\s*/,/sg;
259 2         9 $copy =~ s/^\s+//s;
260 2         13 $copy =~ s/\s+$//s;
261              
262             # Find the outermost braces
263 2 50       21 unless ( $copy =~ /^(.+?\()(.+)(\).*)\z/ ) {
264             # Give up
265 0         0 return $sql;
266             }
267 2         11 my $create = $1;
268 2         9 my $colspec = $2;
269 2         6 my $suffix = $3;
270              
271             # Split the columns
272 2         26 my @columns = split /(?<=,)/, $colspec;
273              
274             # Reassemble the pieces
275 4         31 return join '', (
276             "$create\n",
277 2         10 ( map { " $_\n" } @columns ),
278             "$suffix\n",
279             );
280             }
281              
282              
283              
284              
285              
286             #####################################################################
287             # Generation of Base Documentation
288              
289             sub write {
290 2     2 0 4 my $self = shift;
291 2         4 my $file = shift;
292 2         2190 my $input = shift;
293 2         5 my $hash = shift;
294              
295             # Strip the leading pipes off the template
296 2         341 $input =~ s/^\|//gm;
297              
298             # Process the template
299 2         17 my $template = $self->template;
300 2         5 my $output = '';
301 2         19 my $rv = $template->process(\$input, $hash, \$output);
302 2 50       560 unless ( $rv ) {
303 0         0 die $template->error;
304             }
305              
306             # Write the file
307 2         8 local *FILE;
308 2 50       16691 open( FILE, '>', $file ) or die "open: $!";
309 2         23 print FILE $output;
310 2         147 close FILE;
311              
312 2         39 return 1;
313             }
314              
315             sub trace {
316 4     4 0 16 my $self = shift;
317 4 50       223 if ( $self->{trace} ) {
318 0         0 print @_;
319             }
320 4         40 return 1;
321             }
322              
323             sub write_db {
324 1     1 0 2 my $self = shift;
325 1         2 my $tables = shift;
326 1         6 my $pkg = $self->from;
327 1         12 my $methods = Class::Inspector->methods($pkg);
328              
329             # Determine the file we're going to be writing to
330 1         289 my $file = File::Spec->catfile(
331             $self->to,
332             split( /::/, $pkg )
333             ) . '.pod';
334              
335             # Generate and write the file
336 1         7 $self->trace("Generating $file...\n");
337 21         41 $self->write( $file, template_db(), {
338             self => $self,
339             pkg => $pkg,
340             tables => $tables,
341             orlite2pod => $ORLite::Pod::VERSION,
342             method => {
343 1         4 map { $_ => 1 } @$methods,
344             },
345             } );
346             }
347              
348              
349              
350              
351              
352             #####################################################################
353             # Generation of Table-Specific Documentation
354              
355             sub write_table {
356 1     1 0 4 my $self = shift;
357 1         2 my $tables = shift;
358 1         4 my $table = shift;
359 1         6 my $root = $self->from;
360 1         4 my $pkg = $table->{class};
361 1         13 my $methods = Class::Inspector->methods($pkg);
362              
363             # Determine the file we're going to be writing to
364 1         260 my $file = File::Spec->catfile(
365             $self->to,
366             split( /::/, $pkg )
367             ) . '.pod';
368              
369             # Create the parent directory if needed
370 1         61 my $dir = File::Basename::dirname($file);
371 1 50       17 unless ( -d $dir ) {
372 1         270 File::Path::make_path( $dir, { verbose => 0 } );
373             }
374              
375             # Generate and write the file
376 1         20 $self->trace("Generating $file...\n");
377 17         49 $self->write( $file, template_table(), {
378             self => $self,
379             pkg => $pkg,
380             root => $root,
381             tables => $tables,
382             table => $table,
383             method => {
384 1         4 map { $_ => 1 } @$methods,
385             },
386             } );
387             }
388              
389              
390              
391              
392              
393             #####################################################################
394             # Root Template
395              
396 1     1 0 4 sub template_db { <<'END_TT' }
397             |=head1 NAME
398             |
399             |[%+ pkg %] - An ORLite-based ORM Database API
400             |
401             |=head1 DESCRIPTION
402             |
403             |TO BE COMPLETED
404             |
405             |=head1 METHODS
406             |
407             [% IF method.dsn %]
408             |=head2 dsn
409             |
410             | my $string = [%+ pkg %]->dsn;
411             |
412             |The C accessor returns the L connection string used to connect
413             |to the SQLite database as a string.
414             |
415             [% END %]
416             [% IF method.dbh %]
417             |=head2 dbh
418             |
419             | my $handle = [%+ pkg %]->dbh;
420             |
421             |To reliably prevent potential L deadlocks resulting from multiple
422             |connections in a single process, each ORLite package will only ever
423             |maintain a single connection to the database.
424             |
425             |During a transaction, this will be the same (cached) database handle.
426             |
427             |Although in most situations you should not need a direct DBI connection
428             |handle, the C method provides a method for getting a direct
429             |connection in a way that is compatible with connection management in
430             |L.
431             |
432             |Please note that these connections should be short-lived, you should
433             |never hold onto a connection beyond your immediate scope.
434             |
435             |The transaction system in ORLite is specifically designed so that code
436             |using the database should never have to know whether or not it is in a
437             |transation.
438             |
439             |Because of this, you should B call the -Edisconnect method
440             |on the database handles yourself, as the handle may be that of a
441             |currently running transaction.
442             |
443             |Further, you should do your own transaction management on a handle
444             |provided by the method.
445             |
446             |In cases where there are extreme needs, and you B have to
447             |violate these connection handling rules, you should create your own
448             |completely manual DBI-Econnect call to the database, using the connect
449             |string provided by the C method.
450             |
451             |The C method returns a L object, or throws an exception on
452             |error.
453             |
454             [% END %]
455             [% IF method.begin %]
456             |=head2 begin
457             |
458             | [%+ pkg %]->begin;
459             |
460             |The C method indicates the start of a transaction.
461             |
462             |In the same way that ORLite allows only a single connection, likewise
463             |it allows only a single application-wide transaction.
464             |
465             |No indication is given as to whether you are currently in a transaction
466             |or not, all code should be written neutrally so that it works either way
467             |or doesn't need to care.
468             |
469             |Returns true or throws an exception on error.
470             |
471             [% END %]
472             [% IF method.commit %]
473             |=head2 commit
474             |
475             | [%+ pkg %]->commit;
476             |
477             |The C method commits the current transaction. If called outside
478             |of a current transaction, it is accepted and treated as a null operation.
479             |
480             |Once the commit has been completed, the database connection falls back
481             |into auto-commit state. If you wish to immediately start another
482             |transaction, you will need to issue a separate -Ebegin call.
483             |
484             |Returns true or throws an exception on error.
485             |
486             [% END %]
487             [% IF method.rollback %]
488             |=head2 rollback
489             |
490             |The C method rolls back the current transaction. If called outside
491             |of a current transaction, it is accepted and treated as a null operation.
492             |
493             |Once the rollback has been completed, the database connection falls back
494             |into auto-commit state. If you wish to immediately start another
495             |transaction, you will need to issue a separate -Ebegin call.
496             |
497             |If a transaction exists at END-time as the process exits, it will be
498             |automatically rolled back.
499             |
500             |Returns true or throws an exception on error.
501             |
502             |=head2 do
503             |
504             | [%+ pkg %]->do(
505             | 'insert into table ( foo, bar ) values ( ?, ? )', {},
506             | \$foo_value,
507             | \$bar_value,
508             | );
509             |
510             |The C method is a direct wrapper around the equivalent L method,
511             |but applied to the appropriate locally-provided connection or transaction.
512             |
513             |It takes the same parameters and has the same return values and error
514             |behaviour.
515             |
516             [% END %]
517             [% IF method.selectall_arrayref %]
518             |=head2 selectall_arrayref
519             |
520             |The C method is a direct wrapper around the equivalent
521             |L method, but applied to the appropriate locally-provided connection
522             |or transaction.
523             |
524             |It takes the same parameters and has the same return values and error
525             |behaviour.
526             |
527             [% END %]
528             [% IF method.selectall_hashref %]
529             |=head2 selectall_hashref
530             |
531             |The C method is a direct wrapper around the equivalent
532             |L method, but applied to the appropriate locally-provided connection
533             |or transaction.
534             |
535             |It takes the same parameters and has the same return values and error
536             |behaviour.
537             |
538             [% END %]
539             [% IF method.selectcol_arrayref %]
540             |=head2 selectcol_arrayref
541             |
542             |The C method is a direct wrapper around the equivalent
543             |L method, but applied to the appropriate locally-provided connection
544             |or transaction.
545             |
546             |It takes the same parameters and has the same return values and error
547             |behaviour.
548             |
549             [% END %]
550             [% IF method.selectrow_array %]
551             |=head2 selectrow_array
552             |
553             |The C method is a direct wrapper around the equivalent
554             |L method, but applied to the appropriate locally-provided connection
555             |or transaction.
556             |
557             |It takes the same parameters and has the same return values and error
558             |behaviour.
559             |
560             [% END %]
561             [% IF method.selectrow_arrayref %]
562             |=head2 selectrow_arrayref
563             |
564             |The C method is a direct wrapper around the equivalent
565             |L method, but applied to the appropriate locally-provided connection
566             |or transaction.
567             |
568             |It takes the same parameters and has the same return values and error
569             |behaviour.
570             |
571             [% END %]
572             [% IF method.selectrow_hashref %]
573             |=head2 selectrow_hashref
574             |
575             |The C method is a direct wrapper around the equivalent
576             |L method, but applied to the appropriate locally-provided connection
577             |or transaction.
578             |
579             |It takes the same parameters and has the same return values and error
580             |behaviour.
581             |
582             [% END %]
583             [% IF method.prepare %]
584             |=head2 prepare
585             |
586             |The C method is a direct wrapper around the equivalent
587             |L method, but applied to the appropriate locally-provided connection
588             |or transaction
589             |
590             |It takes the same parameters and has the same return values and error
591             |behaviour.
592             |
593             |In general though, you should try to avoid the use of your own prepared
594             |statements if possible, although this is only a recommendation and by
595             |no means prohibited.
596             |
597             [% END %]
598             [% IF method.pragma %]
599             |=head2 pragma
600             |
601             | # Get the user_version for the schema
602             | my $version = [% pkg %]->pragma('user_version');
603             |
604             |The C method provides a convenient method for fetching a pragma
605             |for a database. See the L documentation for more details.
606             |
607             [% END %]
608             |=head1 SUPPORT
609             |
610             |B<[%+ pkg %]> is based on L.
611             |
612             |Documentation created by L [% orlite2pod %].
613             |
614             |[% IF self.rt %]
615             |Bugs should be reported via the CPAN bug tracker at
616             |
617             |L
618             |
619             |For other issues, contact the author.
620             [% ELSE %]
621             |For general support please see the support section of the main
622             |project documentation.
623             [% END %]
624             |
625             [% IF self.author_pod %]
626             |=head1 AUTHOR
627             |
628             |[%+ self.author_pod %]
629             [% END %]
630             |=head1 COPYRIGHT
631             |
632             |Copyright [% self.copyyear %] [%+ self.author %].
633             |
634             |This program is free software; you can redistribute
635             |it and/or modify it under the same terms as Perl itself.
636             |
637             |The full text of the license can be found in the
638             |LICENSE file included with this module.
639             |
640             END_TT
641              
642              
643              
644              
645              
646             #####################################################################
647             # Table Template
648              
649 1     1 0 6 sub template_table { <<'END_TT' }
650             |=head1 NAME
651             |
652             |[%+ pkg %] - [% root %] class for the [% table.name %] table
653             |
654             |=head1 DESCRIPTION
655             |
656             |TO BE COMPLETED
657             |
658             |=head1 METHODS
659             |
660             [% IF method.base %]
661             |=head2 base
662             |
663             | # Returns '[% root %]'
664             | my $namespace = [% pkg %]->base;
665             |
666             |Normally you will only need to work directly with a table class,
667             |and only with one ORLite package.
668             |
669             |However, if for some reason you need to work with multiple ORLite packages
670             |at the same time without hardcoding the root namespace all the time, you
671             |can determine the root namespace from an object or table class with the
672             |C method.
673             |
674             [% END %]
675             [% IF method.table %]
676             |=head2 table
677             |
678             | # Returns '[% table.name %]'
679             | print [% pkg %]->table;
680             |
681             |While you should not need the name of table for any simple operations,
682             |from time to time you may need it programatically. If you do need it,
683             |you can use the C method to get the table name.
684             |
685             [% END %]
686             [% IF method.load %]
687             |=head2 load
688             |
689             | my $object = [% pkg %]->load( $[% table.pk %] );
690             |
691             |If your table has single column primary key, a C method will be
692             |generated in the class. If there is no primary key, the method is not
693             |created.
694             |
695             |The C method provides a shortcut mechanism for fetching a single
696             |object based on the value of the primary key. However it should only
697             |be used for cases where your code trusts the record to already exists.
698             |
699             |It returns a C<[% pkg %]> object, or throws an exception if the
700             |object does not exist.
701             |
702             [% END %]
703             [% IF method.select %]
704             |=head2 select
705             |
706             | # Get all objects in list context
707             | my @list = [% pkg %]->select;
708             |
709             | # Get a subset of objects in scalar context
710             | my $array_ref = [% pkg %]->select(
711             | 'where [% table.pk %] > ? order by [% table.pk %]',
712             | 1000,
713             | );
714             |
715             |The C query on the
716             |[%+ table.name %] table.
717             |
718             |It takes an optional argument of a SQL phrase to be added after the
719             |C section of the query, followed by variables
720             |to be bound to the placeholders in the SQL phrase. Any SQL that is
721             |compatible with SQLite can be used in the parameter.
722             |
723             |Returns a list of B<[% pkg %]> objects when called in list context, or a
724             |reference to an C of B<[% pkg %]> objects when called in scalar
725             |context.
726             |
727             |Throws an exception on error, typically directly from the L layer.
728             |
729             [% END %]
730             [% IF method.iterate %]
731             |=head2 iterate
732             |
733             | [%+ pkg %]->iterate( sub {
734             | print $_->[% table.pk %] . "\n";
735             | } );
736             |
737             |The C method enables the processing of large tables one record at
738             |a time without loading having to them all into memory in advance.
739             |
740             |This plays well to the strength of SQLite, allowing it to do the work of
741             |loading arbitrarily large stream of records from disk while retaining the
742             |full power of Perl when processing the records.
743             |
744             |The last argument to C must be a subroutine reference that will be
745             |called for each element in the list, with the object provided in the topic
746             |variable C<$_>.
747             |
748             |This makes the C code fragment above functionally equivalent to the
749             |following, except with an O(1) memory cost instead of O(n).
750             |
751             | foreach ( [% pkg %]->select ) {
752             | print $_->[% table.pk %] . "\n";
753             | }
754             |
755             |You can filter the list via SQL in the same way you can with C
756             |
757             | [%+ pkg %]->iterate(
758             | 'order by ?', '[% table.pk %]',
759             | sub {
760             | print $_->[% table.pk %] . "\n";
761             | }
762             | );
763             |
764             |You can also use it in raw form from the root namespace for better control.
765             |Using this form also allows for the use of arbitrarily complex queries,
766             |including joins. Instead of being objects, rows are provided as C
767             |references when used in this form.
768             |
769             | [%+ root %]->iterate(
770             | 'select name from [% table.name %] order by [% table.pk %]',
771             | sub {
772             | print $_->[0] . "\n";
773             | }
774             | );
775             |
776             [% END %]
777             [% IF method.count %]
778             |=head2 count
779             |
780             | # How many objects are in the table
781             | my $rows = [% pkg %]->count;
782             |
783             | # How many objects
784             | my $small = [% pkg %]->count(
785             | 'where [% table.pk %] > ?',
786             | 1000,
787             | );
788             |
789             |The C method executes a C
790             |[%+ table.name %] table.
791             |
792             |It takes an optional argument of a SQL phrase to be added after the
793             |C section of the query, followed by variables
794             |to be bound to the placeholders in the SQL phrase. Any SQL that is
795             |compatible with SQLite can be used in the parameter.
796             |
797             |Returns the number of objects that match the condition.
798             |
799             |Throws an exception on error, typically directly from the L layer.
800             |
801             [% END %]
802             [% IF method.new %]
803             |=head2 new
804             |
805             | TO BE COMPLETED
806             |
807             |The C constructor is used to create a new abstract object that
808             |is not (yet) written to the database.
809             |
810             |Returns a new L<[% pkg %]> object.
811             |
812             [% END %]
813             [% IF method.create %]
814             |=head2 create
815             |
816             | my $object = [% pkg %]->create(
817             |[%- FOREACH column IN table.columns %]
818             | [%+ column.name %] => 'value',
819             |[%- END %]
820             | );
821             |
822             |The C constructor is a one-step combination of C and
823             |C that takes the column parameters, creates a new
824             |L<[% pkg %]> object, inserts the appropriate row into the
825             |L<[% table.name %]> table, and then returns the object.
826             |
827             |If the primary key column C<[% table.pk %]> is not provided to the
828             |constructor (or it is false) the object returned will have
829             |C<[% table.pk %]> set to the new unique identifier.
830             |
831             |Returns a new L<[% table.name %]> object, or throws an exception on
832             |error, typically from the L layer.
833             |
834             [% END %]
835             [% IF method.insert %]
836             |=head2 insert
837             |
838             | $object->insert;
839             |
840             |The C method commits a new object (created with the C method)
841             |into the database.
842             |
843             |If a the primary key column C<[% table.pk %]> is not provided to the
844             |constructor (or it is false) the object returned will have
845             |C<[% table.pk %]> set to the new unique identifier.
846             |
847             |Returns the object itself as a convenience, or throws an exception
848             |on error, typically from the L layer.
849             |
850             [% END %]
851             [% IF method.delete %]
852             |=head2 delete
853             |
854             | # Delete a single instantiated object
855             | $object->delete;
856             |
857             | # Delete multiple rows from the [% table.name %] table
858             | [%+ pkg %]->delete('where [% table.pk %] > ?', 1000);
859             |
860             |The C method can be used in a class form and an instance form.
861             |
862             |When used on an existing B<[% pkg %]> instance, the C method
863             |removes that specific instance from the C<[% table.name %]>, leaving
864             |the object intact for you to deal with post-delete actions as you wish.
865             |
866             |When used as a class method, it takes a compulsory argument of a SQL
867             |phrase to be added after the C section
868             |of the query, followed by variables to be bound to the placeholders
869             |in the SQL phrase. Any SQL that is compatible with SQLite can be used
870             |in the parameter.
871             |
872             |Returns true on success or throws an exception on error, or if you
873             |attempt to call delete without a SQL condition phrase.
874             |
875             [% END %]
876             [% IF method.truncate %]
877             |=head2 truncate
878             |
879             | # Delete all records in the [% table.name %] table
880             | [%+ pkg %]->truncate;
881             |
882             |To prevent the common and extremely dangerous error case where
883             |deletion is called accidentally without providing a condition,
884             |the use of the C method without a specific condition
885             |is forbidden.
886             |
887             |Instead, the distinct method C is provided to delete
888             |all records in a table with specific intent.
889             |
890             |Returns true, or throws an exception on error.
891             |
892             [% END %]
893             |=head1 ACCESSORS
894             |
895             [% pk = table.pk %]
896             [% IF method.$pk %]
897             |=head2 [% pk %]
898             |
899             | if ( $object->[% pk %] ) {
900             | print "Object has been inserted\n";
901             | } else {
902             | print "Object has not been inserted\n";
903             | }
904             |
905             |Returns true, or throws an exception on error.
906             |
907             [% END %]
908             |REMAINING ACCESSORS TO BE COMPLETED
909             |
910             |=head1 SQL
911             |
912             |The [% table.name %] table was originally created with the
913             |following SQL command.
914             |
915             |[%+ table.create | indent(' ') -%]
916             |
917             |=head1 SUPPORT
918             |
919             |[%+ pkg %] is part of the L<[% root %]> API.
920             |
921             |See the documentation for L<[% root %]> for more information.
922             |
923             [% IF self.author_pod %]
924             |=head1 AUTHOR
925             |
926             |[%+ self.author_pod %]
927             |
928             [% END %]
929             |=head1 COPYRIGHT
930             |
931             |Copyright [% self.copyyear %] [%+ self.author %].
932             |
933             |This program is free software; you can redistribute
934             |it and/or modify it under the same terms as Perl itself.
935             |
936             |The full text of the license can be found in the
937             |LICENSE file included with this module.
938             |
939             END_TT
940              
941             1;
942              
943             =pod
944              
945             =head1 SUPPORT
946              
947             Bugs should be reported via the CPAN bug tracker at
948              
949             L
950              
951             For other issues, contact the author.
952              
953             =head1 AUTHOR
954              
955             Adam Kennedy Eadamk@cpan.orgE
956              
957             =head1 COPYRIGHT
958              
959             Copyright 2009 - 2011 Adam Kennedy.
960              
961             This program is free software; you can redistribute
962             it and/or modify it under the same terms as Perl itself.
963              
964             The full text of the license can be found in the
965             LICENSE file included with this module.
966              
967             =cut