File Coverage

blib/lib/MyConText/Phrase.pm
Criterion Covered Total %
statement 9 103 8.7
branch 0 26 0.0
condition 0 6 0.0
subroutine 3 8 37.5
pod 0 4 0.0
total 12 147 8.1


line stmt bran cond sub pod time code
1              
2             package MyConText::Phrase;
3 1     1   596 use strict;
  1         2  
  1         30  
4 1     1   5 use MyConText::Column;
  1         1  
  1         20  
5 1     1   3 use vars qw! @ISA !;
  1         3  
  1         991  
6             @ISA = qw! MyConText::Column !;
7              
8             # Open in the backend just sets the object
9             sub open {
10 0     0 0   my ($class, $ctx) = @_;
11 0           return bless { 'ctx' => $ctx }, $class;
12             }
13             # Create creates the table(s) according to the parameters
14             sub _create_tables {
15 0     0     my ($class, $ctx) = @_;
16 0           my $COUNT_FIELD = '';
17 0           my $CREATE_DATA = <
18             create table $ctx->{'data_table'} (
19             word_id $MyConText::BITS_TO_INT{$ctx->{'word_id_bits'}} unsigned not null,
20             doc_id $MyConText::BITS_TO_INT{$ctx->{'doc_id_bits'}} unsigned not null,
21             idx longblob default '' not null,
22             index (word_id),
23             index (doc_id)
24             )
25             EOF
26              
27 0 0         $ctx->{'word_id_table'} = $ctx->{'table'}.'_words'
28             unless defined $ctx->{'word_id_table'};
29            
30            
31 0           my $CREATE_WORD_ID = <
32             create table $ctx->{'word_id_table'} (
33             word varchar($ctx->{'word_length'}) binary
34             default '' not null,
35             id $MyConText::BITS_TO_INT{$ctx->{'word_id_bits'}} unsigned not null auto_increment,
36             primary key (id),
37             unique (word)
38             )
39             EOF
40              
41 0           my $dbh = $ctx->{'dbh'};
42 0 0         $dbh->do($CREATE_DATA) or return $dbh->errstr;
43 0           push @{$ctx->{'created_tables'}}, $ctx->{'data_table'};
  0            
44 0 0         $dbh->do($CREATE_WORD_ID) or return $dbh->errstr;
45 0           push @{$ctx->{'created_tables'}}, $ctx->{'word_id_table'};
  0            
46 0           return;
47             }
48             sub add_document {
49 0     0 0   my ($self, $id, $words) = @_;
50             # here the value in the %$words hash is an array of word
51             # positions
52 0           my $ctx = $self->{'ctx'};
53 0           my $dbh = $ctx->{'dbh'};
54 0           my $data_table = $ctx->{'data_table'};
55 0           my $word_id_table = $ctx->{'word_id_table'};
56 0 0         if (not defined $self->{'insert_wordid_sth'}) {
57 0           $self->{'insert_wordid_sth'} = $dbh->prepare("
58             insert into $word_id_table (word) values (?)
59             ");
60 0           $self->{'insert_wordid_sth'}->{'PrintError'} = 0;
61 0           $self->{'insert_wordid_sth'}->{'RaiseError'} = 0;
62             }
63 0           my $insert_wordid_sth = $self->{'insert_wordid_sth'};
64              
65 0           my $count_bits = $ctx->{'count_bits'};
66 0 0         my $insert_worddoc_sth = ( defined $self->{'insert_worddoc_sth'}
67             ? $self->{'insert_worddoc_sth'}
68             : $self->{'insert_worddoc_sth'} =
69             $dbh->prepare("
70             insert into $data_table
71             select id, ?, ? from $word_id_table
72             where word = ?")
73             );
74            
75 0           my $packstring = $MyConText::BITS_TO_PACK{$ctx->{'position_bits'}};
76              
77 0           my $num_words = 0;
78 0           for my $word ( keys %$words ) {
79 0           $insert_wordid_sth->execute($word);
80 0           my $values = pack $packstring.'*', @{$words->{$word}};
  0            
81 0           $insert_worddoc_sth->execute($id, $values, $word);
82 0           $num_words++;
83             }
84 0           return $num_words;
85             }
86             sub update_document {
87 0     0 0   my ($self, $id, $words) = @_;
88 0           my $ctx = $self->{'ctx'};
89 0           my $dbh = $ctx->{'dbh'};
90 0           my $data_table = $ctx->{'data_table'};
91 0           $dbh->do("delete from $data_table where doc_id = ?", {}, $id);
92              
93 0           $self->add_document($id, $words);
94             }
95             sub contains_hashref {
96 0     0 0   my $self = shift;
97 0           my $ctx = $self->{'ctx'};
98 0           my $dbh = $ctx->{'dbh'};
99 0           my $data_table = $ctx->{'data_table'};
100 0           my $word_id_table = $ctx->{'word_id_table'};
101              
102 0           my $packstring = $MyConText::BITS_TO_PACK{$ctx->{'position_bits'}};
103              
104              
105 0           my $SQL = <<"EOF";
106             select doc_id, idx
107             from $data_table, $word_id_table
108             where word like ?
109             and id = word_id
110             order by doc_id
111             EOF
112 0           my @sths;
113 0           for (my $i = 0; $i < @_; $i++) {
114 0           $sths[$i] = $dbh->prepare($SQL);
115 0           $sths[$i]->execute($_[$i]);
116             }
117              
118 0           my (@overflow, @finished) = ((), ());
119 0           my $finished_count = 0;
120              
121 0           my $out = {};
122              
123 0           my $i = 0;
124 0           my $actdoc;
125 0           my (%word_out, %doc_out) = ((), ());
126              
127             # budeme cyklit; promenna $i rika, ktere slovo prave
128             # zpracovavame
129 0           while ($finished_count < @_) {
130 0           my ($doc, $data);
131             # pokud mame neco ulozeno z predchoziho behu, nasosneme
132 0 0         if (defined $overflow[$i]) {
133 0           ($doc, $data) = @{$overflow[$i]};
  0            
134 0           $overflow[$i] = undef;
135             }
136             # jinak nacteme z databaze
137             else {
138 0           ($doc, $data) = $sths[$i]->fetchrow_array;
139 0 0         if (not defined $doc) {
140 0 0         $finished_count++ unless defined $finished[$i];
141 0           $finished[$i] = 1;
142             }
143             }
144              
145             # bud jde o dalsi data pro ten samy dokument, nebo jde o
146             # data pro dalsi dokument, nebo pro toto slovo uz zadna
147             # data pro zadny dokument nejsou
148 0 0 0       if (not defined $doc or (defined $actdoc and $doc != $actdoc)) {
      0        
149             # pokud jde o data dalsiho dokumentu, ulozime si je
150 0           $overflow[$i] = [ $doc, $data ];
151 0 0         if ($i == 0) { %doc_out = %word_out; }
  0            
152             else {
153             # protoze prechazime na dalsi slovo,
154             # zjistime, co z doc_out zbylo
155 0           my %tmp;
156 0           for (keys %doc_out) {
157 0 0         if (not exists $word_out{$_+$i}) {
158 0           $tmp{$_} = 1;
159             }
160             }
161 0           for (keys %tmp) { delete $doc_out{$_}; }
  0            
162             }
163            
164             # kazdopadne prejdeme na dalsi slovo (pro ten
165             # samy dokument)
166 0           $i++;
167 0           %word_out = ();
168 0 0         if ($i >= @_) {
169             # pokud uz jsme pro dany dokument prosli
170             # vsechna slova
171 0           $i = 0;
172 0 0         $out->{$actdoc} = scalar(keys %doc_out)
173             if keys %doc_out;
174 0           %doc_out = ();
175 0           $actdoc = undef;
176             }
177              
178 0           next;
179             }
180              
181 0           $actdoc = $doc;
182 0           my @values = unpack $packstring.'*', $data;
183 0           %word_out = (%word_out, map { ( $_ => 1 ) } @values);
  0            
184             }
185            
186 0           for (my $i = 0; $i < @_; $i++) {
187 0           $sths[$i]->finish;
188             }
189            
190 0           $out;
191             }
192              
193             *parse_and_index_data = \&MyConText::parse_and_index_data_list;
194              
195             1;
196