diff options
author | Mitch Jackson <mitch@freeside.biz> | 2019-03-03 16:35:25 -0500 |
---|---|---|
committer | Mitch Jackson <mitch@freeside.biz> | 2019-03-03 19:53:31 -0500 |
commit | 50a717fa7328dfb36d8d3d6c30d616399cda771f (patch) | |
tree | 15cdccb2fbb44b294676626b8d8c7332246cb89a /FS/FS/DBI.pm | |
parent | c06c0fb20f33de42af60208e43e41d84f3df66ea (diff) |
RT# 82942 Add FS::DBI, to fix database connection encoding bug
- Add FS::DBI
- Drop-in replacement for DBI
- Ensures client_encoding is set to UTF8 for DBD::Pg
- Implement FS::DBI in FS::UID, where nearly all freeside
database connections are established
Diffstat (limited to 'FS/FS/DBI.pm')
-rw-r--r-- | FS/FS/DBI.pm | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/FS/FS/DBI.pm b/FS/FS/DBI.pm new file mode 100644 index 0000000..c6ff125 --- /dev/null +++ b/FS/FS/DBI.pm @@ -0,0 +1,72 @@ +package FS::DBI; +use strict; +use warnings; +use base qw( DBI ); + +=head1 NAME + +FS::DBI - Freeside wrapper for DBI + +=head1 SYNOPSIS + + use FS::DBI; + + $dbh = FS::DBI->connect( @args ); + $dbh->do( + 'UPDATE table SET foo = ? WHERE bar = ?', + undef, + $foo, $bar + ) or die $dbh->errstr; + +See L<DBI> + +=head1 DESCRIPTION + +Allow Freeside to manage how DBI is used when necessary + +=head2 Legacy databases and DBD::Pg v3.0+ + +Breaking behavior was introduced in DBD::Pg version 3.0.0 +in regards to L<DBD::Pg/pg_enable_utf8>. + +Some freedside databases are legacy databases with older encodings +and locales. pg_enable_utf8 no longer sets client_encoding to utf8 +on non-utf8 databases, causing crashes and data corruption. + +FS::DBI->connect() enforces utf8 client_encoding on all DBD::Pg connections + +=head1 METHODS + +=head2 connect @connect_args + +For usage, see L<DBI/connect> + +Force utf8 client_encoding on DBD::Pg connections + +=cut + +sub connect { + my $class = shift; + my $dbh = $class->SUPER::connect( @_ ); + + if ( $_[0] =~ /^DBI::Pg/ ) { + $dbh->do('SET client_encoding TO UTF8;') + or die sprintf 'Error setting client_encoding to UTF8: %s', $dbh->errstr; + + # DBD::Pg requires touching this attribute when changing the client_encoding + # on an already established connection, to get expected behavior. + $dbh->{pg_enable_utf8} = -1; + } + + $dbh; +} + +# Stub required to subclass DBI +package FS::DBI::st; +use base qw( DBI::st ); + +# Stub required to subclass DBI +package FS::DBI::db; +use base qw( DBI::db ); + +1; |