sub is_geometry
{
- my $field = shift;
- return 1 if $field->data_type eq 'geometry';
+ my $field = shift;
+ return 1 if $field->data_type eq 'geometry';
}
sub is_geography
if(exists $table->{extra}{temporary}) {
$temporary = $table->{extra}{temporary} ? "TEMPORARY " : "";
}
+ my $inherits = "";
+ if(my $tlist = $table->extra('inherits')) {
+ $inherits = sprintf(' INHERITS (%s)', join(', ',@$tlist));
+ }
my $create_statement;
$create_statement = join("\n", @comments);
}
$create_statement .= qq[CREATE ${temporary}TABLE $qt$table_name_ur$qt (\n].
join( ",\n", map { " $_" } @field_defs, @constraint_defs ).
- "\n)"
+ "\n)$inherits"
;
$create_statement .= @index_defs ? ';' : q{};
$create_statement .= ( $create_statement =~ /;$/ ? "\n" : q{} )
. join(";\n", @index_defs);
- #
- # Geometry
- #
- if(grep { is_geometry($_) } $table->get_fields){
+ #
+ # Geometry
+ #
+ if(grep { is_geometry($_) } $table->get_fields){
$create_statement .= ";";
my @geometry_columns;
foreach my $col ($table->get_fields) { push(@geometry_columns,$col) if is_geometry($col); }
- $create_statement .= "\n".join("\n", map{ drop_geometry_column($_) } @geometry_columns) if $options->{add_drop_table};
- $create_statement .= "\n".join("\n", map{ add_geometry_column($_) } @geometry_columns);
- }
+ $create_statement .= "\n".join("\n", map{ drop_geometry_column($_) } @geometry_columns) if $options->{add_drop_table};
+ $create_statement .= "\n".join("\n", map{ add_geometry_column($_) } @geometry_columns);
+ }
return $create_statement, \@fks;
}
#
$field_def .= ' NOT NULL' unless $field->is_nullable;
- #
- # Geometry constraints
- #
- if(is_geometry($field)){
- foreach ( create_geometry_constraints($field) ) {
- my ($cdefs, $fks) = create_constraint($_,
- {
- quote_field_names => $qf,
- quote_table_names => $qt,
- table_name => $table_name,
- });
- push @$constraint_defs, @$cdefs;
- push @$fks, @$fks;
- }
+ #
+ # Geometry constraints
+ #
+ if(is_geometry($field)){
+ foreach ( create_geometry_constraints($field) ) {
+ my ($cdefs, $fks) = create_constraint($_,
+ {
+ quote_field_names => $qf,
+ quote_table_names => $qt,
+ table_name => $table_name,
+ });
+ push @$constraint_defs, @$cdefs;
+ push @$fks, @$fks;
+ }
}
return $field_def;
}
sub create_geometry_constraints{
- my $field = shift;
-
- my @constraints;
- push @constraints, SQL::Translator::Schema::Constraint->new(
- name => "enforce_dims_".$field->name,
- expression => "(ST_NDims($field) = ".$field->{extra}{dimensions}.")",
- table => $field->table,
- type => CHECK_C,
- );
-
- push @constraints, SQL::Translator::Schema::Constraint->new(
- name => "enforce_srid_".$field->name,
- expression => "(ST_SRID($field) = ".$field->{extra}{srid}.")",
- table => $field->table,
- type => CHECK_C,
- );
- push @constraints, SQL::Translator::Schema::Constraint->new(
- name => "enforce_geotype_".$field->name,
- expression => "(GeometryType($field) = '".$field->{extra}{geometry_type}."'::text OR $field IS NULL)",
- table => $field->table,
- type => CHECK_C,
- );
-
- return @constraints;
+ my $field = shift;
+
+ my @constraints;
+ push @constraints, SQL::Translator::Schema::Constraint->new(
+ name => "enforce_dims_".$field->name,
+ expression => "(ST_NDims($field) = ".$field->{extra}{dimensions}.")",
+ table => $field->table,
+ type => CHECK_C,
+ );
+
+ push @constraints, SQL::Translator::Schema::Constraint->new(
+ name => "enforce_srid_".$field->name,
+ expression => "(ST_SRID($field) = ".$field->{extra}{srid}.")",
+ table => $field->table,
+ type => CHECK_C,
+ );
+ push @constraints, SQL::Translator::Schema::Constraint->new(
+ name => "enforce_geotype_".$field->name,
+ expression => "(GeometryType($field) = '".$field->{extra}{geometry_type}."'::text OR $field IS NULL)",
+ table => $field->table,
+ type => CHECK_C,
+ );
+
+ return @constraints;
}
sub create_index
if ( defined $new_default &&
(!defined $old_default || $old_default ne $new_default) );
- # fixes bug where removing the DEFAULT statement of a column
- # would result in no change
+ # fixes bug where removing the DEFAULT statement of a column
+ # would result in no change
- push @out, sprintf('ALTER TABLE %s ALTER COLUMN %s DROP DEFAULT',
+ push @out, sprintf('ALTER TABLE %s ALTER COLUMN %s DROP DEFAULT',
$to_field->table->name,
$to_field->name)
if ( !defined $new_default && defined $old_default );
my $out = sprintf('ALTER TABLE %s DROP COLUMN %s',
$qt . $old_field->table->name . $qt,
$qf . $old_field->name . $qf);
- $out .= "\n".drop_geometry_column($old_field) if is_geometry($old_field);
+ $out .= "\n".drop_geometry_column($old_field) if is_geometry($old_field);
return $out;
}
sub add_geometry_column{
- my ($field,$options) = @_;
-
- my $out = sprintf("INSERT INTO geometry_columns VALUES ('%s','%s','%s','%s','%s','%s','%s')",
- '',
- $field->table->schema->name,
- $options->{table} ? $options->{table} : $field->table->name,
- $field->name,
- $field->{extra}{dimensions},
- $field->{extra}{srid},
- $field->{extra}{geometry_type});
+ my ($field,$options) = @_;
+
+ my $out = sprintf("INSERT INTO geometry_columns VALUES ('%s','%s','%s','%s','%s','%s','%s')",
+ '',
+ $field->table->schema->name,
+ $options->{table} ? $options->{table} : $field->table->name,
+ $field->name,
+ $field->{extra}{dimensions},
+ $field->{extra}{srid},
+ $field->{extra}{geometry_type});
return $out;
}
sub drop_geometry_column
{
- my $field = shift;
+ my $field = shift;
- my $out = sprintf("DELETE FROM geometry_columns WHERE f_table_schema = '%s' AND f_table_name = '%s' AND f_geometry_column = '%s'",
- $field->table->schema->name,
- $field->table->name,
- $field->name);
+ my $out = sprintf("DELETE FROM geometry_columns WHERE f_table_schema = '%s' AND f_table_name = '%s' AND f_geometry_column = '%s'",
+ $field->table->schema->name,
+ $field->table->name,
+ $field->name);
return $out;
}
sub add_geometry_constraints{
- my $field = shift;
+ my $field = shift;
- my @constraints = create_geometry_constraints($field);
+ my @constraints = create_geometry_constraints($field);
- my $out = join("\n", map { alter_create_constraint($_); } @constraints);
+ my $out = join("\n", map { alter_create_constraint($_); } @constraints);
- return $out;
+ return $out;
}
sub drop_geometry_constraints{
- my $field = shift;
+ my $field = shift;
- my @constraints = create_geometry_constraints($field);
+ my @constraints = create_geometry_constraints($field);
- my $out = join("\n", map { alter_drop_constraint($_); } @constraints);
+ my $out = join("\n", map { alter_drop_constraint($_); } @constraints);
- return $out;
+ return $out;
}
sub alter_table {
my $qt = $options->{quote_table_names} || '';
$options->{alter_table_action} = "RENAME TO $qt$new_table$qt";
- my @geometry_changes;
- push @geometry_changes, map { drop_geometry_column($_); } grep { is_geometry($_) } $old_table->get_fields;
- push @geometry_changes, map { add_geometry_column($_, { table => $new_table }); } grep { is_geometry($_) } $old_table->get_fields;
+ my @geometry_changes;
+ push @geometry_changes, map { drop_geometry_column($_); } grep { is_geometry($_) } $old_table->get_fields;
+ push @geometry_changes, map { add_geometry_column($_, { table => $new_table }); } grep { is_geometry($_) } $old_table->get_fields;
$options->{geometry_changes} = join ("\n",@geometry_changes) if scalar(@geometry_changes);
return sprintf(
'ALTER TABLE %s DROP CONSTRAINT %s',
- $qt . $c->table->name . $qt,
+ $qt . $c->table->name . $qt,
# attention: Postgres has a very special naming structure
# for naming foreign keys, it names them uses the name of
# the table as prefix and fkey as suffix, concatenated by a underscore
use Test::SQL::Translator qw(maybe_plan);
BEGIN {
- maybe_plan(134, 'SQL::Translator::Parser::PostgreSQL');
+ maybe_plan(147, 'SQL::Translator::Parser::PostgreSQL');
SQL::Translator::Parser::PostgreSQL->import('parse');
}
check (f_int between 1 and 5)
);
+ create table t_test3 (
+ test_field varchar(25)
+ ) inherits (t_test2);
+
+ create table t_test4 () inherits (t_test3);
+
CREATE TABLE products_1 (
product_no integer,
name text,
isa_ok( $schema, 'SQL::Translator::Schema', 'Schema object' );
my @tables = $schema->get_tables;
-is( scalar @tables, 5, 'Five tables' );
+is( scalar @tables, 7, 'Seven tables' );
my $t1 = shift @tables;
is( $t1->name, 't_test1', 'Table t_test1 exists' );
my $t2_c3 = shift @t2_constraints;
is( $t2_c3->type, CHECK_C, "Constraint is a 'CHECK'" );
+# test table inheritance
+my $t3 = shift @tables;
+is( $t3->name, 't_test3', 'Table t_test3 exists' );
+is_deeply( $t3->extra->{inherits}, ['t_test2'], 'Table t_test3 inherits from t_test2' );
+
+my @t3_fields = $t3->get_fields;
+is( scalar @t3_fields, 1, '1 field in t_test3' );
+
+my $t3_f1 = shift @t3_fields;
+is( $t3_f1->name, 'test_field', 'First field is "test_field"' );
+is( $t3_f1->data_type, 'varchar', 'Field is an varchar' );
+is( $t3_f1->is_nullable, 1, 'Field can be null' );
+is( $t3_f1->size, 25, 'Size is "25"' );
+is( $t3_f1->default_value, undef, 'Default value is undefined' );
+is( $t3_f1->is_primary_key, 0, 'Field is not PK' );
+
+my @t3_constraints = $t3->get_constraints;
+is( scalar @t3_constraints, 0, "No constraints on table" );
+
+my $t4 = shift @tables;
+is( $t4->name, 't_test4', 'Table t_test4 exists' );
+is( scalar $t4->get_fields, undef, 'No fields in t_test4' );
+is_deeply( $t4->extra->{inherits}, ['t_test3'], 'Table t_test4 inherits from t_test3' );
+
# test temporary tables
is( exists $schema->get_table('products_1')->extra()->{'temporary'}, "", "Table is NOT temporary");
is( $schema->get_table('products_2')->extra('temporary'), 1,"Table is TEMP");