File Coverage

blib/lib/Class/DBI/DB2.pm
Criterion Covered Total %
statement 15 72 20.8
branch 0 18 0.0
condition 0 6 0.0
subroutine 5 14 35.7
pod 7 9 77.7
total 27 119 22.6


line stmt bran cond sub pod time code
1             package Class::DBI::DB2;
2              
3             =head1 NAME
4              
5             Class::DBI::DB2 - Extensions to Class::DBI for DB2
6              
7             =head1 SYNOPSIS
8              
9             package Music::DBI;
10             use base 'Class::DBI::DB2';
11             __PACKAGE__->set_db( 'Main', 'dbi:DB2:dbname', 'user', 'password', );
12              
13             package Artist;
14             use base 'Music::DBI';
15             __PACKAGE__->set_up_table('Artist');
16              
17             __PACKAGE__->autoinflate(dates => 'Time::Piece');
18              
19             # Somewhere else ...
20              
21             my $type = $class->column_type('column_name');
22             my $colno = $class->column_no('column_name');
23             my $nulls = $class->column_nulls('column_name');
24            
25             # ... see the Class::DBI documentation for details on Class::DBI usage
26              
27             =head1 DESCRIPTION
28              
29             Class::DBI::DB2 automates the setup of Class::DBI columns and primary key
30             for IBM DB2.
31              
32             This is an extension to Class::DBI that currently implements:
33              
34             * Automatic column name discovery.
35            
36             * Automatic primary key(s) detection.
37              
38             * Automatic column type detection (for use with autoinflate).
39              
40             * Automatic column number detection (where column order is needed).
41              
42             Instead of setting Class::DBI as your base class, use this.
43              
44             =cut
45              
46 2     2   160065 use strict;
  2         6  
  2         109  
47             require Class::DBI;
48 2     2   11 use base 'Class::DBI';
  2         3  
  2         7749  
49              
50 2     2   369718 use vars qw($VERSION);
  2         13  
  2         4724  
51             $VERSION = '0.16';
52              
53             =head1 OBJECT METHODS
54              
55             =head2 set_up_table
56              
57             __PACKAGE__->set_up_table("table_name");
58              
59             An optional second argument can supply your own alias for your table name.
60              
61             __PACKAGE__->set_up_table("table_name", "table_alias");
62              
63             Traditionally, to use Class::DBI, you have to set up the columns:
64              
65             __PACKAGE__->columns(All => qw/list of columns/);
66             __PACKAGE__->columns(Primary => 'column_name');
67              
68             While this allows for more flexibility if you're going to arrange your
69             columns into a variety of groupings, sometimes you just want to create the
70             'all columns' list.
71              
72             The columns call will extract the list of all the columns, and the primary key
73             and set them up for you. It will die horribly if the table contains
74             no primary key(s).
75              
76             =cut
77              
78 0     0   0 sub _croak { require Carp; Carp::croak(@_); }
  0         0  
79              
80             __PACKAGE__->set_sql(
81             create_table => 'CREATE TABLE __TABLE__ (%s)');
82             __PACKAGE__->set_sql(drop_table => 'DROP TABLE __TABLE__');
83             __PACKAGE__->set_sql(
84             desc_table => "SELECT COLNAME, COLNO, TYPENAME, NULLS FROM SYSCAT.COLUMNS WHERE TABSCHEMA = ? and TABNAME = ? order by colno");
85             __PACKAGE__->set_sql(
86             exists => 'SELECT count(*) FROM SYSCAT.TABLES WHERE TABSCHEMA = ? and TABNAME = ?');
87              
88             sub desc_table {
89 0     0 0 0 my $class = shift;
90 0         0 my ($tabschema,$table) = split '\.', $class->table;
91 0         0 return $class->search_desc_table(uc($tabschema),uc($table));
92             }
93              
94             sub set_up_table
95             {
96 0     0 1 0 my $class = shift;
97 0   0     0 $class->table( my $tabname = shift || $class->table, shift );
98 0         0 my $dbh = $class->db_Main;
99 0         0 my ($tabschema,$table) = split '\.', $class->table;
100              
101             # find primary key(s)
102 0         0 my ( @primary );
103 0         0 my $sth = $dbh->prepare(<<"SQL");
104             SELECT c.COLNAME FROM SYSCAT.KEYCOLUSE kc, SYSCAT.TABCONST tc, SYSCAT.COLUMNS c
105             WHERE kc.CONSTNAME=tc.CONSTNAME AND kc.TABSCHEMA=tc.TABSCHEMA
106             AND kc.TABNAME=tc.TABNAME AND kc.TABSCHEMA=c.TABSCHEMA AND
107             kc.TABNAME=c.TABNAME AND kc.COLNAME=c.COLNAME AND kc.TABSCHEMA = ? AND
108             kc.TABNAME = ? AND tc.TYPE = 'P' ORDER BY kc.COLSEQ
109             SQL
110 0         0 $sth->execute( uc($tabschema), uc($table) );
111 0         0 my $primaries = $sth->fetchall_arrayref; $sth->finish;
  0         0  
112 0         0 map {push @primary, $_->[0]} @$primaries;
  0         0  
113 0 0       0 $class->_croak("$table has no primary key") unless @primary;
114              
115             # find all columns
116 0         0 my ( @cols );
117 0         0 $sth = $dbh->prepare(<<"SQL");
118             SELECT COLNAME, COLNO, TYPENAME, NULLS FROM SYSCAT.COLUMNS
119             WHERE TABSCHEMA = ? and TABNAME = ? order by colno
120             SQL
121 0         0 $sth->execute( uc($tabschema), uc($table) );
122 0         0 my $columns = $sth->fetchall_arrayref; $sth->finish;
  0         0  
123 0         0 map {push @cols, $_->[0]} @$columns;
  0         0  
124              
125 0         0 $class->columns( All => @cols );
126 0         0 $class->columns( Primary => @primary );
127             }
128              
129             =head2 autoinflate
130              
131             __PACKAGE__->autoinflate(column_type => 'Inflation::Class');
132              
133             __PACKAGE__->autoinflate(timestamp => 'Time::Piece');
134             __PACKAGE__->autoinflate(dates => 'Time::Piece');
135              
136             This will automatically set up has_a() relationships for all columns of
137             the specified type to the given class.
138              
139             It is assumed that all classes passed will be able to inflate
140             and deflate without needing extra has_a arguments, with the example of
141             Time::Piece objects, that uses Time::Piece::DB2 (which you'll have to
142             have installed!).
143              
144             The special type 'dates' will autoinflate all columns of type date,
145             time or timestamp.
146              
147             =cut
148              
149             sub autoinflate {
150 0     0 1 0 my ($class, %how) = @_;
151 0   0     0 $how{$_} ||= $how{dates} for qw/DATE TIME TIMESTAMP/;
152 0         0 my $info = $class->_column_info;
153 0         0 foreach my $col (keys %$info) {
154 0         0 (my $type = $info->{$col}->{typename}) =~ s/\W.*//;
155 0 0       0 next unless $how{$type};
156 0         0 my %args;
157 0 0       0 if ($how{$type} eq "Time::Piece") {
158 0         0 eval "use Time::Piece::DB2";
159 0 0       0 $class->_croak($@) if $@;
160 0         0 $args{inflate} = "from_db2_" . lc($type);
161 0         0 $args{deflate} = "db2_" . lc($type);
162             }
163 0         0 $class->has_a(lc($col) => $how{$type}, %args);
164             }
165             }
166              
167             sub exists {
168 2     2 0 3 my $class = shift;
169 2         9 my ($tabschema,$table) = split '\.', $class->table;
170 2         39 return $class->sql_exists->select_val(uc($tabschema),uc($table));
171             }
172              
173             =head2 create_table
174              
175             $class->create_table(q{
176             name VARCHAR(40) NOT NULL,
177             rank VARCHAR(20) NOT NULL,
178             serial INTEGER NOT NULL
179             PRIMARY KEY(name)
180             });
181              
182             This creates the table for the class, with the given schema. If the
183             table already exists we do nothing.
184              
185             A typical use would be:
186              
187             Music::CD->table('cd');
188             Music::CD->create_table(q{
189             cdid INTEGER NOT NULL,
190             artist INTEGER NOT NULL,
191             title VARCHAR(255) NOT NULL,
192             year DATE,
193             PRIMARY KEY(cdid),
194             CONSTRAINT TITLE_UNIQ UNIQUE (artist,title)
195             });
196             Music::CD->set_up_table;
197              
198             =cut
199              
200             sub create_table {
201 0     0 1 0 my ($class, $schema) = @_;
202 0 0       0 if ($class->exists == 0) {
203 0         0 $class->sql_create_table(uc($schema))->execute;
204             }
205             }
206              
207             =head2 drop_table
208              
209             $class->drop_table;
210              
211             Drops the table for this class, if it exists.
212              
213             =cut
214              
215             sub drop_table {
216 2     2 1 3983 my $class = shift;
217 2         10 my ($tabschema,$table) = split '\.', $class->table;
218 2 0       44 if ($class->exists == 1) {
219 0           $class->sql_drop_table->execute;
220             }
221             }
222              
223             =head2 column_type
224              
225             my $type = $class->column_type('column_name');
226              
227             This returns the 'typename' of this table's 'column_name' (VARCHAR(20), INTEGER, etc.)
228              
229             =head2 column_no
230              
231             my $colno = $class->column_no('column_name');
232              
233             This returns the 'colno' of this table's 'column_name' (0..n) Useful when a column order
234             is needed, for example, when loading a table from a flat-file.
235              
236             =head2 column_nulls
237              
238             my $null = $class->column_nulls('column_name');
239              
240             This returns the 'nulls' of this table's 'column_name' (Y,N)
241              
242             =cut
243              
244             sub _column_info {
245 0     0     my $class = shift;
246 0           my ($tabschema,$table) = split '\.', $class->table;
247 0           my @columns = $class->desc_table();
248 0           return { map { $_->{colname} => $_ } @columns };
  0            
249             }
250              
251             sub column_no {
252 0     0 1   my $class = shift;
253 0 0         my $col = shift or die "Need a column for column_no";
254 0           return $class->_column_info->{uc($col)}->{colno};
255             }
256              
257             sub column_nulls {
258 0     0 1   my $class = shift;
259 0 0         my $col = shift or die "Need a column for column_nulls";
260 0           return $class->_column_info->{uc($col)}->{nulls};
261             }
262              
263             sub column_type {
264 0     0 1   my $class = shift;
265 0 0         my $col = shift or die "Need a column for column_type";
266 0           return $class->_column_info->{uc($col)}->{typename};
267             }
268              
269             =head1 AUTHOR
270              
271             Mark Ferris, Emark.ferris@geac.comE.
272              
273             =head1 COPYRIGHT
274              
275             Copyright (C) 2004 Mark Ferris. All rights reserved.
276              
277             This library is free software; you can redistribute it and/or modify
278             it under the same terms as Perl itself.
279              
280             =head1 SEE ALSO
281              
282             L. IBM DB2 (http://www-4.ibm.com/software/data/db2/)
283              
284             =cut
285              
286             1;