This time, with feeling ... here's the attachments.
--
Jeff
#########################################################
package AnyData::Format::Hash;
#########################################################
# copyright (c) 2000, Jeff Zucker <[EMAIL PROTECTED]>
# all rights reserved
#########################################################
=head1 NAME
AnyData::Format::Hash - easy tiedhash or DBI/SQL access to hashes
=head1 SYNOPSIS
use AnyData;
my $table = adHash( 'Ini', $filename,'r',$flags );
while (my $row = each %$table) {
print $row->{name},"\n" if $row->{country} =~ /us|mx|ca/;
}
# ... other tied hash operations
OR
use DBI
my $dbh = DBI->connect('dbi:AnyData:');
$dbh->func('table1','Init', $filename,$flags,'ad_catalog');
my $hits = $dbh->selectall_arrayref( qq{
SELECT name FROM table1 WHERE country = 'us'
});
# ... other DBI/SQL operations
=head1 DESCRIPTION
Please refer to the documentation for AnyData.pm and DBD::AnyData.pm
for further details.
=head1 AUTHOR & COPYRIGHT
copyright 2000, Jeff Zucker <[EMAIL PROTECTED]>
all rights reserved
=cut
use AnyData::Format::Base;
use strict;
use vars qw/@ISA $VERSION/;
@ISA = qw(AnyData::Format::Base);
use Data::Dumper;
$Data::Dumper::Indent = 1;
$Data::Dumper::Useqq = 0;
$VERSION = '0.06';
sub new {
my $class = shift;
my $self = shift || {};
$self->{has_export_method} = 1;
$self->{export_on_close} = 1;
$self->{comment} ||= '^#';
$self->{slurp_mode} = 1;
return bless $self, $class;
}
sub storage_type {'RAM'}
#sub get_data { return import(@_) }
#sub init_parser{};
#sub read_fields{};
sub import {
my $self = shift;
my $data = shift;
my $storage = shift;
return $self->get_data($data,$self->{col_names});
}
sub get_data {
my $self = shift;
my $str = shift;
if ($str and ref $str eq 'ARRAY') {
# $str = join '', @$str;
}
my $full_table;
my $table;
if (ref $str eq 'HASH') {
while (my($k,$v)=each %$str) {
push @$full_table,$v;
}
}
elsif ( ref $str eq 'ARRAY') {
for my $v1(@$str) {
push @$full_table,$v1;
}
}
else {
# if ($str =~ /^([EMAIL PROTECTED])$/) {
if ($str =~ /(.+)/s) {
$str = $1; # $str now untainted :-(
}
use mylibs; zwarn $str; exit;
eval $str;
die $@ if $@;
if ($table and ref $table eq 'HASH') {
while (my($k,$v)=each %$table) {
push @$full_table,$v;
}
}
else {
$full_table = $table;
}
#print Dumper $table;
}
$table = $full_table;
#use mylibs; zwarn $table;
# my @col_names = split ',', shift @$table;
my @col_names = ();
my %is_col;
my @new_table;
for my $hash_ref(@$table) {
for my $col(keys %$hash_ref) {
if (!$is_col{$col}++) {
push @col_names,$col;
}
}
my @row;
for my $col(@col_names) {
my $value = defined $hash_ref->{$col}
? $hash_ref->{$col}
: undef;
push @row, $value;
}
push @new_table,[EMAIL PROTECTED];
}
#zwarn [EMAIL PROTECTED]; zwarn [EMAIL PROTECTED];
return [EMAIL PROTECTED], [EMAIL PROTECTED];
}
sub export {
#print "EXPORTING!";
my $self = shift;
my $storage = shift;
my $col_names = $storage->{col_names};
my $table = $storage->{records};
my $fh = $storage->{fh};
my $newtable;
for my $row(@$table) {
my $rowhash;
@[EMAIL PROTECTED] = @$row;
for my $c(@$col_names) {
delete $rowhash->{$c} unless defined $rowhash->{$c};
}
#$newtable->{$rowhash->{table}} = $rowhash;
push @$newtable, $rowhash;
}
=pod
if (my $default = $newtable->{schema_defaults}) {
while (my($k,$v)=each %$newtable) {
next if $k eq 'schema_defaults';
for my $c(@$col_names) {
next unless $newtable->{$k}->{$c}
and $default->{$c}
and $newtable->{$k}->{$c} eq $default->{$c};
delete $newtable->{$k}->{$c};
}
}
}
=cut
$table = Dumper $newtable;
$table =~ s/^\$VAR1/\$table/;
$table =~ s/^\$ARRAY/\$table/;
return $table unless $fh;
return $fh->print( $table );
}
#########################################################
package AnyData::Format::ComplexIni;
#########################################################
# copyright (c) 2000, Jeff Zucker <[EMAIL PROTECTED]>
# all rights reserved
#########################################################
=head1 NAME
AnyData::Format::Ini - easy tiedhash or DBI/SQL access to ini files
=head1 SYNOPSIS
use AnyData;
my $table = adHash( 'Ini', $filename,'r',$flags );
while (my $row = each %$table) {
print $row->{name},"\n" if $row->{country} =~ /us|mx|ca/;
}
# ... other tied hash operations
OR
use DBI
my $dbh = DBI->connect('dbi:AnyData:');
$dbh->func('table1','Init', $filename,$flags,'ad_catalog');
my $hits = $dbh->selectall_arrayref( qq{
SELECT name FROM table1 WHERE country = 'us'
});
# ... other DBI/SQL operations
=head1 DESCRIPTION
This is a parser for Ini files including simple formats like:
ext = .jpg
dir = /foo
as well as more complex formats like
[photoslop]
ext = .jpg
dir = /pics
[musicmatch]
ext = .mp3
dir = /sounds
It also supports the use of comments (marked by default with a semicolon, but settable
by the user.
Please refer to the documentation for AnyData.pm and DBD::AnyData.pm
for further details.
=head1 AUTHOR & COPYRIGHT
copyright 2000, Jeff Zucker <[EMAIL PROTECTED]>
all rights reserved
=cut
use AnyData::Format::Base;
use strict;
use vars qw/@ISA $VERSION/;
@ISA = qw(AnyData::Format::Base);
use Data::Dumper;
$VERSION = '0.01';
sub new {
my $class = shift;
my $self = shift || {};
$self->{has_export_method} = 1;
$self->{export_on_close} = 1;
$self->{comment} ||= ';';
$self->{comment_sep} ||= '~';
$self->{slurp_mode} = 1;
return bless $self, $class;
}
sub storage_type { 'RAM'; }
sub get_data { return import(@_) }
sub import {
my $self = shift;
my $str = shift;
if (ref $str eq 'ARRAY') {
$str = $str->[0];
}
my $has_class = 1 if $str =~ /^\[.+\]\s*$/sm;
my(%row,$class,@table,%is_col,@cols);
my $eol = $self->{eol};
if (!$has_class) {
for (split $eol,$str) {
my($key,$value) = /^\s*([^=]+)=\s*(.*)$/;
next unless $key;
if ($key =~ /^$self->{comment}(.+)$/) {
$key = 'comment';
$value = $1;
}
push @table, [$key,$value];
}
return [EMAIL PROTECTED], ['key','value'];
}
@cols = ('key');
for (split $eol,$str) {
my($key,$value);
if (/^\[\s*(.+)\s*\]\s*$/) {
$class = $1;
next;
}
if (/^;(.+)$/) {
$key = 'comment';
$value = $1;
}
else {
($key,$value) = /^\s*([^=]+)=\s*(.*)$/;
}
next unless $key;
if ( $key =~ /^$self->{comment}(.+)$/){
$key = 'comment';
$value = $1;
}
else {
push @cols, $key if !$is_col{$key}++;
}
$row{($class||'')}{$key} .= $self->{comment_sep}
. $value if $key eq 'comment';
$row{($class||'')}{$key} = $value unless $key eq 'comment';
}
while (my($class,$line)= each %row) {
my @newrow;
push @newrow, $class;
for my $col(@cols) {
next if $col eq 'key';
push @newrow, $line->{$col};
}
push @table, [EMAIL PROTECTED];
}
return [EMAIL PROTECTED], [EMAIL PROTECTED];
}
# this requires a change to AnyData.pm
# I'll work on it later after AnyData is patched.
sub export {
my($self,$storage) = @_;
my $col_names = $storage->{col_names};
my $col_nums = $storage->{col_nums};
print "!", $col_nums->{comment};
my $table = $storage->{records};
#use Data::Dumper; print Dumper $table; print "###"; exit;
my $fh = $storage->{fh};
for my $row(@$table) {
printf "[%s]\n",$row->[0] if $row->[0];
}
}