X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FSQL%2FTranslator%2FParser%2FDBIx%2FClass.pm;h=1b6266f30ad672006dfcb45d180c1df9b8e35917;hb=0da8b7da7a9df7b84e9a3228cd1f5feb1d65bb07;hp=94b241e325389198a5e71589c5757467dbc97b7a;hpb=45f1a484fec2dc2cae461c37af1a597d580ed8e8;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/SQL/Translator/Parser/DBIx/Class.pm b/lib/SQL/Translator/Parser/DBIx/Class.pm index 94b241e..1b6266f 100644 --- a/lib/SQL/Translator/Parser/DBIx/Class.pm +++ b/lib/SQL/Translator/Parser/DBIx/Class.pm @@ -14,6 +14,7 @@ $DEBUG = 0 unless defined $DEBUG; use Exporter; use Data::Dumper; +use Digest::SHA1 qw( sha1_hex ); use SQL::Translator::Utils qw(debug normalize_name); use base qw(Exporter); @@ -107,13 +108,12 @@ sub parse { if (!$source->compare_relationship_keys($unique_constraints{$uniq}, \@primary)) { $table->add_constraint( type => 'unique', - name => "$uniq", + name => _create_unique_symbol($uniq), fields => $unique_constraints{$uniq} ); my $index = $table->add_index( - # TODO: Pick a better than that wont conflict - name => $unique_constraints{$uniq}->[0], + name => _create_unique_symbol(join('_', @{$unique_constraints{$uniq}})), fields => $unique_constraints{$uniq}, type => 'NORMAL', ); @@ -179,17 +179,19 @@ sub parse { if (scalar(@keys)) { $table->add_constraint( type => 'foreign_key', - name => $table->name . "_fk_$keys[0]", + name => _create_unique_symbol($table->name + . '_fk_' + . join('_', @keys)), fields => \@keys, reference_fields => \@refkeys, reference_table => $rel_table, on_delete => $on_delete, on_update => $on_update, - defined $is_deferrable ? ( deferrable => $is_deferrable ) : (), + (defined $is_deferrable ? ( deferrable => $is_deferrable ) : ()), ); my $index = $table->add_index( - name => join('_', @keys), + name => _create_unique_symbol(join('_', @keys)), fields => \@keys, type => 'NORMAL', ); @@ -209,5 +211,31 @@ sub parse { return 1; } -1; +# TODO - is there a reasonable way to pass configuration? +# Default of 64 comes from mysql's limit. +our $MAX_SYMBOL_LENGTH ||= 64; +our $COLLISION_TAG_LENGTH ||= 8; + +# ------------------------------------------------------------------- +# $resolved_name = _create_unique_symbol($desired_name) +# +# If desired_name is really long, it will be truncated in a way that +# has a high probability of leaving it unique. +# ------------------------------------------------------------------- +sub _create_unique_symbol { + my $desired_name = shift; + return $desired_name if length $desired_name <= $MAX_SYMBOL_LENGTH; + my $truncated_name = substr $desired_name, 0, $MAX_SYMBOL_LENGTH - $COLLISION_TAG_LENGTH - 1; + + # Hex isn't the most space-efficient, but it skirts around allowed + # charset issues + my $digest = sha1_hex($desired_name); + my $collision_tag = substr $digest, 0, $COLLISION_TAG_LENGTH; + + return $truncated_name + . '_' + . $collision_tag; +} + +1;