package Dimedis::Sql::CSV; use strict; use vars qw($VERSION); use Carp; use Data::Dumper; use FileHandle; use File::Path; $VERSION = '0.20'; ##------------------------------------------------------------------------------ # CLASS # Dimedis::Sql::CSV # # PURPOSE # Diese Klasse ermöglicht das Lesen und Schreiben einer CSV-Datei. #
# Beim Erzeugen eines neuen CSV-Objektes wird die im Konstruktor angegebene
# Datei entweder zum Lesen oder zum Schreiben geöffnet (abhängig vom
# optionalen Parameter write).
#
# Mit dem delimiter-Parameter kann das Trennzeichen für die
# einzelnen Spalten der CSV-Datei angegeben werden (Default-Trennzeichen
# ist ";").
#
# Wurde die Datei zum Schreiben geöffnet, dann kann über die Methode
# append() eine neue Zeile hinzugefügt werden.
#
# Wurde die Datei zum Lesen geöffnet, dann kann über die Methode
#
# Übergeben wird eine Referenz auf eine Liste, welche die hinzuzufügenden
# Daten enthält. Die einzelnen List-Elemente werden beim Schreiben in die
# CSV-Datei durch das im Konstruktor angegebene Trennzeichen voneinander
# getrennt.
#
# Backslashes, Newlines und Tabulatoren, die in den übergebenen Daten
# enthalten sind, werden vor dem Schreiben in die CSV-Datei escaped.
#
# INPUT
# data_lr -- Referenz auf die Liste der hinzuzufügenden Daten
#-------------------------------------------------------------------------------
sub append {
my $self = shift;
my %par = @_;
my $fh = $self->{fh};
#--- Parameterprüfung
my $data_lr = $par{data_lr} or croak("'data_lr' missing");
foreach ( @{$data_lr} ) {
#--- escape '\'
s/\\/\\\\/g;
#--- escape newlines
s/\n/\\n/g;
s/\r/\\r/g;
#--- escape tabs
s/\t/\\t/g;
}
my $data_string = join ( $self->{delimiter}, @{$data_lr} );
print $fh "$data_string\n" or die "Can't write file: $!\n";
}
##------------------------------------------------------------------------------
# METHOD
# public: read_line
#
# DESCRIPTION
# Liest eine einzelne Zeile aus der CSV-Datei ein
#
# Die Methode liefert eine Referenz auf eine Liste, welche die gelesenen
# Daten enthält. Als Trennzeichen zwischen den einzelnen Spalten der
# gelesenen Zeile gilt der im Konstruktor angegebene
# Backslashes, Newlines und Tabulatoren, die vor dem Schreiben in die
# CSV-Datei escaped wurden, werden hier wieder unescaped.
#
# RETURN
# Referenz auf die Liste der eingelesenen Daten oder read_line() eine einzelne Zeile gelesen werden.
#
# AUTHOR
# Sabine Tonn delimiter-
# Parameter.
# undef,
# wenn das Dateiende erreicht wurde
#-------------------------------------------------------------------------------
sub read_line {
my $self = shift;
my $fh = $self->{fh};
my $data_record;
if ( $data_record = <$fh> ) {
#--- Zeilenumbruch am Ende der Zeile abschneiden
chomp $data_record;
my @data = split ( /$self->{delimiter}/, $data_record );
foreach ( @data ) {
#--- unescape '\t'
s/([^\\])\\t/$1\t/g;
s/^\\t/\t/g;
#--- unescape '\n', '\r'
s/([^\\])\\n/$1\n/g;
s/^\\n/\n/g;
s/([^\\])\\r/$1\r/g;
s/^\\r/\r/g;
#--- unescape '\\'
s/\\\\/\\/g;
}
return \@data;
}
#--- Dateiende
else {
return undef;
}
}
sub DESTROY {
my $self = shift;
#--- CSV-Datei schließen
my $fh = $self->{fh};
close($fh) if $fh;
}