File Coverage

blib/lib/DB2/db.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package DB2::db;
2              
3 2     2   88634 use diagnostics;
  2         451972  
  2         27  
4 2     2   968 use strict;
  2         5  
  2         82  
5 2     2   11 use warnings;
  2         9  
  2         69  
6 2     2   845 use DBI;
  0            
  0            
7             use Carp;
8             use List::MoreUtils qw(none);
9             use User::pwent;
10             use File::Spec;
11              
12             our $VERSION = '0.25';
13              
14             my %localDB;
15             our $debug = exists $ENV{DB2_db_debug} ? $ENV{DB2_db_debug} + 0 : undef;
16              
17             sub _debug
18             {
19             if ($debug)
20             {
21             if ($debug > 1)
22             {
23             require Carp;
24             local $Carp::CarpLevel = $Carp::CarpLevel + 1;
25             Carp::cluck(@_);
26             }
27             else
28             {
29             warn @_;
30             }
31             }
32             }
33              
34             =head1 NAME
35              
36             DB2::db - Framework wrapper around DBD::DB2 for a specific database
37              
38             =head1 SYNOPSIS
39              
40             package myDB;
41             use DB2::db
42             our @ISA = qw( DB2::db );
43              
44             ...
45              
46             use myDB;
47              
48             my $db = myDB->new;
49             my $tbl = $db->get_table('myTable');
50             my $row = $tbl->find($id);
51              
52             =head1 DESCRIPTION
53              
54             The DB2::db module can simplify your interaction with a DB2 database using
55             the DBI module. The cost is generally a little bit of speed since it
56             cannot know which columns you may be interested in. This is not always
57             bad since you may not know either.
58              
59             Please note that unlike many of the DBIx::* modules, this framework is
60             intended to create your tables (and database) as well as manage them. Most
61             DBIx modules will assume your tables are already created and leave the ability
62             to recreate your tables up to you. The design for DB2::db is intended to
63             allow you to develop on one machine and deploy on another with a little
64             less effort. In exchange, however, it can be significantly more
65             work to set up your perl scripts in the first place. That said, the extra
66             work in setting up your perl modules is probably only a little more than
67             the work it would require to create a DDL script to create all your tables.
68              
69             =head1 SETUP
70              
71             Prior to using your db object, you will need to set $ENV{DB2INSTANCE}.
72             This is so the DB2 driver will be able to figure out your instance. DB2::db
73             defaults to an instance called 'db2ee':
74              
75             BEGIN {$ENV{DB2INSTANCE} = 'db2ee' unless $ENV{DB2INSTANCE}};
76              
77             The default instance for DB2 is "db2inst1" on Unix, and "db2" on Windows.
78             Thus this default is equally wrong everywhere. If you want to change this
79             default outside of a BEGIN block, you must do so before creating your
80             DB2::db object.
81              
82             =cut
83              
84             BEGIN {$ENV{DB2INSTANCE} = 'db2ee' unless exists $ENV{DB2INSTANCE}};
85              
86             =head1 FUNCTIONS
87              
88             Some functions you have to override to get any meaningful use - these
89             are the generics of the framework. Others you may call. Yet others
90             should not be called at all.
91              
92             =over 4
93              
94             =item C
95              
96             Do not override this one. This will return a cached version of your
97             database object if there is one. Also known as the singleton approach.
98             If you need to initialise it, you're best off doing so after creation
99             in your own method.
100              
101             =cut
102              
103             sub new
104             {
105             my $class = shift;
106             $class = ref $class || $class || __PACKAGE__;
107              
108             return $localDB{$class} if ($localDB{$class});
109              
110             my $self = {};
111             bless $self, $class;
112              
113             (my $base_pkg = $class) =~ s/::[^:]+$//;
114             $self->{PKG_GROUP} = $base_pkg;
115             $self->setup_row_table_relationships();
116              
117             $localDB{$class} = $self;
118             }
119              
120             =item C
121              
122             Override this, returning the database name that will be connected to
123             with this object. Failure to override will result in a crash quickly.
124              
125             =cut
126              
127             sub db_name {
128             my $self = shift;
129             my %dsn = $self->_dsn();
130             $dsn{database} || confess 'need to override db_name or dsn'
131             }
132              
133             =item C
134              
135             Override this returning a hash with keys for database, host, and port
136             for constructing the dsn. Useful if the database may not be local.
137              
138             If you override dsn to just return C $db_name>, this should
139             be equivalent to overriding db_name. This can give more flexibility as
140             to which db to use - allowing you to use a remote db for production, but
141             a local db for development, for example.
142              
143             =cut
144              
145             # used to normalise values
146             sub _dsn
147             {
148             my $self = shift;
149             my %dsn = $self->dsn();
150             if (keys %dsn)
151             {
152             %dsn = map {
153             lc $_ => $dsn{$_}
154             } keys %dsn;
155              
156             # allow shortnames (as per odbc)
157             $dsn{database} ||= $dsn{db} if exists $dsn{db};
158             $dsn{hostname} ||= $dsn{host} if exists $dsn{host};
159              
160             $dsn{protocol} ||= 'TCPIP' if scalar keys %dsn > 1;
161             }
162             %dsn;
163             }
164              
165             sub dsn { () }
166              
167             =item C
168              
169             Override this if necessary. The default is no user, which will imply
170             that the current user (however that is defined for your platform) will
171             be the user for authentication purposes. Usually you will need to
172             get this information before creation of your database object.
173              
174             =cut
175              
176             sub user_name { undef }
177              
178             =item C
179              
180             Similar to C, override if necessary. Should be overridden
181             if user_name is overridden. Must return the unencrypted password.
182              
183             =cut
184              
185             sub user_pw { undef }
186              
187             =item C
188              
189             This is used for any connection-specific parameters needed for the
190             underlying DBD::DB2 object. The default is to turn off AutoCommit
191             (since this framework handles commits already). Example:
192              
193             sub connect_attr {
194             my $self = shift;
195             my %attr = (
196             %{$self->SUPER::connect_attr()},
197             LongReadLen => 102400,
198             );
199             \%attr;
200             }
201              
202             =cut
203              
204             sub connect_attr {
205             { AutoCommit => 0, PrintError => 1 }
206             }
207              
208             =item C
209              
210             Override this to tell DB2::db about your tables. Call
211             add_row_table_relationship once for each table (see its documentation
212             below).
213              
214             B The order will be preserved and used
215             when attempting to create the database. Ensure the tables are listed
216             in such an order that Cs always point to tables that will be
217             created before the current table.
218              
219             =cut
220              
221             sub setup_row_table_relationships
222             {
223             my $self = shift;
224             carp 'should override setup_row_table_relationships';
225             my $rln = $self->get_row_table_relationships();
226             for my $h (@$rln)
227             {
228             $self->add_row_table_relationship(%$h,IS_FULL_PKG_NAME => 1);
229             }
230             }
231              
232             =item C
233              
234             While initialising the row/table relationships, call this in the order of
235             the tables that would need to be created.
236              
237             $self->add_row_table_relationship(
238             ROW => 'MyRow',
239             TABLE => 'MyTable',
240             %other_options
241             )
242              
243             Do this once for each table you have.
244              
245             Note that if ROW is missing, it will be assumed to be the same as Table,
246             but with an R suffix. e.g., C<$self-Eadd_row_table_relationship(TABLE =E 'tbl')>
247             will assume that the Row's object type is C
248              
249             Other options include:
250              
251             =over 4
252              
253             =item IS_FULL_PKG_NAME
254              
255             If this is true, it is assumed that you have fully qualified your
256             package names for both the row and the table. Otherwise, the default
257             is to use the same package as your database object is in. For example,
258             if your object is in the package My (e.g., C), then specifying C
259             'MyRow'> implies C instead. This can save a bunch of typing if
260             you have a deeply-nested package tree, or if you decide to change the
261             package later.
262              
263             =item ROW_IS_FULL_PKG_NAME
264              
265             =item TABLE_IS_FULL_PKG_NAME
266              
267             Specific to the ROW and TABLE, respectively.
268              
269             =back
270              
271             =cut
272              
273             # Needs to be optimised better (part of the whole point, isn't it?)
274              
275             sub add_row_table_relationship
276             {
277             my $self = shift;
278             my $options = $_[0];
279             unless (ref $options and ref $options eq 'HASH')
280             {
281             $options = { @_ };
282             }
283              
284             $options->{TABLE} = $self->{PKG_GROUP} . '::' . $options->{TABLE}
285             unless $options->{IS_FULL_PKG_NAME} or $options->{TABLE_IS_FULL_PKG_NAME};
286             if ($options->{ROW})
287             {
288             $options->{ROW} = $self->{PKG_GROUP} . '::' . $options->{ROW}
289             unless $options->{IS_FULL_PKG_NAME} or $options->{ROW_IS_FULL_PKG_NAME};
290             }
291             else
292             {
293             $options->{ROW} = $options->{TABLE} . 'R';
294             }
295              
296             push @{$self->{RELN}{MASTER}}, { map { $_ => $options->{$_} } qw(ROW TABLE) };
297             }
298              
299             =item C
300              
301             Same as C, except that the first parameter is the
302             table name, and the rest are options. For example,
303              
304             $self->add_table("tbl", ROW => "tbl::row");
305              
306             is exactly the same as:
307              
308             $self->add_row_table_relationship(TABLE => "tbl", ROW => "tbl::row");
309              
310             Which means that if you follow conventions, you only need to specify:
311              
312             $self->add_table("tbl");
313              
314             if your row package is C. Order is still important. C
315             and C can be intermingled.
316              
317             =cut
318              
319             sub add_table
320             {
321             my $self = shift;
322             my $tbl = shift;
323             my %options = @_;
324             $options{TABLE} = $tbl;
325             $self->add_row_table_relationship(\%options);
326             }
327              
328             =item C
329              
330             And, finally, a shortcut to calling add_table repeatedly if you're just
331             using the defaults anyway.
332              
333             $self->add_tables(qw/
334             tbl1
335             tbl2
336             /);
337              
338             =cut
339              
340             sub add_tables
341             {
342             my $self = shift;
343             local $_;
344             $self->add_table($_) foreach @_;
345             }
346              
347             =item C
348              
349             B - Use setup_row_table_relationships instead.
350              
351             Override this with the DB2::Table/DB2::Row relationships. This will be
352             used to extrapolate what objects to create for each query. DB2::Table
353             objects will be instantiated as required, but no sooner.
354              
355             Format of expected output:
356             [
357             { ROW => 'Row_type_1', TABLE => 'Table_type_1' },
358             { ROW => 'Row_type_2', TABLE => 'Table_type_2' },
359             ]
360              
361             The order of these hashrefs is important. The order is used in
362             determining what order to create the tables during table creation in
363             C.
364              
365             I mean package names. "Classes" for you Java and C++ types out there.
366             When DB2::db needs to create a row object to handle the data retrieved from
367             the database table, it will look up in this array what to C, and
368             then create a new object of the designated type.
369              
370             =cut
371              
372             sub get_row_table_relationships
373             {
374             confess 'need to override setup_row_table_relationships';
375             }
376              
377             =item C
378              
379             Changes the default package for both tables and rows while adding tables.
380              
381             For example:
382              
383             package My::db;
384              
385             #...
386              
387             $self->add_table('foo'); # My::foo and My::fooR
388             $self->set_default_package('Your');
389             $self->add_table('bar'); # Your::bar and Your::barR
390              
391             =cut
392              
393             sub set_default_package
394             {
395             my $self = shift;
396             $self->{PKG_GROUP} = shift;
397             }
398              
399             sub _get_rows_to_tables {
400             my $self = shift;
401             unless ($self->{RELN}{ROW})
402             {
403             $self->{RELN}{ROW} = {
404             map { $_->{ROW} => $_->{TABLE} } @{$self->{RELN}{MASTER}}
405             };
406             }
407             $self->{RELN}{ROW};
408             }
409             sub _get_tables_to_rows {
410             my $self = shift;
411             unless ($self->{RELN}{TABLE})
412             {
413             $self->{RELN}{TABLE} = {
414             map { $_->{TABLE} => $_->{ROW} } @{$self->{RELN}{MASTER}}
415             };
416             }
417             $self->{RELN}{TABLE};
418             }
419             # This would be:
420             # keys %{shift->_get_tables_to_rows}
421             # but order is important.
422             sub _get_tables {
423             my $self = shift;
424             unless ($self->{RELN}{TABLE_ORDER})
425             {
426             $self->{RELN}{TABLE_ORDER} = [
427             map { $_->{TABLE} } @{$self->{RELN}{MASTER}}
428             ];
429             }
430             @{$self->{RELN}{TABLE_ORDER}};
431             }
432              
433             =item C
434              
435             While you should not need this, it is available to request the type
436             name of the DB2::Row class given a table type name.
437              
438             =cut
439              
440             sub get_row_type_for_table
441             {
442             my $self = shift;
443             my $table_type = shift;
444             my $conv = $self->_get_tables_to_rows;
445             my $row_type = exists $conv->{$table_type} ? $conv->{$table_type} : $table_type . 'R';
446              
447             # only try to grab it if it doesn't already exist.
448             no strict 'refs';
449             unless (exists ${"${row_type}::ISA"}[0])
450             {
451             # If the row-type is given, try loading it. Rather than using
452             # eval STR to eval "require $row_pm", we do it ourselves. This
453             # is slightly faster (Benchmark shows about 20% faster).
454             (my $row_pm = $row_type . '.pm') =~ s.::./.g;
455             eval { require $row_pm; 1 } or do
456             # if the row type doesn't exist, we'll just create it ourselves.
457             {
458             my $table = $self->get_table($table_type);
459             my $base_type = $table->get_base_row_type();
460              
461             eval "package $row_type; use base '$base_type'; 1" or
462             croak($@);
463             }
464             }
465             $row_type;
466             }
467              
468             =item C
469              
470             Returns the singleton table object (instantiated if necessary) given
471             its type name. If only one table is known about that ends with the given
472             name, it will be returned (shortcut).
473              
474             For example, $mydb->get_table('Foo') will get the table object if it's
475             really called Bar::Foo, Baz::Foo, Bar::Baz::Foo, or just Foo, but not
476             Baz::FooBar or Baz::BarFoo. But only if there is only a single match.
477             If there is more than one match, then the call will fail. If a case-sensitive
478             match fails to find any matches, then a case-insensitive match is attempted.
479              
480             =cut
481              
482             sub _guess_table
483             {
484             my $self = shift;
485             my $tbl = shift;
486             $tbl =~ s./+.::.g;
487             $tbl =~ s.:::+.::.g;
488              
489             # "normal" cases.
490             return $tbl if exists $self->{TABLES}{$tbl};
491              
492             my $tbl_to_rows = $self->_get_tables_to_rows;
493             return $tbl if exists $tbl_to_rows->{$tbl};
494              
495             # shortcuts.
496             return $self->{SHORTNAME_TABLES}{$tbl} if exists $self->{SHORTNAME_TABLES}{$tbl};
497              
498             # if there isn't a shortcut (yet), see if we can create one.
499             # only can do this if it's unique!
500             my @candidates = grep { /::\Q$tbl\E$/ } keys %$tbl_to_rows;
501              
502             # if no match yet, try case independant.
503             @candidates = grep { /::\Q$tbl\E$/i } keys %$tbl_to_rows
504             if scalar @candidates == 0;
505              
506             if (scalar @candidates == 1)
507             {
508             $self->{SHORTNAME_TABLES}{$tbl} = $candidates[0];
509             return $self->{SHORTNAME_TABLES}{$tbl};
510             }
511             undef;
512             }
513              
514             sub get_table
515             {
516             my $self = shift;
517             my $table = shift;
518             my $table_type = $self->_guess_table($table);
519             if ($table_type and exists $self->_get_tables_to_rows->{$table_type})
520             {
521             unless (ref $self->{TABLES}{$table_type})
522             {
523             no strict 'refs';
524             unless ($table_type and exists ${"${table_type}::ISA"}[0])
525             {
526             (my $table_pm = $table_type) =~ s.::./.g;
527             $table_pm .= '.pm';
528             eval { require $table_pm };
529             croak $@ if $@;
530             }
531             $self->{TABLES}{$table_type} = $table_type->new($self);
532             }
533             $self->{TABLES}{$table_type}
534             }
535             else
536             {
537             carp("Unknown type: $table");
538             undef;
539             }
540             }
541              
542             =item C
543              
544             Similar to C, you should not need this. Gets
545             the table I for the given row type name.
546              
547             =cut
548              
549             sub get_table_for_row_type
550             {
551             my $self = shift;
552             my $row_type = shift;
553             my $conv = $self->_get_rows_to_tables;
554             if (exists $conv->{$row_type})
555             {
556             $self->get_table($conv->{$row_type});
557             }
558             else
559             {
560             undef;
561             }
562             }
563              
564             # default is "true", so we want to make sure we take that into consideration
565             sub _is_autocommit
566             {
567             my $self = shift;
568             my $connect_attr = $self->connect_attr;
569              
570             not exists $connect_attr->{AutoCommit} or $connect_attr->{AutoCommit};
571             }
572              
573             =item C
574              
575             Returns the DBD::DB2 object that contains the actual connection to the
576             database, performing the connection if required.
577              
578             =cut
579              
580             sub _data_source {
581             my $self = shift;
582             my %dsn = $self->_dsn();
583             if (scalar keys %dsn > 1)
584             {
585             "dbi:DB2:" . join '; ', map {
586             uc($_) . "=$dsn{$_}"
587             } grep {
588             exists $dsn{$_}
589             } qw(database hostname port protocol uid pwd);
590             }
591             else
592             {
593             "dbi:DB2:" . uc ($dsn{database} || $dsn{db})
594             }
595             }
596              
597             sub connection
598             {
599             my $self = shift;
600             unless ($self->{dbh} and $self->{dbh}{Active})
601             {
602             $self->{dbh} = DBI->connect($self->_data_source,
603             $self->user_name,
604             $self->user_pw,
605             $self->connect_attr);
606             }
607             $self->{dbh}
608             }
609              
610             =item C
611              
612             Disconnects from the database (happens automatically, so shouldn't be
613             needed).
614              
615             =cut
616              
617             sub disconnect
618             {
619             my $self = shift;
620             if ($self and $self->{dbh})
621             {
622             $self->{dbh}->commit unless $self->_is_autocommit;
623             $self->{dbh}->disconnect;
624             }
625             delete $self->{dbh};
626             }
627              
628             =item C
629              
630             This is used as part of the setup of the database. It will go through
631             all the known tables and create them after first creating the database.
632             It is assumed that the person running this has authority to do so.
633              
634             To initialise your entire system, just run:
635              
636             perl -M[your_db_type] -e '[your_db_type]->create_db'
637              
638             For example:
639              
640             perl -MMy::db -e 'My::db->create_db'
641              
642             =cut
643              
644             sub create_db
645             {
646             my $self = shift;
647             $self = $self->new unless ref $self;
648              
649             require Sys::Hostname;
650              
651             my %dsn = $self->_dsn();
652             if (not keys %dsn or
653             scalar keys %dsn == 1 or
654             $dsn{hostname} eq 'localhost' or
655             $dsn{hostname} eq Sys::Hostname::hostname())
656             {
657             unless ($self->{quiet})
658             {
659             print '*' x 50, "\n";
660             print ' ' x 15, "setting up ", $self->db_name, "\n";
661             print '*' x 50, "\n";
662             }
663              
664             if (none { $_ eq $self->_data_source() } DBI->data_sources('DB2'))
665             {
666             unless ($self->{quiet})
667             {
668             print " ---> creating database\n";
669             }
670             my $opts = $self->create_db_opts();
671             $opts = (defined $opts and length $opts) ? " $opts" : "";
672              
673             eval {
674             my $insthome = getpwnam($ENV{DB2INSTANCE})->dir();
675             $ENV{PATH} = File::Spec->catdir($insthome, qw(sqllib bin)) . ':' . $ENV{PATH};
676             };
677              
678             system("db2", "create db " . $self->db_name() . $opts);
679             }
680             }
681              
682             my $dbh = $self->connection;
683             die "Cannot connect to " . $self->db_name() unless $dbh;
684              
685             for my $tbl ($self->_get_tables)
686             {
687             $self->get_table($tbl)->create_table();
688             }
689             $self->disconnect;
690             }
691              
692             =item C
693              
694             Override this to specify any create db options during database create.
695              
696             Default is to set the pagesize to 32 K.
697              
698             =cut
699              
700             sub create_db_opts
701             {
702             'pagesize 32 K';
703             }
704              
705             sub DESTROY
706             {
707             my $self = shift;
708             delete $localDB{ref $self};
709             if ($self->{dbh})
710             {
711             $self->disconnect;
712             }
713             }
714              
715             =back
716              
717             =head1 AUTHOR
718              
719             Darin McBride
720              
721             This framework evolved out of frustration writing reusable DDL to
722             create tables. Once I had some objects that did that, it was slow
723             extention to the point where they were usable for everything I could
724             think of.
725              
726             Most of the features here are because I'm incredibly lazy. I like to solve
727             problems, but only twice. The first time is to learn it, the second time
728             is to use my new knowledge. After that, I expect the computer to do it
729             for me.
730              
731             =head1 CREDITS
732              
733             Much thanks to DB2PERL for help with the DBI, and DBD::DB2 in
734             particular, including some bug fixes (both in DBD::DB2 and in DB2::db),
735             and feature enhancements to DBD::DB2 that came a little earlier than
736             originally planned.
737              
738             =head1 COPYRIGHT
739              
740             The DB2::db and associated modules are Copyright 2001-2008, Darin McBride.
741             All rights reserved.
742              
743             You may distribute under the terms of either the GNU General Public
744             License or the Artistic License, as specified in the Perl README file.
745              
746             =head1 BUGS
747              
748             Support for using this framework on a VIEW is completely missing.
749              
750             =head1 SEE ALSO
751              
752             DBI, DBD::DB2
753              
754             =cut
755              
756             1;