Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add DB comments for PG producer #137

Merged
merged 5 commits into from
Jul 8, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 64 additions & 12 deletions lib/SQL/Translator/Producer/PostgreSQL.pm
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,40 @@ producer.
Now handles PostGIS Geometry and Geography data types on table definitions.
Does not yet support PostGIS Views.

=head2 Producer Args

=over 4

=item postgres_version

The version of postgres to generate DDL for. Turns on features only available in later versions. The following features are supported

=over 4

=item IF EXISTS

If your postgres_version is higher than 8.003 (I should hope it is by now), then the DDL
generated for dropping objects in the database will contain IF EXISTS.

=back

=item attach_comments

Generates table and column comments via the COMMENT command rather than as a comment in
the DDL. You could then look it up with \dt+ or \d+ (for tables and columns respectively)
in psql. The comment is dollar quoted with $comment$ so you can include ' in it. Just to clarify: you get this

CREATE TABLE foo ...;
COMMENT on TABLE foo IS $comment$hi there$comment$;

instead of this

-- comment
CREAT TABLE foo ...;

=back


=cut

use strict;
Expand Down Expand Up @@ -163,6 +197,7 @@ sub produce {
postgres_version => $postgres_version,
add_drop_table => $add_drop_table,
type_defs => \%type_defs,
attach_comments => $pargs->{attach_comments}
});

push @table_defs, $table_def;
Expand Down Expand Up @@ -265,6 +300,7 @@ sub create_table
my $add_drop_table = $options->{add_drop_table} || 0;
my $postgres_version = $options->{postgres_version} || 0;
my $type_defs = $options->{type_defs} || {};
my $attach_comments = $options->{attach_comments};

my $table_name = $table->name or next;
my $table_name_qt = $generator->quote($table_name);
Expand All @@ -275,11 +311,16 @@ sub create_table

my @comment_statements;
if ( my $comments = $table->comments ) {
# this follows the example in the MySQL producer, where all comments are added as
# table comments, even though they could have originally been parsed as DDL comments
# quoted via $$ string so there can be 'quotes' inside the comments
my $comment_ddl = "COMMENT on TABLE $table_name_qt IS \$comment\$$comments\$comment\$";
push @comment_statements, $comment_ddl;
if ( $attach_comments) {
# this follows the example in the MySQL producer, where all comments are added as
# table comments, even though they could have originally been parsed as DDL comments
# quoted via $$ string so there can be 'quotes' inside the comments
my $comment_ddl = "COMMENT on TABLE $table_name_qt IS \$comment\$$comments\$comment\$";
push @comment_statements, $comment_ddl;
} elsif (!$no_comments) {
$comments =~ s/^/-- /mg;
push @comments, "-- Comments:\n$comments\n--\n";
}
}

#
Expand All @@ -291,13 +332,16 @@ sub create_table
postgres_version => $postgres_version,
type_defs => $type_defs,
constraint_defs => \@constraint_defs,
attach_comments => $attach_comments
});
my $field_comments = $field->comments;
next unless $field_comments;
my $field_name_qt = $generator->quote($field->name);
my $comment_ddl =
"COMMENT on COLUMN $table_name_qt.$field_name_qt IS \$comment\$$field_comments\$comment\$";
push @comment_statements, $comment_ddl;
if ( $attach_comments ) {
my $field_comments = $field->comments;
next unless $field_comments;
my $field_name_qt = $generator->quote($field->name);
my $comment_ddl =
"COMMENT on COLUMN $table_name_qt.$field_name_qt IS \$comment\$$field_comments\$comment\$";
push @comment_statements, $comment_ddl;
}

}

Expand Down Expand Up @@ -410,10 +454,18 @@ sub create_view {
my $constraint_defs = $options->{constraint_defs} || [];
my $postgres_version = $options->{postgres_version} || 0;
my $type_defs = $options->{type_defs} || {};
my $attach_comments = $options->{attach_comments};

$field_name_scope{$table_name} ||= {};
my $field_name = $field->name;
my $field_def = $generator->quote($field_name);

my $field_comments = '';
if ( !$attach_comments and my $comments = $field->comments ) {
$comments =~ s/(?<!\A)^/ -- /mg;
$field_comments = "-- $comments\n ";
}

my $field_def = $field_comments . $generator->quote($field_name);

#
# Datatype
Expand Down
1 change: 1 addition & 0 deletions t/46xml-to-pg.t
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ $sqlt = SQL::Translator->new(
no_comments => 1,
show_warnings => 0,
add_drop_table => 1,
producer_args => { attach_comments => 1 }
);

die "Can't find test schema $xmlfile" unless -e $xmlfile;
Expand Down
3 changes: 2 additions & 1 deletion t/47postgres-producer.t
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ my $PRODUCER = \&SQL::Translator::Producer::PostgreSQL::create_field;
is_foreign_key => 0,
is_unique => 0 );
$table->add_field($field);
my ($create, $fks) = SQL::Translator::Producer::PostgreSQL::create_table($table, { quote_table_names => q{"} });
my ($create, $fks) = SQL::Translator::Producer::PostgreSQL::create_table(
$table, { quote_table_names => q{"}, attach_comments => 1 });
is($table->name, 'foo.bar');

my $expected = <<EOESQL;
Expand Down
6 changes: 6 additions & 0 deletions t/60roundtrip.t
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ my $plan = [
producer_args => {},
parser_args => {},
},
{
engine => 'PostgreSQL',
name => 'Postgres w/ attached comments',
producer_args => { attach_comments => 1 },
parser_args => {},
},
{
engine => 'SQLServer',
producer_args => {},
Expand Down