From: Rafael Kitover Date: Mon, 6 Jun 2011 10:04:31 +0000 (-0400) Subject: more work on multi-db_schema X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e4be49c99edfa51b5dee57848ab589fa9bff38a2;p=dbsrgits%2FDBIx-Class-Schema-Loader.git more work on multi-db_schema --- diff --git a/lib/DBIx/Class/Schema/Loader.pm b/lib/DBIx/Class/Schema/Loader.pm index f49a426..04a850c 100644 --- a/lib/DBIx/Class/Schema/Loader.pm +++ b/lib/DBIx/Class/Schema/Loader.pm @@ -453,19 +453,7 @@ Can be imported into your dump script and called as a function as well: =head2 Multiple Database Schemas -Currently the loader is limited to working within a single schema -(using the underlying RDBMS's definition of "schema"). If you have a -multi-schema database with inter-schema relationships (which is easy -to do in PostgreSQL or DB2 for instance), you currently can only -automatically load the tables of one schema, and relationships to -tables in other schemas will be silently ignored. - -At some point in the future, an intelligent way around this might be -devised, probably by allowing the C option to be an -arrayref of schemas to load. - -In "normal" L usage, manually-defined -source classes and relationships have no problems crossing vendor schemas. +See L. =head1 ACKNOWLEDGEMENTS diff --git a/lib/DBIx/Class/Schema/Loader/Base.pm b/lib/DBIx/Class/Schema/Loader/Base.pm index 622be52..11065f4 100644 --- a/lib/DBIx/Class/Schema/Loader/Base.pm +++ b/lib/DBIx/Class/Schema/Loader/Base.pm @@ -304,8 +304,12 @@ decides to execute will be C-ed before execution. =head2 db_schema Set the name of the schema to load (schema in the sense that your database -vendor means it). Does not currently support loading more than one schema -name. +vendor means it). + +Can be set to an arrayref of schema names for multiple schemas, or the special +value C<%> for all schemas. + +Multiple schemas have only been tested on PostgreSQL. =head2 constraint @@ -848,6 +852,27 @@ sub new { } } + if (defined $self->db_schema) { + if (ref $self->db_schema eq 'ARRAY') { + if (@{ $self->db_schema } > 1) { + $self->{qualify_objects} = 1; + } + elsif (@{ $self->db_schema } == 0) { + $self->{db_schema} = undef; + } + } + elsif (not ref $self->db_schema) { + if ($self->db_schema eq '%') { + $self->{qualify_objects} = 1; + } + + $self->{db_schema} = [ $self->db_schema ]; + } + else { + croak 'db_schema must be an array or single value'; + } + } + $self; } @@ -1873,14 +1898,12 @@ sub _is_result_class_method { sub _resolve_col_accessor_collisions { my ($self, $table, $col_info) = @_; - my $table_name = ref $table ? $$table : $table; - while (my ($col, $info) = each %$col_info) { my $accessor = $info->{accessor} || $col; next if $accessor eq 'id'; # special case (very common column) - if ($self->_is_result_class_method($accessor, $table_name)) { + if ($self->_is_result_class_method($accessor, $table)) { my $mapped = 0; if (my $map = $self->col_collision_map) { @@ -1894,7 +1917,7 @@ sub _resolve_col_accessor_collisions { if (not $mapped) { warn <<"EOF"; -Column '$col' in table '$table_name' collides with an inherited method. +Column '$col' in table '$table' collides with an inherited method. See "COLUMN ACCESSOR COLLISIONS" in perldoc DBIx::Class::Schema::Loader::Base . EOF $info->{accessor} = undef; @@ -1983,8 +2006,8 @@ sub _setup_src_meta { } my $full_table_name = ($self->qualify_objects ? - ($self->_quote($self->db_schema) . '.') : '') - . (ref $table_name ? $$table_name : $table_name); + ($self->_quote($table->schema) . '.') : '') + . (ref $table_name eq 'SCALAR' ? $$table_name : $table_name); # be careful to not create refs Data::Dump can "optimize" $full_table_name = \do {"".$full_table_name} if ref $table_name; diff --git a/lib/DBIx/Class/Schema/Loader/DBI.pm b/lib/DBIx/Class/Schema/Loader/DBI.pm index 964e923..f052bb7 100644 --- a/lib/DBIx/Class/Schema/Loader/DBI.pm +++ b/lib/DBIx/Class/Schema/Loader/DBI.pm @@ -169,10 +169,10 @@ sub _table_as_sql { my $sql_maker = $self->schema->storage->sql_maker; my $name_sep = $sql_maker->name_sep; - my $db_schema = $self->db_schema; + my $schema = $table->schema; - if($db_schema) { - return $self->_quote($self->{db_schema}) + if ($schema) { + return $self->_quote($schema) . $name_sep . $self->_quote($table); } diff --git a/lib/DBIx/Class/Schema/Loader/DBI/Pg.pm b/lib/DBIx/Class/Schema/Loader/DBI/Pg.pm index 913e1d1..4bb5d23 100644 --- a/lib/DBIx/Class/Schema/Loader/DBI/Pg.pm +++ b/lib/DBIx/Class/Schema/Loader/DBI/Pg.pm @@ -6,8 +6,8 @@ use base qw/ DBIx::Class::Schema::Loader::DBI::Component::QuotedDefault DBIx::Class::Schema::Loader::DBI /; -use Carp::Clan qw/^DBIx::Class/; use mro 'c3'; +use DBIx::Class::Schema::Loader::Table (); our $VERSION = '0.07010'; @@ -16,18 +16,9 @@ our $VERSION = '0.07010'; DBIx::Class::Schema::Loader::DBI::Pg - DBIx::Class::Schema::Loader::DBI PostgreSQL Implementation. -=head1 SYNOPSIS - - package My::Schema; - use base qw/DBIx::Class::Schema::Loader/; - - __PACKAGE__->loader_options( debug => 1 ); - - 1; - =head1 DESCRIPTION -See L. +See L and L. =cut @@ -36,7 +27,7 @@ sub _setup { $self->next::method(@_); - $self->{db_schema} ||= 'public'; + $self->{db_schema} ||= ['public']; if (not defined $self->preserve_case) { $self->preserve_case(0); @@ -51,18 +42,30 @@ sub _tables_list { my ($self, $opts) = @_; my $dbh = $self->schema->storage->dbh; - my @tables = $dbh->tables(undef, $self->db_schema, '%', '%'); - my $schema_quoted = $tables[0] =~ /^"/; + my @tables; - if ($schema_quoted) { - s/^"[^"]+"\.// for @tables; - } - else { - s/^[^.]+\.// for @tables; - } + foreach my $schema (@{ $self->db_schema }) { + my @raw_tables = $dbh->tables(undef, $schema, '%', '%'); - s/^"([^"]+)"\z/$1/ for @tables; + foreach my $table_name (@raw_tables) { + my $schema_quoted = $table_name =~ /^"/; + + if ($schema_quoted) { + $table_name =~ s/^"([^"]+)"\.//; + } + else { + $table_name =~ s/^([^.]+)\.//; + } + my $table = DBIx::Class::Schema::Loader::Table->new(schema => $1); + + $table_name =~ s/^"([^"]+)"\z/$1/; + + $table->name($table_name); + + push @tables, $table; + } + } return $self->_filter_tables(\@tables, $opts); } @@ -103,7 +106,7 @@ sub _table_uniq_info { c.relname = ?} ); - $uniq_sth->execute($self->db_schema, $table); + $uniq_sth->execute($table->schema, $table); while(my $row = $uniq_sth->fetchrow_arrayref) { my ($tableid, $indexname, $col_nums) = @$row; $col_nums =~ s/^\s+//; @@ -134,7 +137,7 @@ sub _table_comment { FROM pg_class WHERE relname=? AND relnamespace=( SELECT oid FROM pg_namespace WHERE nspname=?) - }, undef, $table, $self->db_schema + }, undef, $table, $table->schema ); return $table_comment } @@ -147,7 +150,7 @@ sub _column_comment { FROM pg_class WHERE relname=? AND relnamespace=( SELECT oid FROM pg_namespace WHERE nspname=?) - }, undef, $table, $self->db_schema + }, undef, $table, $table->schema ); return $self->schema->storage->dbh->selectrow_array('SELECT col_description(?,?)', undef, $table_oid, $column_number ); @@ -251,7 +254,7 @@ SELECT typtype FROM pg_catalog.pg_type WHERE typname = ? EOF - if ($typetype eq 'e') { + if ($typetype && $typetype eq 'e') { # The following will extract a list of allowed values for the # enum. my $typevalues = $self->schema->storage->dbh diff --git a/lib/DBIx/Class/Schema/Loader/TableLike.pm b/lib/DBIx/Class/Schema/Loader/TableLike.pm index 366eb43..bdfbfe9 100644 --- a/lib/DBIx/Class/Schema/Loader/TableLike.pm +++ b/lib/DBIx/Class/Schema/Loader/TableLike.pm @@ -27,7 +27,13 @@ __PACKAGE__->mk_group_accessors(simple => qw/ /); use overload - '""' => 'name'; + '""' => sub { $_[0]->name }; + +sub new { + my $class = shift; + + return bless { @_ }, $class; +} =head1 SEE ALSO diff --git a/t/lib/dbixcsl_common_tests.pm b/t/lib/dbixcsl_common_tests.pm index 0739692..9067be9 100644 --- a/t/lib/dbixcsl_common_tests.pm +++ b/t/lib/dbixcsl_common_tests.pm @@ -574,12 +574,12 @@ sub test_schema { ); is( - sprintf("%.3f", $class35->column_info('a_double')->{default_value}), '10.555', + sprintf("%.3f", $class35->column_info('a_double')->{default_value}||0), '10.555', 'constant numeric default', ); is( - sprintf("%.3f", $class35->column_info('a_negative_double')->{default_value}), -10.555, + sprintf("%.3f", $class35->column_info('a_negative_double')->{default_value}||0), -10.555, 'constant negative numeric default', );