995c561d7e0fd36c621fba8c32a0da299f2bb234
[dbsrgits/DBIx-Class-Schema-Loader.git] / lib / DBIx / Class / Schema / Loader / DBI / Sybase.pm
1 package DBIx::Class::Schema::Loader::DBI::Sybase;
2
3 use strict;
4 use warnings;
5 use base 'DBIx::Class::Schema::Loader::DBI';
6 use Carp::Clan qw/^DBIx::Class/;
7 use Class::C3;
8
9 our $VERSION = '0.04999_06';
10
11 =head1 NAME
12
13 DBIx::Class::Schema::Loader::DBI::Sybase - DBIx::Class::Schema::Loader::DBI Sybase Implementation.
14
15 =head1 SYNOPSIS
16
17   package My::Schema;
18   use base qw/DBIx::Class::Schema::Loader/;
19
20   __PACKAGE__->loader_options( debug => 1 );
21
22   1;
23
24 =head1 DESCRIPTION
25
26 See L<DBIx::Class::Schema::Loader::Base>.
27
28 =cut
29
30 sub _setup {
31     my $self = shift;
32
33     $self->next::method(@_);
34     $self->{db_schema} ||= 'dbo';
35 }
36
37 sub _rebless {
38     my $self = shift;
39
40     my $dbh = $self->schema->storage->dbh;
41     my $DBMS_VERSION = @{$dbh->selectrow_arrayref(qq{sp_server_info \@attribute_id=1})}[2];
42     if ($DBMS_VERSION =~ /^Microsoft /i) {
43         my $subclass = 'DBIx::Class::Schema::Loader::DBI::MSSQL';
44         if ($self->load_optional_class($subclass) && !$self->isa($subclass)) {
45             bless $self, $subclass;
46             $self->_rebless;
47       }
48     } else {
49         $self->schema->storage->sql_maker->quote_char([qw/[ ]/])
50             unless $self->schema->storage->sql_maker->quote_char;
51
52         $self->schema->storage->sql_maker->name_sep('.')
53             unless $self->schema->storage->sql_maker->name_sep;
54     }
55 }
56
57 sub _table_columns {
58     my ($self, $table) = @_;
59
60     my $dbh = $self->schema->storage->dbh;
61     my $columns = $dbh->selectcol_arrayref(qq{SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = '$table' AND type = 'U')});
62
63     return $columns;
64 }
65
66 sub _table_pk_info {
67     my ($self, $table) = @_;
68
69     my $dbh = $self->schema->storage->dbh;
70     my $sth = $dbh->prepare(qq{sp_pkeys '$table'});
71     $sth->execute;
72
73     my @keydata;
74
75     while (my $row = $sth->fetchrow_hashref) {
76         push @keydata, lc $row->{column_name};
77     }
78
79     return \@keydata;
80 }
81
82 sub _table_fk_info {
83     my ($self, $table) = @_;
84
85     my ($local_cols, $remote_cols, $remote_table, @rels);
86     my $dbh = $self->schema->storage->dbh;
87     # hide "Object does not exist in this database." when trying to fetch fkeys
88     $dbh->{syb_err_handler} = sub { return 0 if $_[0] == 17461; }; 
89     my $sth = $dbh->prepare(qq{sp_fkeys \@FKTABLE_NAME = '$table'});
90     $sth->execute;
91
92     while (my $row = $sth->fetchrow_hashref) {
93         next unless $row->{FK_NAME};
94         my $fk = $row->{FK_NAME};
95         push @{$local_cols->{$fk}}, lc $row->{FKCOLUMN_NAME};
96         push @{$remote_cols->{$fk}}, lc $row->{PKCOLUMN_NAME};
97         $remote_table->{$fk} = $row->{PKTABLE_NAME};
98     }
99
100     foreach my $fk (keys %$remote_table) {
101         push @rels, {
102                      local_columns => \@{$local_cols->{$fk}},
103                      remote_columns => \@{$remote_cols->{$fk}},
104                      remote_table => $remote_table->{$fk},
105                     };
106
107     }
108     return \@rels;
109 }
110
111 sub _table_uniq_info {
112     my ($self, $table) = @_;
113
114     my $dbh = $self->schema->storage->dbh;
115     my $sth = $dbh->prepare(qq{sp_helpconstraint \@objname='$table', \@nomsg='nomsg'});
116     $sth->execute;
117
118     my $constraints;
119     while (my $row = $sth->fetchrow_hashref) {
120         if (exists $row->{constraint_type}) {
121             my $type = $row->{constraint_type} || '';
122             if ($type =~ /^unique/i) {
123                 my $name = lc $row->{constraint_name};
124                 push @{$constraints->{$name}},
125                     ( split /,/, lc $row->{constraint_keys} );
126             }
127         } else {
128             my $def = $row->{definition} || next;
129             next unless $def =~ /^unique/i;
130             my $name = lc $row->{name};
131             my ($keys) = $def =~ /\((.*)\)/;
132             $keys =~ s/\s*//g;
133             my @keys = map lc, split /,/ => $keys;
134             push @{$constraints->{$name}}, @keys;
135         }
136     }
137
138     my @uniqs = map { [ $_ => $constraints->{$_} ] } keys %$constraints;
139     return \@uniqs;
140 }
141
142 sub _extra_column_info {
143     my ($self, $info) = @_;
144     my %extra_info;
145
146     my ($table, $column) = @$info{qw/TABLE_NAME COLUMN_NAME/};
147
148     my $dbh = $self->schema->storage->dbh;
149     my $sth = $dbh->prepare(qq{SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = '$table') AND (status & 0x80) = 0x80 AND name = '$column'});
150     $sth->execute();
151
152     if ($sth->fetchrow_array) {
153         $extra_info{is_auto_increment} = 1;
154     }
155
156     return \%extra_info;
157 }
158
159 =head1 SEE ALSO
160
161 L<DBIx::Class::Schema::Loader>, L<DBIx::Class::Schema::Loader::Base>,
162 L<DBIx::Class::Schema::Loader::DBI>
163
164 =head1 AUTHOR
165
166 Justin Hunter C<justin.d.hunter@gmail.com>
167
168 =cut
169
170 1;