suppress 'bad table' warnings for filtered tables, preserve case of MSSQL table names
[dbsrgits/DBIx-Class-Schema-Loader.git] / lib / DBIx / Class / Schema / Loader / DBI / MSSQL.pm
index af33e4a..10af9bd 100644 (file)
@@ -6,33 +6,39 @@ use base 'DBIx::Class::Schema::Loader::DBI::Sybase::Common';
 use Carp::Clan qw/^DBIx::Class/;
 use Class::C3;
 
-our $VERSION = '0.05002';
+our $VERSION = '0.05003';
 
 =head1 NAME
 
 DBIx::Class::Schema::Loader::DBI::MSSQL - DBIx::Class::Schema::Loader::DBI MSSQL Implementation.
 
-=head1 SYNOPSIS
-
-  package My::Schema;
-  use base qw/DBIx::Class::Schema::Loader/;
+=head1 DESCRIPTION
 
-  __PACKAGE__->loader_options( debug => 1 );
+Base driver for Microsoft SQL Server, used by
+L<DBIx::Class::Schema::Loader::DBI::Sybase::Microsoft_SQL_Server> for support
+via L<DBD::Sybase> and
+L<DBIx::Class::Schema::Loader::DBI::ODBC::Microsoft_SQL_Server> for support via
+L<DBD::ODBC>.
 
-  1;
+See L<DBIx::Class::Schema::Loader> and L<DBIx::Class::Schema::Loader::Base> for
+usage information.
 
-=head1 DESCRIPTION
+=cut
 
-See L<DBIx::Class::Schema::Loader::Base>.
+sub _tables_list {
+    my ($self, $opts) = @_;
 
-=cut
+    my $dbh = $self->schema->storage->dbh;
+    my $sth = $dbh->prepare(<<'EOF');
+SELECT t.table_name
+FROM information_schema.tables t
+WHERE t.table_schema = ?
+EOF
+    $sth->execute($self->db_schema);
 
-sub _setup {
-    my $self = shift;
+    my @tables = map @$_, @{ $sth->fetchall_arrayref };
 
-    $self->next::method(@_);
-    $self->{db_schema} ||= $self->_build_db_schema;
-    $self->_set_quote_char_and_name_sep;
+    return $self->_filter_tables(\@tables, $opts);
 }
 
 sub _table_pk_info {
@@ -80,15 +86,20 @@ sub _table_uniq_info {
     my ($self, $table) = @_;
 
     my $dbh = $self->schema->storage->dbh;
-    my $sth = $dbh->prepare(qq{SELECT CCU.CONSTRAINT_NAME, CCU.COLUMN_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CCU
-                               JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON (CCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME)
-                               JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU ON (CCU.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME AND CCU.COLUMN_NAME = KCU.COLUMN_NAME)
-                               WHERE CCU.TABLE_NAME = @{[ $dbh->quote($table) ]} AND CONSTRAINT_TYPE = 'UNIQUE' ORDER BY KCU.ORDINAL_POSITION});
+    local $dbh->{FetchHashKeyName} = 'NAME_lc';
+
+    my $sth = $dbh->prepare(qq{
+SELECT ccu.constraint_name, ccu.column_name
+FROM information_schema.constraint_column_usage ccu
+JOIN information_schema.table_constraints tc on (ccu.constraint_name = tc.constraint_name)
+JOIN information_schema.key_column_usage kcu on (ccu.constraint_name = kcu.constraint_name and ccu.column_name = kcu.column_name)
+wHERE lower(ccu.table_name) = @{[ $dbh->quote(lc $table) ]} AND constraint_type = 'UNIQUE' ORDER BY kcu.ordinal_position
+    });
     $sth->execute;
     my $constraints;
     while (my $row = $sth->fetchrow_hashref) {
-        my $name = lc $row->{CONSTRAINT_NAME};
-        my $col  = lc $row->{COLUMN_NAME};
+        my $name = $row->{constraint_name};
+        my $col  = lc $row->{column_name};
         push @{$constraints->{$name}}, $col;
     }
 
@@ -96,50 +107,54 @@ sub _table_uniq_info {
     return \@uniqs;
 }
 
-sub _extra_column_info {
-    my ($self, $info) = @_;
-    my %extra_info;
+sub _columns_info_for {
+    my $self    = shift;
+    my ($table) = @_;
 
-    my ($table, $column) = @$info{qw/TABLE_NAME COLUMN_NAME/};
+    my $result = $self->next::method(@_);
 
-    my $dbh = $self->schema->storage->dbh;
-    my $sth = $dbh->prepare(qq{
-        SELECT COLUMN_NAME 
-        FROM INFORMATION_SCHEMA.COLUMNS
-        WHERE COLUMNPROPERTY(object_id(@{[ $dbh->quote($table) ]}, 'U'), '$column', 'IsIdentity') = 1
-          AND TABLE_NAME = @{[ $dbh->quote($table) ]} AND COLUMN_NAME = @{[ $dbh->quote($column) ]}
-    });
-    $sth->execute();
+    while (my ($col, $info) = each %$result) {
+        my $dbh = $self->schema->storage->dbh;
 
-    if ($sth->fetchrow_array) {
-        $extra_info{is_auto_increment} = 1;
-    }
+        my $sth = $dbh->prepare(qq{
+SELECT column_name 
+FROM information_schema.columns
+WHERE columnproperty(object_id(@{[ $dbh->quote(lc $table) ]}, 'U'), @{[ $dbh->quote(lc $col) ]}, 'IsIdentity') = 1
+AND lower(table_name) = @{[ $dbh->quote(lc $table) ]} AND lower(column_name) = @{[ $dbh->quote(lc $col) ]}
+        });
+        if (eval { $sth->execute; $sth->fetchrow_array }) {
+            $info->{is_auto_increment} = 1;
+            $info->{data_type} =~ s/\s*identity//i;
+            delete $info->{size};
+        }
 
 # get default
-    $sth = $dbh->prepare(qq{
-        SELECT COLUMN_DEFAULT
-        FROM INFORMATION_SCHEMA.COLUMNS
-        WHERE TABLE_NAME = @{[ $dbh->quote($table) ]} AND COLUMN_NAME = @{[ $dbh->quote($column) ]}
-    });
-    $sth->execute;
-    my ($default) = $sth->fetchrow_array;
-
-    if (defined $default) {
-        # strip parens
-        $default =~ s/^\( (.*) \)\z/$1/x;
-
-        # Literal strings are in ''s, numbers are in ()s (in some versions of
-        # MSSQL, in others they are unquoted) everything else is a function.
-        $extra_info{default_value} =
-            $default =~ /^['(] (.*) [)']\z/x ? $1 :
-                $default =~ /^\d/ ? $default : \$default;
+        $sth = $dbh->prepare(qq{
+SELECT column_default
+FROM information_schema.columns
+wHERE lower(table_name) = @{[ $dbh->quote(lc $table) ]} AND lower(column_name) = @{[ $dbh->quote(lc $col) ]}
+        });
+        my ($default) = eval { $sth->execute; $sth->fetchrow_array };
+
+        if (defined $default) {
+            # strip parens
+            $default =~ s/^\( (.*) \)\z/$1/x;
+
+            # Literal strings are in ''s, numbers are in ()s (in some versions of
+            # MSSQL, in others they are unquoted) everything else is a function.
+            $info->{default_value} =
+                $default =~ /^['(] (.*) [)']\z/x ? $1 :
+                    $default =~ /^\d/ ? $default : \$default;
+        }
     }
 
-    return \%extra_info;
+    return $result;
 }
 
 =head1 SEE ALSO
 
+L<DBIx::Class::Schema::Loader::DBI::Sybase::Microsoft_SQL_Server>,
+L<DBIx::Class::Schema::Loader::DBI::ODBC::Microsoft_SQL_Server>,
 L<DBIx::Class::Schema::Loader>, L<DBIx::Class::Schema::Loader::Base>,
 L<DBIx::Class::Schema::Loader::DBI>
 
@@ -155,3 +170,4 @@ the same terms as Perl itself.
 =cut
 
 1;
+# vim:et sts=4 sw=4 tw=0: