App-csv2sqlite

 view release on metacpan or  search on metacpan

lib/App/csv2sqlite.pm  view on Meta::CPAN

  $class->new( $class->getopt($args) );
}

around BUILDARGS => sub {
  my ($orig, $self, @args) = @_;
  my $args = $self->$orig(@args);

  if( my $enc = delete $args->{encoding} ){
    ($args->{loader_options} ||= {})->{file_encoding} ||= $enc;
  }

  return $args;
};

has csv_files => (
  is         => 'ro',
  coerce     => sub { ref $_[0] eq 'ARRAY' ? $_[0] : [ $_[0] ] },
);

has csv_options => (
  is         => 'ro',
  default    => sub { +{} },
);

has loader_options => (
  is         => 'ro',
  default    => sub { +{} },
);

has dbname => (
  is         => 'ro',
);

has dbh => (
  is         => 'lazy',
);

sub _build_dbh {
  my ($self) = @_;
  # TODO: does the dbname need to be escaped in some way?
  my $dbh = DBI->connect('dbi:SQLite:dbname=' . $self->dbname, undef, undef, {
    RaiseError => 1,
    PrintError => 0,
    sqlite_unicode => $self->encoding ? 1 : 0,
  });
  return $dbh;
}

sub encoding {
  return $_[0]->loader_options->{file_encoding};
}

sub help { Getopt::Long::HelpMessage(2); }


sub getopt {
  my ($class, $args) = @_;
  my $opts = {};

  {
    local @ARGV = @$args;
    my $p = Getopt::Long::Parser->new(
      config => [qw(pass_through auto_help auto_version)],
    );
    $p->getoptions($opts,
      'csv_files|csv-file|csvfile|csv=s@',
      # TODO: 'named_csv_files=s%'
      # or maybe --csv and --named should be subs that append to an array ref to keep order?
      'csv_options|csv-opt|csvopt|o=s%',
      # TODO: tableloader options like 'drop' or maybe --no-create
      'loader_options|loader-opt|loaderopt|l=s%',
      'dbname|database=s',
      'encoding|enc|e=s',
    ) or $class->help;
    $args = [@ARGV];
  }

  # last arguments
  $opts->{dbname} ||= pop @$args;

  # first argument
  if( @$args ){
    push @{ $opts->{csv_files} ||= [] }, @$args;
  }

  return $opts;
}

sub load_tables {
  my ($self) = @_;

  # TODO: option for wrapping the whole loop in a transaction rather than each table

  foreach my $file ( @{ $self->csv_files } ){
    my %opts = (
      %{ $self->loader_options },
      csv_opts => { %{ $self->csv_options } },
      file => $file,
    );

    # TODO: This could work but i hate the escaping thing.
    # Allow table=file (use "=file" for files with an equal sign).
    #if( $file =~ /^([^=:]*)[=:](.+)$/ ){ $opts{name} = $1 if $1; $opts{file} = $2; }

    DBIx::TableLoader::CSV->new(
      %opts,
      dbh  => $self->dbh,
    )->load;
  }

  return;
}

sub run {
  my $class = shift || __PACKAGE__;
  my $args = @_ ? shift : [@ARGV];

  my $self = $class->new_from_argv($args);
  $self->load_tables;
}

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 1.875 second using v1.00-cache-2.02-grep-82fe00e-cpan-72ae3ad1e6da )