Revert my previous changes (rev 1722 reverted back to rev 1721)
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Filter / Globals.pm
1 package SQL::Translator::Filter::Globals;
2
3 # -------------------------------------------------------------------
4 # Copyright (C) 2002-2009 SQLFairy Authors
5 #
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License as
8 # published by the Free Software Foundation; version 2.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 # 02111-1307  USA
19 # -------------------------------------------------------------------
20
21 =head1 NAME
22
23 SQL::Translator::Filter::Globals - Add global fields and indices to all tables.
24
25 =head1 SYNOPSIS
26
27   # e.g. Add timestamp field to all tables.
28   use SQL::Translator;
29
30   my $sqlt = SQL::Translator->new(
31       from => 'MySQL',
32       to   => 'MySQL',
33       filters => [
34         Globals => {
35             fields => [
36                 {
37                     name => 'modified'
38                     data_type => 'TIMESTAMP'
39                 }
40             ],
41             indices => [
42                 { 
43                     fields => 'modifed',
44                 },
45             ]
46             constraints => [
47                 {
48                 }
49             ]
50         },
51       ],
52   ) || die "SQLFairy error : ".SQL::Translator->error;
53   my $sql = $sqlt->translate || die "SQLFairy error : ".$sqlt->error;
54
55 =cut
56
57 use strict;
58 use vars qw/$VERSION/;
59 $VERSION = '1.59';
60
61 sub filter {
62     my $schema = shift;
63     my %args = @_;
64     my $global_table = $args{global_table} ||= '_GLOBAL_';
65
66     my (@global_fields, @global_indices, @global_constraints);
67     push @global_fields,      @{ $args{fields} }      if $args{fields};
68     push @global_indices,     @{ $args{indices} }     if $args{indices};
69     push @global_constraints, @{ $args{constraints} } if $args{constraints};
70
71     # Pull fields and indices off global table and then remove it.
72     if ( my $gtbl = $schema->get_table( $global_table ) ) {
73
74         foreach ( $gtbl->get_fields ) {
75             # We don't copy the order attrib so the added fields should get
76             # pushed on the end of each table.
77             push @global_fields, {
78                 name                  => $_->name,
79                 comments              => "".$_->comments,
80                 data_type             => $_->data_type,
81                 default_value         => $_->default_value,
82                 size                  => [$_->size],
83                 extra                 => scalar($_->extra),
84                 foreign_key_reference => $_->foreign_key_reference,
85                 is_auto_increment     => $_->is_auto_increment,
86                 is_foreign_key        => $_->is_foreign_key,
87                 is_nullable           => $_->is_nullable,
88                 is_primary_key        => $_->is_primary_key,
89                 is_unique             => $_->is_unique,
90                 is_valid              => $_->is_valid,
91             };
92         }
93
94         foreach ( $gtbl->get_indices ) {
95             push @global_indices, {
96                 name    => $_->name,
97                 type    => $_->type,
98                 fields  => [$_->fields],
99                 options => [$_->options],
100                 extra   => scalar($_->extra),
101             };
102         }
103
104         foreach ( $gtbl->get_constraints ) {
105             push @global_constraints, {
106                 name             => $_->name,
107                 fields           => [$_->fields],
108                 deferrable       => $_->deferrable,
109                 expression       => $_->expression,
110                 match_type       => $_->match_type,
111                 options          => [$_->options],
112                 on_delete        => $_->on_delete,
113                 on_update        => $_->on_update,
114                 reference_fields => [$_->reference_fields],
115                 reference_table  => $_->reference_table,
116                 table            => $_->table,
117                 type             => $_->type,
118                 extra            => scalar($_->extra),
119             };
120         }
121
122         $schema->drop_table($gtbl);
123     }
124
125     # Add globalis to tables
126     foreach my $tbl ( $schema->get_tables ) {
127
128         foreach my $new_fld ( @global_fields ) {
129             # Don't add if field already there
130             next if $tbl->get_field( $new_fld->{name} );
131             $tbl->add_field( %$new_fld );
132         }
133
134         foreach my $new_index ( @global_indices ) {
135             $tbl->add_index( %$new_index );
136         }
137
138         foreach my $new_constraint ( @global_constraints ) {
139             $tbl->add_constraint( %$new_constraint );
140         }
141     }
142 }
143
144 1;
145
146 __END__
147
148 =head1 DESCRIPTION
149
150 Adds global fields, indices and constraints to all tables in the schema.
151 The globals to add can either be defined in the filter args or using a _GLOBAL_
152 table (see below).
153
154 If a table already contains a field with the same name as a global then it is
155 skipped for that table.
156
157 =head2 The _GLOBAL_ Table
158
159 An alternative to using the args is to add a table called C<_GLOBAL_> to the
160 schema and then just use the filter. Any fields and indices defined on this table
161 will be added to all the tables in the schema and the _GLOBAL_ table removed.
162
163 The name of the global can be changed using a C<global_table> arg to the
164 filter.
165
166 =head1 SEE ALSO
167
168 L<perl(1)>, L<SQL::Translator>
169
170 =head1 BUGS
171
172 Will generate duplicate indices if an index already exists on a table the same
173 as one added globally.
174
175 Will generate duplicate constraints if a constraint already exists on a table
176 the same as one added globally.
177
178 =head1 TODO
179
180 Some extra data values that can be used to control the global addition. e.g.
181 'skip_global'.
182
183 =head1 AUTHOR
184
185 Mark Addison <grommit@users.sourceforge.net>
186
187 =cut