File Coverage

Relations.pm
Criterion Covered Total %
statement 119 135 88.1
branch 40 62 64.5
condition 9 18 50.0
subroutine 21 21 100.0
pod 20 20 100.0
total 209 256 81.6


line stmt bran cond sub pod time code
1             # This package contains some generalized functions for
2             # dealing with databases and queries. It serves as the
3             # base module for all other Relations packages.
4              
5             package Relations;
6             require Exporter;
7             require 5.004;
8              
9             # You can run this file through either pod2man or pod2html to produce pretty
10             # documentation in manual or html file format (these utilities are part of the
11             # Perl 5 distribution).
12              
13             # Copyright 2001 GAF-3 Industries, Inc. All rights reserved.
14             # Written by George A. Fitch III (aka Gaffer), gaf3@gaf3.com
15              
16             # This program is free software, you can redistribute it and/or modify it under
17             # the same terms as Perl istelf
18              
19             $Relations::VERSION='0.95';
20              
21             @ISA = qw(Exporter);
22              
23             @EXPORT = qw(
24             rearrange
25             delimit_clause
26             as_clause
27             equals_clause
28             comma_clause
29             assign_clause
30             add_as_clause
31             add_equals_clause
32             add_comma_clause
33             add_assign_clause
34             set_as_clause
35             set_equals_clause
36             set_comma_clause
37             set_assign_clause
38             to_array
39             to_hash
40             add_array
41             add_hash
42             get_input
43             configure_settings
44             );
45              
46             @EXPORT_OK = qw(
47             rearrange
48             delimit_clause
49             as_clause
50             equals_clause
51             comma_clause
52             assign_clause
53             add_as_clause
54             add_equals_clause
55             add_comma_clause
56             add_assign_clause
57             set_as_clause
58             set_equals_clause
59             set_comma_clause
60             set_assign_clause
61             to_array
62             to_hash
63             add_array
64             add_hash
65             get_input
66             configure_settings
67             );
68              
69             %EXPORT_TAGS = ();
70              
71             # From here on out, be strict and clean.
72              
73 6     6   2439 use strict;
  6         11  
  6         12324  
74              
75              
76              
77             ### Rearranges arguments from either the straight ordered format, or named format,
78             ### into their respective variables.
79              
80             ### This code was modified from the standard CGI module by Lincoln D. Stein
81              
82             sub rearrange {
83              
84             ### First we're going to get whatever's sent and make sure there's
85             ### something to parse
86              
87             # Get how to order of the arguments and the arguments themselves.
88              
89 27     27 1 115 my ($order,@param) = @_;
90              
91             # Return unless there's something to parse.
92              
93 27 50       110 return () unless @param;
94              
95             ### Second, we're going to format whatever's sent in an array, with the
96             ### even members being the keys, and the odd members being the values.
97             ### If the caller just sent the argument in the order the function
98             ### requires without names, we'll just return those values in their.
99             ### sent order.
100            
101             # If the first parameter is a hash.
102              
103 27 100       69 if (ref($param[0]) eq 'HASH') {
104              
105             # Then we have to change it to an array, with the evens = keys,
106             # odds = values.
107              
108 2         4 @param = %{$param[0]};
  2         10  
109              
110             }
111              
112             # If it's not a hash
113            
114             else {
115              
116             # Then return the values array as is, unless the first member of the array
117             # is preceeded by a '-', which would be indicated of a named parameters
118             # calling style, i.e. 'function(-name => $value)'.
119              
120 25 100 66     200 return @param unless (defined($param[0]) && substr($param[0],0,1) eq '-');
121              
122             }
123              
124             ### Third, we're going to figure out the where each arguments value is to
125             ### go in the array returned.
126              
127             # Declare some locals (Howdy folks!) to figure out the order in which to
128             # return the argument values.
129              
130 3         6 my ($i,%pos);
131              
132             # Initialize count
133              
134 3         5 $i = 0;
135              
136             # Go through each value in the order array
137              
138 3         6 foreach (@$order) {
139              
140             # The order of this argument name is the current location of the counter.
141              
142 9         17 $pos{uc $_} = $i;
143              
144             # Increase the counter to the next position.
145              
146 9         15 $i++;
147              
148             }
149              
150             ### Fourth, we're going insert the argument values into the return array in
151             ### their proper order, and then send the results array on it's way.
152              
153             # Declare the array that will return the argument values in there proper
154             # order.
155              
156 3         4 my (@result);
157              
158             # Preextend the results array to match the length of the order aray. I
159             # guess this speeds things up a bit.
160              
161 3         8 $#result = $#$order; # preextend
162              
163             # While there's arguments and values left to parse.
164              
165 3         7 while (@param) {
166              
167             # The argument's name is the even member (zero is even, right?)
168              
169 9         32 my $key = uc(shift(@param));
170              
171             # Take out the '-' preceeding the name of the argument
172              
173 9         24 $key =~ s/^\-//;
174              
175             # If we calculated a position for this argument name.
176              
177 9 50       21 if (exists $pos{$key}) {
178              
179             # Then store the arguments value at the arguments proper position in the
180             # result array.
181              
182 9         27 $result[$pos{$key}] = shift(@param);
183              
184             }
185              
186             }
187              
188             # Return the array of arugments' values.
189              
190 3         16 @result;
191              
192             }
193              
194              
195              
196             ### This routine is used for concatenting hashes, arrays and (leaving alone)
197             ### strings to be used in different clauses within an SQL statement.
198             ### If sent a hash, the key-value pairs will be concatentated with the minor
199             ### string those pairs will be concatenated with the major string, and
200             ### that string returned. If an array is sent, the members of the array
201             ### will be concatenated with the major string, and that string returned.
202             ### If a string is sent, that string will be returned.
203              
204             sub delimit_clause {
205              
206             # Get delimitters passed
207              
208 16     16 1 48 my ($minor) = shift;
209 16         16 my ($major) = shift;
210 16         20 my ($reverse) = shift;
211              
212             # Declare the various form of the sent clause
213              
214 16         17 my (%clause,@clause,$clause);
215              
216             ### First, figure out whether we were passed a hash ref, an array ref
217             ### or string.
218              
219             # Create a hash from the next argument hash reference, if next the
220             # argument is in fact a hash reference.
221              
222 16 100       36 %clause = %{$_[0]} if (ref($_[0]) eq 'HASH');
  14         45  
223              
224             # Create an array from the clause_info array reference, if next the
225             # argument is in fact an array reference.
226              
227 16 100       40 @clause = @{$_[0]} if (ref($_[0]) eq 'ARRAY');
  1         3  
228              
229             # Create a string from clause_info string, unless we
230             # already determined it was a hash or array.
231              
232 16 100 100     78 $clause = $_[0] unless (%clause || @clause);
233              
234             ### Second concatenate, we're appropriate. Hash ref's use the key-value
235             ### to establish a relationship, like equals, as, etc., and each pair
236             ### represents a piece of the clause, like something between and's in
237             ### a where clause. Array ref's have each member being a piece of the
238             ### clause. Strings are all the pieces of the clause concanated together.
239              
240             # Go through the keys and values, adding to the array to make it seem
241             # we were really passed an array.
242              
243 16         35 foreach my $key (keys %clause) {
244              
245             # Unless we're supposed to reverse the order, like in a select or
246             # from clause
247              
248 20 100       63 push @clause, $reverse ? "$clause{$key}$minor$key" : "$key$minor$clause{$key}";
249              
250             }
251              
252             # If the clause array has members, meaning we were passed an array
253             # ref of clause info, (or made to think that we were), concatenate
254             # the array into a string, as if we were really passed a string.
255              
256 16 100       56 $clause = join $major, @clause if (scalar @clause);
257              
258             # Return the string since that's all we were passed, (or made to think
259             # we were).
260              
261 16         65 return $clause;
262              
263             }
264              
265              
266              
267             ### Builds the meat for a select or from clause of an SQL
268             ### statement.
269              
270             sub as_clause {
271              
272             # Get the clause to be as'ed
273              
274 3     3 1 14 my ($as) = shift;
275              
276             # If there's something to delimit return the proper clause
277             # manimpulation
278            
279 3 50       12 return delimit_clause(' as ',',',1,$as) if defined($as);
280              
281             # If where here, than there's nothing to
282             # delimit. So return that.
283              
284 0         0 return '';
285              
286             }
287              
288              
289              
290             ### Builds the meat for a where or having clause of an
291             ### SQL statment. Concats with and, not or.
292              
293             sub equals_clause {
294              
295             # Get the clause to be equals'ed
296              
297 3     3 1 12 my ($equals) = shift;
298              
299             # If there's something to delimit, return the proper
300             # clause manimpulation
301              
302 3 50       11 return delimit_clause('=',' and ',0,$equals) if defined($equals);
303              
304             # If where here, than there's nothing to
305             # delimit.
306              
307 0         0 return '';
308              
309             }
310              
311              
312              
313             ### Builds the meat for a group by, order by, or limit
314             ### clause of an SQL statement. You can send it a hash,
315             ### but the order could be changed. That's why you
316             ### should only send it an array or string.
317              
318             sub comma_clause {
319              
320             # Get the clause to be comma'ed
321              
322 3     3 1 10 my ($comma) = shift;
323              
324             # If there's something to delimit, return the proper
325             # clause manimpulation
326            
327 3 50       12 return delimit_clause(',',',',0,$comma) if defined($comma);
328              
329             # If where here, than there's nothing to
330             # delimit.
331              
332 0         0 return '';
333              
334             }
335              
336              
337              
338             ### Builds the meat for a set clause of an SQL
339             ### statement.
340              
341             sub assign_clause {
342              
343             # Get the clause to be assign'ed
344              
345 3     3 1 11 my ($assign) = shift;
346              
347             # If there's something to delimit, return the
348             # proper clause manimpulation
349              
350 3 50       11 return delimit_clause('=',',',0,$assign) if defined($assign);
351              
352             # If where here, than there's nothing to
353             # delimit.
354              
355 0         0 return '';
356              
357             }
358              
359              
360              
361             ### Add the meat for a select or from clause of
362             ### an SQL statement.
363              
364             sub add_as_clause {
365              
366             # Get the clause to be add as'ed
367              
368 1     1 1 11 my ($as) = shift;
369 1         3 my ($add_as) = shift;
370              
371             # If there's something to add and there's
372             # something already there, return what's
373             # there, plus a comma, plus what's to be
374             # added.
375              
376 1 50 33     15 return $as . ',' . as_clause($add_as) if defined($add_as) && length($as);
377              
378             # If there's still something to add, but
379             # nothing already there, return what's to
380             # be added.
381              
382 0 0       0 return as_clause($add_as) if defined($add_as);
383            
384             # If we're here than there's nothing
385             # to be added so just return what's
386             # already there.
387              
388 0         0 return $as;
389              
390             }
391              
392              
393              
394             ### Add the meat for a where or having clause of
395             ### an SQL statement.
396              
397             sub add_equals_clause {
398              
399             # Get the clause to be add equals'ed
400              
401 1     1 1 10 my ($equals) = shift;
402 1         2 my ($add_equals) = shift;
403              
404             # If there's something to add, and there's
405             # something already there, return what's there,
406             # plus an and, plus what's to be added.
407              
408 1 50 33     10 return $equals . ' and ' . equals_clause($add_equals) if defined($add_equals) && length($equals);
409              
410             # If we're here than there's nothing
411             # already there so just return what's
412             # to be added.
413              
414 0 0       0 return equals_clause($add_equals) if defined($add_equals);
415            
416             # If we're here than there's nothing
417             # to be added so just return what's
418             # already there.
419              
420 0         0 return $equals;
421              
422             }
423              
424              
425              
426             ### Add the meat for a order by, group by, or
427             ### limit clause of an SQL statement.
428              
429             sub add_comma_clause {
430              
431             # Get the clause to be add comma'ed
432              
433 1     1 1 8 my ($comma) = shift;
434 1         2 my ($add_comma) = shift;
435              
436             # If there's something to add and there's
437             # something already there, return what's
438             # there, plus a comma, plus what's to be
439             # added.
440              
441 1 50 33     11 return $comma . ',' . comma_clause($add_comma) if defined($add_comma) && length($comma);
442              
443             # If we're here than there's nothing
444             # already there so just return what's
445             # to be added.
446              
447 0 0       0 return comma_clause($add_comma) if defined($add_comma);
448              
449             # If we're here than there's nothing
450             # to be added so just return what's
451             # already there.
452              
453 0         0 return $comma;
454              
455             }
456              
457              
458              
459             ### Add the meat for a set caluse of an SQL statement.
460              
461             sub add_assign_clause {
462              
463             # Get the clause to be add assign'ed
464              
465 1     1 1 9 my ($assign) = shift;
466 1         2 my ($add_assign) = shift;
467              
468             # If there's something to add, and there's
469             # something already there, return what's there,
470             # plus a comma, plus what's to be added.
471              
472 1 50 33     8 return $assign . ',' . assign_clause($add_assign) if defined($add_assign) && length($assign);
473              
474             # If we're here than there's nothing
475             # already there so just return what's
476             # to be added.
477              
478 0 0       0 return assign_clause($add_assign) if defined($add_assign);
479              
480             # If we're here than there's nothing
481             # to be added so just return what's
482             # already there.
483              
484 0         0 return $assign;
485              
486             }
487              
488              
489              
490             ### Sets the meat for a set clause of an SQL statement.
491             ### If there's something to be set, it overrides what's
492             ### already there. If there's nothing to set, it'll
493             ### leave what's there alone.
494              
495             sub set_as_clause {
496              
497             # Get the clause to be set as'ed
498              
499 1     1 1 12 my ($as) = shift;
500 1         2 my ($set_as) = shift;
501              
502             # If there's something to set, just
503             # return what's to be set.
504              
505 1 50       5 return as_clause($set_as) if defined($set_as);
506            
507             # If we're here than there's nothing
508             # to be set so just return what's
509             # already there.
510              
511 0         0 return $as;
512              
513             }
514              
515              
516              
517             ### Sets the meat for a where or having clause of
518             ### an SQL statement. If there's something to be
519             ### set, it overrides what's already there. If
520             ### there's nothing to set, it'll leave what's there
521             ### alone.
522              
523             sub set_equals_clause {
524              
525             # Get the clause to be set equals'ed
526              
527 1     1 1 7 my ($equals) = shift;
528 1         2 my ($set_equals) = shift;
529              
530             # If there's something to set, just
531             # return what's to be set.
532              
533 1 50       14 return equals_clause($set_equals) if defined($set_equals);
534              
535             # If we're here than there's nothing
536             # to be set so just return what's
537             # already there.
538              
539 0         0 return $equals;
540              
541             }
542              
543              
544              
545             ### Sets the meat for a order by, group by, or
546             ### limit clause of an SQL statement. If there's
547             ### something to be set, it overrides what's
548             ### already there. If there's nothing to set, it'll
549             ### leave what's there alone.
550              
551             sub set_comma_clause {
552              
553             # Get the clause to be set comma'ed
554              
555 1     1 1 7 my ($comma) = shift;
556 1         21 my ($set_comma) = shift;
557              
558             # If there's something to set,
559             # return what's to be set.
560              
561 1 50       6 return comma_clause($set_comma) if defined($set_comma);
562            
563             # If we're here than there's nothing
564             # to be set so just return what's
565             # already there.
566              
567 0         0 return $comma;
568              
569             }
570              
571              
572              
573             ### Sets the meat for a set clause of an SQL statement.
574             ### If there's something to be set, it overrides what's
575             ### already there. If there's nothing to set, it'll
576             ### leave what's there alone.
577              
578             sub set_assign_clause {
579              
580             # Get the clause to be set assign'ed
581              
582 1     1 1 8 my ($assign) = shift;
583 1         2 my ($set_assign) = shift;
584              
585             # If there's something to set,
586             # return what's to be set.
587              
588 1 50       4 return assign_clause($set_assign) if defined($set_assign);
589            
590             # If we're here than there's nothing
591             # to be set so just return what's
592             # already there.
593              
594 0         0 return $assign;
595              
596             }
597              
598              
599              
600             ### Takes a delimitted string or array ref and
601             ### returns an array ref. If an array ref is sent,
602             ### a copy of the array is returned, not the
603             ### original array.
604              
605             sub to_array {
606              
607             # Grab the value sent and what to split by only
608             # if split was sent. Else split by a comma.
609              
610 7     7 1 44 my $value = shift;
611 7 100       13 my $split = scalar @_ ? shift : ',';
612              
613             # Declare the return array. Set it to the $value
614             # if $value's a ref, else split $value by commas.
615              
616 7 100       62 my @value = ref($value) ? @$value : split $split, $value;
617              
618             # Return the array refence
619            
620 7         17 return \@value;
621              
622             }
623              
624              
625              
626             ### Takes a delimitted string, array ref or hash ref
627             ### and returns a hash ref. The hash reference will
628             ### have the individual values as keys with their
629             ### values set to true. If an hash ref is sent, a
630             ### copy of the hash is returned, not the original
631             ### hash.
632              
633             sub to_hash {
634              
635             # Grab the value sent and what to split by only
636             # if split was sent. Else split by a comma.
637              
638 5     5 1 40 my $value = shift;
639 5 100       12 my $split = scalar @_ ? shift : ',';
640              
641             # Declare the hash to send back.
642              
643 5         6 my %value = ();
644              
645             # Unless it's a hash reference
646              
647 5 100       9 unless (ref($value) eq 'HASH') {
648              
649             # Assume its a comma delimitted string or an
650             # array ref and send it to to_array
651              
652 3         5 $value = to_array($value,$split);
653              
654             # Go through each one, settting the
655             # key's value to true.
656              
657 3         5 foreach my $key (@{$value}) {
  3         6  
658              
659 9         18 $value{$key} = 1;
660              
661             }
662              
663             } else {
664              
665             # Dump the sent hash into our hash
666              
667 2         6 %value = %$value;
668              
669             }
670              
671             # Return the hash refence
672            
673 5         15 return \%value;
674              
675             }
676              
677              
678              
679             ### Takes two array refs and places one onto the
680             ### end of the other
681              
682             sub add_array {
683              
684             # Grab the arrays sent.
685              
686 1     1 1 12 my $value = shift;
687 1         9 my $adder = shift;
688              
689             # Push the adder onto the value
690              
691 1         2 push @{$value},@{$adder};
  1         2  
  1         3  
692              
693             # Return the value
694            
695 1         4 return $value;
696              
697             }
698              
699              
700              
701             ### Takes two hash refs and adds the key value pairs
702             ### from one to the other.
703              
704             sub add_hash {
705              
706             # Grab the hashes sent.
707              
708 1     1 1 9 my $value = shift;
709 1         2 my $adder = shift;
710              
711             # Go through each adder key
712              
713 1         1 foreach my $add (keys %{$adder}) {
  1         28  
714              
715 1         4 $value->{$add} = $adder->{$add};
716              
717             }
718              
719             # Return the value
720            
721 1         3 return $value;
722              
723             }
724              
725              
726              
727             ### Asks a question, gets input from the user,
728             ### cleans the input, and return the input if
729             ### given by the user, else returns the defaults
730             ### value.
731              
732             sub get_input {
733              
734             # Get the arguments sent.
735              
736 20     20 1 63 my ($question,
737             $default) = rearrange(['QUESTION',
738             'DEFAULT'],@_);
739              
740             # Ask the question, get the answer, and
741             # clean the answer.
742              
743 20         79 print "$question [$default]:";
744 20         170 my $answer = ;
745 20         32 chomp $answer;
746              
747             # If an answer was given, return it, else
748             # return the default.
749              
750 20 100       114 return length($answer) ? $answer : $default;
751              
752             }
753              
754              
755              
756             ### Creates a default database settings module.
757             ### Takes in the defaults, prompts the user for
758             ### info. If the user sends info, that's used.
759             ### Once the settings are determined, it creates
760             ### a Settings.pm file in the current direfctory.
761              
762             sub configure_settings {
763              
764             # Get the defaults sent. These we be used if
765             # the user just hits return for each one.
766              
767 3     3 1 26 my ($def_database,
768             $def_username,
769             $def_password,
770             $def_host,
771             $def_port) = rearrange(['DATABASE',
772             'USERNAME',
773             'PASSWORD',
774             'HOST',
775             'PORT'],@_);
776              
777             # Declare the actual values to
778              
779 3         10 my ($database,$username,$password,$host,$port,$confirm);
780              
781             # Prompt the user for each value
782              
783 3         97 print "
784             Before we can get started, I need to know some
785             info about your MySQL settings. Please fill in
786             the blanks below. To accept the default values
787             in the []'s, just hit return.
788             ";
789              
790 3         12 print "
791             MYSQL DATABASE NAME
792             Make sure the database isn't the same as the name
793             as an existing database of yours, since the this
794             script will delete that database when run.
795             ";
796              
797 3         16 $database = get_input("\nDatabase name",$def_database);;
798              
799 3         10 print "
800             MYSQL USERNAME AND PASSWORD
801             Make sure the this username password account can
802             create and destroy databases.
803             ";
804              
805 3         9 $username = get_input("\nUsername",$def_username);;
806 3         11 $password = get_input("\nPassword",$def_password);;
807              
808 3         8 print "
809             MYSQL HOST AND PORT
810             Make sure the computer running the demo can connect to
811             this host and port, or this script will not function
812             properly.
813             ";
814              
815 3         11 $host = get_input("\nHost",$def_host);;
816 3         12 $port = get_input("\nPort",$def_port);;
817              
818             # Let the user know the defaults.
819              
820 3         17 print "
821             Using settings:
822             database: $database
823             username: $username
824             password: $password
825             host: $host
826             port: $port
827             ";
828              
829             # Double check with the user
830              
831 3         12 $confirm = get_input("\nCreate Settings.pm? (y/n)",'n');;
832              
833 3 100       15 die "Settings configuration aborted" unless $confirm =~ /^y/i;
834              
835             # Create a Settings.pm file
836              
837 2         296 open SETTINGS, ">Settings.pm";
838              
839 2         36 print SETTINGS "\$database = '$database';\n";
840 2         8 print SETTINGS "\$username = '$username';\n";
841 2         8 print SETTINGS "\$password = '$password';\n";
842 2         9 print SETTINGS "\$host = '$host';\n";
843 2         6 print SETTINGS "\$port = '$port';\n";
844              
845 2           close SETTINGS;
846              
847             }
848              
849             $Relations::VERSION;
850              
851             __END__