X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FSQL%2FTranslator%2FProducer%2FPostgreSQL.pm;h=7fd7159feefc27a962981d31f255b719e6d5d185;hb=86609eaa2d3092e3b65d6161da52a77e5a5c5e31;hp=16307bf8e7fd592edd610b0def35e8dc47259428;hpb=2230ed2ad27ef0f68ad2380c3cfa741168932a2e;p=dbsrgits%2FSQL-Translator.git diff --git a/lib/SQL/Translator/Producer/PostgreSQL.pm b/lib/SQL/Translator/Producer/PostgreSQL.pm index 16307bf..7fd7159 100644 --- a/lib/SQL/Translator/Producer/PostgreSQL.pm +++ b/lib/SQL/Translator/Producer/PostgreSQL.pm @@ -27,7 +27,7 @@ $DEBUG = 0 unless defined $DEBUG; use base qw(SQL::Translator::Producer); use SQL::Translator::Schema::Constants; -use SQL::Translator::Utils qw(debug header_comment parse_dbms_version); +use SQL::Translator::Utils qw(debug header_comment parse_dbms_version batch_alter_table_statements); use SQL::Translator::Generator::DDL::PostgreSQL; use Data::Dumper; @@ -358,8 +358,8 @@ sub create_table my $temporary = ""; - if(exists $table->{extra}{temporary}) { - $temporary = $table->{extra}{temporary} ? "TEMPORARY " : ""; + if(exists $table->extra->{temporary}) { + $temporary = $table->extra->{temporary} ? "TEMPORARY " : ""; } my $create_statement; @@ -528,20 +528,20 @@ sub create_geometry_constraints{ my @constraints; push @constraints, SQL::Translator::Schema::Constraint->new( name => "enforce_dims_".$field->name, - expression => "(ST_NDims($field) = ".$field->{extra}{dimensions}.")", + expression => "(ST_NDims($field) = ".$field->extra->{dimensions}.")", table => $field->table, type => CHECK_C, ); push @constraints, SQL::Translator::Schema::Constraint->new( name => "enforce_srid_".$field->name, - expression => "(ST_SRID($field) = ".$field->{extra}{srid}.")", + expression => "(ST_SRID($field) = ".$field->extra->{srid}.")", table => $field->table, type => CHECK_C, ); push @constraints, SQL::Translator::Schema::Constraint->new( name => "enforce_geotype_".$field->name, - expression => "(GeometryType($field) = '".$field->{extra}{geometry_type}."'::text OR $field IS NULL)", + expression => "(GeometryType($field) = '".$field->extra->{geometry_type}."'::text OR $field IS NULL)", table => $field->table, type => CHECK_C, ); @@ -755,7 +755,7 @@ sub convert_datatype # Geography # if($data_type eq 'geography'){ - $data_type .= '('.$field->{extra}{geography_type}.','. $field->{extra}{srid} .')' + $data_type .= '('.$field->extra->{geography_type}.','. $field->extra->{srid} .')' } return $data_type; @@ -831,7 +831,7 @@ sub alter_field $to_field->name) if ( !defined $new_default && defined $old_default ); - # add geometry column and contraints + # add geometry column and constraints push @out, add_geometry_column($to_field) if is_geometry($to_field); push @out, add_geometry_constraints($to_field) if is_geometry($to_field); @@ -876,9 +876,9 @@ sub add_geometry_column{ $field->table->schema->name, $options->{table} ? $options->{table} : $field->table->name, $field->name, - $field->{extra}{dimensions}, - $field->{extra}{srid}, - $field->{extra}{geometry_type}); + $field->extra->{dimensions}, + $field->extra->{srid}, + $field->extra->{geometry_type}); return $out; } @@ -968,17 +968,25 @@ sub alter_drop_constraint { my $qc = $options->{quote_field_names} || ''; $generator->quote_chars([$qt]); + # attention: Postgres has a very special naming structure for naming + # foreign keys and primary keys. It names them using the name of the + # table as prefix and fkey or pkey as suffix, concatenated by an underscore + my $c_name; + if( $c->name ) { + # Already has a name, just quote it + $c_name = $qc . $c->name . $qc; + } elsif ( $c->type eq FOREIGN_KEY ) { + # Doesn't have a name, and is foreign key, append '_fkey' + $c_name = $qc . $c->table->name . '_' . + ($c->fields)[0] . '_fkey' . $qc; + } elsif ( $c->type eq PRIMARY_KEY ) { + # Doesn't have a name, and is primary key, append '_pkey' + $c_name = $qc . $c->table->name . '_pkey' . $qc; + } + return sprintf( 'ALTER TABLE %s DROP CONSTRAINT %s', - $generator->quote($c->table->name), - # attention: Postgres has a very special naming structure - # for naming foreign keys, it names them uses the name of - # the table as prefix and fkey as suffix, concatenated by a underscore - $c->type eq FOREIGN_KEY - ? $c->name - ? $qc . $c->name . $qc - : $qc . $c->table->name . '_' . ($c->fields)[0] . '_fkey' . $qc - : $qc . $c->name . $qc + $qt . $c->table->name . $qt, $c_name ); } @@ -1011,6 +1019,47 @@ sub drop_table { return $out; } +sub batch_alter_table { + my ( $table, $diff_hash, $options ) = @_; + my $qt = $options->{quote_table_names} || ''; + $generator->quote_chars([$qt]); + + # as long as we're not renaming the table we don't need to be here + if ( @{$diff_hash->{rename_table}} == 0 ) { + return batch_alter_table_statements($diff_hash, $options); + } + + # first we need to perform drops which are on old table + my @sql = batch_alter_table_statements($diff_hash, $options, qw( + alter_drop_constraint + alter_drop_index + drop_field + )); + + # next comes the rename_table + my $old_table = $diff_hash->{rename_table}[0][0]; + push @sql, rename_table( $old_table, $table, $options ); + + # for alter_field (and so also rename_field) we need to make sure old + # field has table name set to new table otherwise calling alter_field dies + $diff_hash->{alter_field} = + [map { $_->[0]->table($table) && $_ } @{$diff_hash->{alter_field}}]; + $diff_hash->{rename_field} = + [map { $_->[0]->table($table) && $_ } @{$diff_hash->{rename_field}}]; + + # now add everything else + push @sql, batch_alter_table_statements($diff_hash, $options, qw( + add_field + alter_field + rename_field + alter_create_index + alter_create_constraint + alter_table + )); + + return @sql; +} + 1; # -------------------------------------------------------------------