f8f17df724456239a63563c34302bec038c8e762
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Filter / Names.pm
1 package SQL::Translator::Filter::Names;
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::Names - Tweak the names of schema objects.
24
25 =head1 SYNOPSIS
26
27   #! /usr/bin/perl -w
28   use SQL::Translator;
29
30   # Lowercase all table names and upper case the first letter of all field
31   # names. (MySql style!)
32   #
33   my $sqlt = SQL::Translator->new(
34       filename => \@ARGV,
35       from     => 'MySQL',
36       to       => 'MySQL',
37       filters => [
38         Names => {
39             'tables' => 'lc',
40             'fields' => 'ucfirst',
41         },
42       ],
43   ) || die "SQLFairy error : ".SQL::Translator->error;
44   print($sqlt->translate) || die "SQLFairy error : ".$sqlt->error;
45
46 =cut
47
48 use strict;
49 use vars qw/$VERSION/;
50 $VERSION = '1.99';
51
52 sub filter {
53     my $schema = shift;
54     my %args = %{$_[0]};
55
56     # Tables
57     #if ( my $func = $args{tables} ) {
58     #    _filtername($_,$func) foreach ( $schema->get_tables );
59     #}
60     # ,
61     foreach my $type ( qw/tables procedures triggers views/ ) {
62         if ( my $func = $args{$type} ) {
63             my $meth = "get_$type";
64             _filtername($_,$func) foreach $schema->$meth;
65         }
66     }
67
68     # Fields
69     if ( my $func = $args{fields} ) {
70         _filtername($_,$func)
71         foreach map { $_->get_fields } $schema->get_tables ;
72     }
73
74 }
75
76 # _filtername( OBJ, FUNC_NAME )
77 # Update the name attribute on the schema object given using the named filter.
78 # Objects with no name are skipped.
79 # Returns true if the name was changed. Dies if there is an error running func.
80 sub _filtername {
81     my ($obj,$func) = @_;
82     return unless my $name = $obj->name;
83     $func = _getfunc($func);
84     my $newname = eval { $func->($name) };
85     die "$@" if $@; # TODO - Better message!
86     return if $name eq $newname;
87     $_->name($newname);
88 }
89
90 # _getfunc( NAME ) - Returns code ref to func NAME or dies.
91 sub _getfunc {
92     my ($name) = @_;
93     no strict 'refs';
94     my $func = "SQL::Translator::Filter::Names::$name";
95     die "Table name filter - unknown function '$name'\n" unless exists &$func;
96     \&$func;
97 }
98
99
100
101 # The name munging functions
102 #=============================================================================
103 # Get called with name to munge as first arg and return the new name. Die on
104 # errors.
105
106 sub lc { lc shift; }
107 sub uc { uc shift; }
108 sub ucfirst { ucfirst shift; }
109
110 1; #==========================================================================
111
112 __END__
113
114 =head1 DESCRIPTION
115
116 =head1 SEE ALSO
117
118 L<perl(1)>, L<SQL::Translator>
119
120 =head1 BUGS
121
122 =head1 TODO
123
124 =over 4
125
126 =item Name Groups
127
128 Define a bunch of usefull groups to run the name filters over. e.g. all, fkeys,
129 pkeys etc.
130
131 =item More Functions
132
133 e.g. camelcase, titlecase, single word etc.
134 Also a way to pass in a regexp.
135
136 May also want a way to pass in arguments for the func e.g. prefix.
137
138 =item Multiple Filters on the same name (filter order)?
139
140 Do we actually need this, you could just run lots of filters. Would make adding
141 func args to the interface easier.
142
143     filters => [
144         [ 'Names', { all => 'lc' } ],
145         [ 'Names', {
146             tables => 'lc',
147             fields => 'ucfirst',
148         } ],
149     ],
150
151 Mind you if you could give the filter a list this wouldn't be a problem!
152
153     filters => [
154         [ 'Names',
155             all    => 'lc'
156             fields => 'ucfirst',
157         ],
158     ],
159
160 Which is nice. Might have to change the calling conventions for filters.
161 Would also provide an order to run the filters in rather than having to hard
162 code it into the filter it's self.
163
164 =back
165
166 =head1 AUTHOR
167
168 =cut