Alzabo
view release on metacpan or search on metacpan
lib/Alzabo/RDBMSRules/PostgreSQL.pm view on Meta::CPAN
sub blob_type { return 'BYTEA' }
sub column_types
{
return ( qw( INTEGER
INT2
INT8
NUMERIC
FLOAT
FLOAT4
CHAR
VARCHAR
TEXT
BYTEA
DATE
TIME
TIMESTAMP
INTERVAL
SERIAL
BIGSERIAL
BOOLEAN
BIT
),
'BIT VARYING',
qw( INET
CIDR
MACADDR ) );
}
my %features = map { $_ => 1 } qw ( extended_column_types
constraints
functional_indexes
allows_raw_default
);
sub feature
{
shift;
return $features{+shift};
}
sub quote_identifiers { 1 }
sub quote_identifiers_character { '"' }
sub schema_sql
{
my $self = shift;
validate_pos( @_, { isa => 'Alzabo::Schema' } );
my $schema = shift;
my @sql = $self->SUPER::schema_sql($schema);
# This has to come at the end because we don't know which tables
# reference other tables.
foreach my $t ( $schema->tables )
{
foreach my $con ( grep { /\s*(?:check|constraint)/i } $t->attributes )
{
push @sql, $self->table_constraint_sql($t);
}
foreach my $fk ( $t->all_foreign_keys )
{
push @sql, $self->foreign_key_sql($fk);
}
}
return @sql;
}
sub table_sql
{
my $self = shift;
my $table = shift;
my $create_sequence = shift;
# Create table sequence by default
$create_sequence = 1 unless defined $create_sequence;
my $sql = qq|CREATE TABLE "| . $table->name . qq|" (\n |;
$sql .= join ",\n ", map { $self->column_sql($_) } $table->columns;
my @att = $table->attributes;
if (my @pk = $table->primary_key)
{
$sql .= ",\n";
$sql .= ' PRIMARY KEY (';
$sql .= join ', ', map { '"' . $_->name . '"' } @pk;
$sql .= ")\n";
}
$sql .= ")\n";
my @sql = ($sql);
foreach my $i ( $table->indexes )
{
push @sql, $self->index_sql($i);
}
if ($create_sequence)
{
foreach my $c ( grep { $_->sequenced } $table->columns )
{
push @sql, $self->_sequence_sql($c);
}
}
lib/Alzabo/RDBMSRules/PostgreSQL.pm view on Meta::CPAN
if ( $fk->from_is_dependent )
{
$sql .= 'CASCADE';
}
else
{
my @from = $fk->columns_from;
unless ( ( grep { $_->nullable } @from ) == @from )
{
$sql .= 'SET DEFAULT';
}
else
{
$sql .= 'SET NULL';
}
}
$self->{state}{fk_sql}{ $fk->id } = 1;
return $sql;
}
sub _fk_name
{
my $id = $_[1]->id;
return
( length $id > 63
? 'fk_' . Digest::MD5::md5_hex( $_[1]->id )
: $id
);
}
sub table_constraint_sql
{
my $self = shift;
my $table = shift;
return map { 'ALTER TABLE "' . $table->name . '" ADD ' . $_ } $table->attributes;
}
sub drop_table_sql
{
my $self = shift;
my $table = shift;
my $is_recreate = shift;
my @sql;
if ($is_recreate)
{
# We need to drop foreign keys referring to this table before
# we drop it.
foreach my $fk ( $table->all_foreign_keys )
{
push @sql, $self->drop_foreign_key_sql( $fk->reverse );
}
}
push @sql, $self->SUPER::drop_table_sql($table);
unless ($is_recreate)
{
foreach my $c ( $table->columns )
{
push @sql, $self->_drop_sequence_sql($c) if $c->sequenced;
}
}
return @sql;
}
sub _drop_sequence_sql
{
my $self = shift;
my $col = shift;
return if $col->type =~ /^(?:SERIAL(?:4|8)?|BIGSERIAL)$/;
my $seq_name = $self->_sequence_name($col);
return qq|DROP SEQUENCE "$seq_name";\n|;
}
sub drop_column_sql
{
my $self = shift;
my %p = @_;
recreate_table_exception();
}
sub recreate_table_sql
{
my $self = shift;
my %p = @_;
# This is a hack to prevent this SQL from being made multiple
# times (which would be pointless)
return () if $self->{state}{table_sql}{ $p{new}->name };
push @{ $self->{state}{deferred_sql} },
$self->_restore_foreign_key_sql( $p{new} );
return ( $self->_temp_table_sql( $p{new}, $p{old} ),
$self->drop_table_sql( $p{old}, 1 ),
# the 0 param indicates that we should not create sequences
$self->table_sql( $p{new}, 0 ),
$self->_restore_table_data_sql( $p{new}, $p{old} ),
$self->_drop_temp_table( $p{new} ),
);
}
sub _temp_table_sql
{
my $self = shift;
my $new_table = shift;
my $old_table = shift;
( run in 0.842 second using v1.01-cache-2.11-cpan-5a3173703d6 )