File Coverage

blib/lib/DBIx/Class/UTF8Columns.pm
Criterion Covered Total %
statement 33 33 100.0
branch 9 10 90.0
condition 17 26 65.3
subroutine 8 8 100.0
pod 4 4 100.0
total 71 81 87.6


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