add header_comment
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Producer / SQLServer.pm
1 package SQL::Translator::Producer::SQLServer;
2
3 use strict;
4 use warnings;
5 our ( $DEBUG, $WARN );
6 our $VERSION = '1.59';
7 $DEBUG = 1 unless defined $DEBUG;
8
9 use SQL::Translator::Schema::Constants;
10 use SQL::Translator::Utils qw(debug header_comment);
11 use SQL::Translator::Generator::DDL::SQLServer;
12
13 sub produce {
14     my $translator     = shift;
15     my $future = SQL::Translator::Generator::DDL::SQLServer->new(
16       add_comments    => !$translator->no_comments,
17       add_drop_tables => $translator->add_drop_table,
18     );
19
20     my $no_comments    = $translator->no_comments;
21     my $add_drop_table = $translator->add_drop_table;
22     my $schema         = $translator->schema;
23
24     my $output = $future->header_comments;
25     $output .= $future->drop_tables($schema);
26
27     my @foreign_constraints = ();
28
29     for my $table ( grep { $_->name } $schema->get_tables ) {
30         my $table_name_ur = $future->quote($table->name);
31
32         my ( @comments );
33
34         push @comments, "\n\n--\n-- Table: $table_name_ur\n--"
35            unless $no_comments;
36
37         push @comments, map { "-- $_" } $table->comments;
38
39         push @foreign_constraints, map $future->foreign_key_constraint($_),
40            grep { $_->type eq FOREIGN_KEY } $table->get_constraints;
41
42         $output .= join( "\n\n",
43             @comments,
44             # index defs
45             $future->table($table),
46             (map $future->unique_constraint_multiple($_),
47                grep {
48                   $_->type eq UNIQUE &&
49                   grep { $_->is_nullable } $_->fields
50                } $table->get_constraints),
51
52             (map $future->index($_), $table->get_indices)
53         );
54     }
55
56 # Add FK constraints
57     $output .= join ("\n", '', @foreign_constraints) if @foreign_constraints;
58
59 # create view/procedure are NOT prepended to the input $sql, needs
60 # to be filled in with the proper syntax
61
62     return $output;
63 }
64
65 1;
66
67 =pod
68
69 =head1 SQLServer Create Table Syntax
70
71 TODO
72
73
74 =head1 NAME
75
76 SQL::Translator::Producer::SQLServer - MS SQLServer producer for SQL::Translator
77
78 =head1 SYNOPSIS
79
80   use SQL::Translator;
81
82   my $t = SQL::Translator->new( parser => '...', producer => 'SQLServer' );
83   $t->translate;
84
85 =head1 DESCRIPTION
86
87 B<WARNING>B This is still fairly early code, basically a hacked version of the
88 Sybase Producer (thanks Sam, Paul and Ken for doing the real work ;-)
89
90 =head1 Extra Attributes
91
92 =over 4
93
94 =item field.list
95
96 List of values for an enum field.
97
98 =back
99
100 =head1 TODO
101
102  * !! Write some tests !!
103  * Reserved words list needs updating to SQLServer.
104  * Triggers, Procedures and Views DO NOT WORK
105
106
107     # Text of view is already a 'create view' statement so no need to
108     # be fancy
109     foreach ( $schema->get_views ) {
110         my $name = $_->name();
111         $output .= "\n\n";
112         $output .= "--\n-- View: $name\n--\n\n" unless $no_comments;
113         my $text = $_->sql();
114         $text =~ s/\r//g;
115         $output .= "$text\nGO\n";
116     }
117
118     # Text of procedure already has the 'create procedure' stuff
119     # so there is no need to do anything fancy. However, we should
120     # think about doing fancy stuff with granting permissions and
121     # so on.
122     foreach ( $schema->get_procedures ) {
123         my $name = $_->name();
124         $output .= "\n\n";
125         $output .= "--\n-- Procedure: $name\n--\n\n" unless $no_comments;
126         my $text = $_->sql();
127       $text =~ s/\r//g;
128         $output .= "$text\nGO\n";
129     }
130
131 =head1 SEE ALSO
132
133 SQL::Translator.
134
135 =head1 AUTHORS
136
137 Mark Addison E<lt>grommit@users.sourceforge.netE<gt> - Bulk of code from
138 Sybase producer, I just tweaked it for SQLServer. Thanks.
139
140 =cut