From: ivan Date: Sun, 6 Dec 2009 21:37:29 +0000 (+0000) Subject: initial support for handling changes to a column's type or size X-Git-Tag: DBIx_DBSchema_0_38~7 X-Git-Url: http://git.freeside.biz/gitweb/?p=DBIx-DBSchema.git;a=commitdiff_plain;h=1041236795634d90ecdbb132935193602f83dd34 initial support for handling changes to a column's type or size --- diff --git a/Changes b/Changes index 38b8351..ebeeeaf 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,7 @@ Revision history for Perl extension DBIx::DBSchema. numeric defaults in Pg. - Pg: use default_db_schema when adding SERIAL columns instead of hardcoding "public". + - Pg: Initial support for handling changes to a column's type or size. 0.36 Thu Dec 13 17:49:35 PST 2007 - Patch from ISHIGAKI@cpan.org to suppress unnecessary warnings about diff --git a/DBSchema.pm b/DBSchema.pm index ac4941b..a53cb1a 100644 --- a/DBSchema.pm +++ b/DBSchema.pm @@ -10,7 +10,7 @@ use DBIx::DBSchema::Column; use DBIx::DBSchema::ColGroup::Unique; use DBIx::DBSchema::ColGroup::Index; -$VERSION = "0.37_02"; +$VERSION = "0.37_03"; $VERSION = eval $VERSION; # modperlstyle: convert the string into a number $DEBUG = 0; diff --git a/DBSchema/Column.pm b/DBSchema/Column.pm index b13d5c0..0d00159 100644 --- a/DBSchema/Column.pm +++ b/DBSchema/Column.pm @@ -5,7 +5,7 @@ use vars qw($VERSION); use Carp; use DBIx::DBSchema::_util qw(_load_driver _dbh); -$VERSION = '0.12'; +$VERSION = '0.13'; =head1 NAME @@ -267,7 +267,10 @@ sub line { my $default; my $orig_default = $self->default; if ( $driver_class->can("_column_value_needs_quoting") ) { - if ($driver_class->_column_value_needs_quoting($self)) { + if ( $driver_class->_column_value_needs_quoting($self) + && !ref($self->default) + ) + { $default = $dbh->quote($self->default); } else { $default = ref($self->default) ? ${$self->default} : $self->default; @@ -429,35 +432,51 @@ sub sql_alter_column { my $dbd = "DBIx::DBSchema::DBD::$driver"; my $hashref = $dbd->alter_column_callback( $dbh, $table, $self, $new ); - # change the name... + if ( $hashref->{'sql_alter'} ) { - # change the type... - - if ( $hashref->{'sql_alter_null' } ) { - - push @sql, $hashref->{'sql_alter_null'}; + push @sql, $hashref->{'sql_alter'}; } else { - # change nullability from NOT NULL to NULL - if ( ! $self->null && $new->null ) { - - push @sql, "ALTER TABLE $table ALTER COLUMN $name DROP NOT NULL"; - + # change the name... + # not yet implemented. how do we tell which old column it was? + + # change the type... + if ( $hashref->{'sql_alter_type'} ) { + push @sql, $hashref->{'sql_alter_type'}; } - - # change nullability from NULL to NOT NULL... - # this one could be more complicated, need to set a DEFAULT value and update - # the table first... - if ( $self->null && ! $new->null ) { - - push @sql, "ALTER TABLE $table ALTER COLUMN $name SET NOT NULL"; - + + # change nullability... + + if ( $hashref->{'sql_alter_null'} ) { + + push @sql, $hashref->{'sql_alter_null'}; + + } else { + + # change nullability from NOT NULL to NULL + if ( ! $self->null && $new->null ) { + + push @sql, "ALTER TABLE $table ALTER COLUMN $name DROP NOT NULL"; + + } + + # change nullability from NULL to NOT NULL... + # this one could be more complicated, need to set a DEFAULT value and update + # the table first... + if ( $self->null && ! $new->null ) { + + push @sql, "ALTER TABLE $table ALTER COLUMN $name SET NOT NULL"; + + } + } + # change default + + # change other stuff... + } - - # change other stuff... @sql; diff --git a/DBSchema/DBD.pm b/DBSchema/DBD.pm index be08320..1a421d2 100644 --- a/DBSchema/DBD.pm +++ b/DBSchema/DBD.pm @@ -3,7 +3,7 @@ package DBIx::DBSchema::DBD; use strict; use vars qw($VERSION); -$VERSION = '0.05'; +$VERSION = '0.06'; =head1 NAME @@ -198,7 +198,11 @@ columns to an existing table. Should return a hash reference, empty for no action, or with one or more of the following keys defined: -sql_alter_null - Alter SQL statment for changing nullability to be used instead of the default +sql_alter - Alter SQL statement(s) for changing everything about a column. Specifying this overrides processing of individual changes (type, nullability, default, etc.). + +sql_alter_type - Alter SQL statement(s) for changing type and length (there is no default). + +sql_alter_null - Alter SQL statement(s) for changing nullability to be used instead of the default. =cut diff --git a/DBSchema/DBD/Pg.pm b/DBSchema/DBD/Pg.pm index da49009..0064d56 100644 --- a/DBSchema/DBD/Pg.pm +++ b/DBSchema/DBD/Pg.pm @@ -5,7 +5,7 @@ use vars qw($VERSION @ISA %typemap); use DBD::Pg 1.32; use DBIx::DBSchema::DBD; -$VERSION = '0.13'; +$VERSION = '0.14'; @ISA = qw(DBIx::DBSchema::DBD); die "DBD::Pg version 1.32 or 1.41 (or later) required--". @@ -219,6 +219,21 @@ sub alter_column_callback { my( $proto, $dbh, $table, $old_column, $new_column ) = @_; my $name = $old_column->name; + my %canonical = ( + 'SMALLINT' => 'INT2', + 'INT' => 'INT4', + 'BIGINT' => 'INT8', + 'SERIAL' => 'INT4', + 'BIGSERIAL' => 'INT8', + 'DECIMAL' => 'NUMERIC', + 'REAL' => 'FLOAT4', + 'BLOB' => 'BYTEA', + 'TIMESTAMP' => 'TIMESTAMPTZ', + ); + foreach ($old_column, $new_column) { + $_->type($canonical{uc($_->type)}) if $canonical{uc($_->type)}; + } + my $pg_server_version = $dbh->{'pg_server_version'}; my $warning = ''; unless ( $pg_server_version =~ /\d/ ) { @@ -228,6 +243,30 @@ sub alter_column_callback { my $hashref = {}; + #change type + if ( ( $canonical{uc($old_column->type)} || uc($old_column->type) ) + ne ( $canonical{uc($new_column->type)} || uc($new_column->type) ) + || $old_column->length ne $new_column->length + ) + { + + warn $warning if $warning; + if ( $pg_server_version >= 80000 ) { + + $hashref->{'sql_alter_type'} = + "ALTER TABLE $table ALTER COLUMN ". $new_column->name. + " TYPE ". $new_column->type. + ( ( defined($new_column->length) && $new_column->length ) + ? '('.$new_column->length.')' + : '' + ) + + } else { + warn "WARNING: can't yet change column types for Pg < version 8\n"; + } + + } + # change nullability from NOT NULL to NULL if ( ! $old_column->null && $new_column->null ) {