SQLite changed their exception text again
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / UTF8Columns.pm
CommitLineData
5dd9c59c 1package DBIx::Class::UTF8Columns;
2use strict;
3use warnings;
4use base qw/DBIx::Class/;
5dd9c59c 5
4e8964d5 6__PACKAGE__->mk_classdata( '_utf8_columns' );
5dd9c59c 7
8=head1 NAME
9
3c2a505c 10DBIx::Class::UTF8Columns - Force UTF8 (Unicode) flag on columns (DEPRECATED)
7c14c3cf 11
5dd9c59c 12=head1 SYNOPSIS
13
14 package Artist;
d88ecca6 15 use base 'DBIx::Class::Core';
16
17 __PACKAGE__->load_components(qw/UTF8Columns/);
5dd9c59c 18 __PACKAGE__->utf8_columns(qw/name description/);
d4daee7b 19
5dd9c59c 20 # then belows return strings with utf8 flag
21 $artist->name;
22 $artist->get_column('description');
23
24=head1 DESCRIPTION
25
7c14c3cf 26This module allows you to get and store utf8 (unicode) column data
27in a database that does not natively support unicode. It ensures
28that column data is correctly serialised as a byte stream when
29stored and de-serialised to unicode strings on retrieval.
30
3c2a505c 31 THE USE OF THIS MODULE (AND ITS COUSIN DBIx::Class::ForceUTF8) IS VERY
32 STRONGLY DISCOURAGED, PLEASE READ THE WARNINGS BELOW FOR AN EXPLANATION.
33
aa9bcbfb 34If you want to continue using this module and do not want to receive
4d1e63f4 35further warnings set the environment variable C<DBIC_UTF8COLUMNS_OK>
3c2a505c 36to a true value.
37
38=head2 Warning - Module does not function properly on create/insert
39
40Recently (April 2010) a bug was found deep in the core of L<DBIx::Class>
41which affects any component attempting to perform encoding/decoding by
42overloading L<store_column|DBIx::Class::Row/store_column> and
43L<get_columns|DBIx::Class::Row/get_columns>. As a result of this problem
44L<create|DBIx::Class::ResultSet/create> sends the original column values
45to the database, while L<update|DBIx::Class::ResultSet/update> sends the
46encoded values. L<DBIx::Class::UTF8Columns> and L<DBIx::Class::ForceUTF8>
4a0eed52 47are both affected by this bug.
3c2a505c 48
49It is unclear how this bug went undetected for so long (it was
50introduced in March 2006), No attempts to fix it will be made while the
51implications of changing such a fundamental behavior of DBIx::Class are
52being evaluated. However in this day and age you should not be using
53this module anyway as Unicode is properly supported by all major
54database engines, as explained below.
55
56If you have specific questions about the integrity of your data in light
8273e845 57of this development - please
3c2a505c 58L<join us on IRC or the mailing list|DBIx::Class/GETTING HELP/SUPPORT>
59to further discuss your concerns with the team.
60
7c14c3cf 61=head2 Warning - Native Database Unicode Support
62
63If your database natively supports Unicode (as does SQLite with the
64C<sqlite_unicode> connect flag, MySQL with C<mysql_enable_utf8>
65connect flag or Postgres with the C<pg_enable_utf8> connect flag),
66then this component should B<not> be used, and will corrupt unicode
67data in a subtle and unexpected manner.
68
69It is far better to do Unicode support within the database if
3c2a505c 70possible rather than converting data to and from raw bytes on every
71database round trip.
5dd9c59c 72
7c14c3cf 73=head2 Warning - Component Overloading
d38cd95c 74
75Note that this module overloads L<DBIx::Class::Row/store_column> in a way
76that may prevent other components overloading the same method from working
77correctly. This component must be the last one before L<DBIx::Class::Row>
78(which is provided by L<DBIx::Class::Core>). DBIx::Class will detect such
79incorrect component order and issue an appropriate warning, advising which
80components need to be loaded differently.
81
5dd9c59c 82=head1 SEE ALSO
83
84L<Template::Stash::ForceUTF8>, L<DBIx::Class::UUIDColumns>.
85
86=head1 METHODS
87
88=head2 utf8_columns
89
90=cut
91
92sub utf8_columns {
93 my $self = shift;
4e8964d5 94 if (@_) {
95 foreach my $col (@_) {
96 $self->throw_exception("column $col doesn't exist")
97 unless $self->has_column($col);
d38cd95c 98 }
4e8964d5 99 return $self->_utf8_columns({ map { $_ => 1 } @_ });
100 } else {
101 return $self->_utf8_columns;
5dd9c59c 102 }
5dd9c59c 103}
104
105=head1 EXTENDED METHODS
106
107=head2 get_column
108
109=cut
110
111sub get_column {
112 my ( $self, $column ) = @_;
113 my $value = $self->next::method($column);
114
d38cd95c 115 utf8::decode($value) if (
116 defined $value and $self->_is_utf8_column($column) and ! utf8::is_utf8($value)
117 );
5dd9c59c 118
55087b99 119 return $value;
5dd9c59c 120}
121
e063fe2c 122=head2 get_columns
123
124=cut
125
126sub get_columns {
127 my $self = shift;
128 my %data = $self->next::method(@_);
129
d38cd95c 130 foreach my $col (keys %data) {
131 utf8::decode($data{$col}) if (
132 exists $data{$col} and defined $data{$col} and $self->_is_utf8_column($col) and ! utf8::is_utf8($data{$col})
133 );
e063fe2c 134 }
135
55087b99 136 return %data;
e063fe2c 137}
138
5dd9c59c 139=head2 store_column
140
141=cut
142
143sub store_column {
144 my ( $self, $column, $value ) = @_;
145
4a0eed52 146 # the dirtiness comparison must happen on the non-encoded value
d38cd95c 147 my $copy;
148
149 if ( defined $value and $self->_is_utf8_column($column) and utf8::is_utf8($value) ) {
150 $copy = $value;
151 utf8::encode($value);
5dd9c59c 152 }
153
154 $self->next::method( $column, $value );
d38cd95c 155
156 return $copy || $value;
5dd9c59c 157}
158
d38cd95c 159# override this if you want to force everything to be encoded/decoded
160sub _is_utf8_column {
2ba92e45 161 # my ($self, $col) = @_;
162 return ($_[0]->utf8_columns || {})->{$_[1]};
d38cd95c 163}
5dd9c59c 164
d38cd95c 165=head1 AUTHORS
5dd9c59c 166
d38cd95c 167See L<DBIx::Class/CONTRIBUTORS>.
5dd9c59c 168
d38cd95c 169=head1 LICENSE
5dd9c59c 170
d38cd95c 171You may distribute this code under the same terms as Perl itself.
5dd9c59c 172
173=cut
174
1751;