Bug 142119 - Support SphinxSE (needs MySQL support)

git-svn-id: svn://svn.office.custis.ru/3rdparty/bugzilla.org/trunk@1893 6955db30-a419-402b-8a0d-67ecbb4d7f56
master
vfilippov 2013-12-24 11:38:12 +00:00
parent 0ac500667f
commit 532330b915
4 changed files with 50 additions and 11 deletions

View File

@ -107,6 +107,7 @@ sub connect_sphinx
my $host = $lc->{sphinx_host};
my $port = $lc->{sphinx_port};
my $sock = $lc->{sphinx_sock};
$host = '' if $sock;
my $dsn = "dbi:mysql:host=$host;database=none";
$dsn .= ";port=$port" if $port;
@ -116,6 +117,7 @@ sub connect_sphinx
mysql_enable_utf8 => 1,
# Needs to be explicitly specified for command-line processes.
mysql_auto_reconnect => 1,
raise_error => 0,
});
$sphinx->do("SET NAMES utf8");

View File

@ -3287,21 +3287,40 @@ sub _populate_bugs_fulltext
$bug_ids = undef if $bug_ids && !@$bug_ids;
my $dbh = Bugzilla->dbh;
# These vary between different fulltext search engines (MySQL, Sphinx)
my ($table, $limit1, $id_field, $quote, $sph) = ('bugs_fulltext', $dbh->sql_limit(1), 'bug_id', 'quote_fulltext', $dbh);
my ($table, $id_field, $quote, $sph) = ('bugs_fulltext', 'bug_id', 'quote_fulltext', $dbh);
my $nonempty;
if (Bugzilla->localconfig->{sphinx_index})
{
$sph = Bugzilla->dbh_sphinx;
$limit1 = 'LIMIT 1';
$table = Bugzilla->localconfig->{sphinx_index};
$id_field = 'id';
$quote = 'quote';
# Sphinx can't do fullscan for index without attributes,
# so we check if the index is empty by trying to insert a MAX_INT id
$sph->{PrintError} = 0;
$nonempty = !$sph->do("INSERT INTO $table (id) VALUES (-1)");
$sph->{PrintError} = 1;
if (my $conn = Bugzilla->localconfig->{sphinxse_port})
{
$conn = "sphinx://".Bugzilla->localconfig->{sphinx_host}.':'.Bugzilla->localconfig->{sphinxse_port}.'/'.$table;
$dbh->do("DROP TABLE IF EXISTS bugs_fulltext_sphinx");
$dbh->do("CREATE TABLE bugs_fulltext_sphinx (".
"id BIGINT NOT NULL, ".
"`weight` INT NOT NULL, ".
"`query` VARCHAR(3072) NOT NULL, ".
"INDEX(`query`)".
") ENGINE=SPHINX CONNECTION='$conn'");
}
}
else
{
$nonempty = $sph->selectrow_array("SELECT $id_field FROM $table ".$dbh->sql_limit(1));
}
my $fulltext = $sph->selectrow_array("SELECT $id_field FROM $table $limit1");
my ($datasize, $time) = (0, time);
my ($lastdata, $lasttime) = ($datasize, $time);
# We only populate the table if it's empty or if we've been given a
# set of bug ids.
if ($bug_ids || !$fulltext)
if ($bug_ids || !$nonempty)
{
# ... and if there are bugs in the bugs table.
$bug_ids ||= $dbh->selectcol_arrayref("SELECT bug_id FROM bugs");

View File

@ -174,6 +174,14 @@ EOT
default => '',
desc => "# Sphinx UNIX socket (listening MySQL protocol)\n",
},
{
name => 'sphinxse_port',
default => 0,
desc => <<EOT
# To use MySQL Sphinx Storage Engine (bundled with MariaDB), specify
# a non-zero port on which Sphinx is listening for non-SphinxQL requests
EOT
},
{
name => 'db_check',
default => 1,

View File

@ -2135,14 +2135,12 @@ sub _content_matches
{
my $self = shift;
my $dbh = Bugzilla->dbh;
my $table = "bugs_fulltext_".$self->{sequence};
my $text = $self->{value};
if (my $index = Bugzilla->localconfig->{sphinx_index})
{
# Using Sphinx
my $sph = Bugzilla->dbh_sphinx;
my $query = 'SELECT id, WEIGHT() `weight` FROM '.$index.
' WHERE MATCH(?) LIMIT 1000 OPTION field_weights=(short_desc=5, comments=1, comments_private=1)';
# Escape search query
my $pattern_part = '\[\]:\(\)!@~&\/^$';
$text = trim($text);
@ -2154,6 +2152,21 @@ sub _content_matches
}
$text =~ s/((?:^|[^\\])(?:\\\\)*)([$pattern_part])/$1\\$2/gs;
$text = ($self->{user}->is_insider ? '@(short_desc,comments,comments_private) ' : '@(short_desc,comments) ') . $text;
if (Bugzilla->localconfig->{sphinxse_port})
{
# Using SphinxSE
$text =~ s/;/\\\\;/gso;
$self->{term} = {
table => "bugs_fulltext_sphinx $table",
where => "$table.query=".$dbh->quote("$text;mode=extended;limit=1000;fieldweights=short_desc,5,comments,1,comments_private,1"),
bugid_field => "$table.id",
};
return;
}
# Using SphinxQL
my $sph = Bugzilla->dbh_sphinx;
my $query = 'SELECT `id`, WEIGHT() `weight` FROM '.$index.
' WHERE MATCH(?) LIMIT 1000 OPTION field_weights=(short_desc=5, comments=1, comments_private=1)';
my $ids = $sph->selectall_arrayref($query, undef, $text) || [];
$self->{term} = {
term => @$ids ? 'bugs.bug_id IN ('.join(', ', map { $_->[0] } @$ids).')' : '1=0',
@ -2167,9 +2180,6 @@ sub _content_matches
return;
}
my $dbh = Bugzilla->dbh;
my $table = "bugs_fulltext_".$self->{sequence};
# Create search terms to add to the SELECT and WHERE clauses.
# These are (search term, rank term, search term, rank term, ...)
my @terms = (