package DBIx::Data::Store::Raw;

use strictures 1;

use DBIx::Connector;

sub new {
  my $proto = shift;
  bless({ %{$_[0]} }, ref($proto)||$proto);
}

sub connect {
  my $class = shift;
  $class->new({ connect_info => [ @_ ] });
}

sub connect_info { shift->{connect_info} }

sub _connector { $_[0]->{_connector} ||= $_[0]->_build__connector }

sub _build__connector {
  DBIx::Connector->new(@{$_[0]->connect_info});
}

sub run_row { shift->_exec_calling('fetchrow_arrayref', @_) }

sub run_rowset { shift->_exec_calling('fetchall_arrayref', @_) }

sub run_rowstream {
  shift->_exec_calling(sub {
    DBIx::Data::Stream::STH->new({ sth => $_[0] })
  }, @_);
}

sub _exec_calling {
  my ($self, $sth_method, $to_call, $sth_args) = @_;
  
  $self->_exec(
    ref($to_call) eq 'CODE'
      ? sub { $self->$to_call($sth_method, $_[0], $sth_args) }
      : sub {
          $self->_sth_for($_[0], $to_call, $sth_args)->$sth_method
        }
  );
}

sub _exec {
  $_[0]->_connector->run($_[1]);
}

sub _sth_for {
  my ($self, $dbh, $sql, $args) = @_;
  my $sth = $dbh->prepare_cached($sql, {}, 3);
  $sth->execute(@$args);
  return $sth;
}

1;
