package SQL::Admin::Driver::Pg::Producer;
use base qw( SQL::Admin::Driver::Base::Producer );

use strict;
use warnings;

our $VERSION = v0.5.0;

######################################################################

use SQL::Admin::Driver::Pg::Keywords qw( :all );

our %DATA_TYPE_MAP = (
);

######################################################################

our $ESCAPE_ALL_IDENTIFIERS      = 0;
our $ESCAPE_NONRESERVED_KEYWORDS = 0;
our $ESCAPE_SQL_KEYWORDS         = 0;

######################################################################

our %REFERENTIAL_ACTION = (
    cascade   => [ 'CASCADE' ],
    no_action => [ 'NO', 'ACTION' ],
    restrict  => [ 'RESTRICT' ],
    set_null  => [ 'SET', 'NULL' ],
);

######################################################################
######################################################################

sub _escape_identifier {                 # ;
    my ($self, $identifier) = @_;
    my $lc = lc $identifier;

    $identifier = '"' . $identifier . '"'
      if $ESCAPE_ALL_IDENTIFIERS
        || $RESERVED_KEYWORDS{ $lc }
        || ($ESCAPE_NONRESERVED_KEYWORDS && $NONRESERVED_KEYWORDS{ $lc })
        || ($ESCAPE_SQL_KEYWORDS         && $SQL_KEYWORDS{ $lc })
      ;

    ##################################################################

    $identifier;
}


######################################################################
######################################################################
sub data_type {                          # ;
    my ($self, $data, $parent) = @_;

    return 'serial' if $parent->{autoincrement};

    $data = $DATA_TYPE_MAP{lc $data}
      if exists $DATA_TYPE_MAP{lc $data};

    $self->SUPER::data_type ($data, $parent);
}


######################################################################
######################################################################
sub current_timestamp {                  # ;
    'CURRENT_TIMESTAMP';
}


######################################################################
######################################################################
sub current_time {                       # ;
    'CURRENT_TIME';
}


######################################################################
######################################################################
sub current_date {                       # ;
    'CURRENT_DATE';
}


######################################################################
######################################################################
sub default_clause {                     # ;
    my ($self, $def) = @_;

    'DEFAULT', $self->__apply (%$def);
}


######################################################################
######################################################################

sub autoincrement {                      # ;
}


######################################################################
######################################################################
sub sequence_type {                      # ;
}


######################################################################
######################################################################
sub sequence_options {                   # ;
}


######################################################################
######################################################################
sub sequence_start_with {                # ;
}


######################################################################
######################################################################
sub sequence_increment_by {              # ;
}


######################################################################
######################################################################
sub sequence_minvalue {                  # ;
}


######################################################################
######################################################################
sub sequence_maxvalue {                  # ;
}


######################################################################
######################################################################
sub sequence_cache {                     # ;
}


######################################################################
######################################################################

sub alter_table_actions {                # ;
    my ($self, $def) = @_;

    map $self->__apply (alter_table_action => $_), @$def;
}


######################################################################
######################################################################
sub alter_table_action {                 # ;
    my ($self, $def) = @_;

    print '>>> ', join ' ', keys %$def;
    $self->__apply (%$def);
}


######################################################################
######################################################################
sub delete_rule {                        # ;
    my ($self, $def) = @_;

    print ">> delete rule: $def\n";
    map +('ON', 'DELETE', @{ $REFERENTIAL_ACTION{$_} }), grep defined, $def;
}


######################################################################
######################################################################
sub update_rule {                        # ;
    my ($self, $def) = @_;

    print ">> update rule: $def\n";
    map +('ON', 'UPDATE', @{ $REFERENTIAL_ACTION{$_} }), grep defined, $def;
}


######################################################################
######################################################################

sub create_sequence {                    # ;
    my ($self, $def) = @_;

    (
        'CREATE',
        'SEQUENCE',
        $self->__call (sequence_name => $def),
        $self->__call (sequence_type => $def),
        $self->__call (sequence_options => $def),
    );
}


######################################################################
######################################################################
sub index_name {                         # ;
    my ($self, $def) = @_;

    $self->_escape_identifier ($def->{name});
}


######################################################################
######################################################################
sub create_index {                       # ;
    my ($self, $def) = @_;
    join ' ', (
        'CREATE',
        $self->__call (index_unique => $def),
        'INDEX',
        $self->__call (index_name => $def),
        'ON',
        $self->__call (table_name => $def),
        $self->__call (index_column_list => $def),
        $self->__call (index_options => $def),
    );
}


######################################################################
######################################################################
sub create_table {                       # ;
    my ($self, $def) = @_;

    join ' ', (
        'CREATE',
        'TABLE',
        $self->__call (table_name    => $def),
        $self->__call (table_content => $def),
        $self->__call (table_options => $def),
    );
}


######################################################################
######################################################################
sub alter_table {                        # ;
    my ($self, $def) = @_;

    my @list = map $self->__apply (%$_), @{ $def->{alter_table_actions} };

    return unless @list;

    (
        'ALTER',
        'TABLE',
        $self->__call (table_name => $def),
        @list
    );
}


######################################################################
######################################################################

sub create_schema {                      # ;
    my ($self, $def) = @_;

    (
        'CREATE',
        'SCHEMA',
        $self->_escape_identifier ($def->{schema_identifier}),
    );
}


######################################################################
######################################################################

package SQL::Admin::Driver::Pg::Producer;

1;