File Coverage

blib/lib/AnyData/Storage/TiedHash.pm
Criterion Covered Total %
statement 94 102 92.1
branch 32 52 61.5
condition 4 6 66.6
subroutine 11 13 84.6
pod 0 3 0.0
total 141 176 80.1


line stmt bran cond sub pod time code
1             ######################################
2             package AnyData::Storage::TiedHash;
3             ######################################
4 6     6   29 use strict;
  6         7  
  6         181  
5 6     6   25 use warnings;
  6         7  
  6         6150  
6              
7             sub FETCH {
8 22     22   78 my($self,$key) = @_;
9 22         18 my(@rows,$row,$found);
10 22 100       66 return $self->{ad}->col_names if($key eq '__colnames');
11 16 50       33 return $self->{ad}->key_col if $key eq '__key';
12 16         19 my $ismultiple = ref $key;
13 16         42 $self->{ad}->seek_first_record;
14 16         60 while ($row = $self->{ad}->fetchrow_hashref) {
15 34 100       93 if ( $self->{ad}->match($row,$key) ) {
16 16         18 $found++;
17 16 50       35 last unless $ismultiple;
18 0         0 push @rows, $row;
19             }
20             }
21 16 50       28 return \@rows if $ismultiple;
22 16 50       100 return $found ? $row : undef;
23             }
24              
25             sub TIEHASH {
26 10     10   13 my $class = shift;
27 10         17 my $ad = shift;
28 10   50     26 my $perms = shift || 'r';
29 10   50     38 my $records = shift || {};
30 10         55 my $self = {
31             INDEX => 0,
32             RECORDS => $records,
33             ad => $ad,
34             del_marker => "\0",
35             needs_packing => 0,
36             PERMS => $perms,
37             };
38 10         37 return bless $self, $class;
39             }
40              
41             sub verify_columns {
42 36     36 0 34 my $col_names = shift;
43 36         59 my $val = shift;
44 36         46 my %is_col = map {$_ => 1} @$col_names;
  108         171  
45 36         54 my $errstr = "ERROR: XXX is not a column in the table!\n";
46 36 50       93 $errstr .= scalar @$col_names
47             ? " columns are: " . join "~",@$col_names,"\n"
48             : " couldn't find any column names\n";
49 36 50       59 if (ref $val eq 'HASH') {
50 36         80 for (keys %$val) {
51 66         124 $errstr =~ s/XXX/$_/;
52 66 50       204 die $errstr if !$is_col{$_};
53             }
54             }
55             else {
56 0         0 $errstr =~ s/XXX/$val/;
57 0 0       0 $is_col{$val}
58             ? return 1
59             : die $errstr;
60             }
61             }
62              
63             sub STORE {
64 36     36   258 my($self,$key,$value) = @_;
65             #my @c = caller 1;
66 36 50       96 $self->{errstr} = "Can't store: file is opened in 'r' read-only mode!"
67             if $self->{PERMS} eq 'r';
68 36 50       62 return undef if $self->{errstr};
69 36         32 my @colnames = @{ $self->{ad}->col_names };
  36         72  
70 36         62 verify_columns(\@colnames,$value);
71 36 100       95 return $self->{ad}->update_multiple_rows($key,$value)
72             if ref $key eq 'HASH';
73 30         74 $self->{ad}->seek(0,2);
74 30         24 my @newrow;
75 30         52 for my $i(0..$#colnames) {
76 90         115 $newrow[$i] = $value->{$colnames[$i]};
77 90 100       165 next if defined $newrow[$i];
78 30 50       67 $newrow[$i] = $key if $colnames[$i] eq $self->{ad}->key_col;
79 30 50       67 $newrow[$i] = undef unless $newrow[$i];
80             }
81 30         75 return $self->{ad}->push_row(@newrow);
82             }
83              
84             sub DELETE {
85 6     6   40 my($self,$key)=@_;
86 6 50       16 die "Can't delete: file is opened in 'r' read-only mode!"
87             if $self->{PERMS} eq 'r';
88 6         6 my $row;
89             my $count;
90 6 50       12 return $self->{ad}->delete_multiple_rows($key) if ref $key;
91 6 50       14 if ($row = $self->FETCH($key) ) {
92 6         14 $self->{ad}->delete_single_row;
93 6         6 $self->{needs_packing}++;
94 6         6 $count++;
95             }
96             #return $row;
97 6         16 return $count;
98             }
99              
100             sub EXISTS {
101 0     0   0 my($self,$key)=@_;
102 0         0 return $self->FETCH($key);
103             }
104              
105             sub FIRSTKEY {
106 8     8   10 my $self = shift;
107 8         39 $self->{ad}->seek_first_record();
108 8         19 my $found =0;
109 8         9 my $row;
110 8         26 while (!$found) {
111 8 50       26 $row = $self->{ad}->fetchrow_hashref() or last;
112 8         11 $found++;
113 8         11 last;
114             }
115 8 50       85 return $found ? $row : undef;
116             }
117              
118             sub NEXTKEY {
119 30     30   164 my $self = shift;
120 30         27 my $row;
121 30         29 my $lastcol=0;
122 30         23 my $found=0;
123 30         62 while (!$found) {
124 30 100       66 $row = $self->{ad}->fetchrow_hashref() or last;
125 23         25 $found++;
126 23         27 last;
127             }
128 30 100       96 return $found ? $row : undef;
129             }
130              
131             sub adRows {
132 10     10 0 14 my $self = shift;
133 10         13 my $key = shift;
134 10         11 my $count=0;
135 10         50 $self->{ad}->seek_first_record;
136 10 50       47 if (!$key) {
137 0         0 while (my $row = $self->{ad}->fetchrow_hashref) {
138 0         0 $count++;
139             }
140             }
141             else {
142 10         32 while (my $row = $self->{ad}->fetchrow_hashref) {
143 43 50       93 $count++ if $self->{ad}->match($row,$key);
144             }
145             }
146 10         54 return $count;
147             }
148              
149             sub adColumn {
150 12     12 0 16 my($self,$column,$flags)=@_;
151 12   100     37 $flags ||= '';
152 12         17 my @results=();
153 12         29 $self->{ad}->seek_first_record;
154 12         28 while (my $row = $self->{ad}->fetchrow_hashref) {
155 48         147 push @results, $row->{$column}
156             }
157 12         13 my %is_member;
158 12 100       55 @results = grep(!$is_member{$_}++, @results) if $flags; $flags =~ /u/i;
  12         22  
159             # @results = sort @results if $flags =~ /a/i;
160             # @results = reverse sort @results if $flags =~ /d/i;
161 12         53 return @results;
162             }
163              
164 0     0     sub DESTROY {
165             #my $self=shift;
166             #undef $self->{ad};
167             #print "HASH DESTROYED";
168             }
169             ##############################
170             # END OF AnyData::Tiedhash
171             ##############################
172             1;