From: Jess Robinson Date: Thu, 9 Oct 2008 22:27:41 +0000 (+0000) Subject: Now supporting scalar refs as default values! (rjbs) X-Git-Tag: v0.11008~294 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=bc8e2aa1b99deb86306edc02f2661bd238896bd4;p=dbsrgits%2FSQL-Translator.git Now supporting scalar refs as default values! (rjbs) --- diff --git a/Changes b/Changes index 6144f16..188832a 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,7 @@ # ---------------------------------------------------------- # # ---------------------------------------------------------- +* Applied patch from rjbs with minor changes, now we support scalar refs in default values! * Fixed SQLite producer to end index statements in newlines, in scalar context * Decreed that all list context statements shall not end in ; or ;\n * Fixed SQLite, Diff and MySQL producers to agree with Decree. diff --git a/lib/SQL/Translator/Producer.pm b/lib/SQL/Translator/Producer.pm index 1b2baf2..3366dc1 100644 --- a/lib/SQL/Translator/Producer.pm +++ b/lib/SQL/Translator/Producer.pm @@ -26,6 +26,37 @@ $VERSION = sprintf "%d.%02d", q$Revision: 1.8 $ =~ /(\d+)\.(\d+)/; sub produce { "" } +# Do not rely on this if you are not bundled with SQL::Translator. +# -- rjbs, 2008-09-30 +## $exceptions contains an arrayref of paired values +## Each pair contains a pattern match or string, and a value to be used as +## the default if matched. +## They are special per Producer, and provide support for the old 'now()' +## default value exceptions +sub _apply_default_value { + my (undef, $field_ref, $default, $exceptions) = @_; + + if ($exceptions and ! ref $default) { + for (my $i = 0; $i < @$exceptions; $i += 2) { + my ($pat, $val) = @$exceptions[ $i, $i + 1 ]; + if (ref $pat and $default =~ $pat) { + $default = $val; + last; + } elsif (lc $default eq lc $pat) { + $default = $val; + last + } + } + } + + if (ref $default) { + $$field_ref .= " DEFAULT $$default"; + } else { + $$field_ref .= " DEFAULT '$default'"; + } + +} + 1; # ------------------------------------------------------------------- diff --git a/lib/SQL/Translator/Producer/MySQL.pm b/lib/SQL/Translator/Producer/MySQL.pm index f09d5d7..9121160 100644 --- a/lib/SQL/Translator/Producer/MySQL.pm +++ b/lib/SQL/Translator/Producer/MySQL.pm @@ -554,11 +554,13 @@ sub create_field # Default? XXX Need better quoting! my $default = $field->default_value; if ( defined $default ) { - if ( uc $default eq 'NULL') { - $field_def .= ' DEFAULT NULL'; - } else { - $field_def .= " DEFAULT '$default'"; - } + SQL::Translator::Producer->_apply_default_value( + \$field_def, + $default, + [ + 'NULL' => \'NULL', + ], + ); } if ( my $comments = $field->comments ) { diff --git a/lib/SQL/Translator/Producer/Oracle.pm b/lib/SQL/Translator/Producer/Oracle.pm index e603124..b43ef99 100644 --- a/lib/SQL/Translator/Producer/Oracle.pm +++ b/lib/SQL/Translator/Producer/Oracle.pm @@ -548,7 +548,11 @@ sub create_field { # then sub "1/0," otherwise just test the truthity of the # argument and use that (naive?). # - if ( + if (ref $default and defined $$default) { + $default = $$default; + } elsif (ref $default) { + $default = 'NULL'; + } elsif ( $data_type =~ /^number$/i && $default !~ /^-?\d+$/ && $default !~ m/null/i diff --git a/lib/SQL/Translator/Producer/PostgreSQL.pm b/lib/SQL/Translator/Producer/PostgreSQL.pm index ac68634..495f529 100644 --- a/lib/SQL/Translator/Producer/PostgreSQL.pm +++ b/lib/SQL/Translator/Producer/PostgreSQL.pm @@ -485,7 +485,6 @@ sub create_view { my $list = $extra{'list'} || []; # todo deal with embedded quotes my $commalist = join( ', ', map { qq['$_'] } @$list ); - my $seq_name; if ($postgres_version >= 8.3 && $field->data_type eq 'enum') { my $type_name = $field->table->name . '_' . $field->name . '_type'; @@ -497,20 +496,19 @@ sub create_view { } # - # Default value -- disallow for timestamps + # Default value # -# my $default = $data_type =~ /(timestamp|date)/i -# ? undef : $field->default_value; my $default = $field->default_value; if ( defined $default ) { - my $qd = "'"; - $qd = '' if ($default eq 'now()' || - $default eq 'CURRENT_TIMESTAMP'); - $field_def .= sprintf( ' DEFAULT %s', - ( $field->is_auto_increment && $seq_name ) - ? qq[nextval('"$seq_name"'::text)] : - ( $default =~ m/null/i ) ? 'NULL' : "$qd$default$qd" - ); + SQL::Translator::Producer->_apply_default_value( + \$field_def, + $default, + [ + 'NULL' => \'NULL', + 'now()' => 'now()', + 'CURRENT_TIMESTAMP' => 'CURRENT_TIMESTAMP', + ], + ); } # diff --git a/lib/SQL/Translator/Producer/SQLServer.pm b/lib/SQL/Translator/Producer/SQLServer.pm index 1a0c294..a65cf30 100644 --- a/lib/SQL/Translator/Producer/SQLServer.pm +++ b/lib/SQL/Translator/Producer/SQLServer.pm @@ -189,7 +189,6 @@ sub produce { my $list = $extra{'list'} || []; # \todo deal with embedded quotes my $commalist = join( ', ', map { qq['$_'] } @$list ); - my $seq_name; if ( $data_type eq 'enum' ) { my $check_name = mk_name( @@ -256,13 +255,15 @@ sub produce { # my $default = $field->default_value; if ( defined $default ) { - $field_def .= sprintf( ' DEFAULT %s', - ( $field->is_auto_increment && $seq_name ) - ? qq[nextval('"$seq_name"'::text)] : - ( $default =~ m/null/i ) ? 'NULL' : "'$default'" + SQL::Translator::Producer->_apply_default_value( + \$field_def, + $default, + [ + 'NULL' => \'NULL', + ], ); } - + push @field_defs, $field_def; } diff --git a/lib/SQL/Translator/Producer/SQLite.pm b/lib/SQL/Translator/Producer/SQLite.pm index 4526951..99fc885 100644 --- a/lib/SQL/Translator/Producer/SQLite.pm +++ b/lib/SQL/Translator/Producer/SQLite.pm @@ -287,17 +287,16 @@ sub create_field # Default? XXX Need better quoting! my $default = $field->default_value; - if ( defined $default ) { - if ( uc $default eq 'NULL') { - $field_def .= ' DEFAULT NULL'; - } elsif ( $default eq 'now()' || - $default eq 'CURRENT_TIMESTAMP' ) { - $field_def .= ' DEFAULT CURRENT_TIMESTAMP'; - } elsif ( $default =~ /val\(/ ) { - next; - } else { - $field_def .= " DEFAULT '$default'"; - } + if (defined $default) { + SQL::Translator::Producer->_apply_default_value( + \$field_def, + $default, + [ + 'NULL' => \'NULL', + 'now()' => 'now()', + 'CURRENT_TIMESTAMP' => 'CURRENT_TIMESTAMP', + ], + ); } return $field_def; diff --git a/t/47postgres-producer.t b/t/47postgres-producer.t index 5dc7ccc..8203602 100644 --- a/t/47postgres-producer.t +++ b/t/47postgres-producer.t @@ -14,7 +14,7 @@ use FindBin qw/$Bin/; #============================================================================= BEGIN { - maybe_plan(9, + maybe_plan(13, 'SQL::Translator::Producer::PostgreSQL', 'Test::Differences', ) @@ -22,7 +22,7 @@ BEGIN { use Test::Differences; use SQL::Translator; - +my $PRODUCER = \&SQL::Translator::Producer::PostgreSQL::create_field; my $table = SQL::Translator::Schema::Table->new( name => 'mytable'); @@ -104,6 +104,76 @@ my $field5_sql = SQL::Translator::Producer::PostgreSQL::create_field($field5,{ p is($field5_sql, 'enum_field mytable_enum_field_type NOT NULL', 'Create real enum field works'); +{ + # let's test default values! -- rjbs, 2008-09-30 + my %field = ( + table => $table, + data_type => 'VARCHAR', + size => 10, + is_auto_increment => 0, + is_nullable => 1, + is_foreign_key => 0, + is_unique => 0, + ); + + { + my $simple_default = SQL::Translator::Schema::Field->new( + %field, + name => 'str_default', + default_value => 'foo', + ); + + is( + $PRODUCER->($simple_default), + q{str_default character varying(10) DEFAULT 'foo'}, + 'default str', + ); + } + + { + my $null_default = SQL::Translator::Schema::Field->new( + %field, + name => 'null_default', + default_value => \'NULL', + ); + + is( + $PRODUCER->($null_default), + q{null_default character varying(10) DEFAULT NULL}, + 'default null', + ); + } + + { + my $null_default = SQL::Translator::Schema::Field->new( + %field, + name => 'null_default_2', + default_value => 'NULL', # XXX: this should go away + ); + + is( + $PRODUCER->($null_default), + q{null_default_2 character varying(10) DEFAULT NULL}, + 'default null from special cased string', + ); + } + + { + my $func_default = SQL::Translator::Schema::Field->new( + %field, + name => 'func_default', + default_value => \'func(funky)', + ); + + is( + $PRODUCER->($func_default), + q{func_default character varying(10) DEFAULT func(funky)}, + 'unquoted default from scalar ref', + ); + } +} + + my $view1 = SQL::Translator::Schema::View->new( name => 'view_foo', fields => [qw/id name/],