Introducing DBIx::Class::Schema::SanityChecker
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / MethodAttributes.pm
index cea3961..0365dad 100644 (file)
@@ -6,7 +6,6 @@ use warnings;
 use DBIx::Class::_Util qw( uniq refdesc visit_namespaces );
 use Scalar::Util qw( weaken refaddr );
 
-use mro 'c3';
 use namespace::clean;
 
 my ( $attr_cref_registry, $attr_cache_active );
@@ -76,6 +75,16 @@ sub MODIFY_CODE_ATTRIBUTES {
     weaken( $attr_cref_registry->{$code}{weakref} = $code )
   }
 
+
+  # increment the pkg gen, this ensures the sanity checkers will re-evaluate
+  # this class when/if the time comes
+  mro::method_changed_in($class) if (
+    ! DBIx::Class::_ENV_::OLD_MRO
+      and
+    ( $attrs->{dbic} or $attrs->{misc} )
+  );
+
+
   # handle legacy attrs
   if( $attrs->{misc} ) {
 
@@ -94,6 +103,7 @@ sub MODIFY_CODE_ATTRIBUTES {
     ))];
   }
 
+
   # handle DBIC_* attrs
   if( $attrs->{dbic} ) {
     my $slot = $attr_cref_registry->{$code};
@@ -108,6 +118,7 @@ sub MODIFY_CODE_ATTRIBUTES {
     ];
   }
 
+
   # FIXME - DBIC essentially gobbles up any attribute it can lay its hands on:
   # decidedly not cool
   #
@@ -132,8 +143,22 @@ sub MODIFY_CODE_ATTRIBUTES {
 sub VALID_DBIC_CODE_ATTRIBUTE {
   #my ($class, $attr) = @_;
 
-  # initially no valid attributes
-  0;
+###
+### !!! IMPORTANT !!!
+###
+### *DO NOT* yield to the temptation of using free-form-argument attributes.
+### The technique was proven instrumental in Catalyst a decade ago, and
+### was more recently revived in Sub::Attributes. Yet, while on the surface
+### they seem immensely useful, per-attribute argument lists are in fact an
+### architectural dead end.
+###
+### In other words: you are *very strongly urged* to ensure the regex below
+### does not allow anything beyond qr/^ DBIC_method_is_ [A-Z_a-z0-9]+ $/x
+###
+
+  $_[1] =~ /^ DBIC_method_is_ (?:
+    indirect_sugar
+  ) $/x;
 }
 
 sub FETCH_CODE_ATTRIBUTES {
@@ -189,11 +214,16 @@ L</VALID_DBIC_CODE_ATTRIBUTE> below.
 The following method attributes are currently recognized under the C<DBIC_*>
 prefix:
 
-=over
+=head3 DBIC_method_is_indirect_sugar
 
-=item * None so far
+The presence of this attribute indicates a helper "sugar" method. Overriding
+such methods in your subclasses will be of limited success at best, as DBIC
+itself and various plugins are much more likely to invoke alternative direct
+call paths, bypassing your override entirely. Good examples of this are
+L<DBIx::Class::ResultSet/create> and L<DBIx::Class::Schema/connect>.
 
-=back
+See also the check
+L<DBIx::Class::Schema::SanityChecker/no_indirect_method_overrides>.
 
 =head1 METHODS