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 )