File Coverage

blib/lib/MyLibrary/Librarian.pm
Criterion Covered Total %
statement 66 190 34.7
branch 25 90 27.7
condition 1 39 2.5
subroutine 10 13 76.9
pod 10 10 100.0
total 112 342 32.7


line stmt bran cond sub pod time code
1             package MyLibrary::Librarian;
2              
3 1     1   1642 use MyLibrary::DB;
  1         4  
  1         31  
4 1     1   6 use Carp;
  1         2  
  1         65  
5 1     1   6 use strict;
  1         2  
  1         1917  
6              
7             =head1 NAME
8              
9             MyLibrary::Librarian
10              
11              
12             =head1 SYNOPSIS
13              
14             # use the module
15             use MyLibrary::Librarian;
16            
17             # create a new librarian
18             my $librarian = MyLibrary::Librarian->new();
19            
20             # give the librarian characteristics
21             $librarian->name('Fred Kilgour');
22             $librarian->email('kilgour@oclc.org');
23             $librarian->telephone('1 (800) 555-1212');
24             $librarian->url('http://oclc.org/~kilgour/');
25            
26             # associate (classify) the librarian with term ids
27             $librarian->term_ids(new => [3, 614, 601]);
28              
29             # disassociate certain term ids from this librarian
30             $librarian->term_ids(del => [@del_term_ids]);
31              
32             # retrieve list of term ids with sort parameter
33             my @term_ids = $librarian->term_ids(sort => 'name');
34            
35             # save the librarian to the database; create a new record
36             $librarian->commit();
37            
38             # get the id of the current librarian object
39             $id = $librarian->id();
40            
41             # get a librarian based on an id
42             my $librarian = MyLibrary::Librarian->new(id => $id);
43            
44             # display information about the librarian
45             print ' ID: ', $librarian->id(), "\n";
46             print ' Name: ', $librarian->name(), "\n";
47             print ' Email: ', $librarian->email(), "\n";
48             print 'Telephone: ', $librarian->telephone(), "\n";
49             print ' URL: ', $librarian->url(), "\n";
50            
51             # retrieve complete, sorted list of librarian objects
52             my @librarians = MyLibrary::Librarian->get_librarians();
53            
54             # process each librarian
55             foreach my $l (@librarians) {
56            
57             # print each librarian's name and email address
58             print $l->name(), ' <', $l->email(), "> \n";
59            
60             }
61              
62              
63             =head1 DESCRIPTION
64              
65             Use this module to get and set the characteristics of librarians to a MyLibrary database. Characteristics currently include: ID (primary database key), name, email address, telephone number, home page URL, and a set of integers (primary database keys) denoting what terms the librarian has been classified under.
66              
67              
68             =head1 METHODS
69              
70             This section describes the methods available in the package.
71              
72              
73             =head2 new()
74              
75             Use this method to create a librarian object. Called with no options, this method creates an empty object. Called with an id option, this method uses the id as a database key and fills the librarian object with data from the underlying database.
76              
77             # create a new librarian object
78             my $librarian = MyLibrary::Librarian->new();
79            
80             # create a librarian object based on a previously existing ID
81             my $librarian = MyLibrary::Librarian->new(id => 3);
82              
83              
84             =head2 id()
85              
86             This method returns an integer representing the database key of the currently created librarian object.
87              
88             # get id of current librarian object
89             my $id = $librarian->id();
90              
91             You cannot set the id attribute.
92              
93              
94             =head2 name()
95              
96             This method gets and sets the name from the librarian from the current librarian object:
97              
98             # get the name of the current librarian object
99             my $name = $librarian->name();
100            
101             # set the current librarian object's name
102             $librarian->name('Melvile Dewey');
103            
104              
105             =head2 telephone()
106              
107             Use this method to get and set the telephone number of the current librarian object:
108              
109             # get the telephone number
110             my $phone = $librarian->telephone();
111            
112             # set the current librarian object's telephone number
113             $librarian->telephone('1 (800) 555-1212');
114              
115              
116             =head2 email()
117              
118             Like the telephone and name methods, use this method to get and set the librarian object's email attribute:
119              
120             # get the email address
121             my $email_address = $librarian->email();
122            
123             # set the current librarian object's email address
124             $librarian->email('info@library.org');
125              
126              
127             =head2 url()
128              
129             Set or get the URL attribute of the librarian object using this method:
130              
131             # get the URL attribute
132             my $home_page = $librarian->url();
133            
134             # set the URL
135             $librarian->url('http://dewey.library.nd.edu/');
136            
137              
138             =head2 term_ids()
139              
140             This method gets and sets the term ids with which this libraian object is associated. Given no input, it returns a list of integers or undef if no term associations exist. Any input given is expected to be a list of integers. Related terms can be added or deleted given the correct input parameter. The returned list of term ids can be sorted by name using the sort parameter.
141              
142             # set the term id's
143             $librarian->term_ids(new => [33, 24, 83]);
144            
145             # get the term id's of the current librarian object
146             my @ids = $librarian->term_ids();
147              
148             # get the term id's of the current librarian object sorted by name
149             my @ids = $librarian->term_ids(sort => 'name');
150            
151             # require the Term package
152             use MyLibrary::Term;
153            
154             # process each id
155             foreach my $i (@ids) {
156            
157             # create a term object
158             my $term->MyLibrary::Term->new(id => $i);
159            
160             # print the term associated with the librarian object
161             print $librarian->name, ' has been classified with the term: ', $term->name, ".\n";
162            
163             }
164              
165             # remove term associations
166             $librarian->term_ids(del => [@removed_term_ids]);
167            
168             =head2 commit()
169              
170             Use this method to save the librarian object's attributes to the underlying database. If the object's data has never been saved before, then this method will create a new record in the database. If you used the new and passed it an id option, then this method will update the underlying database.
171              
172             This method will return true upon success.
173              
174             # save the current librarian object to the underlying database
175             $librarian->commit();
176              
177              
178             =head2 delete()
179              
180             This method simply deletes the current librarian object from the underlying database.
181              
182             # delete (drop) this librarian from the database
183             $librarian->delete();
184            
185            
186             =head2 get_librarians()
187              
188             Use this method to get all the librarians from the underlying database sorted by their name. This method returns an
189             array of objects enabling you to loop through each object in the array and subsequent characteristics of each object;
190              
191             # get all librarians
192             my @librarians = MyLibrary::Librarian->get_librarians();
193            
194             # process each librarian
195             foreach my $l (@librarians) {
196            
197             # print the name
198             print $l->name, "\n";
199            
200             }
201              
202              
203             =head1 ACKNOWLEDGEMENTS
204              
205             I would like to thank the following people for providing input on how this package can be improved: Brian Cassidy and Ben Ostrowsky.
206              
207              
208             =head1 AUTHORS
209              
210             Eric Lease Morgan
211             Robert Fox
212              
213              
214             =head1 HISTORY
215              
216             September 29, 2003 - first public release.
217             April, 2004 - many modifications.
218              
219             =cut
220              
221              
222             sub new {
223              
224             # declare local variables
225 1     1 1 855 my ($class, %opts) = @_;
226 1         3 my $self = {};
227 1         2 my @term_ids = ();
228              
229             # check for an id
230 1 50       6 if ($opts{id}) {
231            
232             # check for valid input, an integer
233 0 0       0 if ($opts{id} =~ /\D/) {
234            
235             # output an error and return nothing
236 0         0 croak "The id passed as input to the new method must be an integer: id = $opts{id} ";
237            
238             }
239            
240             # get a handle
241 0         0 my $dbh = MyLibrary::DB->dbh();
242            
243             # find this record
244 0         0 my $rv = $dbh->selectrow_hashref('SELECT * FROM librarians WHERE librarian_id = ?', undef, $opts{id});
245            
246 0 0       0 if (ref($rv) eq "HASH") {
247 0         0 $self = $rv;
248 0         0 $self->{term_ids} = $dbh->selectcol_arrayref("SELECT term_id FROM terms_librarians WHERE librarian_id = " . $opts{id});
249             } else {
250 0         0 return;
251             }
252            
253             }
254            
255             # return the object
256 1         4 return bless ($self, $class);
257            
258             }
259              
260              
261             sub id {
262              
263 0     0 1 0 my $self = shift;
264 0         0 return $self->{librarian_id};
265              
266             }
267              
268              
269             sub telephone {
270              
271             # declare local variables
272 2     2 1 4 my ($self, $telephone) = @_;
273            
274             # check for the existence of a telephone number
275 2 100       9 if ($telephone) { $self->{telephone} = $telephone }
  1         2  
276            
277             # return it
278 2         7 return $self->{telephone};
279            
280             }
281              
282              
283             sub name {
284              
285             # declare local variables
286 2     2 1 544 my ($self, $name) = @_;
287            
288             # check for the existence of a name
289 2 100       5 if ($name) { $self->{name} = $name }
  1         8  
290            
291             # return it
292 2         8 return $self->{name};
293            
294             }
295              
296              
297             sub email {
298              
299             # declare local variables
300 2     2 1 3 my ($self, $email) = @_;
301            
302             # check for the existence of an email address
303 2 100       6 if ($email) { $self->{email} = $email }
  1         2  
304            
305             # return it
306 2         5 return $self->{email};
307            
308             }
309              
310              
311             sub term_ids {
312              
313             # get myself and then the ids
314 1     1 1 2 my $self = shift;
315 1         3 my %opts = @_;
316 1         2 my @new_related_terms;
317 1 50       4 if ($opts{new}) {
318 1         2 @new_related_terms = @{$opts{new}};
  1         3  
319             }
320 1         2 my @del_related_terms;
321 1 50       4 if ($opts{del}) {
322 0         0 @del_related_terms = @{$opts{del}};
  0         0  
323             }
324 1         4 my $sort_type;
325 1 50       4 if ($opts{sort}) {
326 0 0       0 if ($opts{sort} eq 'name') {
327 0         0 $sort_type = 'name';
328             }
329             }
330 1         1 my @related_terms;
331             my $strict_relations;
332 1 50       4 if ($opts{strict}) {
333 1 50 0     5 if ($opts{strict} eq 'on') {
    50 0        
    0 0        
      0        
334 0         0 $strict_relations = 'on';
335             } elsif ($opts{strict} eq 'off') {
336 1         2 $strict_relations = 'off';
337             } elsif (($opts{strict} !~ /^\d$/ && ($opts{strict} == 1 || $opts{strict} == 0)) || $opts{strict} ne 'off' || $opts{strict} ne 'on') {
338 0         0 $strict_relations = 'on';
339             } else {
340 0         0 $strict_relations = $opts{strict};
341             }
342             } else {
343 0         0 $strict_relations = 'on';
344             }
345              
346 1 50       2 if (@new_related_terms) {
347 1         2 TERMS: foreach my $new_related_term (@new_related_terms) {
348 3 50       14 if ($new_related_term !~ /^\d+$/) {
349 0         0 croak "Only numeric digits may be submitted as term ids for librarian relations. $new_related_term submitted.";
350             }
351 3 50       6 if ($strict_relations eq 'on') {
352 0         0 my $dbh = MyLibrary::DB->dbh();
353 0         0 my $term_list = $dbh->selectcol_arrayref('SELECT term_id FROM terms');
354 0         0 my $found_term;
355 0         0 TERM_VAL: foreach my $term_list_val (@$term_list) {
356 0 0       0 if ($term_list_val == $new_related_term) {
357 0         0 $found_term = 1;
358 0         0 last TERM_VAL;
359             } else {
360 0         0 $found_term = 0;
361             }
362             }
363 0 0       0 if ($found_term == 0) {
364 0         0 next TERMS;
365             }
366             }
367 3         3 my $found;
368 3 100       7 if ($self->{term_ids}) {
369 2         2 TERMS_PRESENT: foreach my $related_term (@{$self->{term_ids}}) {
  2         5  
370 3 50       6 if ($new_related_term == $related_term) {
371 0         0 $found = 1;
372 0         0 last TERMS_PRESENT;
373             } else {
374 3         5 $found = 0;
375             }
376             }
377             } else {
378 1         2 $found = 0;
379             }
380 3 50       7 if ($found) {
381 0         0 next TERMS;
382             } else {
383 3         3 push(@{$self->{term_ids}}, $new_related_term);
  3         8  
384             }
385             }
386             }
387 1 50       3 if (@del_related_terms) {
388 0         0 foreach my $del_related_term (@del_related_terms) {
389 0         0 my @terms = @{$self->{term_ids}};
  0         0  
390 0         0 my $j = scalar(@{$self->{term_ids}});
  0         0  
391 0         0 for (my $i = 0; $i < scalar(@{$self->{term_ids}}); $i++) {
  0         0  
392 0 0       0 if ($self->{term_ids}[$i] == $del_related_term) {
393 0         0 splice(@{$self->{term_ids}}, $i, 1);
  0         0  
394 0         0 $i = $j;
395             }
396             }
397             }
398             }
399            
400             # return a dereferenced array
401 1 50 33     15 if (ref($self->{term_ids}) eq "ARRAY" && scalar(@{$self->{term_ids}}) >= 1) {
  1         8  
402 1 50       3 if ($sort_type) {
403 0 0       0 if ($sort_type eq 'name') {
404 0         0 my $dbh = MyLibrary::DB->dbh();
405 0         0 my $term_id_string;
406 0         0 foreach my $term_id (@{$self->{term_ids}}) {
  0         0  
407 0         0 $term_id_string .= "$term_id, ";
408             }
409 0         0 chop($term_id_string);
410 0         0 chop($term_id_string);
411 0         0 $self->{term_ids} = $dbh->selectcol_arrayref("SELECT term_id from terms WHERE term_id IN ($term_id_string) ORDER BY term_name");
412             }
413             }
414 1         1 return @{$self->{term_ids}};
  1         6  
415             } else {
416 0         0 return;
417             }
418             }
419              
420              
421             sub url {
422              
423             # declare local variables
424 2     2 1 3 my ($self, $url) = @_;
425            
426             # check for the existence of librarian's url
427 2 100       6 if ($url) { $self->{url} = $url }
  1         2  
428            
429             # return it
430 2         4 return $self->{url};
431            
432             }
433              
434              
435             sub commit {
436              
437             # get object
438 1     1 1 559 my $self = shift;
439              
440             # get a database handle
441 1         10 my $dbh = MyLibrary::DB->dbh();
442            
443             # see if the object has an id
444 0 0         if ($self->id()) {
445            
446             # update the librarians table with this id
447 0           my $return = $dbh->do('UPDATE librarians SET name = ?, telephone = ?, email = ?, url = ? WHERE librarian_id = ?', undef, $self->name(), $self->telephone(), $self->email(), $self->url(), $self->id());
448 0 0 0       if ($return > 1 || ! $return) { croak "Librarian update in commit() failed. $return records were updated." }
  0            
449              
450             # update librarian=>term relational integrity
451 0           my @term_ids = @{$self->{term_ids}};
  0            
452 0 0 0       if (scalar(@term_ids) > 0 && @term_ids) {
    0 0        
453 0           my $arr_ref = $dbh->selectall_arrayref('SELECT term_id FROM terms_librarians WHERE librarian_id =?', undef, $self->id());
454             # determine which term ids stay put
455 0 0         if (scalar(@{$arr_ref}) > 0) {
  0            
456 0           foreach my $arr_val (@{$arr_ref}) {
  0            
457 0           my $j = scalar(@term_ids);
458 0           for (my $i = 0; $i < $j; $i++) {
459 0 0         if ($arr_val->[0] == $term_ids[$i]) {
460 0           splice(@term_ids, $i, 1);
461 0           $i = $j;
462             }
463             }
464             }
465             }
466             # add the new associations
467 0           foreach my $term_id (@term_ids) {
468 0           my $return = $dbh->do('INSERT INTO terms_librarians (term_id, librarian_id) VALUES (?,?)', undef, $term_id, $self->id());
469 0 0 0       if ($return > 1 || ! $return) { croak "Unable to update librarian=>term relational integrity. $return row
  0            
470             s were inserted." }
471             }
472             # determine which term associations to delete
473 0           my @del_related_terms;
474 0           my @term_ids = @{$self->{term_ids}};
  0            
475 0 0         if (scalar(@{$arr_ref}) > 0) {
  0            
476 0           foreach my $arr_val (@{$arr_ref}) {
  0            
477 0           my $found;
478 0           for (my $i = 0; $i < scalar(@term_ids); $i++) {
479 0 0         if ($arr_val->[0] == $term_ids[$i]) {
480 0           $found = 1;
481 0           last;
482             } else {
483 0           $found = 0;
484             }
485             }
486 0 0         if (!$found) {
487 0           push (@del_related_terms, $arr_val->[0]);
488             }
489             }
490             }
491             # delete removed associations
492 0           foreach my $del_rel_term (@del_related_terms) {
493 0           my $return = $dbh->do('DELETE FROM terms_librarians WHERE term_id = ? AND librarian_id = ?', undef, $del_rel_term, $self->id());
494 0 0 0       if ($return > 1 || ! $return) { croak "Unable to delete librarian=>term association. $return rows were deleted." }
  0            
495             }
496             } elsif (scalar(@term_ids) <= 0 || !@term_ids) {
497 0           my $return = $dbh->do('DELETE FROM terms_librarians WHERE librarian_id = ?', undef, $self->id());
498             }
499            
500             } else {
501            
502             # get a new sequence
503 0           my $id = MyLibrary::DB->nextID();
504            
505             # create a new record
506 0           my $return = $dbh->do('INSERT INTO librarians (librarian_id, name, telephone, email, url) VALUES (?, ?, ?, ?, ?)', undef, $id, $self->name(), $self->telephone(), $self->email(), $self->url());
507 0 0 0       if ($return > 1 || ! $return) { croak 'Librarian commit() failed.'; }
  0            
508 0           $self->{librarian_id} = $id;
509            
510             # update librarian=>term relational integrity, if list of term ids was supplied via the constructor
511 0 0         unless (!$self->{term_ids}) {
512 0           my @term_ids = @{$self->{term_ids}};
  0            
513 0 0 0       if (scalar(@term_ids) > 0 && @term_ids) {
514 0           foreach my $term_id (@term_ids) {
515 0           my $return = $dbh->do('INSERT INTO terms_librarians (term_id, librarian_id) VALUES (?,?)', undef, $term_id, $self->id());
516 0 0 0       if ($return > 1 || ! $return) { croak "Unable to update librarian=>term relational integrity. $return rows were inserted." }
  0            
517             }
518             }
519             }
520            
521             }
522            
523             # done
524 0           return 1;
525             }
526              
527              
528             sub delete {
529              
530             # get myself
531 0     0 1   my $self = shift;
532              
533             # check for id
534 0 0         return 0 unless $self->{librarian_id};
535              
536             # delete this record
537 0           my $dbh = MyLibrary::DB->dbh();
538 0           my $rv = $dbh->do('DELETE FROM librarians WHERE librarian_id = ?', undef, $self->{librarian_id});
539 0 0         if ($rv != 1) { croak ("Delete failed. Deleted $rv records.") }
  0            
540              
541             # delete term associations
542 0           $rv = $dbh->do('DELETE FROM terms_librarians WHERE librarian_id = ?', undef, $self->{librarian_id});
543              
544             # done
545 0           return 1;
546              
547             }
548              
549              
550             sub get_librarians {
551              
552             # scope varibles
553 0     0 1   my $self = shift;
554 0           my @rv = ();
555            
556             # create and execute a query
557 0           my $dbh = MyLibrary::DB->dbh();
558 0           my $rows = $dbh->prepare('SELECT librarian_id FROM librarians ORDER BY name');
559 0           $rows->execute;
560            
561             # process each found row
562 0           while (my $r = $rows->fetchrow_array) {
563            
564             # fill up the return value
565 0           push(@rv, $self->new(id => $r));
566            
567             }
568            
569             # return the array
570 0           return @rv;
571            
572             }
573              
574              
575             # return true, or else
576             1;