summaryrefslogtreecommitdiff
path: root/cpan/dist
diff options
context:
space:
mode:
authorfukachan <fukachan>2001-01-26 11:05:37 +0000
committerfukachan <fukachan>2001-01-26 11:05:37 +0000
commit8c72d379c06bc5a072c42d6be5aa74695dfe6c01 (patch)
tree87621e51865e23bd5dc497b821459f4e2290a3df /cpan/dist
parent9ae24261ac65b4530a36ceab0b0ce3c42d360df5 (diff)
downloadfml8-8c72d379c06bc5a072c42d6be5aa74695dfe6c01.tar.gz
fml8-8c72d379c06bc5a072c42d6be5aa74695dfe6c01.tar.bz2
fml8-8c72d379c06bc5a072c42d6be5aa74695dfe6c01.zip
Initial revision
Diffstat (limited to 'cpan/dist')
-rw-r--r--cpan/dist/AsciiDB-TagFile/Changes46
-rw-r--r--cpan/dist/AsciiDB-TagFile/MANIFEST14
-rw-r--r--cpan/dist/AsciiDB-TagFile/Makefile.PL12
-rw-r--r--cpan/dist/AsciiDB-TagFile/README33
-rw-r--r--cpan/dist/AsciiDB-TagFile/TagFile.pm406
-rw-r--r--cpan/dist/AsciiDB-TagFile/TagRecord.pm141
-rw-r--r--cpan/dist/AsciiDB-TagFile/t/tietag.pl15
-rw-r--r--cpan/dist/AsciiDB-TagFile/t/tietag1.t35
-rw-r--r--cpan/dist/AsciiDB-TagFile/t/tietag2.t40
-rw-r--r--cpan/dist/AsciiDB-TagFile/t/tietag3.t41
-rw-r--r--cpan/dist/AsciiDB-TagFile/t/tietag4.t23
-rw-r--r--cpan/dist/AsciiDB-TagFile/t/tietag5.t27
-rw-r--r--cpan/dist/AsciiDB-TagFile/t/tietag6.t50
-rw-r--r--cpan/dist/AsciiDB-TagFile/tdata/sampletfr3
14 files changed, 886 insertions, 0 deletions
diff --git a/cpan/dist/AsciiDB-TagFile/Changes b/cpan/dist/AsciiDB-TagFile/Changes
new file mode 100644
index 00000000..917709dc
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/Changes
@@ -0,0 +1,46 @@
+Revision history for Perl extension AsciiDB::TagFile.
+
+1.00 Fri Oct 3 19:36:47 1997
+ - original version; created by Jose A. Rodriguez <josear@ac.upc.es>
+
+1.01 Thu Dec 11 19:17:01 1997
+ - Added FILEMODE parameter; by Jose A. Rodriguez <josear@ac.upc.es>
+ - Added support for EXISTS
+
+1.02 Thu Jan 8 16:41:34 1998
+ - Reduced memory usage (removed an internal hash)
+
+ Suggested by Michael Pepper <pepper@w3pg.com>:
+
+ - Removed perl version 5.004 dependences (foreach my $variable...)
+ - Fixed bug, now record copies work (ie. $a{'r1'} = $a{'r2'})
+ - Fixed bug, now a warning is displayed if the DIRECTORY does not
+ exist
+ - Added basic support for locking
+
+1.03 Tue Feb 17 09:58:05 1998
+ - Fixed bug, sometimes deleted records weren't removed from the
+ file system
+ - Added a feature to limit the number of records in memory (cache size)
+ (thanks to Michael Pepper for the testing && suggesting
+ features)
+
+1.04 Sat Feb 27 13:05:27 1999
+ Repported by Carsten Heyl <heyl@kirk.nads.de> and
+ "Garnet R. Chaney" <gchaney@webmill.com>:
+
+ - Fixed bug that prevented the value "0" from being written
+
+ Suggested by Carsten Heyl <heyl@kirk.nads.de>:
+
+ - Added a feature to encode/decode keys when saved to the filesystem
+
+1.05 Mon Mar 1 17:05:15 1999
+ Repported by Chris Nandor <pudge@pobox.com>
+
+ - Module was Unix dependent (used '/' as path component separator,
+ '.' as current directory, etc.)
+ Now the module uses File::Spec (if available) and Cwd, so
+ it should be truly portable.
+
+ Thanks to Chris Nandor for his help (debugging).
diff --git a/cpan/dist/AsciiDB-TagFile/MANIFEST b/cpan/dist/AsciiDB-TagFile/MANIFEST
new file mode 100644
index 00000000..d52b59be
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/MANIFEST
@@ -0,0 +1,14 @@
+MANIFEST
+Makefile.PL
+README
+Changes
+TagFile.pm Tie interface to a set of Tagged Records
+TagRecord.pm Tie interface to a Tagged record
+t/tietag.pl Test file (STORE)
+t/tietag1.t Test file (STORE)
+t/tietag2.t Test file (FETCH)
+t/tietag3.t Test file (DELETE+CheckPoint)
+t/tietag4.t Test file (Read Only)
+t/tietag5.t Test file (Bug fixed in 1.03)
+t/tietag6.t Test file (Limit cache feature)
+tdata/sampletfr Sample record for test files
diff --git a/cpan/dist/AsciiDB-TagFile/Makefile.PL b/cpan/dist/AsciiDB-TagFile/Makefile.PL
new file mode 100644
index 00000000..b1925d16
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/Makefile.PL
@@ -0,0 +1,12 @@
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+ NAME => 'AsciiDB::TagFile',
+ VERSION_FROM => 'TagFile.pm',
+ 'dist' => {
+ TARFLAGS => 'cvf',
+ COMPRESS => 'gzip',
+ SUFFIX => 'gz',
+ },
+);
diff --git a/cpan/dist/AsciiDB-TagFile/README b/cpan/dist/AsciiDB-TagFile/README
new file mode 100644
index 00000000..e677d5d0
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/README
@@ -0,0 +1,33 @@
+
+ AsciiDB::Tag - Tie class for a simple ASCII database
+ ===========================================================================
+ Jose A. Rodriguez Garrido
+ josear+cpan@ac.upc.es
+
+ Usually when you have to store persistent data you don't need a full-blown
+ database server, just a ASCII database would do the trick.
+
+ AsciiDB::Tag allows you to access a simple ASCII database using a
+ perl hash variable. The database format is straightforward so you can edit
+ it by hand if you need so. Each record is stored into a file, and a
+ record is just a set of values tagged by the field name:
+
+ [Name]: Jose A. Rodriguez
+ [Address]: Granollers, Barcelona, SPAIN
+
+ The tie class provides a convenient way to read and update this kind
+ of ASCII databases.
+
+ For comments, bugs or just to say you use or hate this class feel free
+ to send me an e-mail.
+
+ Installation
+ ---------------------------------------------------------------------------
+ As usual:
+
+ perl Makefile.PL
+ make
+ make test
+ make install
+
+
diff --git a/cpan/dist/AsciiDB-TagFile/TagFile.pm b/cpan/dist/AsciiDB-TagFile/TagFile.pm
new file mode 100644
index 00000000..f12707d5
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/TagFile.pm
@@ -0,0 +1,406 @@
+package AsciiDB::TagFile;
+
+# Copyright (c) 1997,1998,1999 Jose A. Rodriguez. All rights reserved.
+# This program is free software; you can redistribute it and/or modify it
+# under the same terms as Perl itself.
+
+require Tie::Hash;
+@ISA = (Tie::Hash);
+
+use Cwd;
+
+use vars qw($VERSION $catPathFileName);
+
+BEGIN {
+ eval "use File::Spec";
+ $catPathFileName = ($@) ?
+ sub { join('/', @_) } : # Unix way
+ sub { File::Spec->catfile(@_) }; # Portable way
+}
+
+$VERSION = '1.05';
+
+use Carp;
+use AsciiDB::TagRecord;
+
+sub TIEHASH {
+ my $class = shift;
+ my %params = @_;
+
+ my $self = {};
+ $self->{_DIRECTORY} = $params{DIRECTORY} || cwd;
+ $self->{_SUFIX} = $params{SUFIX} || '';
+ $self->{_SCHEMA} = $params{SCHEMA};
+ $self->{_READONLY} = $params{READONLY};
+ $self->{_FILEMODE} = $params{FILEMODE};
+ $self->{_LOCK} = $params{LOCK} || 0;
+ $self->{_CACHESIZE} = $params{CACHESIZE};
+
+ unless (-d $self->{_DIRECTORY}) {
+ croak "Directory '$params{DIRECTORY}' does not exist";
+ }
+
+ if (defined $self->{_CACHESIZE}) {
+ $self->{_CACHESIZE} = int($self->{_CACHESIZE});
+
+ if ($self->{_CACHESIZE} == 0) {
+ undef $self->{_CACHESIZE};
+ } elsif ($self->{_CACHESIZE} < 1) {
+ croak "Cache size should be >= 0 (0 means no cache)";
+ $self->{_CACHESIZE} = 1;
+ }
+ }
+
+ # Number of internal keys (ie. '_key')
+ $self->{_INTKEYCOUNT} = 1 + keys %$self;
+
+ bless $self, $class;
+}
+
+sub FETCH {
+ my ($self, $key) = @_;
+
+ return $self->{$key} if exists ($self->{$key});
+
+ return $self->newRecord($key);
+}
+
+sub STORE {
+ my ($self, $key, $value) = @_;
+
+ # Return if the user is assigning an object to itself ($a{A} = $a{A})
+ return if exists $self->{$key} && $self->{$key} == $value;
+
+ $self->newRecord($key) unless (exists $self->{$key});
+
+ my $field;
+ foreach $field (keys %{$self->{$key}}) {
+ $self->{$key}{$field} = $value->{$field};
+ }
+}
+
+sub FIRSTKEY {
+ my $self = shift;
+
+ # Current keys are the union of saved keys and new created but
+ # not saved keys
+ my %currentKeys;
+
+ my $sufix = $self->{_SUFIX};
+
+ map { $currentKeys{$_} = 1 }
+ map { $self->decodeKey($_) }
+ grep { $_ =~ /(.+)\Q$sufix\E$/; $_ = $1 }
+ $self->getDirFiles();
+ map { $currentKeys{$_} = 1 } grep(!/^_/, keys %$self);
+
+ my @currentKeys = keys %currentKeys;
+ $self->{_ITERATOR} = \@currentKeys;
+
+ shift @{$self->{_ITERATOR}};
+}
+
+sub NEXTKEY {
+ my $self = shift;
+
+ shift @{$self->{_ITERATOR}};
+}
+
+sub EXISTS {
+ my ($self, $key) = @_;
+
+ $self->{$key} || -f $self->fileName($key) || 0;
+}
+
+sub DELETE {
+ my ($self, $key) = @_;
+
+ return if $self->{_READONLY};
+
+ unlink $self->fileName($key);
+
+ tied(%{$self->{$key}})->deleteRecord()
+ if tied(%{$self->{$key}});
+
+ delete $self->{$key} if exists $self->{$key};
+}
+
+sub sync {
+ my $self = shift;
+
+ my $record;
+ foreach $record (grep { tied(%$_) } values %{$self}) {
+ tied(%$record)->sync();
+ }
+}
+
+sub purge {
+ my $self = shift;
+ my ($cacheSize) = @_;
+
+ if (defined($cacheSize)) {
+ my $dataRecords = scalar(keys %$self) - $self->{_INTKEYCOUNT};
+ return if $dataRecords < $cacheSize;
+ }
+
+ # This works in 5.004 no 5.003
+ #delete @$self{grep !/^_/, keys %{$self}};
+ # instead we use this...
+ foreach (grep !/^_/, keys %{$self}) {
+ delete $self->{$_};
+ }
+}
+
+sub newRecord {
+ my $self = shift;
+ my ($key) = @_;
+
+ $self->purge($self->{_CACHESIZE}) if defined($self->{_CACHESIZE});
+
+ my %record;
+ tie %record, 'AsciiDB::TagRecord',
+ FILENAME => $self->fileName($key),
+ SCHEMA => $self->{_SCHEMA},
+ READONLY => $self->{_READONLY},
+ FILEMODE => $self->{_FILEMODE};
+
+ $self->{$key} = \%record;
+}
+
+sub encodeKey {
+ my $self = shift;
+ my ($key) = @_;
+
+ my $encodeSub = $self->{_SCHEMA}{KEY}{ENCODE};
+ ($encodeSub) ? &$encodeSub($key) : $key;
+}
+
+sub decodeKey {
+ my $self = shift;
+ my ($key) = @_;
+
+ my $decodeSub = $self->{_SCHEMA}{KEY}{DECODE};
+ ($decodeSub) ? &$decodeSub($key) : $key;
+}
+
+sub fileName {
+ my $self = shift;
+ my ($key) = $self->encodeKey(@_);
+
+ &$catPathFileName($$self{_DIRECTORY}, "$key$$self{_SUFIX}")
+}
+
+sub getDirFiles {
+ my $self = shift;
+
+ local *DIR;
+ opendir(DIR, $$self{_DIRECTORY})
+ || die "Can't opendir $$self{_DIRECTORY}: $!";
+ my @files = grep { -f &$catPathFileName($$self{_DIRECTORY}, $_) }
+ readdir(DIR);
+ closedir DIR;
+
+ @files;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+AsciiDB::TagFile - Tie class for a simple ASCII database
+
+=head1 SYNOPSIS
+
+ # Bind the hash to the class
+ $tieObj = tie %hash, 'AsciiDB::TagFile',
+ DIRECTORY => $directory,
+ SUFIX => $sufix,
+ LOCK => $bool,
+ READONLY => $bool,
+ CACHESIZE => $cacheSize,
+ FILEMODE => $mode,
+ SCHEMA => {
+ ORDER => $arrayRef
+ KEY => {
+ ENCODE => $subRef,
+ DECODE => $subRef
+ }
+ };
+
+ # Save to disk all changed records
+ $tieObj->sync();
+
+ # Remove all records from memory (and save them if needed)
+ $tieObj->purge();
+
+ # Remove all records from memory (and save them if needed)
+ # iif there are more than $cacheSize records in memory
+ $tieObj->purge($cacheSize);
+
+ # Get all record keys
+ @array = keys %hash;
+
+ # Check if a record exists
+ exists $hash{$recordKey}
+
+ # Get a field
+ $scalar = $hash{$recordKey}{$fieldName};
+
+ # Assign to a field
+ $hash{$recordKey}{$fieldName} = $value;
+
+=head1 DESCRIPTION
+
+The B<AsciiDB::TagFile> provides a hash-table-like interface to a simple ASCII
+database.
+
+The ASCII database stores each record in a file:
+
+ $directory/recordKey1$sufix
+ $directory/recordKey2$sufix
+ ...
+ $directory/recordKeyI<N>$sufix
+
+And a record has this format:
+
+ [fieldName1]: value1
+ [fieldName2]: value2
+ ...
+ [fieldNameI<N>]: value2
+
+After you've tied the hash you can access this database as access a hash of
+hashes:
+
+ $hash{recordKey1}{fieldName1} = ...
+
+To bind the %hash to the class AsciiDB::TagFile you have to use the tie
+function:
+
+ tie %hash, 'AsciiDB::TagFile', PARAM1 => $param1, ...;
+
+The parameters are:
+
+=over 4
+
+=item DIRECTORY
+
+The directory where the records will be stored or readed from.
+The default value is the current directory.
+
+=item SUFIX
+
+The records are stored as files. The file name of a record is the
+key plus this sufix (if supplied).
+
+For example, if the record with key 'josear' and sufix '.record', will
+be stored into file: 'josear.record'.
+
+If this parameter is not supplied the records won't have a sufix.
+
+=item LOCK
+
+If you set this parameter to 1 TagFile will perform basic locking.
+Record files will be share locked before reading them, and exclusive
+locked when syncing (writing) them.
+
+This basic locking only guarantees that a record file is always
+written correctly, but as TagFile keep records in memory you can still suffer
+consistency problems reading fields.
+
+The default value is 0, i.e. the database won't be locked.
+
+=item READONLY
+
+If you set this parameter to 1 the database will be read only and
+all changes will be discarted.
+
+The default value is 0, i.e. the database can be changed.
+
+=item CACHESIZE
+
+Records loaded from disk (or simply created) are keeped in memory till
+the tied hash is deleted. You can limit the number of records in memory
+setting this option to a value ($cacheSize).
+
+All records are purged from memory if their count reach $cacheSize.
+
+You can purge the records manually using the purge() method.
+
+Of course, the $caseSize should be a positive number, and you can use
+the 0 value to turn off the caching (useful when testing).
+
+The default value for CACHESIZE is 'infinite' (more or less...)
+
+=item FILEMODE
+
+Filemode assigned to new created files.
+
+If this parameter is not supplied the new created files will have the
+default permissions.
+
+=item SCHEMA
+
+This parameter is a hash reference that contains the database definition.
+
+With ORDER you can specify in which order fields will be saved into the
+file.
+
+For example,
+
+ SCHEMA => {
+ ORDER => [ 'fieldHi', 'field2There', 'fieldWorld' ]
+ }
+
+will save the record this way:
+
+ [fieldHi]: ...
+ [fieldThere]: ...
+ [fieldWorld]: ...
+
+Note: this parameter is mandatory, and you have to specify all the
+fields. B<If you forget to list a field it will not be saved>.
+
+With KEY,ENCODE and KEY,DECODE you can define an special encoding
+for keys when used as filenames.
+
+For example, if using this SCHEMA:
+
+ SCHEMA => {
+ ORDER => ['a', 'b', 'c'],
+ KEY => {
+ ENCODE => sub { $_[0] =~ s{/}{_SLASH_}g; $_[0] },
+ DECODE => sub { $_[0] =~ s{_SLASH_}{/}g; $_[0] },
+ }
+ }
+
+a record with the key 's1/s2' will be saved into filename 's1_SLASH_s2'.
+The DECODE subroutine is used to traslate back to the original key.
+
+NOTE: You should use this feature if you allow filesystem metacharacters
+(as '/', used in Unix to split path components) in your keys.
+
+=back
+
+The data will be saved to disk when the hash is destroyed (and garbage
+collected by perl), so if you need for safety to write the updated data
+you can call the B<sync> method to do it.
+
+=head1 EXAMPLES
+
+ $dbObj = tie %tietag, 'AsciiDB::TagFile',
+ DIRECTORY => 'data',
+ SUFIX => '.tfr',
+ FILEMODE => 0644,
+ SCHEMA => { ORDER => ['name', 'address'] };
+
+ $tietag{'jose'}{'name'} = 'Jose A. Rodriguez';
+ $tietag{'jose'}{'address'} = 'Granollers, Barcelona, SPAIN';
+ $tietag{'cindy'}{'name'} = 'Cindy Crawford';
+ $tietag{'cindy'}{'address'} = 'YouBetIwouldLikeToKnowIt';
+
+ my $key;
+ foreach $key (keys %tietag) {
+ print $tietag{$key}{'name'}, "\t", $tietag{$key}{'address'},
+ "\n";
+ }
diff --git a/cpan/dist/AsciiDB-TagFile/TagRecord.pm b/cpan/dist/AsciiDB-TagFile/TagRecord.pm
new file mode 100644
index 00000000..0464504a
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/TagRecord.pm
@@ -0,0 +1,141 @@
+package AsciiDB::TagRecord;
+
+# Copyright (c) 1997,1998,1999 Jose A. Rodriguez. All rights reserved.
+# This program is free software; you can redistribute it and/or modify it
+# under the same terms as Perl itself.
+
+require Tie::Hash;
+@ISA = (Tie::Hash);
+
+$VERSION = '1.05';
+
+use Carp;
+
+sub TIEHASH {
+ my $class = shift;
+ my %params = @_;
+
+ my $self = {};
+ $self->{_FILENAME} = $params{FILENAME};
+ $self->{_SCHEMA} = $params{SCHEMA};
+ $self->{_READONLY} = $params{READONLY};
+ $self->{_FILEMODE} = $params{FILEMODE};
+ $self->{_LOCK} = $params{LOCK};
+
+ bless $self, $class;
+}
+
+sub FETCH {
+ my ($self, $key) = @_;
+
+ $self->load() unless exists $self->{_LOADED};
+
+ return $self->{$key};
+}
+
+sub STORE {
+ my ($self, $key, $value) = @_;
+
+ return if $self->{_READONLY};
+
+ $self->load() unless
+ exists ($self->{_LOADED}) or (! -f $self->{_FILENAME});
+
+ $self->{$key} = $value;
+ $self->{_LOADED} = 1;
+ $self->{_UPDATED} = 1;
+}
+
+sub FIRSTKEY {
+ my $self = shift;
+
+ my %schema = %{$self->{_SCHEMA}};
+ my @iterator = @{$schema{ORDER}};
+ $self->{_ITERATOR} = \@iterator;
+
+ shift @{$self->{_ITERATOR}};
+}
+
+sub NEXTKEY {
+ my $self = shift;
+
+ shift @{$self->{_ITERATOR}};
+}
+
+sub DELETE {
+ my ($self, $key) = @_;
+
+ $self->load() unless exists $self->{_LOADED};
+
+ delete $self->{$key};
+ $self->{_UPDATED} = 1;
+}
+
+sub DESTROY {
+ my $self = shift;
+
+ $self->sync();
+}
+
+sub load {
+ my $self = shift;
+
+ open (RECORD, $self->{_FILENAME})
+ or croak "Can't open $self->{_FILENAME} record";
+
+ flock(RECORD, 1) if $self->{_LOCK}; # Get shared lock
+
+ my $fieldName = '';
+ my $line;
+ while (defined ($line = <RECORD>)) {
+ if ($line =~ /^\[(.+)\]:\s?(.*)$/) {
+ $self->{$fieldName = $1} = $2;
+ next;
+ }
+
+ chomp $line;
+ $self->{$fieldName} .= "\n$line";
+ }
+
+ close (RECORD); # This close unlocks the file
+
+ $self->{_LOADED} = 1;
+ delete $self->{_UPDATED};
+}
+
+sub deleteRecord {
+ my $self = shift;
+
+ $self->{_LOADED} = 1;
+ $self->{_UPDATED} = 0;
+}
+
+sub sync {
+ my $self = shift;
+
+ return if $self->{_READONLY} || ! $self->{_UPDATED};
+
+ open (RECORD, "> $$self{_FILENAME}")
+ or croak "Can't create $$self{_FILENAME} record";
+
+ flock(RECORD, 2) if $self->{_LOCK}; # Get shared lock
+
+ my %schema = %{$self->{_SCHEMA}};
+ my $fieldName;
+ foreach $fieldName (@{$schema{ORDER}}) {
+ print RECORD ("[$fieldName]: ",
+ defined($self->{$fieldName}) ?
+ $self->{$fieldName} : '', "\n");
+ }
+
+ close (RECORD); # This close unlocks the file
+
+ if (defined $self->{_FILEMODE}) {
+ chmod ($self->{_FILEMODE}, $self->{_FILENAME})
+ or croak "Can't chmod $$self{_FILENAME}";
+ }
+
+ delete $self->{_UPDATED};
+}
+
+1;
diff --git a/cpan/dist/AsciiDB-TagFile/t/tietag.pl b/cpan/dist/AsciiDB-TagFile/t/tietag.pl
new file mode 100644
index 00000000..c6b6554e
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/t/tietag.pl
@@ -0,0 +1,15 @@
+# Define test database properties
+
+tie %tietag, 'AsciiDB::TagFile',
+ DIRECTORY => 'tdata',
+ SUFIX => '.tfr',
+ SCHEMA => {
+ ORDER => ['a', 'b', 'c', 'zero' ],
+ KEY => {
+ ENCODE => sub { $_[0] =~ s{/}{_SLASH_}g; $_[0] },
+ DECODE => sub { $_[0] =~ s{_SLASH_}{/}g; $_[0] },
+ },
+ },
+ @TEST_SETTINGS;
+
+tied(%tietag) or print "not ";
diff --git a/cpan/dist/AsciiDB-TagFile/t/tietag1.t b/cpan/dist/AsciiDB-TagFile/t/tietag1.t
new file mode 100644
index 00000000..152d2bc3
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/t/tietag1.t
@@ -0,0 +1,35 @@
+#!./perl -w
+
+use UNIVERSAL qw(isa);
+
+use AsciiDB::TagFile;
+
+print "1..6\n";
+
+push(@INC, 't');
+require 'tietag.pl';
+print "ok 1\n";
+
+$tietag{'record1'}{'a'} = 'Fa';
+$tietag{'record1'}{'b'} = 'F1b';
+$tietag{'record2'}{'b'} = 'Fb';
+tied(%tietag)->sync();
+print "ok 2\n";
+
+($tietag{'record1'}{'a'} eq 'Fa') or print "not ";
+($tietag{'record2'}{'b'} eq 'Fb') or print "not ";
+print "ok 3\n";
+
+isa(tied(%tietag), 'AsciiDB::TagFile') or print "not ";
+print "ok 4\n";
+
+# Bug: 0 values not written
+$tietag{'record1'}{'zero'} = '0';
+($tietag{'record1'}{'zero'} eq '0') or print "not ";
+print "ok 5\n";
+
+# Encode/Decode: Without this feature special characters like '/'
+# can't be used in a key, becase the produce invalid filenames
+$tietag{'string/string'}{'zero'} = '0';
+($tietag{'string/string'}{'zero'} eq '0') or print "not ";
+print "ok 6\n";
diff --git a/cpan/dist/AsciiDB-TagFile/t/tietag2.t b/cpan/dist/AsciiDB-TagFile/t/tietag2.t
new file mode 100644
index 00000000..4a3cf4cd
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/t/tietag2.t
@@ -0,0 +1,40 @@
+#!./perl -w
+
+use AsciiDB::TagFile;
+
+print "1..9\n";
+
+push(@INC, 't');
+require 'tietag.pl';
+print "ok 1\n";
+
+($tietag{'record1'}{'a'} eq 'Fa') or print "not ";
+print "ok 2\n";
+
+($tietag{'record2'}{'b'} eq 'Fb') or print "not ";
+print "ok 3\n";
+
+(exists $tietag{'record2'}) or print "not ";
+print "ok 4\n";
+
+(!exists $tietag{'NOEXISTS'}) or print "not ";
+print "ok 5\n";
+
+# Bug: record copy not working
+$tietag{'record1'} = $tietag{'record1'};
+$tietag{'record3'} = $tietag{'record1'};
+$tietag{'record3'}{'a'} = 'AValueForRecord3';
+($tietag{'record3'}{'a'} ne $tietag{'record1'}{'a'}) or print "not ";
+print "ok 6\n";
+
+($tietag{'record3'}{'b'} eq $tietag{'record1'}{'b'}) or print "not ";
+print "ok 7\n";
+
+# Bug: 0 values not written
+($tietag{'record1'}{'zero'} eq '0') or print "not ";
+print "ok 8\n";
+
+# Encode/Decode: Without this feature special characters like '/'
+# can't be used in a key, becase the produce invalid filenames
+($tietag{'string/string'}{'zero'} eq '0') or print "not ";
+print "ok 9\n";
diff --git a/cpan/dist/AsciiDB-TagFile/t/tietag3.t b/cpan/dist/AsciiDB-TagFile/t/tietag3.t
new file mode 100644
index 00000000..04defbd4
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/t/tietag3.t
@@ -0,0 +1,41 @@
+#!./perl -w
+
+use AsciiDB::TagFile;
+
+print "1..5\n";
+
+push(@INC, 't');
+require 'tietag.pl';
+my $tieObj = tied(%tietag);
+print "ok 1\n";
+
+delete $tietag{'record1'};
+print "not " if -f $tieObj->fileName('record1');
+print "ok 2\n";
+
+delete $tietag{'record3'};
+print "not " if -f $tieObj->fileName('record3');
+print "ok 3\n";
+
+delete $tietag{'string/string'};
+print "not " if -f $tieObj->fileName('string/string');
+print "ok 4\n";
+
+# Check point: Current record keys should be what expected
+
+my $notOk = 0;
+my @realKeys = sort keys %tietag;
+my @testKeys = sort qw(record2);
+print STDERR "\nKEYS: @realKeys\n" if $ENV{DEBUG};
+while (@realKeys || @testKeys) {
+ my $realKey = shift @realKeys;
+ my $testKey = shift @testKeys;
+
+ if (!defined $realKey || !defined $testKey || $realKey ne $testKey) {
+ $notOk = 1;
+ last;
+ }
+}
+
+print "not " if $notOk;
+print "ok 5\n";
diff --git a/cpan/dist/AsciiDB-TagFile/t/tietag4.t b/cpan/dist/AsciiDB-TagFile/t/tietag4.t
new file mode 100644
index 00000000..7d1f99a4
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/t/tietag4.t
@@ -0,0 +1,23 @@
+#!./perl -w
+# Test the READONLY feature
+
+use AsciiDB::TagFile;
+use vars qw(@TEST_SETTINGS);
+
+print "1..3\n";
+
+@TEST_SETTINGS = (READONLY => 1);
+push(@INC, 't');
+require 'tietag.pl';
+my $tieObj = tied(%tietag);
+print "ok 1\n";
+
+$tietag{'record2'}{'b'} = 'NOTVALID';
+($tietag{'record2'}{'b'} eq 'Fb') or print "not ";
+print "ok 2\n";
+
+delete $tietag{'record2'};
+print "not " if ! -f $tieObj->fileName('record2');
+print "ok 3\n";
+
+unlink $tieObj->fileName('record2') if -f $tieObj->fileName('record2');
diff --git a/cpan/dist/AsciiDB-TagFile/t/tietag5.t b/cpan/dist/AsciiDB-TagFile/t/tietag5.t
new file mode 100644
index 00000000..268d1bcb
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/t/tietag5.t
@@ -0,0 +1,27 @@
+#!./perl -w
+# Test bug fixed in 1.03
+# Create record
+# Delete record
+# Destroy record (no file should be created at this point)
+
+use AsciiDB::TagFile;
+
+print "1..2\n";
+
+my $fileName;
+
+{ # Open scope
+
+push(@INC, 't');
+require 'tietag.pl';
+my $tieObj = tied(%tietag);
+print "ok 1\n";
+
+$tietag{'removed'}{'a'} = 1;
+delete $tietag{'removed'};
+
+$fileName = $tieObj->fileName('removed');
+} # Close scope
+
+print "not " if -e $fileName;
+print "ok 2\n";
diff --git a/cpan/dist/AsciiDB-TagFile/t/tietag6.t b/cpan/dist/AsciiDB-TagFile/t/tietag6.t
new file mode 100644
index 00000000..970266a9
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/t/tietag6.t
@@ -0,0 +1,50 @@
+#!./perl -w
+# Test the 'limit cache size' feature
+
+use AsciiDB::TagFile;
+use vars qw(@TEST_SETTINGS);
+
+$cacheSize = 10;
+$records = 50;
+
+print "1..3\n";
+
+@TEST_SETTINGS = (CACHESIZE => $cacheSize);
+push(@INC, 't');
+require 'tietag.pl';
+my $tieObj = tied(%tietag);
+
+foreach (1..$records) {
+ $tietag{"R$_"}{'a'} = $_;
+
+ do { print "not "; last }
+ if (getDataRecordsCount($tieObj) > $cacheSize);
+}
+
+print "ok 1\n";
+
+$tieObj->purge();
+print "not " if (getDataRecordsCount($tieObj) != 0);
+
+print "ok 2\n";
+
+foreach (1..$records) {
+ my $fieldA = $tietag{"R$_"}{'a'};
+ my $fieldB = $tietag{"R$_"}{'b'};
+
+ do { print "not "; last }
+ if (getDataRecordsCount($tieObj) > $cacheSize);
+}
+
+print "ok 3\n";
+
+foreach (1..$records) {
+ delete $tietag{"R$_"};
+}
+
+sub getDataRecordsCount {
+ my ($obj) = @_;
+
+ my $keyCount = scalar(keys %$obj);
+ $keyCount - $obj->{_INTKEYCOUNT};
+}
diff --git a/cpan/dist/AsciiDB-TagFile/tdata/sampletfr b/cpan/dist/AsciiDB-TagFile/tdata/sampletfr
new file mode 100644
index 00000000..92e086f6
--- /dev/null
+++ b/cpan/dist/AsciiDB-TagFile/tdata/sampletfr
@@ -0,0 +1,3 @@
+[a]: Record 1
+[b]: Record 2
+[c]: Record 3