.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.07) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "DBD::AnyData 3pm" .TH DBD::AnyData 3pm "2010-07-29" "perl v5.10.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" DBD::AnyData \- DBI access to XML, CSV and other formats .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 9 \& use DBI; \& my $dbh = DBI\->connect(\*(Aqdbi:AnyData(RaiseError=>1):\*(Aq); \& $dbh\->func( \*(Aqtrains\*(Aq, \*(AqCSV\*(Aq, \*(Aq/users/joe/cars.csv\*(Aq, \*(Aqad_catalog\*(Aq); \& $dbh\->func( \*(Aqbikes\*(Aq, \*(AqXML\*(Aq, [$xml_str], \*(Aqad_import\*(Aq); \& $dbh\->func( \*(Aqcars\*(Aq, \*(AqDBI\*(Aq, $mysql_dbh, \*(Aqad_import\*(Aq); \& # \& # ... DBI/SQL methods to access/modify the tables \*(Aqcars\*(Aq,\*(Aqbikes\*(Aq,\*(Aqtrains\*(Aq \& # \& print $dbh\->func( \*(Aqcars\*(Aq, \*(AqHTMLtable\*(Aq, \*(Aqad_export\*(Aq); \& \& or \& \& use DBI; \& my $dbh = DBI\->connect(\*(Aqdbi:AnyData(RaiseError=>1):\*(Aq); \& $dbh\->func( \*(AqPipe\*(Aq, \*(Aqdata.pipe\*(Aq, \*(AqXML\*(Aq, \*(Aqdata.xml\*(Aq, \*(Aqad_convert\*(Aq); \& \& or \& \& (many combinations of a dozen other data formats, see below) .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" The DBD::AnyData module provides a \s-1DBI/SQL\s0 interface to data in many formats and from many sources. .PP Currently supported formats include general format flatfiles (\s-1CSV\s0, Fixed Length, Tab or Pipe \*(L"delimited\*(R", etc.), specific formats (passwd files, web logs, etc.), a variety of other kinds of formats (\s-1XML\s0, Mp3, \s-1HTML\s0 tables), and, for some operations, any \s-1DBI\s0 accessible database. The number of supported formats will continue to grow rapidly since there is an open \s-1API\s0 making it easy for any author to create additional format parsers which can be plugged in to AnyData. .PP Data in these various formats can come from local files, from remote files, or from perl data structures such as strings and arrays. .PP Regardless of the format or source of the data, it may be accessed and/or modified using all standard \s-1DBI\s0 methods and a subset of \s-1SQL\s0 syntax. .PP In addition to standard database access to files, the module also supports in-memory tables which allow you to create temporary views; to combine data from a number of sources; to quickly prototype database systems; and to display or save the data in any of the supported formats (e.g. to display data in a \s-1CSV\s0 file as an \s-1HTML\s0 table). These in-memory tables can be created from any combination of \s-1DBI\s0 databases or files of any format. They may also be created from perl data structures which means it's possible to quickly prototype a database system without any file access or rdbms backend. .PP The module also supports converting files between any of the supported formats (e.g. save selected data from MySQL or Oracle to an \s-1XML\s0 file). .PP Here a just a few examples of the capabilities: .PP .Vb 4 \& # SELECT DATA FROM A PASSWD FILE \& # \& $dbh\->func( \*(Aqusers\*(Aq, \*(AqPasswd\*(Aq, \*(Aq/etc/passwd\*(Aq, \*(Aqad_catalog\*(Aq); \& my $sth = $dbh\->prepare("SELECT username,homedir,GID FROM users\*(Aq); \& \& # INSERT A NEW ROW INTO A CSV FILE \& # \& $dbh\->func( \*(Aqcars\*(Aq, \*(AqCSV\*(Aq, \*(Aqcars.csv\*(Aq, \*(Aqad_catalog\*(Aq); \& $dbh\->do("INSERT INTO cars VALUES (\*(AqHonda\*(Aq,\*(AqOdyssey\*(Aq)"); \& \& # READ A REMOTE XML FILE AND PRINT IT AS AN HTML TABLE \& # \& print $dbh\->func( \*(AqXML\*(Aq, $url, \*(AqHTMLtable\*(Aq, \*(Aqad_convert\*(Aq); \& \& # CONVERT A MYSQL DATABASE INTO XML AND SAVE IT IN A NEW FILE \& # \& $dbh\->func( \*(AqDBI\*(Aq, $mysql_dbh, \*(AqXML\*(Aq, \*(Aqdata.xml\*(Aq, \*(Aqad_convert\*(Aq); \& \& # CREATE AND ACCESS A VIEW CONTAINING DATA FROM AN ORACLE DATABASE \& # AND A TAB DELIMITED FILE \& # \& $dbh\->func( \*(Aqcombo\*(Aq, \*(AqDBI\*(Aq, $oracle_dbh, \*(Aqad_import\*(Aq); \& $dbh\->func( \*(Aqcombo\*(Aq, \*(AqTab\*(Aq, \*(Aqdata.tab\*(Aq, \*(Aqad_import\*(Aq); \& my $sth = $dbh\->prepare("SELECT * FROM combo"); .Ve .SH "INSTALLATION" .IX Header "INSTALLATION" To use DBD::AnyData you will need to install these modules, all available from \s-1CPAN\s0 and most available from activeState. .PP .Vb 5 \& * DBI \& * DBI::DBD::SqlEngine \& * SQL::Statement \& * AnyData \& * DBD::AnyData .Ve .PP Note: DBI::DBD::SqlEngine is part of the \s-1DBI\s0 distribution .PP Some advanced features require additional modules: .IP "remote file access" 4 .IX Item "remote file access" requires \s-1LWP\s0 (the libwww bundle) .IP "\s-1XML\s0 access" 4 .IX Item "XML access" requires XML::Parser and XML::Twig .IP "\s-1HTML\s0 table" 4 .IX Item "HTML table" access requires HTML::Parser and HTML::TableExtract .IP "\s-1HTML\s0 table writing" 4 .IX Item "HTML table writing" requires \s-1CGI\s0 .PP AnyData and DBD::AnyData themselves can either be installed via cpan, cpanplus or cpanminus, using the distributed Build.PL manually with .PP .Vb 4 \& perl Build.PL \& ./Build \& ./Build test \& ./Build install .Ve .PP or by copying the AnyData.pm file manually to it's right place within your perl library path. .SH "QUICK START" .IX Header "QUICK START" .SS "The Basics" .IX Subsection "The Basics" .IP "There are four main steps in using DBD::AnyData in a script:" 1 .IX Item "There are four main steps in using DBD::AnyData in a script:" .Vb 4 \& 1. Specify that you want to use the DBI module \& 2. Create a database handle \& 3. Specify the tables, files, and formats you want \& 4. Use DBI/SQL commands to access and/or modify the data .Ve .Sp Steps #1, #2, and #3 can be as little as a single line of code each. .Sp Steps #3 and #4 can be omitted in some situations, see the sections below on \*(L"Working with In-Memory Data\*(R" and \*(L"Converting Data\*(R" .IP "Step #1 : Specify that you want to use the \s-1DBI\s0 module" 1 .IX Item "Step #1 : Specify that you want to use the DBI module" This step is always the same: just put this at the top of your script: .Sp .Vb 1 \& use DBI; .Ve .IP "Step #2 Create a Database Handle" 1 .IX Item "Step #2 Create a Database Handle" This step can vary slightly depending on your needs but is usually this: .Sp .Vb 1 \& my $dbh = DBI\->connect(\*(Aqdbi:AnyData(RaiseError=>1):\*(Aq); .Ve .Sp See the section below on \*(L"Connection Options\*(R" for other forms of connecting. See the section below on \*(L"Using Multiple Databases\*(R" for cases in which you may be creating more than one database handle. .IP "Step #3 : Specify the tables, files, and formats" 1 .IX Item "Step #3 : Specify the tables, files, and formats" This step makes use of one of several methods unique to DBD::AnyData. These methods use the database handle created in step #2 to make a \&\fIfunc()\fR call and specify the name of the method as the last parameter. For example the 'ad_catalog' method would be called like this: .Sp .Vb 1 \& $dbh\->func( ..., \*(Aqad_catalog\*(Aq) .Ve .Sp The \fIad_catalog()\fR method takes three required parameters and one optional parameter: .Sp .Vb 5 \& # $table = the name you will use to refer to the table in SQL commands \& # $format = the format of the data (\*(AqXML\*(Aq, \*(AqCSV\*(Aq, \*(AqFixed\*(Aq, etc.) \& # $file = the name of a local or remote file holding the data \& # $flags = an optional hash of flags required by some data formats \& $dbh\->func( $table, $format, $file, $flags, \*(Aqad_catalog\*(Aq) \& \& # For example: \& $dbh\->func( \*(Aqcars\*(Aq, \*(AqXML\*(Aq, \*(Aqcars.xml\*(Aq, \*(Aqad_catalog\*(Aq ) .Ve .Sp This specifies that the table name 'cars' will be used to access \s-1XML\s0 data stored in the file 'cars.xml'. .Sp Once you have issued a catalog command, you can use the name \f(CW$table\fR in \s-1SQL\s0 commands to access or modify the data in \f(CW$file\fR. The catalog only needs to be specified once for a table/file/format combination and can then be used for an unlimited number of processing commands. .IP "Step #4 : Use \s-1DBI/SQL\s0 commands to access and/or modify data" 1 .IX Item "Step #4 : Use DBI/SQL commands to access and/or modify data" DBD::AnyData supports all standard \s-1DBI\s0 methods and a subset of \s-1SQL\s0 syntax. See the section below \*(L"\s-1SQL\s0 Syntax\*(R" for a description of the supported \s-1SQL\s0 commands. See the \s-1DBI\s0 documentation for detailed description of \s-1DBI\s0 commands. .Sp The \fIdo()\fR method can be used to create or drop a table and insert, delete, or update rows: .Sp .Vb 5 \& $dbh\->do("CREATE TABLE ... ) \& $dbh\->do("DROP TABLE ... ) \& $dbh\->do("INSERT INTO ... ) \& $dbh\->do("UPDATE ... ) \& $dbh\->do("DELETE ... ) .Ve .Sp A combination of the \fIprepare()\fR, \fIexecute()\fR, and \fIfetch()\fR methods can be used to access data: .Sp .Vb 5 \& my $sth = $dbh\->prepare("SELECT * FROM cars WHERE make = \*(AqHonda\*(Aq"); \& $sth\->execute(); \& while (my $row = $sth\->fetchrow_hashref){ \& print $row\->{model}; \& } .Ve .IP "Putting it all together" 1 .IX Item "Putting it all together" This is the complete script needed to access data stored in \&\s-1CSV\s0 format in a file called \*(L"cars.csv\*(R". It prints all data from the \*(L"make\*(R" and \*(L"model\*(R" columns of the database. .Sp .Vb 12 \& # specifies that you will use the DBI module. \& use DBI; \& # creates a database handle \& my $dbh = DBI\->connect(\*(Aqdbi:AnyData(RaiseError=>1):\*(Aq); \& # specifies the table, format, and file holding the data \& $dbh\->func( \*(Aqcars\*(Aq, \*(AqCSV\*(Aq, \*(Aqcars.csv\*(Aq \*(Aqad_catalog\*(Aq); \& # through 8 use DBI and SQL to access data in the file \& my $sth = $dbh\->prepare("SELECT make, model FROM cars"); \& $sth\->execute(); \& while (my $row = $sth\->fetch) { \& print "@$row\en"; \& } .Ve .SS "Customizing table structure" .IX Subsection "Customizing table structure" DBD::AnyData uses a number of defaults when it decides how to read data from a database and in many cases these defaults are all you will need. However, depending on the format and database you are using, you may need to specify other features such as column names, record separators, etc. .PP You can specify this additional information in the \f(CW$flags\fR parameter of the ad_catalog and other DBD::AnyData methods. \f(CW$flags\fR is always a reference to a hash, i.e. one or more key value pairs joined with a =>, separated by commas, and delimited by curly braces: .PP .Vb 1 \& $flags = { key1 => value1, key2 => value2 ... } \& \& # or in the method call: \& $dbh\->func( $table, $format, $file, { key1=>,val1 ... }, \*(Aqad_catalog\*(Aq); .Ve .IP "Column Names" 2 .IX Item "Column Names" Some formats have pre-defined column names: .Sp .Vb 7 \& Passwd username \& passwd \& UID \& GID \& fullname \& homedir \& shell \& \& Weblog remotehost \& usernname \& authuser \& date \& request \& status \& bytes \& referer \& client \& \& Mp3 song \& artist \& album \& year \& genre \& filename \& filesize .Ve .Sp Column names for the other formats can either be specified in the database itself or supplied by you in the \f(CW$flags\fR parameter. .Sp If the column names are specified in the database, they are taken from the first record in the database. For example in a \s-1CSV\s0 (Comma Separated Values) file or a Fixed Length file, the default is to treat the first line of the table as the list of column names. In an HTMLtable file, the default is to look for the first in the first table. In an \s-1XML\s0 file, the default is to use the names of all attributes and all \s-1CDATA\s0 and \s-1PCDATA\s0 elements contained within the first non-initial tag. .Sp In most cases, this first record that defines the column names is in the same format as the rest of the table e.g. a \s-1CSV\s0 string in a \s-1CSV\s0 file, a tab delimited string in a Tab delimited file, etc. The one exception to this is that in a Fixed Length file the first row of the file can contain a *comma\-separated* list of column names, not a fixed length list. HTMLtable and \s-1XML\s0 also use other flags to select the column names (e.g. the number of the table or the depth in the tree to examine). Please see the documentation for these formats for further details of how defaults are selected. .Sp For most formats, if the column names are not contained in the first record in the file, then you can specify them as a comma separated list in the \f(CW$flags\fR parameter, for example: .Sp .Vb 6 \& $dbh\->func( \& \*(Aqcars\*(Aq, \& \*(AqTab\*(Aq, \& \*(Aqdata.tab\*(Aq, \& { col_names => \*(Aqmake,model,year\*(Aq }, \& \*(Aqad_catalog\*(Aq) .Ve .SH "SUPPORTED FORMATS" .IX Header "SUPPORTED FORMATS" .SS "\s-1CSV\s0, Tab, Pipe, Ini, Paragraph" .IX Subsection "CSV, Tab, Pipe, Ini, Paragraph" .SS "Fixed" .IX Subsection "Fixed" Fixed Length format files (where each column is a specified length) are unique in several respects. First, as mentioned above, if you wish to include the column names in the file itself, they should be on the first line of the file as a *comma separated* string. .PP Secondly, there is a mandatory flag called 'pattern' that you must use whenever you use the Fixed length format. This flag specifies the widths of the columns. It uses the standard Perl pack/unpack syntax to specify the pattern. See the Perl documentation for those commands for further details. In most cases simply using a capital 'A' followed by the length of the field suffices: .PP .Vb 1 \& { pattern => \*(AqA10 A12 A4\*(Aq } .Ve .PP This specifies that the table contains three fields with widths of 10, 12, and 14 characters. .SS "\s-1XML\s0" .IX Subsection "XML" .SS "HTMLtable" .IX Subsection "HTMLtable" .SS "\s-1DBI\s0" .IX Subsection "DBI" DBD::AnyData supports importing any \s-1DBI\s0 database into memory and can also convert any \s-1DBI\s0 database into any of the other AnyData formats. .PP Use the format name '\s-1DBI\s0', and instead of a filename, pass the ad_import call a connection in whatever database you are using, and specify a \s-1SQL\s0 \s-1SELECT\s0 statement: .PP .Vb 7 \& my $dbh = DBI\->connect(\*(Aqdbi:AnyData:(RaiseError=>1)\*(Aq); \& $dbh\->func( \& \*(Aqtable1\*(Aq, \& \*(AqDBI\*(Aq, \& DBI\->connect(\*(Aqdbi:mysql:database=test:(RaiseError=>1)\*(Aq), \& {sql=>"SELECT make, model FROM cars WHERE make = \*(Aqhonda\*(Aq"}, \& \*(Aqad_import\*(Aq); .Ve .PP That snippet imports a view from a MySQL database (selecting only the named columns and the selected rows) into an AnyData in-memory table. It can then be queried and/or modified in memory and then either displayed or stored to a file in some other format such as \s-1XML\s0. .PP You may also use a bind_parameters form for the \s-1SQL\s0 call by passing an additional flag with an arrayref of the parameters: .PP .Vb 4 \& { \& sql => "SELECT make,model FROM CARS WHERE make = ?" \& params => [\*(Aqhonda\*(Aq] \& } .Ve .PP To convert from a \s-1DBI\s0 accessible database such as \s-1ORACLE\s0 or MySQL to one of the AnyData formats such as \s-1XML\s0 you must also include a flag with the table_name within the database: .PP .Vb 8 \& my $dbh = DBI\->connect(\*(Aqdbi:AnyData:(RaiseError=>1)\*(Aq); \& $dbh\->func( \& \*(AqDBI\*(Aq, \& DBI\->connect(\*(Aqdbi:mysql:database=test:(RaiseError=>1)\*(Aq), \& \*(AqXML\*(Aq, \& \*(Aqcars.xml\*(Aq, \& {table_name=>\*(Aqcars\*(Aq}, \& \*(Aqad_convert\*(Aq); .Ve .PP Or to print out the same data as an \s-1HTML\s0 table without storing it: .PP .Vb 8 \& my $dbh = DBI\->connect(\*(Aqdbi:AnyData:(RaiseError=>1)\*(Aq); \& print $dbh\->func( \& \*(AqDBI\*(Aq, \& DBI\->connect(\*(Aqdbi:mysql:database=test:(RaiseError=>1)\*(Aq), \& \*(AqHTMLtable\*(Aq, \& undef, \& {table_name=>\*(Aqcars\*(Aq}, \& \*(Aqad_convert\*(Aq); .Ve .PP The \fIad_convert()\fR method works on the entire database. If you need to convert only a selected portion of the databse, use \fIad_import()\fR with a \s-1SELECT\s0 clause and then \fIad_export()\fR it to the new format. .PP The ad_import method by default closes the connection for the imported database. If you need to continue using the handle for the other datbase, pass the flag {keep_connection=>1}: .PP .Vb 10 \& my $dbh = DBI\->connect(\*(Aqdbi:AnyData:(RaiseError=>1)\*(Aq); \& my $mysql_dbh = DBI\->connect(\*(Aqdbi:mysql:database=test:(RaiseError=>1)\*(Aq), \& $dbh\->func( \& \*(Aqcars\*(Aq, \& \*(AqDBI\*(Aq, \& $mysql_dbh, \& { keep_connection=>1 }, \& \*(Aqad_import\*(Aq); \& #... \& $mysql_dbh\->disconnect; .Ve .SS "Passwd, Weblog, Mp3" .IX Subsection "Passwd, Weblog, Mp3" .SS "Other Formats" .IX Subsection "Other Formats" DBD::AnyData supports an open \s-1API\s0 that allows other authors to build support for other formats. This means that the list of supported formats will continually grow. At the moment Wes Hardaker is working on AnyData::Format::SNMP and Earl Cahill is working on AnyData::Format::Storable. Anyone who is interested in working on a new format module, please open a ticket with an appropriate patch or write to dbi\-dev@perl.org. .SH "FURTHER DETAILS" .IX Header "FURTHER DETAILS" .SS "Converting between formats" .IX Subsection "Converting between formats" The \f(CW$dbh\fR\->func(...,'ad_convert') method provides a one-step way to convert between any of the data formats supported by DBD::AnyData. For example: read a \s-1CSV\s0 file and save it as an \s-1XML\s0 file or vice versa. See the section below on \*(L"convert\*(R" for details. See the section on \&\*(L"Working with other \s-1DBI\s0 databases\*(R" for information on converting data from \s-1ORACLE\s0, or MySQL or almost any other database into \s-1XML\s0, \s-1CSV\s0, or any of the DBD::AnyData formats. .SS "Using remote files" .IX Subsection "Using remote files" You can import remote files accessible by \s-1FTP\s0 or \s-1HTTP\s0 directly into a DBD::AnyData in memory database using 'ad_import' or you can use ad_convert to print the remote files as strings or save them to a local file. If the \f(CW$file\fR parameter of ad_import or ad_convert starts with \*(L"ftp\*(R" or \&\*(L"http\*(R", DBD::AnyData will call \s-1LWP\s0 behind the scenes and fetch the file. .PP This will fetch the remote file, parse its \s-1XML\s0, and provide you with an in-memory table which you can query with \s-1DBI/SQL\s0 or save to a local file: .PP .Vb 5 \& $dbh\->func( \& \*(Aqnews\*(Aq, \& \*(AqXML\*(Aq, \& \*(Aqhttp://www.somewhere.org/files/news.xml\*(Aq, \& \*(Aqad_import\*(Aq); .Ve .PP This will fetch the remote file, parse its \s-1XML\s0, and print it out as an \s-1HTML\s0 table: .PP .Vb 5 \& print $dbh\->func( \& \*(AqXML\*(Aq, \& \*(Aqhttp://www.somewhere.org/files/news.xml\*(Aq, \& \*(AqHTMLtable\*(Aq, \& \*(Aqad_convert\*(Aq); .Ve .PP If the remote file requires authorization, you can include values for \&\*(L"user\*(R" and \*(L"pass\*(R" in the \f(CW$flags\fR parameter: .PP .Vb 6 \& $dbh\->func( \& \*(Aqnews\*(Aq, \& \*(AqXML\*(Aq, \& \*(Aqhttp://www.somewhere.org/news.xml\*(Aq, \& { user => \*(Aqfred\*(Aq, passwd => \*(Aqx9y77d\*(Aq }, \& \*(Aqad_import\*(Aq); .Ve .SS "Working with in-memory tables" .IX Subsection "Working with in-memory tables" In addition to normal file storage databases, DBD::AnyData supports databases that are stored and modified in-memory. You may either simply query the databases and then close them, or you can use the ad_export method to display data to the screen or save it to a file. There are a variety of reasons you might want to work with in-memory databases, including: .IP "Prototyping" 4 .IX Item "Prototyping" quickly create a database from a string, an array, or the \s-1DATA\s0 section of a script without needing any file access or rdbms. .IP "Creating Views" 4 .IX Item "Creating Views" pull selected columns and selected rows from an \s-1ORACLE\s0 or MySQL database en masse and work with them in memory rather than having to use the full database. .IP "Combining Data from multiple formats" 4 .IX Item "Combining Data from multiple formats" create a single in-memory table by importing selected columns and rows from e.g. an \s-1XML\s0 file, an Oracle database, and a \s-1CSV\s0 file. .IP "Rollback/Commit" 4 .IX Item "Rollback/Commit" You can make multiple changes to the in-memory database and then, depending on the sucess or failure of those changes either commit by using export to save the changes to disk or skip export which effectively rolls back the database to its state before the import. .PP In-memory tables may be modified with \s-1DBI/SQL\s0 commands and can then be either printed to the screen or saved as a file in any of the AnyData formats. (see the ad_export method below) .PP In-memory tables may be created in several ways: .PP .Vb 4 \& 1. Create and populate the table from one or more local or remote files \& 2. Create and populate the table from a string \& 3. Create and populate the table from an array \& 4. Use DBI/SQL commands to create & populate the table .Ve .IP "Creating in-memory tables from local or remote files" 4 .IX Item "Creating in-memory tables from local or remote files" You can create an in-memory table from a string in a specified format, Note: the string should be enclosed in square brackets. .Sp This reads a \s-1CSV\s0 file into an in-memory table. Further access and modification takes place in-memory without further file access unless you specifically use ad_export to save the table to a file. .Sp .Vb 2 \& # CREATE A TABLE FROM A LOCAL FILE \& $dbh\->func( \*(Aqtest2\*(Aq, \*(AqCSV\*(Aq, $filename, \*(Aqad_import\*(Aq); \& \& # CREATE A TABLE FROM A REMOTE FILE \& $dbh\->func( \*(Aqtest2\*(Aq, \*(AqCSV\*(Aq, $url, \*(Aqad_import\*(Aq); .Ve .Sp See the section on \*(L"Remote File Access\*(R" for further details of using remote Files. .IP "Creating an in-memory table from Strings" 4 .IX Item "Creating an in-memory table from Strings" You can create an in-memory table from a string in a specified format, Note: the string should be enclosed in square brackets. .Sp This example creates an in-memory table from a \s-1CSV\s0 string: .Sp .Vb 4 \& # CREATE A TABLE FROM A CSV STRING \& $dbh\->func( \*(Aqtest2\*(Aq, \*(AqCSV\*(Aq, \& ["id,phrase\en1,foo\en2,bar"], \& \*(Aqad_import\*(Aq); .Ve .IP "Creating an in-memory table from the \s-1DATA\s0 section of a script" 4 .IX Item "Creating an in-memory table from the DATA section of a script" Perl has the really cool feature that if you put text after the marker _\|_END_\|_, you can access that text as if it were from a file using the \s-1DATA\s0 array. This can be great for quick prototyping. .Sp For example this is a complete script to build and access a small table and print out \*(L"Just Another Perl Hacker\*(R": .Sp .Vb 11 \& use DBI; \& my $dbh=DBI\->connect(\*(Aqdbi:AnyData(RaiseError=>1):\*(Aq); \& $dbh\->func( \*(Aqtest\*(Aq, \*(AqXML\*(Aq, [], \*(Aqad_import\*(Aq); \& print $dbh\->selectcol_arrayref(qq{ \& SELECT phrase FROM test WHERE id = 2 \& })\->[0]; \& _\|_END_\|_ \& \& Hello World! \& Just Another Perl Hacker! \& .Ve .Sp The same idea can be used with \s-1DATA\s0 sections of any size in any of the supported formats. .IP "Creating an in-memory table from Arrays" 4 .IX Item "Creating an in-memory table from Arrays" In-memory tables may also be created from arrays. Or, more technically, from references to arrays. The array should consist of rows which are themselves references to arrays of the row values. The first row should be column names. .Sp For example: .Sp .Vb 8 \& # CREATE A TABLE FROM AN ARRAY \& $dbh\->func( \*(Aqtest3\*(Aq, \*(AqARRAY\*(Aq, \& [ \& [\*(Aqid\*(Aq,\*(Aqphrase\*(Aq], \& [1,\*(Aqfoo\*(Aq], \& [2,\*(Aqbar\*(Aq] \& ], \& \*(Aqad_import\*(Aq); .Ve .IP "Creating an in-memory table from \s-1DBI/SQL\s0 commands" 4 .IX Item "Creating an in-memory table from DBI/SQL commands" If you do not use ad_catalog or ad_import to associate a table name with a file, then the table will be an in-memory table, so you can just start right out by using it in \s-1DBI/SQL\s0 commands: .Sp .Vb 8 \& # CREATE & POPULATE A TABLE FROM DBI/SQL COMMANDS \& use DBI; \& my $dbh = DBI\->connect(\*(Aqdbi:AnyData(RaiseError=>1):\*(Aq); \& $dbh\->do("CREATE TABLE test (id TEXT,phrase TEXT)"); \& $dbh\->do("INSERT INTO test VALUES (1,\*(Aqfoo\*(Aq)"); \& $dbh\->do("INSERT INTO test VALUES (2,\*(Aqbar\*(Aq)"); \& $dbh\->do("UPDATE test SET phrase=\*(Aqbaz\*(Aq WHERE id = \*(Aq2\*(Aq"); \& $dbh\->do("DELETE FROM test WHERE id = \*(Aq1\*(Aq"); .Ve .SS "Using Multiple Databases, Simulating Joins" .IX Subsection "Using Multiple Databases, Simulating Joins" You may access any number of databases within a single script and can mix and match from the various data formats. .PP For example, this creates two in-memory tables from two different data formats .PP .Vb 2 \& $dbh\->func( \*(Aqclasses\*(Aq, \*(AqCSV\*(Aq, \*(Aqclasses.csv\*(Aq \*(Aqad_import\*(Aq); \& $dbh\->func( \*(Aqprofs\*(Aq, \*(AqXML\*(Aq, \*(Aqprofs.xml\*(Aq, \*(Aqad_import\*(Aq); .Ve .PP You can also import columns from several different formats into a single table. For example this imports data from an \s-1XML\s0 file, a \s-1CSV\s0 file and a Pipe delimited file into a single in-memory database. Note that the \&\f(CW$table\fR parameter is the same in each call so the data from each import will be appended into that one table. .PP .Vb 3 \& $dbh\->func( \*(Aqtest\*(Aq, \*(AqXML\*(Aq, [$xmlStr], \*(Aqad_import\*(Aq); \& $dbh\->func( \*(Aqtest\*(Aq, \*(AqCSV\*(Aq, [$csvStr], \*(Aqad_import\*(Aq); \& $dbh\->func( \*(Aqtest\*(Aq, \*(AqPipe\*(Aq, [$pipeStr], \*(Aqad_import\*(Aq); .Ve .PP When you import more than one table into a single table like this, the resulting table will be a cross join unless you supply a lookup_key flag. If a lookup_key is supplied, then a the resulting table will be a full outer join on that key column. This feature is experimental for the time being but should work as expected unless there are columns other than the key column with the same names in the various tables. You can specify that the joined table will only contain certain columns by creating a blank empty table before doing the imports. You can specify only certain rows with the sql flag. For example: .PP .Vb 3 \& $dbh\->func(\*(Aqtest\*(Aq,\*(AqARRAY\*(Aq,[],{col_names=>\*(Aqfoo,bar\*(Aqbaz\*(Aq}, \*(Aqad_import\*(Aq); \& $dbh\->func(\*(Aqtest\*(Aq,\*(AqXML\*(Aq,$file1,{lookup_key=>\*(Aqbaz\*(Aq},\*(Aqad_import\*(Aq); \& $dbh\->func(\*(Aqtest\*(Aq,\*(AqCSV\*(Aq,$file1,{lookup_key=>\*(Aqbaz\*(Aq},\*(Aqad_import\*(Aq); .Ve .PP DBD::AnyData does not currently support using multiple tables in a single \s-1SQL\s0 statement. However it does support using multiple tables and querying them separately with different \s-1SQL\s0 statements. This means you can simulate joins by creating two statement handles and using the values from the first handle as a lookup key for the second handle. Like this: .PP .Vb 11 \& $dbh\->func( \*(Aqclasses\*(Aq, \*(AqCSV\*(Aq, \*(Aqclasses.csv\*(Aq \*(Aqad_import\*(Aq); \& $dbh\->func( \*(Aqprofs\*(Aq, \*(AqXML\*(Aq, \*(Aqprofs.xml\*(Aq, \*(Aqad_import\*(Aq); \& my $classes_sth = $dbh\->prepare( "SELECT pid,title FROM classes" ); \& my $profs_sth = $dbh\->prepare( "SELECT name FROM profs WHERE pid = ?" ); \& $classes_sth\->execute; \& while (my($pid,$class_title) = $classes_sth\->fetchrow_array) { \& $profs_sth\->execute($pid); \& my $row = $profs_sth\->fetchrow_arrayref; \& my $prof_name = $row ? $row\->[0] : \*(Aq\*(Aq; \& print "$class_title : $prof_name\en"; \& } \& \& # That will produce the same results as: \& SELECT classes.title,profs.name FROM classes,profs WHERE pid = pid .Ve .SH "REFERENCE" .IX Header "REFERENCE" .SS "Overview of DBD::AnyData Methods" .IX Subsection "Overview of DBD::AnyData Methods" DBD::AnyData makes use of five methods not found in other drivers: .IP "ad_catalog" 12 .IX Item "ad_catalog" specifies a file to be used for \s-1DBI/SQL\s0 continuous file access .IP "ad_import" 12 .IX Item "ad_import" imports data into an in-memory table .IP "ad_export" 12 .IX Item "ad_export" exports data from an in-memory table to a file .IP "ad_clear" 12 .IX Item "ad_clear" clears an in-memory table (deletes it from memory) .IP "ad_convert" 12 .IX Item "ad_convert" converts data from one format to another and either saves it in a new file or returns it as a string .PP These methods are called using \s-1DBI\s0 \fIfunc()\fR, for example: .PP .Vb 1 \& $dbh\->func( $table, $format, \*(Aqad_export\*(Aq); \& \& # Here are the parameters for the various methods: \& $dbh\->func( $table, $format, $file, $flags, \*(Aqad_catalog\*(Aq); \& $dbh\->func( $table, $format, $data, $flags, \*(Aqad_import\*(Aq); \& \& $dbh\->func( $source_format, $source_data, \& $target_format, $target_file, \& $source_flags, $target_flags, \& \*(Aqad_convert\*(Aq); \& \& $dbh\->func( $table, $format, $file, $flags, \*(Aqad_export\*(Aq); \& $dbh\->func( $table, \*(Aqad_clear\*(Aq ); \& \& # $table is a valid SQL table name \& # $format is one of the AnyData formats (\*(AqXML\*(Aq,\*(AqCSV\*(Aq,etc.) \& # $file is a valid file name (relative or absolute) on the local computer \& # $flags is a hashref containing key/value pairs, e.g. \& { col_names => \*(Aqmake,model,year\*(Aq, pattern => \*(AqA10 A12 A4\*(Aq } \& \& # $data is one of: \& # * a valid file name (relative or absolute) on the local computer \& # * a valid absolute FTP or HTTP URL \& # * an arrayref containing arrayrefs of rows with column names first \& # [ \& # [\*(Aqmake\*(Aq,\*(Aqmodel\*(Aq], \& # [\*(AqHonda\*(Aq,\*(AqOdyssy\*(Aq], \& # [\*(AqFord\*(Aq,\*(AqSuburban\*(Aq], \& # ] \& \& # * an arrayref containing a string in a specified format \& # CSV : ["id,phrase\en1,foo\en2,bar"] \& # Pipe : ["id|phrase\en1|foo\en2|bar"] \& \& # * a reference to the DATA section of a file \& # [] \& \& # * a DBI Database handle \& # DBI\->connect(\*(Aqdbi:mysql:database=...) .Ve .PP The ad_catalog method is the standard way to treat files as databases. Each time you access data, it is read from the file and each time you modify data, it is written to the file. The entire file is never read en masse into memory unless you explicitly request it. .PP The ad_import method can import data from local or remote files, from any other \s-1DBI\s0 accessible database, from perl data structures such as arrays and strings. You may import an entire table or only the columns and rows you specify. If the data is imported from a file, all of the data you select is read into memory when you call ad_import so this should not be done with selections larger than will fit in your memory. :\-). All accessing and modification is done in memory. If you want to save the results of any changes, you will need to call ad_export explicitly. .PP Not all formats and data sources will work with all methods. Here is a summary of what will work. \*(L"all sources\*(R" includes local files, remote files, any \s-1DBI\s0 accessible database, perl arrayrefs, perl strings. .PP .Vb 6 \& Import From all formats, all sources \& Convert From all formats, all sources \& Convert To all formats except DBI, local files, arrays or strings only \& Export To all formats except DBI, local files, arrays or strings only \& Catalog all formats except DBI, XML, HTMLtable, Mp3, ARRAY, \& local files only .Ve .SS "connect" .IX Subsection "connect" The \s-1DBI\-\s0>connect call .SS "ad_catalog" .IX Subsection "ad_catalog" .Vb 1 \& PURPOSE: \& \& Creates an association betweeen a table name, a data format, and a file. \& \& SYNTAX: \& \& $dbh\->func( $table, $format, $file, $flags, \*(Aqad_catalog\*(Aq ) \& \& PARAMETERS: \& \& $table = the name of the table to be used in SQL commands \& \& $format = an AnyData format (\*(AqXML\*(Aq,\*(AqCSV\*(Aq, etc.) \& \& $file = the name of a local file (either full path or relative) \& \& $flags = a optional hashref of column names or other values \& \& EXAMPLE: \& \& This specifies that any DBI/SQL statements to the table \& \*(Aqcars\*(Aq will access and/or modify XML data in the file \& \*(Aq/users/me/data.xml\*(Aq \& \& $dbh\->func( \*(Aqcars\*(Aq, \*(AqXML\*(Aq, \*(Aq/usrs/me/data.xml\*(Aq, \*(Aqad_catalog\*(Aq ) \& \& REMARKS: \& \& The format may be any AnyData format *except* DBI, XML, HTMLtable, \& and MP3. .Ve .SS "ad_import" .IX Subsection "ad_import" .Vb 1 \& PURPOSE: \& \& Imports data from any source and any format into an in\-memory table. \& \& SYNTAX: \& \& $dbh\->func( $table, $format, $data_source, $flags, \*(Aqad_import\*(Aq ) \& \& PARAMETERS: \& \& $table = the name of the table to be used in SQL commands \& \& $format = an AnyData format (\*(AqXML\*(Aq,\*(AqCSV\*(Aq, etc.) \& \& $data_source = $file_name \& or $url \& or [$string] \& or [] \& or $reference_to_an array of arrays \& or $DBI_database_handle \& \& (See section "Data Sources" for more specifics of $data_source) \& \& EXAMPLES: \& \& $dbh\->func( \*(Aqcars\*(Aq, \*(AqXML\*(Aq, \*(Aq/usrs/me/data.xml\*(Aq, \*(Aqad_import\*(Aq ) \& \& For further examples, see sections on "In\-Memory Tables", \& "Remote Files", "DBI databases". .Ve .SS "ad_export" .IX Subsection "ad_export" .Vb 1 \& PURPOSE: \& \& Converts an in\-memory table into a specified format and either saves \& it to a file or returns it as a string. \& \& SYNTAX: \& \& $dbh\->func( $table, $format, $file, $flags, \*(Aqad_export\*(Aq ) \& \& OR \& \& my $string = $dbh\->func( $table, $format, $flags, \*(Aqad_export\*(Aq ) \& \& PARAMETERS: \& \& $table = the name of the in\-memory table to export \& \& $format = an AnyData format (\*(AqXML\*(Aq,\*(AqCSV\*(Aq, etc.) \& \& $file = the name of a local file (either full path or relative) \& \& EXAMPLES: \& \& Save a table as an XML file: \& \& $dbh\->func( \*(Aqcars\*(Aq, \*(AqXML\*(Aq, \*(Aq/usrs/me/data.xml\*(Aq, \*(Aqad_export\*(Aq ) \& \& Print a table as an HTML table \& \& print $dbh\->func( \*(Aqcars\*(Aq, \*(AqHTMLtable\*(Aq, \*(Aqad_export\*(Aq ) .Ve .SS "ad_convert" .IX Subsection "ad_convert" .Vb 1 \& PURPOSE: \& \& Converts data from one format into another and either returns it \& as a string in the new format or saves it to a file in the new \& format. \& \& SYNTAX: \& \& my $str = $dbh\->func( \& $source_format, \& $data_source \& $target_format, \& $source_flags, \& $target_flags, \& \*(Aqad_convert\*(Aq ); \& \& OR \& \& $dbh\->func( \& $source_format, \& $data_source \& $target_format, \& $target_file, \& $source_flags, \& $target_flags, \& \*(Aqad_convert\*(Aq ); \& \& PARAMETERS: \& \& $source_format = AnyData format (\*(AqXML\*(Aq,\*(AqCSV\*(Aq, etc.) of the source db \& \& $target_format = AnyData format (\*(AqXML\*(Aq,\*(AqCSV\*(Aq, etc.) of the target db \& \& $target_file = name of file to store converted data in \& \& $data_source = $file_name \& or $url \& or [$string] \& or [] \& or $reference_to_an array of arrays \& or $DBI_database_handle \& \& (See section "Data Sources" for more specifics of $data_source) \& \& EXAMPLES: \& \& # CONVERT A CSV FILE TO AN XML FILE \& # \& $dbh\->func( \*(AqCSV\*(Aq, \*(Aqdata.csv\*(Aq, \*(AqXML\*(Aq, \*(Aqdata.xml\*(Aq, \*(Aqad_convert\*(Aq); \& \& # CONVERT AN ARRAYREF TO AN HTML TABLE AND PRINT IT \& # \& print $dbh\->func( \*(AqARRAY\*(Aq, $aryref, \*(AqHTMLtable\*(Aq, \*(Aqad_convert\*(Aq); \& \& # CONVERT AN ARRAYREF TO XML AND SAVE IT IN A FILE \& # \& $dbh\->func( \*(AqARRAY\*(Aq, $aryref, \*(AqXML\*(Aq, \*(Aqdata.xml\*(Aq, \*(Aqad_convert\*(Aq); \& \& # CONVERT A SELECTION FROM A MySQL DATABASE TO XML \& # AND SAVE IT IN A FILE \& # \& $dbh\->func( \& \*(AqDBI\*(Aq, \& $mysql_dbh, \& \*(AqXML\*(Aq, \& \*(Aqdata.xml\*(Aq, \& {sql=>"SELECT make,model FROM CARS where year > 1996"} \& \*(Aqad_convert\*(Aq); \& \& REMARKS \& \& The format \*(AqDBI\*(Aq (any DBI accessible database) may be used as the \& source of a conversion, but not as the target of a conversion. \& \& The format \*(AqARRAY\*(Aq may be used to indicate that the source of the \& conversion is a reference to an array. Or that the result of the \& conversion should be returned as an array reference. (See above, \& working with in\-memory database for information on the structure of \& the array reference). .Ve .SS "Data Sources" .IX Subsection "Data Sources" .Vb 3 \& The ad_import and ad_convert methods can take data from many \& sources, including local files, remote files, strings, arrays, \& any DBI accessible database, the DATA section of a script. \& \& The $data_source parameter to ad_import and ad_convert will \& vary depending on the specific data source, see below. \& \& Local Files \& \& A string containing the name of a local file. It may either \& be a full path, or a path or file relative to the currently \& defined f_dir (see ?); \& \& e.g. \*(Aq/users/me/data.xml\*(Aq \& \& Remote Files \& \& A string containing the url of the data. Must start with \& \*(Aqftp://\*(Aq or \*(Aqhttp://\*(Aq \& \& e.g. \*(Aqhttp://www.somewhere.org/misc/news.xml\*(Aq \& \& Arrays of Arrays \& \& A reference to an array of data. Each row of the data is \& a reference to an array of values. The first row is the \& column names. E.G.: \& \& [ \& [\*(Aqmake\*(Aq,\*(Aqmodel\*(Aq], \& [\*(AqHonda\*(Aq,\*(AqOdyssy\*(Aq], \& [\*(AqFord\*(Aq,\*(AqSuburban\*(Aq], \& ] \& \& Strings \& \& A string in the specified format including all field and record \& separators. The string should be the only row in an array reference \& (i.e. it should be enclosed in square brackets) \& \& e.g. a CSV string \& \& ["id,phrase\en1,foo\en2,bar"] \& \& or in Pipe Delimited string \& \& ["id|phrase\en1|foo\en2|bar"] \& \& The DATA section of a file \& \& A reference to the array obtained from the lines after \& _\|_END_\|_ in a script. \& \& [] \& \& DBI Databases \& \& A database handle for a specified rdbms. \& \& DBI\->connect(\*(Aqdbi:mysql:database=...) .Ve .SS "ad_clear" .IX Subsection "ad_clear" .Vb 1 \& PURPOSE: \& \& Clears an in\-memory table (deletes it from memory) \& \& SYNTAX: \& \& $dbh\->func( $table, \*(Aqad_clear\*(Aq ) \& \& PARAMETERS: \& \& $table = the name of the in\-memory table to clear \& \& REMARKS: \& \& In\-memory tables will be deleted from memory automatically when the \& database handle used to create them goes out of scope. They will also \& be deleted if you call $dbh\->disconnect() on the database handle \& used to create them. The ad_clear method is a way to free up memory \& if you intend to keep using the database handle but no longer need a \& given table. As with other (all?) Perl memory operations, this frees \& memory for the remainder of your perl script to use but does not decrease \& the total amount of system memory used by the script. .Ve .SS "\s-1SQL\s0 Syntax" .IX Subsection "SQL Syntax" .Vb 6 \& Currently only a limited subset of SQL commands are supported. \& Only a single table may be used in each command. This means \& That there are *no joins*, but see the section above on simulating \& joins. In coming months additional SQL capabilities will be added, \& so keep your eyes out for ANNOUNCE message on usenet or the dbi\-users \& mailing list (see below "Getting More Help"). \& \& Here is a brief synopsis, please see the documentation for \& SQL::Statement for a more complete description of these commands. \& \& CREATE TABLE $table \& ( $col1 $type1, ..., $colN $typeN, \& [ PRIMARY KEY ($col1, ... $colM) ] ) \& \& DROP TABLE $table \& \& INSERT INTO $table \& [ ( $col1, ..., $colN ) ] \& VALUES ( $val1, ... $valN ) \& \& DELETE FROM $table \& [ WHERE $wclause ] \& \& UPDATE $table \& SET $col1 = $val1, ... $colN = $valN \& [ WHERE $wclause ] \& \& SELECT [DISTINCT] $col1, ... $colN \& FROM $table \& [ WHERE $wclause ] \& [ ORDER BY $ocol1 [ASC|DESC], ... $ocolM [ASC|DESC] ] \& \& $wclause [NOT] $col $op $val|$col \& [ AND|OR $wclause2 ... AND|OR $wclauseN ] \& \& $op = | <> | < | > | <= | >= \& | IS NULL | IS NOT NULL | LIKE | CLIKE \& \& The "CLIKE" operator works exactly like "LIKE" but is case insensitive. .Ve .SH "BUGS" .IX Header "BUGS" Please report any bugs or feature requests to \&\f(CW\*(C`bug\-dbd\-anydata at rt.cpan.org\*(C'\fR, or through the web interface at . I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. .SH "SUPPORT" .IX Header "SUPPORT" You can find documentation for this module with the perldoc command. .PP .Vb 1 \& perldoc DBD::AnyData .Ve .PP You can also look for information at: .IP "\(bu" 4 \&\s-1RT:\s0 \s-1CPAN\s0's request tracker .Sp .IP "\(bu" 4 AnnoCPAN: Annotated \s-1CPAN\s0 documentation .Sp .IP "\(bu" 4 \&\s-1CPAN\s0 Ratings .Sp .IP "\(bu" 4 Search \s-1CPAN\s0 .Sp .SH "ACKNOWLEDGEMENTS" .IX Header "ACKNOWLEDGEMENTS" Many people have contributed ideas and code, found bugs, and generally been supportive including Tom Lowery, Andy Duncan, Randal Schwartz, Michel Rodriguez, Wes Hardraker, Bob Starr, Earl Cahill, Bryan Fife, Matt Sisk, Matthew Wickline, Wolfgang Weisseberg. Thanks to Jochen Weidmann for DBD::File and SQL::Statement and of course Tim Bunce and Alligator Descartes for \s-1DBI\s0 and its documentation. .SH "AUTHOR & COPYRIGHT" .IX Header "AUTHOR & COPYRIGHT" Copyright 2000, Jeff Zucker .PP Copyright 2010, Jens Rehsack .PP This program is free software; you can redistribute it and/or modify it under the terms of either: the \s-1GNU\s0 General Public License as published by the Free Software Foundation; or the Artistic License. .PP See http://dev.perl.org/licenses/ for more information. .PP All rights reserved