File Coverage

lib/SQL/Admin/Driver/DB2/DBI.pm
Criterion Covered Total %
statement 12 129 9.3
branch 0 42 0.0
condition 0 3 0.0
subroutine 4 23 17.3
pod 0 11 0.0
total 16 208 7.6


line stmt bran cond sub pod time code
1              
2             package SQL::Admin::Driver::DB2::DBI;
3 1     1   1314 use base qw( SQL::Admin::Driver::Base::DBI );
  1         4  
  1         96  
4              
5 1     1   6 use strict;
  1         2  
  1         36  
6 1     1   5 use warnings;
  1         3  
  1         48  
7              
8             our $VERSION = v0.5.0;
9              
10             ######################################################################
11              
12 1     1   721 use SQL::Admin::Driver::DB2::Parser;
  1         3  
  1         2965  
13              
14             ######################################################################
15              
16             our %TYPE_MAP = (
17             smallint => 'int2',
18             integer => 'int4',
19             bigint => 'int8',
20             vargraphic => 'varchar',
21             varchar => 'varchar',
22             character => 'character',
23             decimal => 'decimal',
24             real => 'real',
25             date => 'date',
26             time => 'time',
27             timestamp => 'timestamp',
28             );
29              
30             our %TYPE_WITH_SIZE = (
31             varchar => 1,
32             character => 1,
33             vargraphic => 2,
34             decimal => 1,
35             );
36              
37             our %TYPE_WITH_SCALE = (
38             decimal => 1,
39             );
40              
41              
42             ######################################################################
43             ######################################################################
44             sub lcws ( $ ) { # ;
45 0     0 0   $_[0] =~ s/\s+$//;
46 0           $_[0] = lc $_[0];
47             }
48              
49              
50             ######################################################################
51             ######################################################################
52             sub driver { # ;
53 0     0 0   shift;
54             }
55              
56              
57             ######################################################################
58             ######################################################################
59             sub parser { # ;
60 0     0 0   my $self = shift;
61 0   0       $self->{parser} ||= SQL::Admin::Driver::DB2::Parser->new;
62             }
63              
64              
65             ######################################################################
66             ######################################################################
67             sub _list_sequence { # ;
68 0     0     my ($self, $catalog) = @_;
69              
70 0           my ($sql, @bind) = $self->sqla->select (
71             [ 'syscat.sequences' ],
72             [ '*' ],
73             {
74             ORIGIN => 'U',
75             SEQTYPE => 'S',
76             seqschema => { 'not like' => 'SYS%' },
77             },
78             );
79              
80 0           my $sth = $self->sth ($sql, @bind);
81 0           while (my $row = $sth->fetchrow_hashref) {
82 0           my $obj = $catalog->add (sequence => (
83             name => lc $row->{SEQNAME},
84             schema => lc $row->{SEQSCHEMA},
85             ));
86 0           $obj->increment_by ($row->{INCREMENT});
87 0           $obj->start_with ($row->{START});
88 0           $obj->minvalue ($row->{MINVALUE});
89 0           $obj->maxvalue ($row->{MAXVALUE});
90 0           $obj->cache ($row->{CACHE});
91             }
92              
93 0           $sth->finish;
94              
95 0           ();
96             }
97              
98              
99             ######################################################################
100             ######################################################################
101             sub _query_table { # ;
102 0     0     my ($self, @schemas) = @_;
103 0           $_ = uc for @schemas;
104              
105 0 0         $self->sqla->select (
106             [ 'syscat.tables' ],
107             [
108             'tabschema as table_schema',
109             'tabname as table_name',
110             'tbspace as hint_db2_tablespace',
111             'case when append_mode = \'N\' then null
112             when append_mode = \'Y\' then \'ON\'
113             else null
114             end as hint_db2_append',
115             'case when pctfree > -1 then pctfree else null end as hint_db2_pctfree',
116             'case when locksize = \'I\' then \'BLOCK\'
117             when locksize = \'R\' then null
118             when locksize = \'T\' then \'TABLE\'
119             else null
120             end as hint_db2_locksize',
121             'colcount as info_db_colcount',
122             'case when card > -1 then card
123             else null
124             end as info_db_rows',
125             ],
126             {
127             tabschema => ( @schemas ? \ @schemas : { 'not like' => 'SYS%' }),
128             type => 'T',
129             },
130             );
131             }
132              
133              
134             ######################################################################
135             ######################################################################
136             sub _query_table_column { # ;
137 0     0     my ($self, @schemas) = @_;
138 0           $_ = uc for @schemas;
139 0 0         $self->sqla->select (
140             [ 'syscat.columns c', 'syscat.tables t' ],
141             [
142             'c.tabschema as table_schema',
143             'c.tabname as table_name',
144             'c.colname as column_name',
145             'c.typename as data_type',
146             'c.length as data_type_size',
147             'c.scale as data_type_scale',
148             'case when c.nulls = \'N\' then 1
149             else null
150             end as not_null',
151             'c.default',
152             'c.keyseq as primary_key_index',
153              
154             'c.colno', 't.colcount',
155             ],
156             {
157             'c.tabschema' => ( @schemas ? \ @schemas : { not_like => 'SYS%' }),
158             't.tabschema' => \ ' = c.tabschema',
159             't.tabname' => \ ' = c.tabname',
160             't.type' => 'T',
161             },
162             [ 't.tabschema, t.tabname, c.colno' ],
163             );
164              
165             }
166              
167              
168             ######################################################################
169             ######################################################################
170             sub _query_table_column_autoincrement { # ;
171 0     0     my ($self, @schemas) = @_;
172 0           $_ = uc for @schemas;
173 0 0         $self->sqla->select (
174             [ 'syscat.colidentattributes' ],
175             [
176             'tabschema as table_schema',
177             'tabname as table_name',
178             'colname as column_name',
179             'start as start_with',
180             'increment as increment_by',
181             'minvalue',
182             'maxvalue',
183             'cache',
184             ],
185             {
186             'tabschema' => ( @schemas ? \ @schemas : { not_like => 'SYS%' }),
187             },
188             );
189             }
190              
191              
192             ######################################################################
193             ######################################################################
194             sub _query_constraint_primary_key { # ;
195 0     0     my ($self, @schemas) = @_;
196 0           $_ = uc for @schemas;
197 0 0         $self->sqla->select (
198             [ 'syscat.columns c', 'syscat.tables t' ],
199             [
200             'c.tabschema as table_schema',
201             'c.tabname as table_name',
202             'c.colname as column_name',
203             'c.keyseq as colno',
204             't.keycolumns as colcount',
205             ],
206             {
207             'c.tabschema' => ( @schemas ? \ @schemas : { not_like => 'SYS%' }),
208             't.tabschema' => \ ' = c.tabschema',
209             't.tabname' => \ ' = c.tabname',
210             't.type' => 'T',
211             'c.keyseq' => { '!=', undef },
212             },
213             [ 'c.tabschema, c.tabname, c.keyseq' ],
214             );
215              
216             }
217              
218              
219             ######################################################################
220             ######################################################################
221             sub _query_constraint_unique { # ;
222 0     0     my ($self, @schemas) = @_;
223 0           $_ = uc for @schemas;
224 0 0         $self->sqla->select (
225             [ 'syscat.constdep c', 'syscat.indexes i', 'syscat.indexcoluse u' ],
226             [
227             'c.tabschema as table_schema',
228             'c.tabname as table_name',
229             'c.constname as constraint_name',
230             'u.colname as column_name',
231             'u.colseq as colno',
232             'i.colcount',
233             ],
234             {
235             'c.tabschema' => ( @schemas ? \ @schemas : { not_like => 'SYS%' }),
236             'c.bschema' => \ ' = i.indschema',
237             'c.bname' => \ ' = i.indname',
238             'u.indschema' => \ ' = i.indschema',
239             'u.indname' => \ ' = i.indname',
240             'i.user_defined' => 0,
241             'i.uniquerule' => 'U',
242             },
243             [ 'c.tabschema, c.tabname, c.constname, u.colseq' ],
244             );
245              
246             }
247              
248              
249             ######################################################################
250             ######################################################################
251             sub _query_constraint_foreign_key { # ;
252 0     0     my ($self, @schemas) = @_;
253 0           $_ = uc for @schemas;
254 0 0         $self->sqla->select (
255             [ 'syscat.references fk', 'syscat.keycoluse tc', 'syscat.keycoluse rc' ],
256             [
257             'fk.constname as constraint_name',
258             'fk.tabschema as table_schema',
259             'fk.tabname as table_name',
260             'tc.colname as column_name',
261             'fk.reftabschema as reftable_schema',
262             'fk.reftabname as reftable_name',
263             'rc.colname as refcolumn_name',
264             'case when fk.deleterule = \'A\' then \'no_action\'
265             when fk.deleterule = \'C\' then \'cascade\'
266             when fk.deleterule = \'N\' then \'set_null\'
267             when fk.deleterule = \'R\' then \'restrict\'
268             end as delete_rule',
269             'case when fk.updaterule = \'A\' then \'no_action\'
270             when fk.updaterule = \'C\' then \'cascade\'
271             when fk.updaterule = \'N\' then \'set_null\'
272             when fk.updaterule = \'R\' then \'restrict\'
273             end as update_rule',
274              
275             'tc.colseq as colno',
276             'fk.colcount',
277             ],
278             {
279             'fk.tabschema' => ( @schemas ? \ @schemas : { not_like => 'SYS%' }),
280             'fk.constname' => \ ' = tc.constname',
281             'fk.refkeyname' => \ ' = rc.constname',
282             'tc.colseq' => \ ' = rc.colseq',
283             },
284             [ 'fk.tabschema, fk.tabname, fk.constname, tc.colseq' ],
285             );
286             }
287              
288              
289             ######################################################################
290             ######################################################################
291             sub _query_index { # ;
292 0     0     my ($self, @schemas) = @_;
293 0           $_ = uc for @schemas;
294 0 0         $self->sqla->select (
295             [ 'syscat.indexes ix', 'syscat.indexcoluse cu' ],
296             [
297             'ix.tabschema as table_schema',
298             'ix.tabname as table_name',
299             'ix.indschema as index_schema',
300             'ix.indname as index_name',
301             'cu.colname as column_name',
302             'case when cu.colorder = \'A\' then \'ASC\'
303             when cu.colorder = \'D\' then \'DESC\'
304             when cu.colorder = \'I\' then null
305             end as column_order',
306             'case when ix.uniquerule = \'U\' then 1
307             when ix.uniquerule = \'D\' then 0
308             else null
309             end as unique',
310             'case when ix.pctfree > -1 then ix.pctfree
311             else null
312             end as hint_db2_pctfree',
313              
314             'cu.colseq as colno',
315             'ix.colcount as colcount',
316             ],
317             {
318             'ix.indschema' => ( @schemas ? \ @schemas : { not_like => 'SYS%' }),
319             'cu.indschema' => \ ' = ix.indschema',
320             'cu.indname' => \ ' = ix.indname',
321             'ix.uniquerule' => [ 'U', 'D' ],
322             'ix.user_defined' => 1,
323             },
324             [ 'ix.indschema, ix.indname, cu.colseq' ],
325             );
326             }
327              
328              
329             ######################################################################
330             ######################################################################
331             sub load_table { # ;
332 0     0 0   my ($self, $catalog, @schemas) = @_;
333              
334 0           my $sth = $self->execute ($self->_query_table (@schemas));
335 0           while (my $row = $sth->fetchrow_hashref) {
336 0           lcws $_ for @$row{qw{ table_schema table_name }};
337              
338 0           my $table = $catalog->add (table => (
339             schema => $row->{table_schema},
340             name => $row->{table_name},
341             ));
342              
343 0           while (my ($key, $value) = each %$row) {
344 0 0         next unless defined $value;
345              
346 0 0         $table->hint ($1, $value) if $key =~ m/^hint_(.*)/;
347 0 0         $table->info ($1, $value) if $key =~ m/^info_(.*)/;
348             }
349             }
350              
351             ##################################################################
352              
353 0           $sth->finish;
354              
355 0           ();
356             }
357              
358              
359             ######################################################################
360             ######################################################################
361             sub load_index { # ;
362 0     0 0   my ($self, $catalog, @schemas) = @_;
363              
364 0           my $column_list = [];
365 0           my $sth = $self->execute ($self->_query_index (@schemas));
366 0           while (my $row = $sth->fetchrow_hashref) {
367 0           push @$column_list, [ lcws $row->{column_name}, $row->{column_order} ];
368              
369 0 0         if ($row->{colno} == $row->{colcount}) {
370 0           my $index = $catalog->add (index => (
371             schema => lcws $row->{index_schema},
372             name => lcws $row->{index_name}
373             ));
374              
375 0           $index->table ($catalog->add (table => (
376             schema => lcws $row->{table_schema},
377             name => lcws $row->{table_name}
378             )));
379              
380 0 0         $index->unique (1) if $row->{unique};
381 0           $index->column_list ($column_list);
382              
383 0           while (my ($key, $value) = each %$row) {
384 0 0         next unless defined $value;
385 0 0         $index->hint ($1, $value) if $key =~ m/^hint_(.*)/;
386             }
387              
388 0           $column_list = [];
389             }
390             }
391              
392             ##################################################################
393              
394 0           $sth->finish;
395              
396 0           ();
397             }
398              
399              
400             ######################################################################
401             ######################################################################
402             sub load_table_column { # ;
403 0     0 0   my ($self, $catalog, @schemas) = @_;
404              
405 0           my $sth = $self->execute ($self->_query_table_column (@schemas));
406 0           while (my $row = $sth->fetchrow_hashref) {
407 0           my $column = $catalog->add (table => (
408             schema => lcws $row->{table_schema},
409             name => lcws $row->{table_name},
410             ))->add (column => (
411             name => lcws $row->{column_name}
412             ));
413              
414 0           my $type = lcws $row->{data_type};
415 0 0         die "Unknown data type: $type\n" unless exists $TYPE_MAP{ $type };
416 0           $column->type ({
417             type => $TYPE_MAP{ $type },
418             (map +(size => $_ * $row->{data_type_size}), grep $_, $TYPE_WITH_SIZE{ $type }),
419             (map +(scale => $row->{data_type_scale}), grep $_, $TYPE_WITH_SCALE{ $type }),
420             });
421              
422             ##############################################################
423              
424 0 0         $column->not_null (1)
425             if $row->{not_null};
426              
427             $column->default ($self->parser->default_clause_value ($_))
428 0           for grep defined, $row->{default};
429             }
430              
431             ##################################################################
432              
433 0           $sth->finish;
434              
435 0           ();
436             }
437              
438              
439             ######################################################################
440             ######################################################################
441             sub load_table_column_autoincrement { # ;
442 0     0 0   my ($self, $catalog, @schemas) = @_;
443              
444 0           my $sth = $self->execute ($self->_query_table_column_autoincrement (@schemas));
445              
446 0           while (my $row = $sth->fetchrow_hashref) {
447 0 0         my $table = $catalog->get (table => (
448             name => lcws $row->{table_name},
449             schema => lcws $row->{table_schema},
450             ))
451             or next;
452              
453 0 0         my $column = $table->column (lcws $row->{column_name})
454             or next;
455              
456 0           $column->autoincrement (1);
457 0           map $column->autoincrement_hint ($_ => $row->{$_}),
458             grep defined $row->{$_},
459             qw( start_with increment_by minvalue maxvalue cache );
460             }
461              
462             ##################################################################
463              
464 0           $sth->finish;
465              
466 0           ();
467             }
468              
469              
470             ######################################################################
471             ######################################################################
472             sub load_constraint_primary_key { # ;
473 0     0 0   my ($self, $catalog, @schemas) = @_;
474              
475 0           my $column_list = [];
476 0           my $sth = $self->execute ($self->_query_constraint_primary_key (@schemas));
477              
478 0           while (my $row = $sth->fetchrow_hashref) {
479 0           push @$column_list, lcws $row->{column_name};
480              
481 0 0         if ($row->{colno} == $row->{colcount}) {
482 0           my $constr = $catalog->add (table => (
483             schema => lcws $row->{table_schema},
484             name => lcws $row->{table_name},
485             ))->add (primary_key => (
486             column_list => $column_list
487             ));
488              
489 0           $column_list = [];
490             }
491             }
492              
493             ##################################################################
494              
495 0           $sth->finish;
496              
497 0           ();
498             }
499              
500              
501             ######################################################################
502             ######################################################################
503             sub load_constraint_unique { # ;
504 0     0 0   my ($self, $catalog, @schemas) = @_;
505              
506 0           my $column_list = [];
507 0           my $sth = $self->execute ($self->_query_constraint_unique (@schemas));
508              
509 0           while (my $row = $sth->fetchrow_hashref) {
510 0           push @$column_list, lcws $row->{column_name};
511              
512 0 0         if ($row->{colno} == $row->{colcount}) {
513 0           my $constr = $catalog->get (table => (
514             schema => lcws $row->{table_schema},
515             name => lcws $row->{table_name}
516             ))->add (unique => (
517             column_list => $column_list,
518             name => lcws $row->{constraint_name},
519             ));
520              
521 0           $column_list = [];
522             }
523             }
524              
525             ##################################################################
526              
527 0           $sth->finish;
528              
529 0           ();
530             }
531             sub load_constraint_foreign_key { # ;
532 0     0 0   my ($self, $catalog, @schemas) = @_;
533              
534 0           my $column_list = [];
535 0           my $refcolumn_list = [];
536 0           my $sth = $self->execute ($self->_query_constraint_foreign_key (@schemas));
537              
538 0           while (my $row = $sth->fetchrow_hashref) {
539 0           push @$column_list, lcws $row->{column_name};
540 0           push @$refcolumn_list, lcws $row->{refcolumn_name};
541              
542 0 0         if ($row->{colno} == $row->{colcount}) {
543 0           my $constr = $catalog->add (table => (
544             schema => lcws $row->{table_schema},
545             name => lcws $row->{table_name}
546             ))->add (foreign_key => (
547             name => lcws $row->{constraint_name},
548             referenced_table => $catalog->add (table => (
549             schema => lcws $row->{reftable_schema},
550             name => lcws $row->{reftable_name}
551             )),
552             referencing_column_list => $column_list,
553             referenced_column_list => $refcolumn_list,
554             update_rule => $row->{update_rule},
555             delete_rule => $row->{delete_rule},
556             ));
557              
558 0           $column_list = [];
559 0           $refcolumn_list = [];
560             };
561             }
562             }
563              
564              
565             ######################################################################
566             ######################################################################
567 0     0 0   sub load_constraint_check { # ; TODO;
568             }
569              
570              
571             ######################################################################
572             ######################################################################
573              
574             package SQL::Admin::Driver::DB2::DBI;
575              
576             1;
577