/[cvs]/nfo/perl/libs/DBD/CSV.pm
ViewVC logotype

Contents of /nfo/perl/libs/DBD/CSV.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations)
Wed Nov 13 18:50:19 2002 UTC (21 years, 6 months ago) by joko
Branch: MAIN
- to be patched

1 # -*- perl -*-
2 #
3 # DBD::CSV - A DBI driver for CSV and similar structured files
4 #
5 # This module is currently maintained by
6 #
7 # Jeff Zucker
8 # <jeff@vpservices.com>
9 #
10 # The original author is Jochen Wiedmann.
11 #
12 # Copyright (C) 1998 by Jochen Wiedmann
13 #
14 # All rights reserved.
15 #
16 # You may distribute this module under the terms of either the GNU
17 # General Public License or the Artistic License, as specified in
18 # the Perl README file.
19 #
20
21 require 5.004;
22 use strict;
23
24
25 require DynaLoader;
26 require DBD::File;
27 require IO::File;
28
29
30 package DBD::CSV;
31
32 use vars qw(@ISA $VERSION $drh $err $errstr $sqlstate);
33
34 @ISA = qw(DBD::File);
35
36 $VERSION = '0.2002';
37
38 $err = 0; # holds error code for DBI::err
39 $errstr = ""; # holds error string for DBI::errstr
40 $sqlstate = ""; # holds error state for DBI::state
41 $drh = undef; # holds driver handle once initialised
42
43
44 package DBD::CSV::dr; # ====== DRIVER ======
45
46 use Text::CSV_XS();
47
48 use vars qw(@ISA @CSV_TYPES);
49
50 @CSV_TYPES = (
51 Text::CSV_XS::IV(), # SQL_TINYINT
52 Text::CSV_XS::IV(), # SQL_BIGINT
53 Text::CSV_XS::PV(), # SQL_LONGVARBINARY
54 Text::CSV_XS::PV(), # SQL_VARBINARY
55 Text::CSV_XS::PV(), # SQL_BINARY
56 Text::CSV_XS::PV(), # SQL_LONGVARCHAR
57 Text::CSV_XS::PV(), # SQL_ALL_TYPES
58 Text::CSV_XS::PV(), # SQL_CHAR
59 Text::CSV_XS::NV(), # SQL_NUMERIC
60 Text::CSV_XS::NV(), # SQL_DECIMAL
61 Text::CSV_XS::IV(), # SQL_INTEGER
62 Text::CSV_XS::IV(), # SQL_SMALLINT
63 Text::CSV_XS::NV(), # SQL_FLOAT
64 Text::CSV_XS::NV(), # SQL_REAL
65 Text::CSV_XS::NV(), # SQL_DOUBLE
66 );
67
68 @DBD::CSV::dr::ISA = qw(DBD::File::dr);
69
70 $DBD::CSV::dr::imp_data_size = 0;
71 $DBD::CSV::dr::data_sources_attr = undef;
72
73 sub connect ($$;$$$) {
74 my($drh, $dbname, $user, $auth, $attr) = @_;
75
76 my $this = $drh->DBD::File::dr::connect($dbname, $user, $auth, $attr);
77 $this->{'csv_tables'} ||= {};
78
79 $this;
80 }
81
82
83 package DBD::CSV::db; # ====== DATABASE ======
84
85 $DBD::CSV::db::imp_data_size = 0;
86
87 @DBD::CSV::db::ISA = qw(DBD::File::db);
88
89 sub csv_cache_sql_parser_object {
90 my $dbh = shift;
91 my $parser = {
92 dialect => 'CSV',
93 RaiseError => $dbh->FETCH('RaiseError'),
94 PrintError => $dbh->FETCH('PrintError'),
95 };
96 my $sql_flags = $dbh->FETCH('csv_sql') || {};
97 %$parser = (%$parser,%$sql_flags);
98 $parser = SQL::Parser->new($parser->{dialect},$parser);
99 $dbh->{csv_sql_parser_object} = $parser;
100 return $parser;
101 }
102
103
104
105 package DBD::CSV::st; # ====== STATEMENT ======
106
107 $DBD::CSV::st::imp_data_size = 0;
108
109 @DBD::CSV::st::ISA = qw(DBD::File::st);
110
111
112 package DBD::CSV::Statement;
113
114 @DBD::CSV::Statement::ISA = qw(DBD::File::Statement);
115
116 sub open_table ($$$$$) {
117 my($self, $data, $table, $createMode, $lockMode) = @_;
118 my $dbh = $data->{Database};
119 my $tables = $dbh->{csv_tables};
120 if (!exists($tables->{$table})) {
121 $tables->{$table} = {};
122 }
123 my $meta = $tables->{$table} || {};
124 my $csv = $meta->{csv} || $dbh->{csv_csv};
125 if (!$csv) {
126 my $class = $meta->{class} || $dbh->{'csv_class'} ||
127 'Text::CSV_XS';
128 my %opts = ( 'binary' => 1 );
129 $opts{'eol'} = $meta->{'eol'} || $dbh->{'csv_eol'} || "\015\012";
130 $opts{'sep_char'} =
131 exists($meta->{'sep_char'}) ? $meta->{'sep_char'} :
132 exists($dbh->{'csv_sep_char'}) ? $dbh->{'csv_sep_char'} : ",";
133 $opts{'quote_char'} =
134 exists($meta->{'quote_char'}) ? $meta->{'quote_char'} :
135 exists($dbh->{'csv_quote_char'}) ? $dbh->{'csv_quote_char'} :
136 '"';
137 $opts{'escape_char'} =
138 exists($meta->{'escape_char'}) ? $meta->{'escape_char'} :
139 exists($dbh->{'csv_escape_char'}) ? $dbh->{'csv_escape_char'} :
140 '"';
141 $csv = $meta->{csv} = $class->new(\%opts);
142 }
143 my $file = $meta->{file} || $table;
144 my $tbl = $self->SUPER::open_table($data, $file, $createMode, $lockMode);
145 if ($tbl) {
146 $tbl->{'csv_csv'} = $csv;
147 my $types = $meta->{types};
148 if ($types) {
149 # The 'types' array contains DBI types, but we need types
150 # suitable for Text::CSV_XS.
151 my $t = [];
152 foreach (@{$types}) {
153 if ($_) {
154 $_ = $DBD::CSV::CSV_TYPES[$_+6] || Text::CSV_XS::PV();
155 } else {
156 $_ = Text::CSV_XS::PV();
157 }
158 push(@$t, $_);
159 }
160 $tbl->{types} = $t;
161 }
162 if (!$createMode) {
163 my($array, $skipRows);
164 if (exists($meta->{skip_rows})) {
165 $skipRows = $meta->{skip_rows};
166 } else {
167 $skipRows = exists($meta->{col_names}) ? 0 : 1;
168 }
169 if ($skipRows--) {
170 if (!($array = $tbl->fetch_row($data))) {
171 die "Missing first row";
172 }
173 $tbl->{col_names} = $array;
174 while ($skipRows--) {
175 $tbl->fetch_row($data);
176 }
177 }
178 $tbl->{first_row_pos} = $tbl->{fh}->tell();
179 if (exists($meta->{col_names})) {
180 $array = $tbl->{col_names} = $meta->{col_names};
181 } elsif (!$tbl->{col_names} || !@{$tbl->{col_names}}) {
182 # No column names given; fetch first row and create default
183 # names.
184 my $a = $tbl->{cached_row} = $tbl->fetch_row($data);
185 $array = $tbl->{'col_names'};
186 for (my $i = 0; $i < @$a; $i++) {
187 push(@$array, "col$i");
188 }
189 }
190 my($col, $i);
191 my $columns = $tbl->{col_nums};
192 foreach $col (@$array) {
193 $columns->{$col} = $i++;
194 }
195 }
196 }
197 $tbl;
198 }
199
200
201 package DBD::CSV::Table;
202
203 @DBD::CSV::Table::ISA = qw(DBD::File::Table);
204
205 sub fetch_row ($$) {
206 my($self, $data) = @_;
207 my $fields;
208 if (exists($self->{cached_row})) {
209 $fields = delete($self->{cached_row});
210 } else {
211 $! = 0;
212 my $csv = $self->{csv_csv};
213 local $/ = $csv->{'eol'};
214 $fields = $csv->getline($self->{'fh'});
215 if (!$fields) {
216 die "Error while reading file " . $self->{'file'} . ": $!" if $!;
217 return undef;
218 }
219 }
220 $self->{row} = (@$fields ? $fields : undef);
221 }
222
223 sub push_row ($$$) {
224 my($self, $data, $fields) = @_;
225 my($csv) = $self->{csv_csv};
226 my($fh) = $self->{'fh'};
227 #
228 # Remove undef from the right end of the fields, so that at least
229 # in these cases undef is returned from FetchRow
230 #
231 while (@$fields && !defined($fields->[$#$fields])) {
232 pop @$fields;
233 }
234 if (!$csv->print($fh, $fields)) {
235 die "Error while writing file " . $self->{'file'} . ": $!";
236 }
237 1;
238 }
239 *push_names = \&push_row;
240
241
242 1;
243
244
245 __END__
246
247 =head1 NAME
248
249 DBD::CSV - DBI driver for CSV files
250
251 =head1 SYNOPSIS
252
253 use DBI;
254 $dbh = DBI->connect("DBI:CSV:f_dir=/home/joe/csvdb")
255 or die "Cannot connect: " . $DBI::errstr;
256 $sth = $dbh->prepare("CREATE TABLE a (id INTEGER, name CHAR(10))")
257 or die "Cannot prepare: " . $dbh->errstr();
258 $sth->execute() or die "Cannot execute: " . $sth->errstr();
259 $sth->finish();
260 $dbh->disconnect();
261
262
263 # Read a CSV file with ";" as the separator, as exported by
264 # MS Excel. Note we need to escape the ";", otherwise it
265 # would be treated as an attribute separator.
266 $dbh = DBI->connect(qq{DBI:CSV:csv_sep_char=\\;});
267 $sth = $dbh->prepare("SELECT * FROM info");
268
269 # Same example, this time reading "info.csv" as a table:
270 $dbh = DBI->connect(qq{DBI:CSV:csv_sep_char=\\;});
271 $dbh->{'csv_tables'}->{'info'} = { 'file' => 'info.csv'};
272 $sth = $dbh->prepare("SELECT * FROM info");
273
274
275 =head1 WARNING
276
277 THIS IS ALPHA SOFTWARE. It is *only* 'Alpha' because the interface (API)
278 is not finalized. The Alpha status does not reflect code quality or
279 stability.
280
281
282 =head1 DESCRIPTION
283
284 The DBD::CSV module is yet another driver for the DBI (Database independent
285 interface for Perl). This one is based on the SQL "engine" SQL::Statement
286 and the abstract DBI driver DBD::File and implements access to
287 so-called CSV files (Comma separated values). Such files are mostly used for
288 exporting MS Access and MS Excel data.
289
290 See L<DBI(3)> for details on DBI, L<SQL::Statement(3)> for details on
291 SQL::Statement and L<DBD::File(3)> for details on the base class
292 DBD::File.
293
294
295 =head2 Prerequisites
296
297 The only system dependent feature that DBD::File uses, is the C<flock()>
298 function. Thus the module should run (in theory) on any system with
299 a working C<flock()>, in particular on all Unix machines and on Windows
300 NT. Under Windows 95 and MacOS the use of C<flock()> is disabled, thus
301 the module should still be usable,
302
303 Unlike other DBI drivers, you don't need an external SQL engine
304 or a running server. All you need are the following Perl modules,
305 available from any CPAN mirror, for example
306
307 ftp://ftp.funet.fi/pub/languages/perl/CPAN/modules/by-module
308
309 =over 4
310
311 =item DBI
312
313 the DBI (Database independent interface for Perl), version 1.00 or
314 a later release
315
316 =item SQL::Statement
317
318 a simple SQL engine
319
320 =item Text::CSV_XS
321
322 this module is used for writing rows to or reading rows from CSV files.
323
324 =back
325
326
327 =head2 Installation
328
329 Installing this module (and the prerequisites from above) is quite simple.
330 You just fetch the archive, extract it with
331
332 gzip -cd DBD-CSV-0.1000.tar.gz | tar xf -
333
334 (this is for Unix users, Windows users would prefer WinZip or something
335 similar) and then enter the following:
336
337 cd DBD-CSV-0.1000
338 perl Makefile.PL
339 make
340 make test
341
342 If any tests fail, let me know. Otherwise go on with
343
344 make install
345
346 Note that you almost definitely need root or administrator permissions.
347 If you don't have them, read the ExtUtils::MakeMaker man page for details
348 on installing in your own directories. L<ExtUtils::MakeMaker>.
349
350 =head2
351
352 The level of SQL support available depends on the version of
353 SQL::Statement installed. Any version will support *basic*
354 CREATE, INSERT, DELETE, UPDATE, and SELECT statements. Only
355 versions of SQL::Statement 1.0 and above support additional
356 features such as table joins, string functions, etc. See the
357 documentation of the latest version of SQL::Statement for details.
358
359 =head2 Creating a database handle
360
361 Creating a database handle usually implies connecting to a database server.
362 Thus this command reads
363
364 use DBI;
365 my $dbh = DBI->connect("DBI:CSV:f_dir=$dir");
366
367 The directory tells the driver where it should create or open tables
368 (a.k.a. files). It defaults to the current directory, thus the following
369 are equivalent:
370
371 $dbh = DBI->connect("DBI:CSV:");
372 $dbh = DBI->connect("DBI:CSV:f_dir=.");
373
374 (I was told, that VMS requires
375
376 $dbh = DBI->connect("DBI:CSV:f_dir=");
377
378 for whatever reasons.)
379
380 You may set other attributes in the DSN string, separated by semicolons.
381
382
383 =head2 Creating and dropping tables
384
385 You can create and drop tables with commands like the following:
386
387 $dbh->do("CREATE TABLE $table (id INTEGER, name CHAR(64))");
388 $dbh->do("DROP TABLE $table");
389
390 Note that currently only the column names will be stored and no other data.
391 Thus all other information including column type (INTEGER or CHAR(x), for
392 example), column attributes (NOT NULL, PRIMARY KEY, ...) will silently be
393 discarded. This may change in a later release.
394
395 A drop just removes the file without any warning.
396
397 See L<DBI(3)> for more details.
398
399 Table names cannot be arbitrary, due to restrictions of the SQL syntax.
400 I recommend that table names are valid SQL identifiers: The first
401 character is alphabetic, followed by an arbitrary number of alphanumeric
402 characters. If you want to use other files, the file names must start
403 with '/', './' or '../' and they must not contain white space.
404
405
406 =head2 Inserting, fetching and modifying data
407
408 The following examples insert some data in a table and fetch it back:
409 First all data in the string:
410
411 $dbh->do("INSERT INTO $table VALUES (1, "
412 . $dbh->quote("foobar") . ")");
413
414 Note the use of the quote method for escaping the word 'foobar'. Any
415 string must be escaped, even if it doesn't contain binary data.
416
417 Next an example using parameters:
418
419 $dbh->do("INSERT INTO $table VALUES (?, ?)", undef,
420 2, "It's a string!");
421
422 Note that you don't need to use the quote method here, this is done
423 automatically for you. This version is particularly well designed for
424 loops. Whenever performance is an issue, I recommend using this method.
425
426 You might wonder about the C<undef>. Don't wonder, just take it as it
427 is. :-) It's an attribute argument that I have never ever used and
428 will be parsed to the prepare method as a second argument.
429
430
431 To retrieve data, you can use the following:
432
433 my($query) = "SELECT * FROM $table WHERE id > 1 ORDER BY id";
434 my($sth) = $dbh->prepare($query);
435 $sth->execute();
436 while (my $row = $sth->fetchrow_hashref) {
437 print("Found result row: id = ", $row->{'id'},
438 ", name = ", $row->{'name'});
439 }
440 $sth->finish();
441
442 Again, column binding works: The same example again.
443
444 my($query) = "SELECT * FROM $table WHERE id > 1 ORDER BY id";
445 my($sth) = $dbh->prepare($query);
446 $sth->execute();
447 my($id, $name);
448 $sth->bind_columns(undef, \$id, \$name);
449 while ($sth->fetch) {
450 print("Found result row: id = $id, name = $name\n");
451 }
452 $sth->finish();
453
454 Of course you can even use input parameters. Here's the same example
455 for the third time:
456
457 my($query) = "SELECT * FROM $table WHERE id = ?";
458 my($sth) = $dbh->prepare($query);
459 $sth->bind_columns(undef, \$id, \$name);
460 for (my($i) = 1; $i <= 2; $i++) {
461 $sth->execute($id);
462 if ($sth->fetch) {
463 print("Found result row: id = $id, name = $name\n");
464 }
465 $sth->finish();
466 }
467
468 See L<DBI(3)> for details on these methods. See L<SQL::Statement(3)> for
469 details on the WHERE clause.
470
471 Data rows are modified with the UPDATE statement:
472
473 $dbh->do("UPDATE $table SET id = 3 WHERE id = 1");
474
475 Likewise you use the DELETE statement for removing rows:
476
477 $dbh->do("DELETE FROM $table WHERE id > 1");
478
479
480 =head2 Error handling
481
482 In the above examples we have never cared about return codes. Of course,
483 this cannot be recommended. Instead we should have written (for example):
484
485 my($query) = "SELECT * FROM $table WHERE id = ?";
486 my($sth) = $dbh->prepare($query)
487 or die "prepare: " . $dbh->errstr();
488 $sth->bind_columns(undef, \$id, \$name)
489 or die "bind_columns: " . $dbh->errstr();
490 for (my($i) = 1; $i <= 2; $i++) {
491 $sth->execute($id)
492 or die "execute: " . $dbh->errstr();
493 if ($sth->fetch) {
494 print("Found result row: id = $id, name = $name\n");
495 }
496 }
497 $sth->finish($id)
498 or die "finish: " . $dbh->errstr();
499
500 Obviously this is tedious. Fortunately we have DBI's I<RaiseError>
501 attribute:
502
503 $dbh->{'RaiseError'} = 1;
504 $@ = '';
505 eval {
506 my($query) = "SELECT * FROM $table WHERE id = ?";
507 my($sth) = $dbh->prepare($query);
508 $sth->bind_columns(undef, \$id, \$name);
509 for (my($i) = 1; $i <= 2; $i++) {
510 $sth->execute($id);
511 if ($sth->fetch) {
512 print("Found result row: id = $id, name = $name\n");
513 }
514 }
515 $sth->finish($id);
516 };
517 if ($@) { die "SQL database error: $@"; }
518
519 This is not only shorter, it even works when using DBI methods within
520 subroutines.
521
522
523 =head2 Metadata
524
525 The following attributes are handled by DBI itself and not by DBD::File,
526 thus they all work as expected:
527
528 Active
529 ActiveKids
530 CachedKids
531 CompatMode (Not used)
532 InactiveDestroy
533 Kids
534 PrintError
535 RaiseError
536 Warn (Not used)
537
538 The following DBI attributes are handled by DBD::File:
539
540 =over 4
541
542 =item AutoCommit
543
544 Always on
545
546 =item ChopBlanks
547
548 Works
549
550 =item NUM_OF_FIELDS
551
552 Valid after C<$sth-E<gt>execute>
553
554 =item NUM_OF_PARAMS
555
556 Valid after C<$sth-E<gt>prepare>
557
558 =item NAME
559
560 Valid after C<$sth-E<gt>execute>; undef for Non-Select statements.
561
562 =item NULLABLE
563
564 Not really working. Always returns an array ref of one's, as DBD::CSV
565 doesn't verify input data. Valid after C<$sth-E<gt>execute>; undef for
566 non-Select statements.
567
568 =back
569
570 These attributes and methods are not supported:
571
572 bind_param_inout
573 CursorName
574 LongReadLen
575 LongTruncOk
576
577 In addition to the DBI attributes, you can use the following dbh
578 attributes:
579
580 =over 8
581
582 =item f_dir
583
584 This attribute is used for setting the directory where CSV files are
585 opened. Usually you set it in the dbh, it defaults to the current
586 directory ("."). However, it is overwritable in the statement handles.
587
588 =item csv_eol
589
590 =item csv_sep_char
591
592 =item csv_quote_char
593
594 =item csv_escape_char
595
596 =item csv_class
597
598 =item csv_csv
599
600 The attributes I<csv_eol>, I<csv_sep_char>, I<csv_quote_char> and
601 I<csv_escape_char> are corresponding to the respective attributes of the
602 Text::CSV_XS object. You want to set these attributes if you have unusual
603 CSV files like F</etc/passwd> or MS Excel generated CSV files with a semicolon
604 as separator. Defaults are "\015\012", ';', '"' and '"', respectively.
605
606 The attributes are used to create an instance of the class I<csv_class>,
607 by default Text::CSV_XS. Alternatively you may pass an instance as
608 I<csv_csv>, the latter takes precedence. Note that the I<binary>
609 attribute I<must> be set to a true value in that case.
610
611 Additionally you may overwrite these attributes on a per-table base in
612 the I<csv_tables> attribute.
613
614 =item csv_tables
615
616 This hash ref is used for storing table dependent metadata. For any
617 table it contains an element with the table name as key and another
618 hash ref with the following attributes:
619
620 =over 12
621
622 =item file
623
624 The tables file name; defaults to
625
626 "$dbh->{f_dir}/$table"
627
628 =item eol
629
630 =item sep_char
631
632 =item quote_char
633
634 =item escape_char
635
636 =item class
637
638 =item csv
639
640 These correspond to the attributes I<csv_eol>, I<csv_sep_char>,
641 I<csv_quote_char>, I<csv_escape_char>, I<csv_class> and I<csv_csv>.
642 The difference is that they work on a per-table base.
643
644 =item col_names
645
646 =item skip_first_row
647
648 By default DBD::CSV assumes that column names are stored in the first
649 row of the CSV file. If this is not the case, you can supply an array
650 ref of table names with the I<col_names> attribute. In that case the
651 attribute I<skip_first_row> will be set to FALSE.
652
653 If you supply an empty array ref, the driver will read the first row
654 for you, count the number of columns and create column names like
655 C<col0>, C<col1>, ...
656
657 =back
658
659 =back
660
661 Example: Suggest you want to use F</etc/passwd> as a CSV file. :-)
662 There simplest way is:
663
664 require DBI;
665 my $dbh = DBI->connect("DBI:CSV:f_dir=/etc;csv_eol=\n;"
666 . "csv_sep_char=:;csv_quote_char=;"
667 . "csv_escape_char=");
668 $dbh->{'csv_tables'}->{'passwd'} = {
669 'col_names' => ["login", "password", "uid", "gid", "realname",
670 "directory", "shell"]
671 };
672 $sth = $dbh->prepare("SELECT * FROM passwd");
673
674 Another possibility where you leave all the defaults as they are and
675 overwrite them on a per table base:
676
677 require DBI;
678 my $dbh = DBI->connect("DBI:CSV:");
679 $dbh->{'csv_tables'}->{'passwd'} = {
680 'eol' => "\n",
681 'sep_char' => ":",
682 'quote_char' => undef,
683 'escape_char' => undef,
684 'file' => '/etc/passwd',
685 'col_names' => ["login", "password", "uid", "gid", "realname",
686 "directory", "shell"]
687 };
688 $sth = $dbh->prepare("SELECT * FROM passwd");
689
690
691 =head2 Driver private methods
692
693 These methods are inherited from DBD::File:
694
695 =over 4
696
697 =item data_sources
698
699 The C<data_sources> method returns a list of subdirectories of the current
700 directory in the form "DBI:CSV:directory=$dirname".
701
702 If you want to read the subdirectories of another directory, use
703
704 my($drh) = DBI->install_driver("CSV");
705 my(@list) = $drh->data_sources('f_dir' => '/usr/local/csv_data' );
706
707 =item list_tables
708
709 This method returns a list of file names inside $dbh->{'directory'}.
710 Example:
711
712 my($dbh) = DBI->connect("DBI:CSV:directory=/usr/local/csv_data");
713 my(@list) = $dbh->func('list_tables');
714
715 Note that the list includes all files contained in the directory, even
716 those that have non-valid table names, from the view of SQL. See
717 L<Creating and dropping tables> above.
718
719 =back
720
721
722 =head2 Data restrictions
723
724 When inserting and fetching data, you will sometimes be surprised: DBD::CSV
725 doesn't correctly handle data types, in particular NULLs. If you insert
726 integers, it might happen, that fetch returns a string. Of course, a string
727 containing the integer, so that's perhaps not a real problem. But the
728 following will never work:
729
730 $dbh->do("INSERT INTO $table (id, name) VALUES (?, ?)",
731 undef, "foo bar");
732 $sth = $dbh->prepare("SELECT * FROM $table WHERE id IS NULL");
733 $sth->execute();
734 my($id, $name);
735 $sth->bind_columns(undef, \$id, \$name);
736 while ($sth->fetch) {
737 printf("Found result row: id = %s, name = %s\n",
738 defined($id) ? $id : "NULL",
739 defined($name) ? $name : "NULL");
740 }
741 $sth->finish();
742
743 The row we have just inserted, will never be returned! The reason is
744 obvious, if you examine the CSV file: The corresponding row looks
745 like
746
747 "","foo bar"
748
749 In other words, not a NULL is stored, but an empty string. CSV files
750 don't have a concept of NULL values. Surprisingly the above example
751 works, if you insert a NULL value for the name! Again, you find
752 the explanation by examining the CSV file:
753
754 ""
755
756 In other words, DBD::CSV has "emulated" a NULL value by writing a row
757 with less columns. Of course this works only if the rightmost column
758 is NULL, the two rightmost columns are NULL, ..., but the leftmost
759 column will never be NULL!
760
761 See L<Creating and dropping tables> above for table name restrictions.
762
763
764 =head1 TODO
765
766 Extensions of DBD::CSV:
767
768 =over 4
769
770 =item CSV file scanner
771
772 Write a simple CSV file scanner that reads a CSV file and attempts
773 to guess sep_char, quote_char, escape_char and eol automatically.
774
775 =back
776
777 These are merely restrictions of the DBD::File or SQL::Statement
778 modules:
779
780 =over 4
781
782 =item Table name mapping
783
784 Currently it is not possible to use files with names like C<names.csv>.
785 Instead you have to use soft links or rename files. As an alternative
786 one might use, for example a dbh attribute 'table_map'. It might be a
787 hash ref, the keys being the table names and the values being the file
788 names.
789
790 =item Column name mapping
791
792 Currently the module assumes that column names are stored in the first
793 row. While this is fine in most cases, there should be a possibility
794 of setting column names and column number from the programmer: For
795 example MS Access doesn't export column names by default.
796
797 =back
798
799
800 =head1 KNOWN BUGS
801
802 =over 8
803
804 =item *
805
806 The module is using flock() internally. However, this function is not
807 available on platforms. Using flock() is disabled on MacOS and Windows
808 95: There's no locking at all (perhaps not so important on these
809 operating systems, as they are for single users anyways).
810
811 =back
812
813
814 =head1 AUTHOR AND COPYRIGHT
815
816 This module is currently maintained by
817
818 Jeff Zucker
819 <jeff@vpservices.com>
820
821 The original author is Jochen Wiedmann.
822
823 Copyright (C) 1998 by Jochen Wiedmann
824
825 All rights reserved.
826
827 You may distribute this module under the terms of either the GNU
828 General Public License or the Artistic License, as specified in
829 the Perl README file.
830
831 =head1 SEE ALSO
832
833 L<DBI(3)>, L<Text::CSV_XS(3)>, L<SQL::Statement(3)>
834
835 For help on the use of DBD::CSV, see the DBI users mailing list:
836
837 http://www.isc.org/dbi-lists.html
838
839 For general information on DBI see
840
841 http://www.symbolstone.org/technology/perl/DBI
842
843 =cut

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed