From: Peter Rabbitson Date: Fri, 8 Jan 2010 16:52:01 +0000 (+0000) Subject: Put utf8columns in line with the store_column fix X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=d38cd95cdbfbd66ff2eddd053e6cbb6f7ad4f102;p=dbsrgits%2FDBIx-Class-Historic.git Put utf8columns in line with the store_column fix --- diff --git a/lib/DBIx/Class.pm b/lib/DBIx/Class.pm index 3a8fa69..d5e742c 100644 --- a/lib/DBIx/Class.pm +++ b/lib/DBIx/Class.pm @@ -4,9 +4,10 @@ use strict; use warnings; use MRO::Compat; +use mro 'c3'; use vars qw($VERSION); -use base qw/Class::C3::Componentised Class::Accessor::Grouped/; +use base qw/DBIx::Class::Componentised Class::Accessor::Grouped/; use DBIx::Class::StartupCheck; sub mk_classdata { diff --git a/lib/DBIx/Class/Componentised.pm b/lib/DBIx/Class/Componentised.pm index 7cb5d54..7b6813e 100644 --- a/lib/DBIx/Class/Componentised.pm +++ b/lib/DBIx/Class/Componentised.pm @@ -4,10 +4,34 @@ package # hide from PAUSE use strict; use warnings; -### -# Keep this class for backwards compatibility -### - use base 'Class::C3::Componentised'; +use Carp::Clan qw/^DBIx::Class|^Class::C3::Componentised/; +use mro 'c3'; + +# this warns of subtle bugs introduced by UTF8Columns hacky handling of store_column +sub inject_base { + my $class = shift; + my $target = shift; + + my @present_components = (@{mro::get_linear_isa ($target)||[]}); + + no strict 'refs'; + for my $comp (reverse @_) { + if ( + $comp->isa ('DBIx::Class::UTF8Columns') + and + my @broken = grep { $_ ne 'DBIx::Class::Row' and defined ${"${_}::"}{store_column} } (@present_components) + ) { + carp "Incorrect loading order of $comp by ${target} will affect other components overriding store_column (" + . join (', ', @broken) + .'). Refer to the documentation of DBIx::Class::UTF8Columns for more info'; + } + else { + unshift @present_components, $comp; + } + } + + $class->next::method($target, @_); +} 1; diff --git a/lib/DBIx/Class/UTF8Columns.pm b/lib/DBIx/Class/UTF8Columns.pm index 7977e63..7e21502 100644 --- a/lib/DBIx/Class/UTF8Columns.pm +++ b/lib/DBIx/Class/UTF8Columns.pm @@ -26,6 +26,15 @@ DBIx::Class::UTF8Columns - Force UTF8 (Unicode) flag on columns This module allows you to get columns data that have utf8 (Unicode) flag. +=head2 Warning + +Note that this module overloads L in a way +that may prevent other components overloading the same method from working +correctly. This component must be the last one before L +(which is provided by L). DBIx::Class will detect such +incorrect component order and issue an appropriate warning, advising which +components need to be loaded differently. + =head1 SEE ALSO L, L. @@ -42,7 +51,7 @@ sub utf8_columns { foreach my $col (@_) { $self->throw_exception("column $col doesn't exist") unless $self->has_column($col); - } + } return $self->_utf8_columns({ map { $_ => 1 } @_ }); } else { return $self->_utf8_columns; @@ -59,10 +68,9 @@ sub get_column { my ( $self, $column ) = @_; my $value = $self->next::method($column); - my $cols = $self->_utf8_columns; - if ( $cols and defined $value and $cols->{$column} ) { - utf8::decode($value) unless utf8::is_utf8($value); - } + utf8::decode($value) if ( + defined $value and $self->_is_utf8_column($column) and ! utf8::is_utf8($value) + ); return $value; } @@ -75,8 +83,10 @@ sub get_columns { my $self = shift; my %data = $self->next::method(@_); - foreach my $col (grep { defined $data{$_} } keys %{ $self->_utf8_columns || {} }) { - utf8::decode($data{$col}) unless utf8::is_utf8($data{$col}); + foreach my $col (keys %data) { + utf8::decode($data{$col}) if ( + exists $data{$col} and defined $data{$col} and $self->_is_utf8_column($col) and ! utf8::is_utf8($data{$col}) + ); } return %data; @@ -89,27 +99,32 @@ sub get_columns { sub store_column { my ( $self, $column, $value ) = @_; - my $cols = $self->_utf8_columns; - if ( $cols and defined $value and $cols->{$column} ) { - utf8::encode($value) if utf8::is_utf8($value); + # the dirtyness comparison must happen on the non-encoded value + my $copy; + + if ( defined $value and $self->_is_utf8_column($column) and utf8::is_utf8($value) ) { + $copy = $value; + utf8::encode($value); } $self->next::method( $column, $value ); + + return $copy || $value; } -=head1 AUTHOR +# override this if you want to force everything to be encoded/decoded +sub _is_utf8_column { + return (shift->utf8_columns || {})->{shift}; +} -Daisuke Murase +=head1 AUTHORS -=head1 COPYRIGHT +See L. -This program is free software; you can redistribute -it and/or modify it under the same terms as Perl itself. +=head1 LICENSE -The full text of the license can be found in the -LICENSE file included with this module. +You may distribute this code under the same terms as Perl itself. =cut 1; - diff --git a/t/85utf8.t b/t/85utf8.t index 2a89fa6..399c46d 100644 --- a/t/85utf8.t +++ b/t/85utf8.t @@ -2,10 +2,25 @@ use strict; use warnings; use Test::More; +use Test::Warn; use lib qw(t/lib); use DBICTest; use utf8; +warning_like (sub { + + package A::Comp; + use base 'DBIx::Class'; + sub store_column { shift->next::method (@_) }; + 1; + + package A::Test; + use base 'DBIx::Class::Core'; + __PACKAGE__->load_components(qw(UTF8Columns +A::Comp)); + 1; +}, qr/Incorrect loading order of DBIx::Class::UTF8Columns/ ); + + my $schema = DBICTest->init_schema(); DBICTest::Schema::CD->load_components('UTF8Columns');