Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 0d33a925

Von Moritz Bunkus vor mehr als 10 Jahren hinzugefügt

  • ID 0d33a925545f60de3962329f62df61b5b99f925d
  • Vorgänger df601bd3
  • Nachfolger 68e4c3a2

rose_auto_create_model.pl: Relationship-Namen anhand der Spaltennamen mappen

Bisher wurde das Umbenennen der generierten Relationships anhand des von
Rose vergebenen Namens der Relationship vorgenommen. Das ist
problematisch, weil diese wiederum von der Reihenfolge abhängen, in der
die Fremdschlüsseldefinitionen von der Datenbank zurückgeliefert werden.

Konkretes Beispiel: Tabelle »follow_up_access« mit den Spalten »who« und
»what«, die beide Fremdschlüssel auf employee sind.

Rose benennt die erzeugten Relationships nach dem Klassennamen
derjenigen Tabelle, auf die die Schlüssel verweisen. Tabelle »employee«
→ Klasse »SL::DB::Employee« → Default-Relationshipname »employee«.

Die erste von der Datenbank gemeldete Fremdschlüsseldefinition bekommt
nun den Namen »employee«. Die zweite sollte diesen ebenfalls bekommen,
aber da der schon vergeben ist, bekommt sie das Suffix »_obj«, ergo
»employee_obj«. Soweit, so gut. Ändert sich nun aber die Reihenfolge, so
werden die Namen genau umgekehrt herum vergeben.

Die Umbenennung anhand des Tripels <Domäne, Tabelle, Spaltennamen>
hingegen ist immer eindeutig.

Unterschiede anzeigen:

scripts/rose_auto_create_model.pl
47 47

  
48 48
my %config;
49 49

  
50
# Maps column names in tables to foreign key relationship names.  For
51
# example:
52
#
53
# »follow_up_access« contains a column named »who«. Rose normally
54
# names the resulting relationship after the class the target table
55
# uses. In this case the target table is »employee« and the
56
# corresponding class SL::DB::Employee. The resulting relationship
57
# would be named »employee«.
58
#
59
# In order to rename this relationship we have to map »who« to
60
# e.g. »granted_by«:
61
#   follow_up_access => { who => 'granted_by' },
62

  
50 63
our %foreign_key_name_map     = (
51 64
  KIVITENDO                   => {
52
    oe                        => { payment => 'payment_terms', },
53
    ar                        => { payment => 'payment_terms', },
54
    ap                        => { payment => 'payment_terms', },
65
    oe                        => { payment_id => 'payment_terms', },
66
    ar                        => { payment_id => 'payment_terms', },
67
    ap                        => { payment_id => 'payment_terms', },
55 68

  
56
    orderitems                => { parts => 'part', trans => 'order', },
57
    delivery_order_items      => { parts => 'part' },
58
    invoice                   => { parts => 'part' },
59
    follow_ups                => { 'employee_obj' => 'created_for' },
69
    orderitems                => { parts_id => 'part', trans_id => 'order', },
70
    delivery_order_items      => { parts_id => 'part' },
71
    invoice                   => { parts_id => 'part' },
72
    follow_ups                => { created_for_user => 'created_for', created_by => 'employee', },
60 73

  
61
    periodic_invoices_configs => { oe => 'order' },
74
    periodic_invoices_configs => { oe_id => 'order' },
62 75
  },
63 76
);
64 77

  
......
89 102
  }
90 103
}
91 104

  
105
sub fix_relationship_names {
106
  my ($domain, $table, $fkey_text) = @_;
107

  
108
  if ($fkey_text !~ m/key_columns \s+ => \s+ \{ \s+ ['"]? ( [^'"\s]+ ) /x) {
109
    die "fix_relationship_names: could not extract the key column for domain/table $domain/$table; foreign key definition text:\n${fkey_text}\n";
110
  }
111

  
112
  my $column_name = $1;
113
  my %changes     = map { %{$_} } grep { $_ } ($foreign_key_name_map{$domain}->{ALL}, $foreign_key_name_map{$domain}->{$table});
114

  
115
  if (my $desired_name = $changes{$column_name}) {
116
    $fkey_text =~ s/^ \s\s [^\s]+ \b/  ${desired_name}/msx;
117
  }
118

  
119
  return $fkey_text;
120
}
121

  
92 122
sub process_table {
93 123
  my ($domain, $table, $package) = @_;
94 124
  my $schema     = '';
......
139 169
  $foreign_key_definition =~ s/::AUTO::/::/g;
140 170

  
141 171
  if ($foreign_key_definition && ($definition =~ /\Q$foreign_key_definition\E/)) {
172
    # These positions refer to the whole setup call, not just the
173
    # parameters/actual relationship definitions.
142 174
    my ($start, $end) = ($-[0], $+[0]);
143 175

  
144
    my %changes = map { %{$_} } grep { $_ } ($foreign_key_name_map{$domain}->{ALL}, $foreign_key_name_map{$domain}->{$table});
145
    while (my ($auto_generated_name, $desired_name) = each %changes) {
146
      $foreign_key_definition =~ s/^ \s \s ${auto_generated_name} \b/  ${desired_name}/msx;
147
    }
176
    # Match the function parameters = the actual relationship
177
    # definitions
178
    next unless $foreign_key_definition =~ m/\(\n(.+)\n\)/s;
148 179

  
149
    # Sort foreign key definitions alphabetically
150
    if ($foreign_key_definition =~ m/\(\n(.+)\n\)/s) {
151
      my ($list_start, $list_end) = ($-[0], $+[0]);
152
      my @foreign_keys            = split m/\n\n/m, $1;
153
      my $sorted_foreign_keys     = "(\n" . join("\n\n", sort @foreign_keys) . "\n)";
180
    my ($list_start, $list_end) = ($-[0], $+[0]);
154 181

  
155
      substr $foreign_key_definition, $list_start, $list_end - $list_start, $sorted_foreign_keys;;
156
    }
182
    # Split the whole chunk on double new lines. The resulting
183
    # elements are one relationship each. Then fix the relationship
184
    # names and sort them by their new names.
185
    my @new_foreign_keys = sort map { fix_relationship_names($domain, $table, $_) } split m/\n\n/m, $1;
186

  
187
    # Replace the function parameters = the actual relationship
188
    # definitions with the new ones.
189
    my $sorted_foreign_keys = "(\n" . join("\n\n", @new_foreign_keys) . "\n)";
190
    substr $foreign_key_definition, $list_start, $list_end - $list_start, $sorted_foreign_keys;
157 191

  
158
    substr($definition, $start, $end - $start) = $foreign_key_definition;
192
    # Replace the whole setup call in the auto-generated output with
193
    # our new version.
194
    substr $definition, $start, $end - $start, $foreign_key_definition;
159 195
  }
160 196

  
161 197
  $definition =~ s/(meta->table.*)\n/$1\n$schema_str/m if $schema;

Auch abrufbar als: Unified diff