File Coverage

blib/lib/Search/Fulltext/SQLite.pm
Criterion Covered Total %
statement 51 54 94.4
branch 5 8 62.5
condition n/a
subroutine 11 11 100.0
pod 0 2 0.0
total 67 75 89.3


line stmt bran cond sub pod time code
1             package Search::Fulltext::SQLite;
2 5     5   33122 use strict;
  5         9  
  5         155  
3 5     5   25 use warnings;
  5         9  
  5         106  
4 5     5   25 use utf8;
  5         9  
  5         26  
5              
6 5     5   11215 use DBI;
  5         93781  
  5         396  
7 5     5   59 use Carp;
  5         9  
  5         509  
8              
9             use constant {
10 5         3461 TABLE => 'fts4table',
11             CONTENT_COL => 'content',
12             DOCID_COL => 'docid',
13 5     5   26 };
  5         8  
14              
15             sub _make_dbh {
16 9     9   23 my $dbfile = shift;
17 9         188 DBI->connect(
18             "dbi:SQLite:dbname=$dbfile", "", "",
19             {
20             RaiseError => 1,
21             AutoCommit => 1,
22             sqlite_unicode => 1,
23             }
24             );
25             }
26              
27             sub new {
28 9     9 0 2236 my ($class, @args) = @_;
29 9 100       55 my %args = ref $args[0] eq 'HASH' ? %{$args[0]} : @args;
  3         14  
30              
31 9 50       129 unless ($args{docs}) { croak "'docs' is required for creating new instance of $class" }
  0         0  
32 9 50       44 unless ($args{dbfile}) { croak "'dbfile' is required for creating new instance of $class" }
  0         0  
33 9 50       54 unless ($args{tokenizer}) { croak "'tokenizer' is required for creating new instance of $class" }
  0         0  
34              
35 9         46 my $self = bless {
36             dbh => _make_dbh($args{dbfile}),
37             %args
38             }, $class;
39 9         55743 $self->_make_fts4_index;
40 8         96 $self;
41             }
42              
43             sub _make_fts4_index {
44 9     9   21 my $self = shift;
45 9         37 my $dbh = $self->{dbh};
46 9         20 my $tokenizer = $self->{tokenizer};
47              
48 9         72 $dbh->do("DROP TABLE IF EXISTS " . TABLE);
49 9         2524 $dbh->do("CREATE VIRTUAL TABLE " . TABLE . " USING fts4(" . CONTENT_COL . ", tokenize=$tokenizer)");
50              
51 8         65539 $dbh->begin_work;
52 8         249 my $sth = $dbh->prepare("INSERT INTO " . TABLE . " (" . CONTENT_COL . ") VALUES (?)");
53 8         595 $sth->execute($_) for @{$self->{docs}};
  8         2989  
54 8         52 $sth->finish;
55 8         13284 $dbh->commit;
56             }
57              
58             sub search_docids {
59 14     14 0 22 my ($self, $query) = @_;
60 14         27 my $dbh = $self->{dbh};
61 14         91 my $sth = $dbh->prepare("SELECT " . DOCID_COL . "-1 FROM " . TABLE . " WHERE " . CONTENT_COL . " MATCH ?");
62 14         2093 $sth->execute($query);
63 14         34 my @docids = ();
64 14         249 while (my @row = $sth->fetchrow_array) { push @docids, $row[0] }
  22         163  
65 14         39 $sth->finish;
66 14         257 \@docids;
67             }
68              
69             sub DESTROY {
70 9     9   11765 my $self = shift;
71 9         1415 $self->{dbh}->disconnect;
72             }
73              
74             1;