X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FUTF8Columns.pm;h=9a54e5bcbb17f86bc6201f7ea0084193b5bee1f6;hb=3c2a505c93702ae84fca6985e306da721de2830a;hp=c04c07377267e8deb2f5560b940f621e931471e3;hpb=4e8964d53864dc5ce61100fcf1418520a935a520;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/UTF8Columns.pm b/lib/DBIx/Class/UTF8Columns.pm index c04c073..9a54e5b 100644 --- a/lib/DBIx/Class/UTF8Columns.pm +++ b/lib/DBIx/Class/UTF8Columns.pm @@ -3,27 +3,81 @@ use strict; use warnings; use base qw/DBIx::Class/; -use Encode; - __PACKAGE__->mk_classdata( '_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 recieve +further warnings set the environmane 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 ths 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 @@ -41,7 +95,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; @@ -58,12 +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} ) { - Encode::_utf8_on($value) unless Encode::is_utf8($value); - } + utf8::decode($value) if ( + defined $value and $self->_is_utf8_column($column) and ! utf8::is_utf8($value) + ); - $value; + return $value; } =head2 get_columns @@ -74,11 +127,13 @@ sub get_columns { my $self = shift; my %data = $self->next::method(@_); - foreach my $col (grep { defined $data{$_} } keys %{ $self->_utf8_columns || {} }) { - Encode::_utf8_on($data{$col}) unless Encode::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 @@ -88,27 +143,33 @@ sub get_columns { sub store_column { my ( $self, $column, $value ) = @_; - my $cols = $self->_utf8_columns; - if ( $cols and defined $value and $cols->{$column} ) { - Encode::_utf8_off($value) if Encode::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 { + # my ($self, $col) = @_; + return ($_[0]->utf8_columns || {})->{$_[1]}; +} -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; -