X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FUTF8Columns.pm;h=db571a69cd5f2054fe5b475e8ce5578b50e5118e;hb=d2308dde5718dc0f828584c3fa24d7417c484040;hp=f060f817cc43c3bd8e12da4f75717aa4415cbf28;hpb=337c98ef113c56111e11a3af9043acdb7133106b;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/UTF8Columns.pm b/lib/DBIx/Class/UTF8Columns.pm index f060f81..db571a6 100644 --- a/lib/DBIx/Class/UTF8Columns.pm +++ b/lib/DBIx/Class/UTF8Columns.pm @@ -3,36 +3,81 @@ use strict; use warnings; use base qw/DBIx::Class/; -BEGIN { - - # Perl 5.8.0 doesn't have utf8::is_utf8() - # Yes, 5.8.0 support for Unicode is suboptimal, but things like RHEL3 ship with it. - if ($] <= 5.008000) { - require Encode; - } else { - require utf8; - } -} - -__PACKAGE__->mk_classdata( '_utf8_columns' ); +__PACKAGE__->mk_group_accessors( inherited => '_utf8_columns' ); =head1 NAME -DBIx::Class::UTF8Columns - Force UTF8 (Unicode) flag on columns +DBIx::Class::UTF8Columns - Force UTF8 (Unicode) flag on columns (DEPRECATED) =head1 SYNOPSIS package Artist; - __PACKAGE__->load_components(qw/UTF8Columns Core/); + use base 'DBIx::Class::Core'; + + __PACKAGE__->load_components(qw/UTF8Columns/); __PACKAGE__->utf8_columns(qw/name description/); - + # then belows return strings with utf8 flag $artist->name; $artist->get_column('description'); =head1 DESCRIPTION -This module allows you to get columns data that have utf8 (Unicode) flag. +This module allows you to get and store utf8 (unicode) column data +in a database that does not natively support unicode. It ensures +that column data is correctly serialised as a byte stream when +stored and de-serialised to unicode strings on retrieval. + + THE USE OF THIS MODULE (AND ITS COUSIN DBIx::Class::ForceUTF8) IS VERY + STRONGLY DISCOURAGED, PLEASE READ THE WARNINGS BELOW FOR AN EXPLANATION. + +If you want to continue using this module and do not want to receive +further warnings set the environment variable C +to a true value. + +=head2 Warning - Module does not function properly on create/insert + +Recently (April 2010) a bug was found deep in the core of L +which affects any component attempting to perform encoding/decoding by +overloading L and +L. As a result of this problem +L sends the original column values +to the database, while L sends the +encoded values. L and L +are both affected by this bug. + +It is unclear how this bug went undetected for so long (it was +introduced in March 2006), No attempts to fix it will be made while the +implications of changing such a fundamental behavior of DBIx::Class are +being evaluated. However in this day and age you should not be using +this module anyway as Unicode is properly supported by all major +database engines, as explained below. + +If you have specific questions about the integrity of your data in light +of this development - please +L +to further discuss your concerns with the team. + +=head2 Warning - Native Database Unicode Support + +If your database natively supports Unicode (as does SQLite with the +C connect flag, MySQL with C +connect flag or Postgres with the C connect flag), +then this component should B be used, and will corrupt unicode +data in a subtle and unexpected manner. + +It is far better to do Unicode support within the database if +possible rather than converting data to and from raw bytes on every +database round trip. + +=head2 Warning - Component Overloading + +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 @@ -49,8 +94,8 @@ sub utf8_columns { if (@_) { foreach my $col (@_) { $self->throw_exception("column $col doesn't exist") - unless $self->has_column($col); - } + unless $self->result_source->has_column($col); + } return $self->_utf8_columns({ map { $_ => 1 } @_ }); } else { return $self->_utf8_columns; @@ -67,17 +112,11 @@ 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) if ( + defined $value and $self->_is_utf8_column($column) and ! utf8::is_utf8($value) + ); - if ($] <= 5.008000) { - Encode::_utf8_on($value) unless Encode::is_utf8($value); - } else { - utf8::decode($value) unless utf8::is_utf8($value); - } - } - - $value; + return $value; } =head2 get_columns @@ -88,16 +127,13 @@ sub get_columns { my $self = shift; my %data = $self->next::method(@_); - foreach my $col (grep { defined $data{$_} } keys %{ $self->_utf8_columns || {} }) { - - if ($] <= 5.008000) { - Encode::_utf8_on($data{$col}) unless Encode::is_utf8($data{$col}); - } else { - 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}) + ); } - %data; + return %data; } =head2 store_column @@ -107,32 +143,36 @@ sub get_columns { sub store_column { my ( $self, $column, $value ) = @_; - my $cols = $self->_utf8_columns; - if ( $cols and defined $value and $cols->{$column} ) { + # the dirtiness comparison must happen on the non-encoded value + my $copy; - if ($] <= 5.008000) { - Encode::_utf8_off($value) if Encode::is_utf8($value); - } else { - utf8::encode($value) if utf8::is_utf8($value); - } + 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 { + # my ($self, $col) = @_; + return ($_[0]->utf8_columns || {})->{$_[1]}; +} -Daisuke Murase +=head1 FURTHER QUESTIONS? -=head1 COPYRIGHT +Check the list of L. -This program is free software; you can redistribute -it and/or modify it under the same terms as Perl itself. +=head1 COPYRIGHT AND LICENSE -The full text of the license can be found in the -LICENSE file included with this module. +This module is free software L +by the L. You can +redistribute it and/or modify it under the same terms as the +L. =cut 1; -