Allow using all the moniker parts in hashref moniker_map
Dagfinn Ilmari Mannsåker [Wed, 24 Jul 2013 21:36:30 +0000 (22:36 +0100)]
Changes
lib/DBIx/Class/Schema/Loader/Base.pm
lib/DBIx/Class/Schema/Loader/DBObject.pm
t/23dumpmore.t

diff --git a/Changes b/Changes
index b9a3923..e10eb1b 100644 (file)
--- a/Changes
+++ b/Changes
@@ -6,6 +6,7 @@ Revision history for Perl extension DBIx::Class::Schema::Loader
         - Allow specifying custom attributes for many_to_many bridges
         - Allow specifying the separator when joining database, schema
           and table names to form a moniker
+        - Allow using all the moniker parts in hashref moniker_map
 
 0.07036  2013-07-08
         - Fix stray comma in Pg on_delete/on_update => CASCADE (RT#84706)
index c1786cc..deafe17 100644 (file)
@@ -555,11 +555,39 @@ Exclude tables matching regex.  Best specified as a qr// regex.
 
 =head2 moniker_map
 
-Overrides the default table name to moniker translation.  Can be either a
-hashref of table keys and moniker values, or a coderef for a translator
-function taking a L<table object|DBIx::Class::Schema::Loader::Table> argument
-(which stringifies to the unqualified table name) and returning a scalar
-moniker.  If the hash entry does not exist, or the function returns a false
+Overrides the default table name to moniker translation. Either
+
+=over
+
+=item *
+
+a nested hashref, which will be traversed according to L</moniker_parts>
+
+For example:
+
+    moniker_parts => [qw(schema name)],
+    moniker_map => {
+        foo => {
+            bar  => "FooishBar",
+        },
+    },
+
+In which case the table C<bar> in the C<foo> schema would get the moniker
+C<FooishBar>.
+
+=item *
+
+a hashref of unqualified table name keys and moniker values
+
+=item *
+
+a coderef for a translator function taking a L<table
+object|DBIx::Class::Schema::Loader::Table> argument (which stringifies to the
+unqualified table name) and returning a scalar moniker
+
+=back
+
+If the hash entry does not exist, or the function returns a false
 value, the code falls back to default behavior for that table name.
 
 The default behavior is to split on case transition and non-alphanumeric
@@ -2355,7 +2383,23 @@ sub _run_user_map {
     my $default_ident = $default_code->( $ident, @extra );
     my $new_ident;
     if( $map && ref $map eq 'HASH' ) {
-        $new_ident = $map->{ $ident };
+        if (my @parts = try{ @{ $ident } }) {
+            my $part_map = $map;
+            while (@parts) {
+                my $part = shift @parts;
+                last unless exists $part_map->{ $part };
+                if ( !ref $part_map->{ $part } && !@parts ) {
+                    $new_ident = $part_map->{ $part };
+                    last;
+                }
+                elsif ( ref $part_map->{ $part } eq 'HASH' ) {
+                    $part_map = $part_map->{ $part };
+                }
+            }
+        }
+        if( !$new_ident && !ref $map->{ $ident } ) {
+            $new_ident = $map->{ $ident };
+        }
     }
     elsif( $map && ref $map eq 'CODE' ) {
         $new_ident = $map->( $ident, $default_ident, @extra );
index 1e6df30..a4a9e2c 100644 (file)
@@ -35,6 +35,7 @@ __PACKAGE__->mk_group_accessors(simple => qw/
 
 use overload
     '""' => sub { $_[0]->name },
+    '@{}' => sub { $_[0]->name_parts },
     fallback => 1;
 
 =head2 new
@@ -153,6 +154,20 @@ sub dbic_name {
     return $self->name;
 }
 
+=head2 name_parts
+
+Returns an arrayref of the values returned by the methods specified in
+the L<moniker_parts|DBIx::Class::Scheam::Loader::Base/moniker_parts> of
+the L</loader> object. The object arrayrefifies to this value.
+
+=cut
+
+sub name_parts {
+    my ($self) = shift;
+    return [ map { $self->$_ } @{$self->loader->moniker_parts} ];
+}
+
+
 =head1 SEE ALSO
 
 L<DBIx::Class::Schema::Loader::Table>, L<DBIx::Class::Schema::Loader>,
index 6e903f8..bebd4b4 100644 (file)
@@ -372,6 +372,32 @@ $t->dump_test(
   },
 );
 
+# test moniker_part_separator + moniker_map
+$t->dump_test(
+  classname => 'DBICTest::DumpMore::1',
+  options => {
+    db_schema => 'my_schema',
+    moniker_parts => ['_schema', 'name'],
+    moniker_part_separator => '::',
+    qualify_objects => 1,
+    use_namespaces => 1,
+    moniker_map => {
+        my_schema => { foo => "MySchema::Floop" },
+    }
+  },
+  warnings => [
+    qr/^db_schema is not supported on SQLite/,
+  ],
+  regexes => {
+    'Result/MySchema/Floop' => [
+      qr/^package DBICTest::DumpMore::1::Result::MySchema::Floop;$/m,
+      qr/^\Q__PACKAGE__->table("my_schema.foo");\E/m,
+      # the has_many relname should not have the schema in it!
+      qr/^__PACKAGE__->has_many\(\n  "bars"/m,
+    ],
+  },
+);
+
 $t->dump_test(
   classname => 'DBICTest::DumpMore::1',
   options => {