The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Data::All - Access to data in many formats from many places

SYNOPSIS 1 (short)

    use Data::All;
    
    #   Create an instance of Data::All for database data
    my $input = Data::All->new(path => '/some/file.csv', profile => 'csv');
    
    #   Open the connection. Nothing happens until you tell it to. 
    $input->open();
    
    #   $rec now contains an arrayref of hashrefs for the data defined in %db.
    #   collection() is a shortcut (see Synopsis 2)
    my $rec  = $input1->read();

    #   Convert $input to another format.
    #   NOTE: The hash reference here is different than the hash used by new()
    $input->convert(to => {path => '/tmp/file.tab', profile => 'tab'}); 

    #   $rec is the same above   
    #   NOTE: The hash reference here is different than the hash used by new()
    my $rec = collection({'path' => '/some/file.csv', profile => 'csv'});
    

SYNOPSIS 2 (long)

    use Data::All;
    
    my $dsn1     = 'DBI:mysql:database=mysql;host=YOURHOST;';
    my $dsn2     = 'DBI:Pg:database=SOMEOTHERDB;host=YOURHOST;';
    my $query1   = 'SELECT `Host`, `User`, `Password` FROM user';
    my $query2   = 'INSERT INTO users (`Password`, `User`, `Host`) VALUES(?,?,?)';
    
    my %db1 = 
    (   path        => [$dsn1, 'user', 'pass', $query1],
        ioconf      => ['db', 'r' ]
    );
    
    #   Notice how the parameters can be sent as a well-ordered arrayref
    #   or as an explicit hashref. 
    my %db2 = 
    (   path        => [$dsn2, 'user', 'pass', $query2],
        ioconf      => { type => 'db', perms => 'w' },
        fields      => ['Password', 'User', 'Host']
    );
    
    #   This is an explicit csv format. This is the same as using 
    #   profile => 'csv'. NOTE: the 'w' is significant as it is passed to 
    #   IO::All so it knows how to properly open and lock the file. 
    my %file1 = 
    (
        path        => ['/tmp/', 'users.csv'],
        ioconf      => ['plain', 'rw'],
        format      => {
            type    => 'delim', 
            breack  => "\n", 
            delim   => ',', 
            quote   => '"', 
            escape  => '\\',
        }
    );
    
    #   The only significantly different here is with_original => 1.
    #   This tells Data::All to include the original record as a field 
    #   value. The field name is _ORIGINAL. This is useful for processing
    #   data when auditing the original source is required.         
    my %file2 = 
    (
        path        => '/tmp/users.fixed',
        ioconf      => {type=> 'plain', perms => 'w', with_original => 1],
        format      => { 
            type    => 'fixed', 
            break   => "\n", 
            lengths => [32,16,64]
        },
        fields      => ['pass','user','host']
    );
    
    #   Create an instance of Data::All for database data
    my $input1 = Data::All->new(%db1);
    
    $input1->open();    #   Open the connection.
    
    #   $rec now contains an arrayref of hashrefs for the data defined in %db.
    my $rec  = $input1->read();
    
    $input1->convert(to => \%db2, $options);    #   Save the mysql data to a postgresql table
    $input1->convert(to => \%file1);            #   And also save it to a file
    
    my $input2 = Data::All->new(%file1);    #   Open the file we just created
    $input2->convert(to =>\%file2);         #   And convert it to a fixed width format
    

DESCRIPTION

Similar to AnyData, but more suited towards converting data types from and to various sources rather than reading data and playing with it. It is like an extension to IO::All which gives you access to data sources; Data::All gives you access to data.

Data::All is based on a few abstracted concepts. The line is a record and a group of records is a collection. This allows a common record storing concept to be used across any number of data sources (delimited file, XML over a socket, a database table, etc...).

Supported formats: delimited and fixed. Supported sources: local filesystem, database, socket (not heavily tested).

Note that currently conversion happens an entire collection at a time which would be an issue if you are dealing with large datasets.

Data::All is a Spiffy module.

TODO LIST

Current major development areas are the interface and format stability. Upcoming development are breadth of features (more formats, more sources, ease of use, reliable subclassing, documentation/tests, and speed).

Misc: TODO: Create Data::All::Transport for taking care of converting formats TODO: Add ability to create temporary files TODO: Allow handling record fields with arrayrefs for anon / non-hash access TODO: Default values for fields (avoid undef db errors) TODO: Allow conversion to happen line by line. TODO: Allow modifying data in memory and saving it back to a file TODO: Consider using a standard internal structure, so every source is converted into this structure (hash, Stone?) TODO: Add SQL as a readable input and output TODO: Expose format functions to Data::All users so simple single record conversion can be thoroughly utilized.

STABILITY

This module is currently undergoing rapid development and there is much left to do. It is still in the alpha stage, so it is definitely not recommended for production use.

It has only been tested on Solaris 8 (SPARC64).

KNOWN BUGS

The record separator does not currently work properly as it is hardcoded to be newline (for delimited and fixed formats).

A perm of rw hasn't been tested, but should work.

The examples probably require a little tweaking to work properly.

SEE ALSO

IO::All, AnyData, Spiffy

AUTHOR

Delano Mandelbaum, <horrible<AT>murderer.ca>

COPYRIGHT AND LICENSE

Copyright (C) 2004 by Delano Mandelbaum

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.3 or, at your option, any later version of Perl 5 you may have available.