1 package DBIx::Class::Schema::Loader::DBI::DB2;
6 DBIx::Class::Schema::Loader::DBI::Component::QuotedDefault
7 DBIx::Class::Schema::Loader::DBI
11 use List::MoreUtils 'any';
14 use DBIx::Class::Schema::Loader::Table ();
16 our $VERSION = '0.07036';
20 DBIx::Class::Schema::Loader::DBI::DB2 - DBIx::Class::Schema::Loader::DBI DB2 Implementation.
24 See L<DBIx::Class::Schema::Loader> and L<DBIx::Class::Schema::Loader::Base>.
31 return ($self->next::method(@_), qw/
32 SYSCAT SYSIBM SYSIBMADM SYSPUBLIC SYSSTAT SYSTOOLS
39 $self->next::method(@_);
41 my $ns = $self->name_sep;
43 $self->db_schema([ $self->dbh->selectrow_array(<<"EOF", {}) ]) unless $self->db_schema;
44 SELECT CURRENT_SCHEMA FROM sysibm${ns}sysdummy1
47 if (not defined $self->preserve_case) {
48 $self->preserve_case(0);
50 elsif ($self->preserve_case) {
51 $self->schema->storage->sql_maker->quote_char('"');
52 $self->schema->storage->sql_maker->name_sep($ns);
56 sub _table_uniq_info {
57 my ($self, $table) = @_;
61 my $sth = $self->{_cache}->{db2_uniq} ||= $self->dbh->prepare(<<'EOF');
62 SELECT kcu.colname, kcu.constname, kcu.colseq
63 FROM syscat.tabconst as tc
64 JOIN syscat.keycoluse as kcu
65 ON tc.constname = kcu.constname
66 AND tc.tabschema = kcu.tabschema
67 AND tc.tabname = kcu.tabname
68 WHERE tc.tabschema = ? and tc.tabname = ? and tc.type = 'U'
71 $sth->execute($table->schema, $table->name);
74 while(my $row = $sth->fetchrow_arrayref) {
75 my ($col, $constname, $seq) = @$row;
76 push(@{$keydata{$constname}}, [ $seq, $self->_lc($col) ]);
78 foreach my $keyname (keys %keydata) {
79 my @ordered_cols = map { $_->[1] } sort { $a->[0] <=> $b->[0] }
80 @{$keydata{$keyname}};
81 push(@uniqs, [ $keyname => \@ordered_cols ]);
90 my ($self, $table) = @_;
92 my $sth = $self->{_cache}->{db2_fk} ||= $self->dbh->prepare(<<'EOF');
93 SELECT tc.constname, sr.reftabschema, sr.reftabname,
94 kcu.colname, rkcu.colname, kcu.colseq,
95 sr.deleterule, sr.updaterule
96 FROM syscat.tabconst tc
97 JOIN syscat.keycoluse kcu
98 ON tc.constname = kcu.constname
99 AND tc.tabschema = kcu.tabschema
100 AND tc.tabname = kcu.tabname
101 JOIN syscat.references sr
102 ON tc.constname = sr.constname
103 AND tc.tabschema = sr.tabschema
104 AND tc.tabname = sr.tabname
105 JOIN syscat.keycoluse rkcu
106 ON sr.refkeyname = rkcu.constname
107 AND kcu.colseq = rkcu.colseq
108 WHERE tc.tabschema = ?
112 $sth->execute($table->schema, $table->name);
123 COLS: while (my @row = $sth->fetchrow_array) {
124 my ($fk, $remote_schema, $remote_table, $local_col, $remote_col,
125 $colseq, $delete_rule, $update_rule) = @row;
127 if (not exists $rels{$fk}) {
128 if ($self->db_schema && $self->db_schema->[0] ne '%'
129 && (not any { $_ eq $remote_schema } @{ $self->db_schema })) {
134 $rels{$fk}{remote_table} = DBIx::Class::Schema::Loader::Table->new(
136 name => $remote_table,
137 schema => $remote_schema,
141 $rels{$fk}{local_columns}[$colseq-1] = $self->_lc($local_col);
142 $rels{$fk}{remote_columns}[$colseq-1] = $self->_lc($remote_col);
144 $rels{$fk}{attrs} ||= {
145 on_delete => $rules{$delete_rule},
146 on_update => $rules{$update_rule},
147 is_deferrable => 1, # DB2 has no deferrable constraints
151 return [ values %rels ];
155 # DBD::DB2 doesn't follow the DBI API for ->tables
157 my ($self, $schema) = @_;
159 return $self->dbh->tables($schema ? { TABLE_SCHEM => $schema } : undef);
162 sub _columns_info_for {
166 my $result = $self->next::method(@_);
168 while (my ($col, $info) = each %$result) {
169 # check for identities
170 my $sth = $self->dbh->prepare_cached(
174 WHERE tabschema = ? AND tabname = ? AND colname = ?
175 AND identity = 'Y' AND generated != ''
178 $sth->execute($table->schema, $table->name, $self->_uc($col));
179 if ($sth->fetchrow_array) {
180 $info->{is_auto_increment} = 1;
183 my $data_type = $info->{data_type};
185 if ($data_type !~ /^(?:(?:var)?(?:char|graphic)|decimal)\z/i) {
186 delete $info->{size};
189 if ($data_type eq 'double') {
190 $info->{data_type} = 'double precision';
192 elsif ($data_type eq 'decimal') {
193 no warnings 'uninitialized';
195 $info->{data_type} = 'numeric';
197 my @size = @{ $info->{size} || [] };
199 if ($size[0] == 5 && $size[1] == 0) {
200 delete $info->{size};
203 elsif ($data_type =~ /^(?:((?:var)?char) \(\) for bit data|(long varchar) for bit data)\z/i) {
204 my $base_type = lc($1 || $2);
206 (my $original_type = $data_type) =~ s/[()]+ //;
208 $info->{original}{data_type} = $original_type;
210 if ($base_type eq 'long varchar') {
211 $info->{data_type} = 'blob';
214 if ($base_type eq 'char') {
215 $info->{data_type} = 'binary';
217 elsif ($base_type eq 'varchar') {
218 $info->{data_type} = 'varbinary';
221 my ($size) = $self->dbh->selectrow_array(<<'EOF', {}, $table->schema, $table->name, $self->_uc($col));
224 WHERE tabschema = ? AND tabname = ? AND colname = ?
227 $info->{size} = $size if $size;
231 if ((eval { lc ${ $info->{default_value} } }||'') =~ /^current (date|time(?:stamp)?)\z/i) {
234 ${ $info->{default_value} } = 'current_timestamp';
236 my $orig_deflt = "current $type";
237 $info->{original}{default_value} = \$orig_deflt;
246 L<DBIx::Class::Schema::Loader>, L<DBIx::Class::Schema::Loader::Base>,
247 L<DBIx::Class::Schema::Loader::DBI>
251 See L<DBIx::Class::Schema::Loader/AUTHOR> and L<DBIx::Class::Schema::Loader/CONTRIBUTORS>.
255 This library is free software; you can redistribute it and/or modify it under
256 the same terms as Perl itself.
261 # vim:et sts=4 sw=4 tw=0: