root/branches/release-38/lib/MT/ObjectDriver/Driver/DBD/Pg.pm @ 2367

Revision 2367, 3.8 kB (checked in by bchoate, 19 months ago)

Issue _set_names when init_dbh is invoked. BugId:79506

  • Property svn:keywords set to Id Revision
Line 
1# Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd.
2# This program is distributed under the terms of the
3# GNU General Public License, version 2.
4#
5# $Id$
6
7package MT::ObjectDriver::Driver::DBD::Pg;
8
9use strict;
10use warnings;
11
12use base qw(
13    MT::ObjectDriver::Driver::DBD::Legacy
14    Data::ObjectDriver::Driver::DBD::Pg
15    MT::ErrorHandler
16);
17
18sub sql_class {
19    require MT::ObjectDriver::SQL::Pg;
20    return 'MT::ObjectDriver::SQL::Pg';
21}
22
23sub ddl_class {
24    require MT::ObjectDriver::DDL::Pg;
25    return 'MT::ObjectDriver::DDL::Pg';
26}
27
28sub dsn_from_config {
29    my $dbd = shift;
30    my $dsn = $dbd->SUPER::dsn_from_config(@_);
31    my ($cfg) = @_;
32    $dsn .= ':dbname=' . $cfg->Database;
33    $dsn .= ';host=' . $cfg->DBHost if $cfg->DBHost;
34    $dsn .= ';port=' . $cfg->DBPort if $cfg->DBPort;
35    return $dsn;
36}
37
38sub ts2db {
39    my $ts = sprintf '%04d-%02d-%02d %02d:%02d:%02d', unpack 'A4A2A2A2A2A2', $_[1];
40    $ts = undef if $ts eq '0000-00-00 00:00:00';
41    return $ts;
42}
43
44sub db2ts {
45    my $ts = $_[1];
46    $ts =~ s/(?:\+|-)\d{2}$//;
47    $ts =~ tr/\- ://d;
48    return $ts;
49}
50
51sub configure {
52    my $dbd = shift;
53    my ($driver) = @_;
54    $driver->pk_generator(\&pk_generator); 
55    return $dbd;
56}
57
58sub pk_generator {
59    my $obj = shift;  # not a method
60    my $driver = UNIVERSAL::isa($obj, 'MT::Object')
61      ? $obj->driver
62      : MT::Object->driver;
63    my $seq    = $driver->dbd->sequence_name(ref $obj);
64    my $dbh    = $driver->rw_handle;
65    my $sth    = $dbh->prepare("SELECT NEXTVAL('$seq')")
66      or die UNIVERSAL::isa($obj, 'MT::ErrorHandler')
67        ? $obj->error($dbh->errstr)
68        : $dbh->errstr;
69    $sth->execute
70      or die UNIVERSAL::isa($obj, 'MT::ErrorHandler')
71        ? $obj->error($dbh->errstr)
72        : $dbh->errstr;
73    $sth->bind_columns(undef, \my($id));
74    $sth->fetch;
75    $sth->finish;
76
77    my $col = $obj->properties->{primary_key};
78    ## If it's a complex primary key, use the second half.
79    if(ref $col) {
80        $col = $col->[1];
81    }
82    $obj->$col($id);
83    return $id;
84}
85
86sub init_dbh {
87    my $dbd = shift;
88    my ($dbh) = @_;
89    $dbd->SUPER::init_dbh(@_);
90    $dbd->_set_names($dbh);
91}
92
93sub _set_names {
94    my $dbd = shift;
95    my ($dbh) = @_;
96    return 1 if exists $dbh->{private_set_names};
97
98    my $cfg = MT->config;
99    my $set_names = $cfg->SQLSetNames;
100    $dbh->{private_set_names} = 1;
101    return 1 if (defined $set_names) && !$set_names;
102
103    my $c = lc $cfg->PublishCharset;
104    my %Charset = ( 'utf-8' => 'UNICODE', 
105                    'shift_jis' => 'SJIS',
106                    'euc-jp' => 'EUC_JP', 
107                    #'iso-8859-1' => 'LATIN1'
108                  );
109    $c = $Charset{$c} ? $Charset{$c}  : $c;
110    eval {
111        local $@;
112        if (!$dbh->do("SET NAMES '" . $c . "'")) {
113            # 'set names' command isn't working for this verison of PostgreSQL,
114            # assign SQLSetNames to 0 to prevent further errors.
115            $cfg->SQLSetNames(0, 1);
116            return 0;
117        } else {
118            if (!defined $set_names) {
119                # SQLSetNames has never been assigned; we had a successful
120                # 'SET NAMES' command, so it's safe to SET NAMES in the future.
121                $cfg->SQLSetNames(1, 1);
122            }
123        }
124    };
125    return 1;
126}
127
128sub sequence_name {
129    my $dbd = shift;
130    my($class) = @_;
131
132    my $key = $class->properties->{primary_key};
133    ## If it's a complex primary key, use the second half.
134    if(ref $key) {
135        $key = $key->[1];
136    }
137
138    # mt_tablename_columnname
139    return join '_', 'mt',
140        $dbd->db_column_name(MT::Object->driver->table_for($class), $key);
141}
142
143sub bind_param_attributes {
144    my ($dbd, $data_type) = @_;
145    my $t = ref($data_type) eq 'HASH'
146      ? $data_type->{type}
147      : $data_type;
148    if ($t eq 'blob') {
149        return { pg_type => DBD::Pg::PG_BYTEA() };
150    }
151    return;
152}
153
1541;
Note: See TracBrowser for help on using the browser.