File Coverage

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


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