Get enum values directly from column_info for PostgreSQL
Dagfinn Ilmari Mannsåker [Sun, 1 Mar 2015 13:06:47 +0000 (13:06 +0000)]
But only if DBD:Pg is new enough to deal with reordered values,
or the server too old to support them.

Changes
lib/DBIx/Class/Schema/Loader/DBI.pm
lib/DBIx/Class/Schema/Loader/DBI/Component/QuotedDefault.pm
lib/DBIx/Class/Schema/Loader/DBI/Pg.pm

diff --git a/Changes b/Changes
index b8645c4..67db5bf 100644 (file)
--- a/Changes
+++ b/Changes
@@ -2,6 +2,7 @@ Revision history for Perl extension DBIx::Class::Schema::Loader
 
         - Fix tests when the path to perl has spaces in it (GH#19)
         - Inline String::CamelCase::wordsplit() due to RT#123030
+        - Get enum values from DBD::Pg if it's new enough
 
 0.07048_01 - 2018-02-23
         - Convert from Module::Install to ExtUtils::MakeMaker + Distar (GH#17)
index 0bfa589..f0cb406 100644 (file)
@@ -506,6 +506,7 @@ sub _columns_info_for {
     my $dbh = $self->schema->storage->dbh;
 
     my %result;
+    my %raw_result;
 
     if (my $sth = try { $self->_dbh_column_info($dbh, undef, $table->schema, $table->name, '%' ) }) {
         COL_INFO: while (my $info = try { $sth->fetchrow_hashref } catch { +{} }) {
@@ -533,6 +534,7 @@ sub _columns_info_for {
             ) || {};
             $column_info = { %$column_info, %$extra_info };
 
+            $raw_result{$col_name} = $info;
             $result{$col_name} = $column_info;
         }
         $sth->finish;
@@ -608,7 +610,7 @@ sub _columns_info_for {
         %result = %lc_result;
     }
 
-    return \%result;
+    return wantarray ? (\%result, \%raw_result) : \%result;
 }
 
 # Need to override this for the buggy Firebird ODBC driver.
index d86e16b..772dbb2 100644 (file)
@@ -24,7 +24,7 @@ sub _columns_info_for {
     my $self    = shift;
     my ($table) = @_;
 
-    my $result = $self->next::method(@_);
+    my ($result,$raw) = $self->next::method(@_);
 
     while (my ($col, $info) = each %$result) {
         if (my $def = $info->{default_value}) {
@@ -52,7 +52,7 @@ sub _columns_info_for {
         }
     }
 
-    return $result;
+    return wantarray ? ($result, $raw) : $result;
 }
 
 1;
index 78e8a9f..317a07d 100644 (file)
@@ -197,7 +197,7 @@ sub _columns_info_for {
     my $self = shift;
     my ($table) = @_;
 
-    my $result = $self->next::method(@_);
+    my ($result, $raw) = $self->next::method(@_);
 
     while (my ($col, $info) = each %$result) {
         my $data_type = $info->{data_type};
@@ -281,7 +281,22 @@ EOF
         elsif (lc($data_type) eq 'character') {
             $info->{data_type} = 'char';
         }
-        else {
+        # DBD::Pg < 3.5.2 can get the order wrong on Pg >= 9.1.0
+        elsif (
+            ($DBD::Pg::VERSION >= 3.005002 or $self->dbh->{pg_server_version} < 90100)
+                and
+            my $values = $raw->{$col}->{pg_enum_values}
+        ) {
+            $info->{extra}{list} = $values;
+
+            # Store its original name in extra for SQLT to pick up.
+            $info->{extra}{custom_type_name} = $info->{data_type};
+
+            $info->{data_type} = 'enum';
+
+            delete $info->{size};
+        }
+        else  {
             my ($typetype) = $self->schema->storage->dbh
                 ->selectrow_array(<<EOF, {}, $data_type);
 SELECT typtype