# vim: set ts=2 sts=2 sw=2 expandtab smarttab: # # This file is part of DBIx-TableLoader-CSV # # This software is copyright (c) 2011 by Randy Stauner. # # This is free software; you can redistribute it and/or modify it under # the same terms as the Perl 5 programming language system itself. # use strict; use warnings; package DBIx::TableLoader::CSV; { $DBIx::TableLoader::CSV::VERSION = '1.100'; } # git description: v1.003-7-gd50f5c5 BEGIN { $DBIx::TableLoader::CSV::AUTHORITY = 'cpan:RWSTAUNER'; } # ABSTRACT: Easily load a CSV into a database table use parent 'DBIx::TableLoader'; use Carp qw(croak carp); use Module::Load (); use Text::CSV 1.21 (); # 'new' inherited sub defaults { my ($self) = @_; return { csv => undef, csv_class => 'Text::CSV', csv_defaults => { # Text::CSV encourages setting { binary => 1 } binary => 1, }, csv_opts => {}, file => undef, ignore_csv_errors => 0, io => undef, no_header => 0, }; } sub get_raw_row { my ($self) = @_; my $row = $self->{csv}->getline($self->{io}); unless( $self->{ignore_csv_errors} ){ if( !$row && !$self->{csv}->eof ){ croak 'CSV parse error: ' . $self->{csv}->error_diag; } } return $row; } sub default_name { my ($self) = @_; # guess name if not provided return $self->{name} ||= $self->{file} ? do { require File::Basename; # core File::Basename::fileparse($self->{file}, qr/\.[^.]*/); } : 'csv'; } sub prepare_data { my ($self) = @_; Module::Load::load($self->{csv_class}); # if an object is not passed in via 'csv', create one from 'csv_opts' $self->{csv} ||= $self->{csv_class}->new({ %{ $self->{csv_defaults} }, %{ $self->{csv_opts} } }) or croak "Cannot use CSV: " . $self->{csv_class}->error_diag(); # if 'io' not provided set it to the handle returned from opening 'file' $self->{io} ||= do { croak("Cannot proceed without a 'file' or 'io' attribute") unless my $file = $self->{file}; open(my $fh, '<', $file) or croak("Failed to open '$file': $!"); binmode($fh); $fh; }; # discard first row if columns given (see POD for 'no_header' option) $self->{first_row} = $self->get_raw_row() if $self->{columns} && !$self->{no_header}; } 1; __END__ =pod =encoding utf-8 =for :stopwords Randy Stauner ACKNOWLEDGEMENTS csv cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan =head1 NAME DBIx::TableLoader::CSV - Easily load a CSV into a database table =head1 VERSION version 1.100 =head1 SYNOPSIS my $dbh = DBI->connect(@connection_args); DBIx::TableLoader::CSV->new(dbh => $dbh, file => $path_to_csv)->load(); # interact with new database table full of data in $dbh =head1 DESCRIPTION This is a subclass of L that handles the common operations of reading a CSV file (using the powerful L (which uses L if available)). This module simplifies the task of transforming a CSV file into a database table. This functionality was the impetus for the parent module (L). In most cases simply calling C is sufficient (see L). The methods defined by this subclass are documented for completeness. =head1 METHODS =head2 new Accepts all options described in L plus some CSV specific options. See L. =head1 get_raw_row Returns C<< $csv->getline($io) >>. After the last row is returned this will check L and croak with the message from L as described by L. (If you wish to disable this behavior you can set C<< ignore_csv_errors => 1 >> in the constructor.) =head1 default_name If the C option is not provided, and the C option is, this returns the file basename. Falls back to C<'csv'>. =head1 prepare_data This is called automatically from the constructor to make things as simple and automatic as possible. =over 4 =item * Load C if it is not. =item * Instantiate C with C and C. =item * Open the C provided unless C is passed instead. =item * Discard the first row if C is provided and C is not. =back =for test_synopsis my (@connection_args, $dbh, $path_to_csv); =head1 OPTIONS There are many options available for configuration. Options specific to this module are listed below. Also see L for options from the base module. Basic usage: =over 4 =item * C - Hashref of options to pass to the C method of C See L for its list of accepted options. =item * C - Path to a csv file The file will be opened (unless C is provided) and its basename will be the default table name (which can be overwritten with the C option). =back Options for more customization/control: =over 4 =item * C - A L compatible object instance If not supplied an instance will be created using C<< $csv_class->new(\%csv_opts) >>. =item * C - The class to instantiate if C is not supplied Defaults to C (which will attempt to load L and fall back to L). =item * C - Hashref of default options for C constructor Includes C<< { binary => 1 } >> (as encouraged by L); To turn off the C option you can pass C<< { binary => 0 } >> to C. If you are using a different C that does not accept the C option you may need to overwrite this with an empty hash. =item * C - Boolean (defaults to false) If L fails to parse a row it will abort and skip the rest of the file. This module detects parser errors and will C with the message from L upon failure to read the whole file. (This behavior is similar to (but separate from) setting C<< auto_diag => 2 >> in the csv options.) Set this option to a true value if you want to accept partially read CSV files rather than getting an error. B that other exceptions can still be thrown (including failure to open the file or if a misconfigured parser or malformed CSV returns a row with an inconsistent number of columns). =item * C - A filehandle or IO-like object from which to read CSV lines This will be used as C<< $csv->getline($io) >>. When providing this option you can still provide C if you want the table name to be determined automatically (but no attempt will be made to open C). =item * C - Table name If not given the table name will be set to the file basename or C<'csv'> if C is not provided. =item * C - Boolean Usually the first row [header] of a CSV is the column names. If you specify C this module assumes you are overwriting the usual header row so the first row of the CSV will be discarded. If there is no header row on the CSV (the first row is data), you must set C to true in order to preserve the first row of the CSV. =back =head1 SEE ALSO =over 4 =item * L =item * L =item * L - Alternative project automating CSV usage =back =head1 SUPPORT =head2 Perldoc You can find documentation for this module with the perldoc command. perldoc DBIx::TableLoader::CSV =head2 Websites The following websites have more information about this module, and may be of help to you. As always, in addition to those websites please use your favorite search engine to discover more resources. =over 4 =item * Search CPAN The default CPAN search engine, useful to view POD in HTML format. L =item * RT: CPAN's Bug Tracker The RT ( Request Tracker ) website is the default bug/issue tracking system for CPAN. L =item * CPAN Ratings The CPAN Ratings is a website that allows community ratings and reviews of Perl modules. L =item * CPAN Testers The CPAN Testers is a network of smokers who run automated tests on uploaded CPAN distributions. L =item * CPAN Testers Matrix The CPAN Testers Matrix is a website that provides a visual overview of the test results for a distribution on various Perls/platforms. L =item * CPAN Testers Dependencies The CPAN Testers Dependencies is a website that shows a chart of the test results of all dependencies for a distribution. L =back =head2 Bugs / Feature Requests Please report any bugs or feature requests by email to C, or through the web interface at L. You will be automatically notified of any progress on the request by the system. =head2 Source Code L git clone https://github.com/rwstauner/DBIx-TableLoader-CSV.git =head1 AUTHOR Randy Stauner =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2011 by Randy Stauner. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut