Prevent invisible skipping of ResultSource proxy overrides
authorPeter Rabbitson <ribasushi@cpan.org>
Mon, 6 Jun 2016 11:58:31 +0000 (13:58 +0200)
committerPeter Rabbitson <ribasushi@cpan.org>
Thu, 28 Jul 2016 12:19:23 +0000 (14:19 +0200)
commit28ef9468343a356954f0e4dc6bba1b834a8b3c3c
treef4b397cb4d4cce6d0f0c0258d9504c6c75dda6f2
parent09d8fb4a05e6cd025924cc08e41484f17a116695
Prevent invisible skipping of ResultSource proxy overrides

*** NOTE ***
This does not add any new default functionality, nor does it alter DBIC's
behavior from how it solidified back in 2006: all this does is alert a user
when things are 99% not DWIM-ing (10 years overdue but better late than...)
*** NOTE ***

During the original design of DBIC the "ResultSourceProxy" system was
established in order to allow easy transition from Class::DBI. Sadly
it was not well abstracted away: it is rather difficult to use a custom
ResultSource subclass. The expansion of the DBIC project never addressed
this properly in the years since.

As a result when one wishes to override a part of the ResultSource
functionality, the overwhelmingly common practice is to hook a method in a
Result class and "hope for the best".

The subtle changes of various internal call-chains (mainly 4006691d) make
this silent uncertainty untenable. As a solution any such override will now
issue a descriptive warning that it has been bypassed during a direct
$rsrc->overriden_function invocation. A user now *must* determine how each
individual override must behave in this situation, and tag it with one of
the provided attributes.

For completeness the blueprint off which this solution was devised is
provided below:

  I = indirect (helper) method, never invoked by DBIC itself

* Rsrc method types
  . = rsrc_instance_specific_attribute type accessor (getter+setter)
  s = setter calling a . internally
  g = getter calling a . internally
  c = custom accessor

* Result method types
  P = proxied directly into ::Core via ::ResultSourceProxy (overridable)
  X = a ::Core proxy to ::ResultSource with extra logic (overridable)
  m = misc... stuff

    ___ Indirect methods ( the sanity checker warns when one "covers" these )
  /
 |   __ Rsrc methods somehow tied into the metadata state
 | /
 ||   _ Available to .../Result/... via ResultSourceProxy
 || /
 |||
 |||
DBIx::Class::ResultSource::View:
  .    is_virtual,
  .    deploy_depends_on,
  .    view_definition

DBIx::Class::ResultSource:
  c    schema

  .    source_name    # no proxy, but see FIXME at top of ::ResultSourceProxy

  .    _columns
  .    _ordered_columns
  .    _primaries
  .    _relationships
  .    _unique_constraints
  .P   column_info_from_storage
  .    name
  .P   result_class
  .P   resultset_attributes
  .P   resultset_class
  .P   source_info
  .    sqlt_deploy_callback

 IsX   add_column
  sX   add_columns
  sX   add_relationship,

 IsP   remove_column
  sP   remove_columns
  sP   add_unique_constraint
 IsP   add_unique_constraints
  sP   sequence
  sP   set_primary_key

 IgP   column_info
  gP   columns_info
  gP   columns

  gP   has_column
  gP   has_relationship
  gP   primary_columns
  gP   relationship_info
  gP   relationships

  gP   unique_constraint_columns
  gP   unique_constraint_names
  gP   unique_constraints

DBIx::Class::ResultSourceProxy::Table:
   m   table
   m   _init_result_source_instance
Changes
lib/DBIx/Class/CDBICompat/ColumnCase.pm
lib/DBIx/Class/CDBICompat/ColumnGroups.pm
lib/DBIx/Class/MethodAttributes.pm
lib/DBIx/Class/ResultSource.pm
lib/DBIx/Class/ResultSourceProxy.pm
lib/DBIx/Class/Schema/SanityChecker.pm
t/resultsource/rsrc_proxy_invocation.t [new file with mode: 0644]