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   33 use strict;
  6         12  
  6         186  
5 6     6   31 use warnings;
  6         11  
  6         7918  
6              
7             sub FETCH {
8 22     22   82 my($self,$key) = @_;
9 22         23 my(@rows,$row,$found);
10 22 100       64 return $self->{ad}->col_names if($key eq '__colnames');
11 16 50       34 return $self->{ad}->key_col if $key eq '__key';
12 16         24 my $ismultiple = ref $key;
13 16         49 $self->{ad}->seek_first_record;
14 16         125 while ($row = $self->{ad}->fetchrow_hashref) {
15 34 100       128 if ( $self->{ad}->match($row,$key) ) {
16 16         23 $found++;
17 16 50       38 last unless $ismultiple;
18 0         0 push @rows, $row;
19             }
20             }
21 16 50       44 return \@rows if $ismultiple;
22 16 50       97 return $found ? $row : undef;
23             }
24              
25             sub TIEHASH {
26 10     10   21 my $class = shift;
27 10         16 my $ad = shift;
28 10   50     40 my $perms = shift || 'r';
29 10   50     62 my $records = shift || {};
30 10         60 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         45 return bless $self, $class;
39             }
40              
41             sub verify_columns {
42 36     36 0 46 my $col_names = shift;
43 36         38 my $val = shift;
44 36         45 my %is_col = map {$_ => 1} @$col_names;
  108         225  
45 36         61 my $errstr = "ERROR: XXX is not a column in the table!\n";
46 36 50       112 $errstr .= scalar @$col_names
47             ? " columns are: " . join "~",@$col_names,"\n"
48             : " couldn't find any column names\n";
49 36 50       74 if (ref $val eq 'HASH') {
50 36         92 for (keys %$val) {
51 66         138 $errstr =~ s/XXX/$_/;
52 66 50       235 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   292 my($self,$key,$value) = @_;
65             #my @c = caller 1;
66 36 50       86 $self->{errstr} = "Can't store: file is opened in 'r' read-only mode!"
67             if $self->{PERMS} eq 'r';
68 36 50       65 return undef if $self->{errstr};
69 36         42 my @colnames = @{ $self->{ad}->col_names };
  36         97  
70 36         75 verify_columns(\@colnames,$value);
71 36 100       145 return $self->{ad}->update_multiple_rows($key,$value)
72             if ref $key eq 'HASH';
73 30         90 $self->{ad}->seek(0,2);
74 30         33 my @newrow;
75 30         59 for my $i(0..$#colnames) {
76 90         140 $newrow[$i] = $value->{$colnames[$i]};
77 90 100       202 next if defined $newrow[$i];
78 30 50       95 $newrow[$i] = $key if $colnames[$i] eq $self->{ad}->key_col;
79 30 50       76 $newrow[$i] = undef unless $newrow[$i];
80             }
81 30         107 return $self->{ad}->push_row(@newrow);
82             }
83              
84             sub DELETE {
85 6     6   44 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         9 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         17 $self->{ad}->delete_single_row;
93 6         10 $self->{needs_packing}++;
94 6         7 $count++;
95             }
96             #return $row;
97 6         29 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   15 my $self = shift;
107 8         33 $self->{ad}->seek_first_record();
108 8         22 my $found =0;
109 8         12 my $row;
110 8         27 while (!$found) {
111 8 50       34 $row = $self->{ad}->fetchrow_hashref() or last;
112 8         12 $found++;
113 8         15 last;
114             }
115 8 50       112 return $found ? $row : undef;
116             }
117              
118             sub NEXTKEY {
119 30     30   154 my $self = shift;
120 30         35 my $row;
121 30         32 my $lastcol=0;
122 30         27 my $found=0;
123 30         64 while (!$found) {
124 30 100       81 $row = $self->{ad}->fetchrow_hashref() or last;
125 23         30 $found++;
126 23         29 last;
127             }
128 30 100       115 return $found ? $row : undef;
129             }
130              
131             sub adRows {
132 10     10 0 19 my $self = shift;
133 10         16 my $key = shift;
134 10         14 my $count=0;
135 10         62 $self->{ad}->seek_first_record;
136 10 50       54 if (!$key) {
137 0         0 while (my $row = $self->{ad}->fetchrow_hashref) {
138 0         0 $count++;
139             }
140             }
141             else {
142 10         49 while (my $row = $self->{ad}->fetchrow_hashref) {
143 43 50       139 $count++ if $self->{ad}->match($row,$key);
144             }
145             }
146 10         67 return $count;
147             }
148              
149             sub adColumn {
150 12     12 0 19 my($self,$column,$flags)=@_;
151 12   100     39 $flags ||= '';
152 12         17 my @results=();
153 12         40 $self->{ad}->seek_first_record;
154 12         38 while (my $row = $self->{ad}->fetchrow_hashref) {
155 48         216 push @results, $row->{$column}
156             }
157 12         14 my %is_member;
158 12 100       61 @results = grep(!$is_member{$_}++, @results) if $flags; $flags =~ /u/i;
  12         23  
159             # @results = sort @results if $flags =~ /a/i;
160             # @results = reverse sort @results if $flags =~ /d/i;
161 12         64 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;