From: Rafael Kitover Date: Wed, 17 Oct 2012 18:49:35 +0000 (-0400) Subject: better schemas support for SQL Server > 2000 X-Git-Tag: 0.07034_01~5 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class-Schema-Loader.git;a=commitdiff_plain;h=7b2db7f3a99d627cd35962744336b3301b3454fc better schemas support for SQL Server > 2000 Use schema_name() instead of user_name() on > 2000 to detect the current schema, and query [$db].sys.schemas instead of [$db].dbo.sysusers for schema names on > 2000. frew has reported that schema_name() has worked better for him for users which aren't the owners of the schema. --- diff --git a/Changes b/Changes index b378bb3..704f03e 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,7 @@ Revision history for Perl extension DBIx::Class::Schema::Loader + - MSSQL: on > 2000 use schema_name() instead of user_name() to detect + current schema and query sys.schemas instead of sysusers. - SQL Anywhere: introspect ON DELETE/UPDATE rules, default is now RESTRICT. is_deferrable still defaults to 1 - rewrite pg fk introspection to use catalog views instead of diff --git a/lib/DBIx/Class/Schema/Loader/DBI/MSSQL.pm b/lib/DBIx/Class/Schema/Loader/DBI/MSSQL.pm index 6d0681e..1890212 100644 --- a/lib/DBIx/Class/Schema/Loader/DBI/MSSQL.pm +++ b/lib/DBIx/Class/Schema/Loader/DBI/MSSQL.pm @@ -51,6 +51,11 @@ been renamed to a more generic option. =cut +# SQL Server 2000: Ancient as time itself, but still out in the wild +sub _is_2k { + return shift->schema->storage->_server_info->{normalized_dbms_version} < 9; +} + sub _system_databases { return (qw/ master model tempdb msdb @@ -63,18 +68,31 @@ sub _system_tables { /); } -sub _owners { +sub _schemas { my ($self, $db) = @_; - my $owners = $self->dbh->selectcol_arrayref(<<"EOF"); + my $owners = $self->dbh->selectcol_arrayref($self->_is_2k ? <<"EOF2K" : <<"EOF"); SELECT name FROM [$db].dbo.sysusers WHERE uid <> gid +EOF2K +SELECT name +FROM [$db].sys.schemas EOF return grep !/^(?:#|guest|INFORMATION_SCHEMA|sys)/, @$owners; } +sub _current_schema { + my $self = shift; + + if ($self->_is_2k) { + return ($self->dbh->selectrow_array('SELECT user_name()'))[0]; + } + + return ($self->dbh->selectrow_array('SELECT schema_name()'))[0]; +} + sub _current_db { my $self = shift; return ($self->dbh->selectrow_array('SELECT db_name()'))[0]; @@ -142,7 +160,7 @@ EOF } else { if ($db ne $current_db) { - $self->dbh->do("USE [$db]"); + $self->_switch_db($db); $self->qualify_objects(1); } @@ -154,7 +172,7 @@ EOF } elsif (ref $self->db_schema eq 'ARRAY' || (not defined $self->db_schema)) { my $owners = $self->db_schema; - $owners ||= [ $self->dbh->selectrow_array('SELECT user_name()') ]; + $owners ||= [ $self->_current_schema ]; $self->qualify_objects(1) if @$owners > 1; @@ -163,7 +181,7 @@ EOF foreach my $db (keys %{ $self->db_schema }) { if ($self->db_schema->{$db} eq '%') { - $self->db_schema->{$db} = [ $self->_owners($db) ]; + $self->db_schema->{$db} = [ $self->_schemas($db) ]; $self->qualify_objects(1); } @@ -359,11 +377,8 @@ sub _columns_info_for { my $result = $self->next::method(@_); - # SQL Server: Ancient as time itself, but still out in the wild - my $is_2k = $self->schema->storage->_server_info->{normalized_dbms_version} < 9; - # get type info (and identity) - my $rows = $self->dbh->selectall_arrayref($is_2k ? <<"EOF2K" : <<"EOF"); + my $rows = $self->dbh->selectall_arrayref($self->_is_2k ? <<"EOF2K" : <<"EOF"); SELECT c.column_name, c.character_maximum_length, c.data_type, c.datetime_precision, c.column_default, (sc.status & 0x80) is_identity FROM [$db].INFORMATION_SCHEMA.COLUMNS c JOIN [$db].dbo.sysusers ss ON