File Coverage

blib/lib/File/Operator.pm
Criterion Covered Total %
statement 54 144 37.5
branch 9 40 22.5
condition n/a
subroutine 8 14 57.1
pod 0 8 0.0
total 71 206 34.4


line stmt bran cond sub pod time code
1             package File::Operator;
2              
3 1     1   708 use strict;
  1         3  
  1         44  
4 1     1   6 use vars qw($VERSION);
  1         2  
  1         52  
5 1     1   5 use Fcntl qw(:flock);
  1         29  
  1         2396  
6              
7             $VERSION = '1.00';
8              
9             sub new {
10 1     1 0 38 my $class=shift;
11 1         4 my %arg=@_;
12             # по умолчанию работаем с текущим каталогом скрипта
13 1 50       7 $arg{'-path'}="." unless(exists($arg{'-path'}));
14 1 50       5 die "Incorrect file name" unless(defined($arg{'-file'}));
15             # если файл не существует, то создаем новый файл
16 1 50       35 unless(-e "$arg{'-path'}/$arg{'-file'}") {
17 1 50       109 open(NEW,">","$arg{'-path'}/$arg{'-file'}") || die "Can't create file: $!";
18 1         178 close(NEW);
19             }
20 1         3 my $fh;
21             # блокируем через семафор (шароварная)
22 1         6 _block($arg{'-path'},LOCK_SH);
23             # оживляем дескриптор $fh
24 1 50       37 open($fh,"<","$arg{'-path'}/$arg{'-file'}") || die "Can't open file: $!";
25 1         7 my $self={
26             file => $fh, # дескриптор файла
27             fpath => $arg{'-path'}, # путь к файлу
28             nfile => $arg{'-file'},# имя файла
29             };
30 1         5 bless($self,$class);
31 1         5 return $self;
32             }
33              
34             sub renew {# обновление дескриптора после закрытия
35 0     0 0 0 my $class=shift;
36 0         0 my $package=__PACKAGE__;
37 0 0       0 die "Bad file name" unless(-e "$class->{'fpath'}/$class->{'nfile'}");
38 0         0 my $fh;
39             # блокируем через семафор
40 0         0 _block($class->{'fpath'},LOCK_SH);
41             # оживляем дескриптор $fh
42 0 0       0 open($fh,"<","$class->{'fpath'}/$class->{'nfile'}") || die "Can't open file: $!";
43 0         0 my $self={
44             file => $fh, # дескриптор файла
45             fpath => $class->{'fpath'}, # путь к файлу
46             nfile => $class->{'nfile'},# имя файла
47             };
48 0         0 bless($self,$package);
49 0         0 return $self;
50             }
51              
52             sub FetchFileToHash {# без аргументов
53 0     0 0 0 my $obj=shift;
54 0         0 my $fh=$obj->{'file'};# сохраняем дескриптор файла в переменной
55 0         0 my %hash=();
56             # считываем файл
57 0         0 seek($fh,0,0);# перемещаемся к началу файла
58 0         0 while(defined(my $line=<$fh>)) {
59 0         0 chomp($line);
60 0         0 my($id,@REC)=split(/\|/,$line);
61 0         0 $hash{$id}=\@REC;
62             }
63 0         0 return %hash;
64             }
65              
66             sub FetchRecord {# аргумент -id
67 0     0 0 0 my $obj=shift;
68 0         0 my $fh=$obj->{'file'};# сохраняем дескриптор файла в переменной
69 0         0 my %param=@_;# принимаем аргументы в хэш
70             # считываем файл в поисках нужного id
71 0         0 seek($fh,0,0);
72 0         0 while(defined(my $line=<$fh>)) {
73 0         0 chomp($line);
74 0         0 my($id,@REC)=split(/\|/,$line);
75 0 0       0 return \@REC if($id eq $param{'-id'});
76             }
77 0         0 my @ERR=();
78 0         0 push(@ERR,"record by id $param{'-id'} not found");
79 0         0 return \@ERR;
80             }
81              
82             sub FetchLastRecords {# аргументы -num (необязательный -raw)
83 0     0 0 0 my $obj=shift;
84 0         0 my $fh=$obj->{'file'};# сохраняем дескриптор файла в переменной
85 0         0 my %param=@_;# принимаем аргументы в хэш
86 0 0       0 $param{'-num'}=1 unless(exists($param{'-num'}));# по умолчанию 1 запись
87 0         0 seek($fh,0,0);
88             # считываем файл в поисках нужного id
89 0         0 my @LIST=<$fh>;# считываем файл в массив
90             # проверяем не превышает ли запрос кол-во элементов в массиве
91 0 0       0 $param{'-num'}=$param{'-num'}>@LIST ? @LIST : $param{'-num'};
92 0         0 @LIST=splice(@LIST,-$param{'-num'});# удаляем N последних элементов и присваиваем их массиву @LIST
93 0 0       0 return \@LIST if exists($param{'-raw'});# выходим здесь - если нужен не форматированный вывод
94             # отсекаем перевод строк и разделитель |
95 0         0 my @LIST_CUT=();
96 0         0 foreach (@LIST) {
97 0         0 chomp;# удаляем перевод строки
98 0         0 s/\|/ /g;# заменяем разделитель | на пробел
99 0         0 push(@LIST_CUT,$_);
100             }
101 0         0 return \@LIST_CUT;
102             }
103              
104             sub WriteRecord { # аргументы -id =>(необязательный) -record =>сыслка на массив
105 1     1 0 12 my $obj=shift;
106 1         7 my $fh=$obj->{'file'};# сохраняем дескриптор файла в переменной
107             #$obj->{'fpath'};# путь до файла
108             #$obj->{'nfile'}; # имя файла
109 1         4 my $File="$obj->{'fpath'}/$obj->{'nfile'}";# для удобства сохраняем данные в переменной
110 1         4 my %param=@_;# принимаем аргументы в хэш
111 1 50       18 $param{'-id'}=time() unless(exists($param{'-id'}));# если -id не передан, сами генерим его
112 1         3 my %hash=();
113 1         2 my $random=time();
114 1         42 my $name=int(rand($random));
115 1         5 $name=$random . $name .".tmp";
116             # открываем временный файл
117 1 50       90 open(TMP,">","$obj->{'fpath'}/$name") || die "can't create temp file: $!";
118             # записываем весь файл $fh во временный
119 1         7 seek($fh,0,0);
120 1         30 while(defined(my $line=<$fh>)) {
121 0         0 print TMP $line;
122             }
123             # дописываем в конец новую запись
124 1         5 $param{'-id'}=~s/\|//g;# удяляем символы |
125 1         15 print TMP "$param{'-id'}|";
126 1         3 foreach (@{$param{'-record'}}) {
  1         4  
127 4         7 s/\|/ /g;# заменяем все символы | на пробелы
128 4         11 print TMP "$_|";
129             }
130 1         3 print TMP "\n";
131 1         52 close(TMP);
132 1         10 close($fh);
133 1         69 my $test=rename($File,"$File.orig");
134 1         41 $test=rename("$obj->{'fpath'}/$name",$File);
135 1 50       10 return $param{'-id'} if $test==1;
136 0         0 return 0;
137             }
138              
139             sub EditRecord { # аргументы -id -record =>сыслка на массив
140 0     0 0 0 my $obj=shift;
141 0         0 my $fh=$obj->{'file'};# сохраняем дескриптор файла в переменной
142 0         0 my $File="$obj->{'fpath'}/$obj->{'nfile'}";# для удобства сохраняем данные в переменной
143 0         0 my %param=@_;# принимаем аргументы в хэш
144 0         0 my %hash=();
145 0         0 my $random=time();
146 0         0 my $name=int(rand($random));
147 0         0 $name=$random . $name .".tmp";
148             # открываем временный файл
149 0 0       0 open(TMP,">","$obj->{'fpath'}/$name") || die "can't create temp file: $!";
150             # считываем файл
151 0         0 seek($fh,0,0);
152 0         0 while(defined(my $line=<$fh>)) {
153 0         0 my($id,@REC)=split(/\|/,$line);
154 0 0       0 print TMP $line if($id ne $param{'-id'});
155 0 0       0 if($id eq $param{'-id'}) {
156 0         0 print TMP "$param{'-id'}|";
157 0         0 foreach (@{$param{'-record'}}) {
  0         0  
158 0         0 s/\|/ /g;# заменяем все символы | на пробелы
159 0         0 print TMP "$_|";
160             }
161 0         0 print TMP "\n";
162             }
163             }
164 0         0 close(TMP);
165 0         0 close($fh);
166 0         0 my $test=rename($File,"$File.orig");
167 0         0 $test=rename("$obj->{'fpath'}/$name",$File);
168 0         0 return $test;
169             }
170              
171             sub DeleteRecord { # аргументы -id
172 0     0 0 0 my $obj=shift;
173 0         0 my $fh=$obj->{'file'};# сохраняем дескриптор файла в переменной
174 0         0 my $File="$obj->{'fpath'}/$obj->{'nfile'}";# для удобства сохраняем данные в переменной
175 0         0 my %param=@_;# принимаем аргументы в хэш
176 0         0 my %hash=();
177 0         0 my $random=time();
178 0         0 my $name=int(rand($random));
179 0         0 $name=$random . $name .".tmp";
180             # открываем временный файл
181 0 0       0 open(TMP,">","$obj->{'fpath'}/$name") || die "can't create temp file: $!";
182             # считываем файл
183 0         0 seek($fh,0,0);
184 0         0 while(defined(my $line=<$fh>)) {
185 0         0 my($id,@REC)=split(/\|/,$line);
186 0 0       0 next if($id eq $param{'-id'});# пропускаем при копировании запись к удалению
187 0         0 print TMP $line;
188             }
189 0         0 close(TMP);
190 0         0 close($fh);
191 0         0 my $test=rename($File,"$File.orig");
192 0         0 $test=rename("$obj->{'fpath'}/$name",$File);
193 0         0 return $test;
194             }
195              
196             sub DESTROY {
197 1     1   177 my $self=shift;
198 1         4 close($self->{'file'});
199 1         8 _unblock();
200             }
201              
202             ## private methods ########
203             sub _block {
204 1     1   3 my($path,$type)=@_;
205 1 50       68 open(SEM,">","$path/.keep_me") || die "Can't create lock file";
206 1         9 my $lock=flock(SEM,$type);
207 1         4 return $lock;
208             }
209              
210             sub _unblock {
211 1     1   126 close(SEM)
212             }
213              
214             1;
215              
216             __END__