package DBIx::Model::Table;
use strict;
use warnings;
use DBIx::Model::Column;
use DBIx::Model::FK;
use Types::Standard qw/ArrayRef Int/;

our $VERSION = '0.0.1_2';
our $INLINE  = {
    _columns => {
        is      => 'ro',
        isa     => ArrayRef,
        default => sub { [] },
    },
    db => {
        is       => 'ro',
        required => 1,
        weaken   => 1,
    },
    name => {
        is       => 'ro',
        required => 1,
    },
    name_lc => {
        is       => 'ro',
        init_arg => undef,
        default  => sub { lc $_[0]->name },
    },
    type => {
        is       => 'ro',
        required => 1,
    },
    ref_count => {
        is      => 'rw',
        isa     => Int,
        default => 0,
    },
    target_count => {
        is      => 'rw',
        isa     => Int,
        default => 0,
    },
    _foreign_keys => {
        is      => 'ro',
        isa     => ArrayRef,
        default => sub { [] },
    },
};

sub add_column {
    my $self = shift;
    my $col  = DBIx::Model::Column->new( @_, table => $self );
    push( @{ $self->_columns }, $col );
    return $col;
}

sub add_foreign_key {
    my $self = shift;
    my $fk   = DBIx::Model::FK->new( @_, table => $self );
    push( @{ $self->_foreign_keys }, $fk );
    return $fk;
}

sub as_string {
    my $self   = shift;
    my $prefix = shift;
    my $str    = $prefix . $self->name;

    foreach my $col ( $self->columns ) {
        $str .= "\n" . $col->as_string( $prefix . '  ' );
    }

    if ( my @pri = $self->primaries ) {
        $str .=
          "\n${prefix}  PRIMARY(" . join( ',', map { $_->name } @pri ) . ')';
    }

    foreach my $fk ( $self->foreign_keys ) {
        $str .= "\n" . $fk->as_string( $prefix . '  ' );
    }

    return $str;
}

sub bump_ref_count {
    my $self = shift;
    $self->ref_count( $self->ref_count + 1 );
}

sub bump_target_count {
    my $self = shift;
    $self->target_count( $self->target_count + 1 );
}

sub columns {
    my $self = shift;
    return @{ $self->_columns } if wantarray;
    return $self->_columns;
}

sub primaries {
    my $self = shift;
    return grep { $_->primary } $self->columns;
}

sub foreign_keys {
    my $self = shift;
    return @{ $self->_foreign_keys } if wantarray;
    return $self->_foreign_keys;
}

### DO NOT EDIT BELOW! (generated by Class::Inline v0.0.1)
#<<<
  require Carp;require Scalar::Util;our@ATTRS_UNEX=(undef);sub new {my$class=
  shift;my$self={@_ ? @_ > 1 ? @_ : %{$_[0]}: ()};map {local$Carp::CarpLevel=
  $Carp::CarpLevel + 1;Carp::croak(
  "missing attribute DBIx::Model::Table::$_ is required")unless exists$self->{
  $_}}'db','name','type';map {delete$self->{$_}}'name_lc';if (@ATTRS_UNEX){map
  {local$Carp::CarpLevel=$Carp::CarpLevel + 1;Carp::carp(
  "DBIx::Model::Table attribute '$_' unexpected");delete$self->{$_ }}sort grep
  {not exists$INLINE->{$_ }}keys %$self}else {@ATTRS_UNEX=map {delete$self->{
  $_ };$_}grep {not exists$INLINE->{$_ }}keys %$self}bless$self,ref$class ||
  $class;map {$self->{$_ }=eval {$INLINE->{$_ }->{'isa'}->($self->{$_ })};
  Carp::croak(qq{DBIx::Model::Table::$_ value invalid ($@)})if $@}grep {exists
  $self->{$_ }}'_columns','_foreign_keys','ref_count','target_count';map {
  Scalar::Util::weaken($self->{$_ })}grep {defined$self->{$_ }// undef}'db';
  $self}sub __ro {my (undef,undef,undef,$sub)=caller(1);local$Carp::CarpLevel=
  $Carp::CarpLevel + 1;Carp::croak("attribute $sub is read-only (value: '" .(
  $_[1]// 'undef')."')")}sub _columns {$_[0]->__ro($_[1])if @_ > 1;$_[0]{
  '_columns'}//= eval {$INLINE->{'_columns'}->{'isa'}->($INLINE->{'_columns'}
  ->{'default'}->($_[0]))};Carp::croak(
  'invalid (DBIx::Model::Table::_columns) default value: ' .$@)if $@;$_[0]{
  '_columns'}}sub _foreign_keys {$_[0]->__ro($_[1])if @_ > 1;$_[0]{
  '_foreign_keys'}//= eval {$INLINE->{'_foreign_keys'}->{'isa'}->($INLINE->{
  '_foreign_keys'}->{'default'}->($_[0]))};Carp::croak(
  'invalid (DBIx::Model::Table::_foreign_keys) default value: ' .$@)if $@;$_[0
  ]{'_foreign_keys'}}sub db {$_[0]->__ro($_[1])if @_ > 1;$_[0]{'db'}}sub name
  {$_[0]->__ro($_[1])if @_ > 1;$_[0]{'name'}}sub name_lc {$_[0]->__ro($_[1])if
  @_ > 1;$_[0]{'name_lc'}//= $INLINE->{'name_lc'}->{'default'}->($_[0])}sub
  ref_count {if (@_ > 1){$_[0]{'ref_count'}=eval {$INLINE->{'ref_count'}->{
  'isa'}->($_[1])};Carp::croak(
  'invalid (DBIx::Model::Table::ref_count) value: '.$@)if $@;return $_[0]}$_[0
  ]{'ref_count'}//= eval {$INLINE->{'ref_count'}->{'isa'}->($INLINE->{
  'ref_count'}->{'default'})};Carp::croak(
  'invalid (DBIx::Model::Table::ref_count) default value: ' .$@)if $@;$_[0]{
  'ref_count'}}sub target_count {if (@_ > 1){$_[0]{'target_count'}=eval {
  $INLINE->{'target_count'}->{'isa'}->($_[1])};Carp::croak(
  'invalid (DBIx::Model::Table::target_count) value: '.$@)if $@;return $_[0]}
  $_[0]{'target_count'}//= eval {$INLINE->{'target_count'}->{'isa'}->($INLINE
  ->{'target_count'}->{'default'})};Carp::croak(
  'invalid (DBIx::Model::Table::target_count) default value: ' .$@)if $@;$_[0]
  {'target_count'}}sub type {$_[0]->__ro($_[1])if @_ > 1;$_[0]{'type'}}
#>>>
### DO NOT EDIT ABOVE! (generated by Class::Inline v0.0.1)

1;
