sphinx 0.9.10.2122 → 2.1.1.3711
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -2
- data/.travis.yml +8 -0
- data/CHANGELOG.md +71 -0
- data/Gemfile +4 -0
- data/README.md +221 -0
- data/Rakefile +40 -35
- data/lib/sphinx.rb +3 -8
- data/lib/sphinx/client.rb +223 -70
- data/lib/sphinx/constants.rb +23 -8
- data/lib/sphinx/response.rb +6 -6
- data/lib/sphinx/timeout.rb +1 -2
- data/lib/sphinx/version.rb +3 -0
- data/spec/client_response_spec.rb +77 -64
- data/spec/client_spec.rb +68 -31
- data/spec/client_validations_spec.rb +61 -7
- data/spec/fixtures/requests/default_search.dat +0 -0
- data/spec/fixtures/requests/default_search_index.dat +0 -0
- data/spec/fixtures/requests/excerpt_custom.dat +0 -0
- data/spec/fixtures/requests/excerpt_default.dat +0 -0
- data/spec/fixtures/requests/excerpt_flags.dat +0 -0
- data/spec/fixtures/requests/field_weights.dat +0 -0
- data/spec/fixtures/requests/filter.dat +0 -0
- data/spec/fixtures/requests/filter_exclude.dat +0 -0
- data/spec/fixtures/requests/filter_float_range.dat +0 -0
- data/spec/fixtures/requests/filter_float_range_exclude.dat +0 -0
- data/spec/fixtures/requests/filter_range.dat +0 -0
- data/spec/fixtures/requests/filter_range_exclude.dat +0 -0
- data/spec/fixtures/requests/filter_range_int64.dat +0 -0
- data/spec/fixtures/requests/filter_ranges.dat +0 -0
- data/spec/fixtures/requests/filters.dat +0 -0
- data/spec/fixtures/requests/filters_different.dat +0 -0
- data/spec/fixtures/requests/geo_anchor.dat +0 -0
- data/spec/fixtures/requests/group_by_attr.dat +0 -0
- data/spec/fixtures/requests/group_by_attrpair.dat +0 -0
- data/spec/fixtures/requests/group_by_day.dat +0 -0
- data/spec/fixtures/requests/group_by_day_sort.dat +0 -0
- data/spec/fixtures/requests/group_by_month.dat +0 -0
- data/spec/fixtures/requests/group_by_week.dat +0 -0
- data/spec/fixtures/requests/group_by_year.dat +0 -0
- data/spec/fixtures/requests/group_distinct.dat +0 -0
- data/spec/fixtures/requests/id_range.dat +0 -0
- data/spec/fixtures/requests/id_range64.dat +0 -0
- data/spec/fixtures/requests/index_weights.dat +0 -0
- data/spec/fixtures/requests/keywords.dat +0 -0
- data/spec/fixtures/requests/limits.dat +0 -0
- data/spec/fixtures/requests/limits_cutoff.dat +0 -0
- data/spec/fixtures/requests/limits_max.dat +0 -0
- data/spec/fixtures/requests/limits_max_cutoff.dat +0 -0
- data/spec/fixtures/requests/match_all.dat +0 -0
- data/spec/fixtures/requests/match_any.dat +0 -0
- data/spec/fixtures/requests/match_boolean.dat +0 -0
- data/spec/fixtures/requests/match_extended.dat +0 -0
- data/spec/fixtures/requests/match_extended2.dat +0 -0
- data/spec/fixtures/requests/match_fullscan.dat +0 -0
- data/spec/fixtures/requests/match_phrase.dat +0 -0
- data/spec/fixtures/requests/max_query_time.dat +0 -0
- data/spec/fixtures/requests/miltiple_queries.dat +0 -0
- data/spec/fixtures/requests/outer_select.dat +0 -0
- data/spec/fixtures/requests/override.dat +0 -0
- data/spec/fixtures/{default_search.php → requests/php/default_search.php} +1 -1
- data/spec/fixtures/{default_search_index.php → requests/php/default_search_index.php} +1 -1
- data/spec/fixtures/{excerpt_custom.php → requests/php/excerpt_custom.php} +1 -1
- data/spec/fixtures/{excerpt_default.php → requests/php/excerpt_default.php} +1 -1
- data/spec/fixtures/{excerpt_flags.php → requests/php/excerpt_flags.php} +1 -1
- data/spec/fixtures/{field_weights.php → requests/php/field_weights.php} +1 -1
- data/spec/fixtures/{filter.php → requests/php/filter.php} +1 -1
- data/spec/fixtures/{filter_exclude.php → requests/php/filter_exclude.php} +1 -1
- data/spec/fixtures/{filter_float_range.php → requests/php/filter_float_range.php} +1 -1
- data/spec/fixtures/{filter_float_range_exclude.php → requests/php/filter_float_range_exclude.php} +1 -1
- data/spec/fixtures/{filter_range.php → requests/php/filter_range.php} +1 -1
- data/spec/fixtures/{filter_range_exclude.php → requests/php/filter_range_exclude.php} +1 -1
- data/spec/fixtures/{filter_range_int64.php → requests/php/filter_range_int64.php} +1 -1
- data/spec/fixtures/{filter_ranges.php → requests/php/filter_ranges.php} +1 -1
- data/spec/fixtures/{filters.php → requests/php/filters.php} +1 -1
- data/spec/fixtures/{filters_different.php → requests/php/filters_different.php} +1 -1
- data/spec/fixtures/{geo_anchor.php → requests/php/geo_anchor.php} +1 -1
- data/spec/fixtures/{group_by_attr.php → requests/php/group_by_attr.php} +1 -1
- data/spec/fixtures/{group_by_attrpair.php → requests/php/group_by_attrpair.php} +1 -1
- data/spec/fixtures/{group_by_day.php → requests/php/group_by_day.php} +1 -1
- data/spec/fixtures/{group_by_day_sort.php → requests/php/group_by_day_sort.php} +1 -1
- data/spec/fixtures/{group_by_month.php → requests/php/group_by_month.php} +1 -1
- data/spec/fixtures/{group_by_week.php → requests/php/group_by_week.php} +1 -1
- data/spec/fixtures/{group_by_year.php → requests/php/group_by_year.php} +1 -1
- data/spec/fixtures/{group_distinct.php → requests/php/group_distinct.php} +1 -1
- data/spec/fixtures/{id_range.php → requests/php/id_range.php} +1 -1
- data/spec/fixtures/{id_range64.php → requests/php/id_range64.php} +1 -1
- data/spec/fixtures/{index_weights.php → requests/php/index_weights.php} +1 -1
- data/spec/fixtures/{keywords.php → requests/php/keywords.php} +1 -1
- data/spec/fixtures/{limits.php → requests/php/limits.php} +1 -1
- data/spec/fixtures/{limits_cutoff.php → requests/php/limits_cutoff.php} +1 -1
- data/spec/fixtures/{limits_max.php → requests/php/limits_max.php} +1 -1
- data/spec/fixtures/{limits_max_cutoff.php → requests/php/limits_max_cutoff.php} +1 -1
- data/spec/fixtures/{match_all.php → requests/php/match_all.php} +1 -1
- data/spec/fixtures/{match_any.php → requests/php/match_any.php} +1 -1
- data/spec/fixtures/{match_boolean.php → requests/php/match_boolean.php} +1 -1
- data/spec/fixtures/{match_extended.php → requests/php/match_extended.php} +1 -1
- data/spec/fixtures/{match_extended2.php → requests/php/match_extended2.php} +1 -1
- data/spec/fixtures/{match_fullscan.php → requests/php/match_fullscan.php} +1 -1
- data/spec/fixtures/{match_phrase.php → requests/php/match_phrase.php} +1 -1
- data/spec/fixtures/{max_query_time.php → requests/php/max_query_time.php} +1 -1
- data/spec/fixtures/{miltiple_queries.php → requests/php/miltiple_queries.php} +1 -1
- data/spec/fixtures/requests/php/outer_select.php +9 -0
- data/spec/fixtures/{set_override.php → requests/php/override.php} +1 -1
- data/spec/fixtures/requests/php/query_flag.php +13 -0
- data/spec/fixtures/requests/php/query_flag_after_reset.php +19 -0
- data/spec/fixtures/{ranking_bm25.php → requests/php/ranking_bm25.php} +1 -1
- data/spec/fixtures/requests/php/ranking_expr.php +9 -0
- data/spec/fixtures/{ranking_fieldmask.php → requests/php/ranking_fieldmask.php} +1 -1
- data/spec/fixtures/{ranking_matchany.php → requests/php/ranking_matchany.php} +1 -1
- data/spec/fixtures/{ranking_none.php → requests/php/ranking_none.php} +1 -1
- data/spec/fixtures/{ranking_proximity.php → requests/php/ranking_proximity.php} +1 -1
- data/spec/fixtures/{ranking_proximity_bm25.php → requests/php/ranking_proximity_bm25.php} +1 -1
- data/spec/fixtures/{ranking_sph04.php → requests/php/ranking_sph04.php} +1 -1
- data/spec/fixtures/{ranking_wordcount.php → requests/php/ranking_wordcount.php} +1 -1
- data/spec/fixtures/{retries.php → requests/php/retries.php} +1 -1
- data/spec/fixtures/{retries_delay.php → requests/php/retries_delay.php} +1 -1
- data/spec/fixtures/{select.php → requests/php/select.php} +1 -1
- data/spec/fixtures/{sort_attr_asc.php → requests/php/sort_attr_asc.php} +1 -1
- data/spec/fixtures/{sort_attr_desc.php → requests/php/sort_attr_desc.php} +1 -1
- data/spec/fixtures/{sort_expr.php → requests/php/sort_expr.php} +1 -1
- data/spec/fixtures/{sort_extended.php → requests/php/sort_extended.php} +1 -1
- data/spec/fixtures/{sort_relevance.php → requests/php/sort_relevance.php} +1 -1
- data/spec/fixtures/{sort_time_segments.php → requests/php/sort_time_segments.php} +1 -1
- data/spec/fixtures/{update_attributes.php → requests/php/update_attributes.php} +1 -1
- data/spec/fixtures/{update_attributes_mva.php → requests/php/update_attributes_mva.php} +1 -1
- data/spec/fixtures/{weights.php → requests/php/weights.php} +1 -1
- data/spec/fixtures/requests/query_flag.dat +0 -0
- data/spec/fixtures/requests/query_flag_after_reset.dat +0 -0
- data/spec/fixtures/requests/ranking_bm25.dat +0 -0
- data/spec/fixtures/requests/ranking_expr.dat +0 -0
- data/spec/fixtures/requests/ranking_fieldmask.dat +0 -0
- data/spec/fixtures/requests/ranking_matchany.dat +0 -0
- data/spec/fixtures/requests/ranking_none.dat +0 -0
- data/spec/fixtures/requests/ranking_proximity.dat +0 -0
- data/spec/fixtures/requests/ranking_proximity_bm25.dat +0 -0
- data/spec/fixtures/requests/ranking_sph04.dat +0 -0
- data/spec/fixtures/requests/ranking_wordcount.dat +0 -0
- data/spec/fixtures/requests/retries.dat +0 -0
- data/spec/fixtures/requests/retries_delay.dat +0 -0
- data/spec/fixtures/requests/select.dat +0 -0
- data/spec/fixtures/requests/sort_attr_asc.dat +0 -0
- data/spec/fixtures/requests/sort_attr_desc.dat +0 -0
- data/spec/fixtures/requests/sort_expr.dat +0 -0
- data/spec/fixtures/requests/sort_extended.dat +0 -0
- data/spec/fixtures/requests/sort_relevance.dat +0 -0
- data/spec/fixtures/requests/sort_time_segments.dat +0 -0
- data/spec/fixtures/requests/update_attributes.dat +0 -0
- data/spec/fixtures/requests/update_attributes_mva.dat +0 -0
- data/spec/fixtures/requests/weights.dat +0 -0
- data/spec/fixtures/responses/build_excerpts.dat +0 -0
- data/spec/fixtures/responses/build_keywords.dat +0 -0
- data/spec/fixtures/responses/flush_attributes.dat +0 -0
- data/spec/fixtures/responses/flush_attrs.dat +2 -0
- data/spec/fixtures/responses/open.dat +0 -0
- data/spec/fixtures/responses/open_twice.dat +0 -0
- data/spec/fixtures/responses/php/build_excerpts.php +8 -0
- data/spec/fixtures/responses/php/build_keywords.php +8 -0
- data/spec/fixtures/responses/php/flush_attributes.php +8 -0
- data/spec/fixtures/responses/php/open.php +8 -0
- data/spec/fixtures/responses/php/open_twice.php +9 -0
- data/spec/fixtures/responses/php/query.php +8 -0
- data/spec/fixtures/responses/php/query_error.php +8 -0
- data/spec/fixtures/responses/php/query_id64.php +8 -0
- data/spec/fixtures/responses/php/run_queries.php +10 -0
- data/spec/fixtures/responses/php/run_queries_error.php +9 -0
- data/spec/fixtures/responses/php/status.php +8 -0
- data/spec/fixtures/responses/php/update_attributes.php +8 -0
- data/spec/fixtures/responses/php/update_attributes_mva.php +8 -0
- data/spec/fixtures/responses/query.dat +0 -0
- data/spec/fixtures/responses/query_error.dat +0 -0
- data/spec/fixtures/responses/query_id64.dat +0 -0
- data/spec/fixtures/responses/run_queries.dat +0 -0
- data/spec/fixtures/responses/run_queries_error.dat +0 -0
- data/spec/fixtures/responses/status.dat +0 -0
- data/spec/fixtures/responses/update_attributes.dat +0 -0
- data/spec/fixtures/responses/update_attributes_mva.dat +0 -0
- data/spec/fixtures/sphinxapi.php +217 -45
- data/spec/spec_helper.rb +18 -3
- data/spec/sphinx/sphinx-id64.conf +6 -6
- data/spec/sphinx/sphinx.conf +6 -6
- data/sphinx.gemspec +19 -121
- metadata +268 -105
- data/README.rdoc +0 -243
- data/VERSION.yml +0 -5
- data/init.rb +0 -1
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/fixtures/sphinxapi.php
CHANGED
@@ -5,7 +5,9 @@
|
|
5
5
|
//
|
6
6
|
|
7
7
|
//
|
8
|
-
// Copyright (c) 2001-
|
8
|
+
// Copyright (c) 2001-2013, Andrew Aksyonoff
|
9
|
+
// Copyright (c) 2008-2013, Sphinx Technologies Inc
|
10
|
+
// All rights reserved
|
9
11
|
//
|
10
12
|
// This program is free software; you can redistribute it and/or modify
|
11
13
|
// it under the terms of the GNU General Public License. You should have
|
@@ -24,13 +26,12 @@ define ( "SEARCHD_COMMAND_UPDATE", 2 );
|
|
24
26
|
define ( "SEARCHD_COMMAND_KEYWORDS", 3 );
|
25
27
|
define ( "SEARCHD_COMMAND_PERSIST", 4 );
|
26
28
|
define ( "SEARCHD_COMMAND_STATUS", 5 );
|
27
|
-
define ( "SEARCHD_COMMAND_QUERY", 6 );
|
28
29
|
define ( "SEARCHD_COMMAND_FLUSHATTRS", 7 );
|
29
30
|
|
30
31
|
/// current client-side command implementation versions
|
31
|
-
define ( "VER_COMMAND_SEARCH",
|
32
|
-
define ( "VER_COMMAND_EXCERPT",
|
33
|
-
define ( "VER_COMMAND_UPDATE",
|
32
|
+
define ( "VER_COMMAND_SEARCH", 0x11D );
|
33
|
+
define ( "VER_COMMAND_EXCERPT", 0x104 );
|
34
|
+
define ( "VER_COMMAND_UPDATE", 0x103 );
|
34
35
|
define ( "VER_COMMAND_KEYWORDS", 0x100 );
|
35
36
|
define ( "VER_COMMAND_STATUS", 0x100 );
|
36
37
|
define ( "VER_COMMAND_QUERY", 0x100 );
|
@@ -60,7 +61,8 @@ define ( "SPH_RANK_PROXIMITY", 4 );
|
|
60
61
|
define ( "SPH_RANK_MATCHANY", 5 );
|
61
62
|
define ( "SPH_RANK_FIELDMASK", 6 );
|
62
63
|
define ( "SPH_RANK_SPH04", 7 );
|
63
|
-
define ( "
|
64
|
+
define ( "SPH_RANK_EXPR", 8 );
|
65
|
+
define ( "SPH_RANK_TOTAL", 9 );
|
64
66
|
|
65
67
|
/// known sort modes
|
66
68
|
define ( "SPH_SORT_RELEVANCE", 0 );
|
@@ -83,7 +85,9 @@ define ( "SPH_ATTR_BOOL", 4 );
|
|
83
85
|
define ( "SPH_ATTR_FLOAT", 5 );
|
84
86
|
define ( "SPH_ATTR_BIGINT", 6 );
|
85
87
|
define ( "SPH_ATTR_STRING", 7 );
|
86
|
-
define ( "
|
88
|
+
define ( "SPH_ATTR_FACTORS", 1001 );
|
89
|
+
define ( "SPH_ATTR_MULTI", 0x40000001 );
|
90
|
+
define ( "SPH_ATTR_MULTI64", 0x40000002 );
|
87
91
|
|
88
92
|
/// known grouping functions
|
89
93
|
define ( "SPH_GROUPBY_DAY", 0 );
|
@@ -349,6 +353,11 @@ function sphUnpackI64 ( $v )
|
|
349
353
|
$mq = floor($m/10000000.0);
|
350
354
|
$l = $m - $mq*10000000.0 + $c;
|
351
355
|
$h = $q*4294967296.0 + $r*429.0 + $mq;
|
356
|
+
if ( $l==10000000 )
|
357
|
+
{
|
358
|
+
$l = 0;
|
359
|
+
$h += 1;
|
360
|
+
}
|
352
361
|
|
353
362
|
$h = sprintf ( "%.0f", $h );
|
354
363
|
$l = sprintf ( "%07.0f", $l );
|
@@ -358,11 +367,40 @@ function sphUnpackI64 ( $v )
|
|
358
367
|
}
|
359
368
|
|
360
369
|
|
370
|
+
function sphFixUint ( $value )
|
371
|
+
{
|
372
|
+
if ( PHP_INT_SIZE>=8 )
|
373
|
+
{
|
374
|
+
// x64 route, workaround broken unpack() in 5.2.2+
|
375
|
+
if ( $value<0 ) $value += (1<<32);
|
376
|
+
return $value;
|
377
|
+
}
|
378
|
+
else
|
379
|
+
{
|
380
|
+
// x32 route, workaround php signed/unsigned braindamage
|
381
|
+
return sprintf ( "%u", $value );
|
382
|
+
}
|
383
|
+
}
|
384
|
+
|
385
|
+
function SetBit ( $flag, $bit, $on )
|
386
|
+
{
|
387
|
+
if ( $on )
|
388
|
+
{
|
389
|
+
$flag += ( 1<<$bit );
|
390
|
+
} else
|
391
|
+
{
|
392
|
+
$reset = 255 ^ ( 1<<$bit );
|
393
|
+
$flag = $flag & $reset;
|
394
|
+
}
|
395
|
+
return $flag;
|
396
|
+
}
|
397
|
+
|
398
|
+
|
361
399
|
/// sphinx searchd client class
|
362
400
|
class SphinxClient
|
363
401
|
{
|
364
402
|
var $_host; ///< searchd host (default is "localhost")
|
365
|
-
var $_port; ///< searchd port (default is
|
403
|
+
var $_port; ///< searchd port (default is 9312)
|
366
404
|
var $_offset; ///< how many records to seek from result-set start (default is 0)
|
367
405
|
var $_limit; ///< how many records to return from result-set starting at offset (default is 20)
|
368
406
|
var $_mode; ///< query matching mode (default is SPH_MATCH_ALL)
|
@@ -383,10 +421,17 @@ class SphinxClient
|
|
383
421
|
var $_anchor; ///< geographical anchor point
|
384
422
|
var $_indexweights; ///< per-index weights
|
385
423
|
var $_ranker; ///< ranking mode (default is SPH_RANK_PROXIMITY_BM25)
|
424
|
+
var $_rankexpr; ///< ranking mode expression (for SPH_RANK_EXPR)
|
386
425
|
var $_maxquerytime; ///< max query time, milliseconds (default is 0, do not limit)
|
387
426
|
var $_fieldweights; ///< per-field-name weights
|
388
427
|
var $_overrides; ///< per-query attribute values overrides
|
389
428
|
var $_select; ///< select-list (attributes or expressions, with optional aliases)
|
429
|
+
var $_query_flags; ///< per-query various flags
|
430
|
+
var $_predictedtime; ///< per-query max_predicted_time
|
431
|
+
var $_outerorderby; ///< outer match sort by
|
432
|
+
var $_outeroffset; ///< outer offset
|
433
|
+
var $_outerlimit; ///< outer limit
|
434
|
+
var $_hasouter;
|
390
435
|
|
391
436
|
var $_error; ///< last error message
|
392
437
|
var $_warning; ///< last warning message
|
@@ -406,7 +451,7 @@ class SphinxClient
|
|
406
451
|
{
|
407
452
|
// per-client-object settings
|
408
453
|
$this->_host = "localhost";
|
409
|
-
$this->_port =
|
454
|
+
$this->_port = 9312;
|
410
455
|
$this->_path = false;
|
411
456
|
$this->_socket = false;
|
412
457
|
|
@@ -431,10 +476,17 @@ class SphinxClient
|
|
431
476
|
$this->_anchor = array ();
|
432
477
|
$this->_indexweights= array ();
|
433
478
|
$this->_ranker = SPH_RANK_PROXIMITY_BM25;
|
479
|
+
$this->_rankexpr = "";
|
434
480
|
$this->_maxquerytime= 0;
|
435
481
|
$this->_fieldweights= array();
|
436
482
|
$this->_overrides = array();
|
437
483
|
$this->_select = "*";
|
484
|
+
$this->_query_flags = 0;
|
485
|
+
$this->_predictedtime = 0;
|
486
|
+
$this->_outerorderby = "";
|
487
|
+
$this->_outeroffset = 0;
|
488
|
+
$this->_outerlimit = 0;
|
489
|
+
$this->_hasouter = false;
|
438
490
|
|
439
491
|
$this->_error = ""; // per-reply fields (for single-query case)
|
440
492
|
$this->_warning = "";
|
@@ -485,9 +537,10 @@ class SphinxClient
|
|
485
537
|
return;
|
486
538
|
}
|
487
539
|
|
488
|
-
assert ( is_int($port) );
|
489
540
|
$this->_host = $host;
|
490
|
-
|
541
|
+
if ( is_int($port) )
|
542
|
+
if ( $port )
|
543
|
+
$this->_port = $port;
|
491
544
|
$this->_path = '';
|
492
545
|
|
493
546
|
}
|
@@ -534,13 +587,20 @@ class SphinxClient
|
|
534
587
|
/// connect to searchd server
|
535
588
|
function _Connect ()
|
536
589
|
{
|
537
|
-
|
538
|
-
|
590
|
+
if ($_ENV['SPHINX_MOCK_REQUEST']) {
|
591
|
+
return fopen('php://stdout', 'w');
|
592
|
+
}
|
539
593
|
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
594
|
+
if ( $this->_socket!==false )
|
595
|
+
{
|
596
|
+
// we are in persistent connection mode, so we have a socket
|
597
|
+
// however, need to check whether it's still alive
|
598
|
+
if ( !@feof ( $this->_socket ) )
|
599
|
+
return $this->_socket;
|
600
|
+
|
601
|
+
// force reopen
|
602
|
+
$this->_socket = false;
|
603
|
+
}
|
544
604
|
|
545
605
|
$errno = 0;
|
546
606
|
$errstr = "";
|
@@ -612,7 +672,7 @@ class SphinxClient
|
|
612
672
|
$left = $len;
|
613
673
|
while ( $left>0 && !feof($fp) )
|
614
674
|
{
|
615
|
-
$chunk = fread ( $fp, $left );
|
675
|
+
$chunk = fread ( $fp, min ( 8192, $left ) );
|
616
676
|
if ( $chunk )
|
617
677
|
{
|
618
678
|
$response .= $chunk;
|
@@ -623,6 +683,11 @@ class SphinxClient
|
|
623
683
|
if ( $this->_socket === false )
|
624
684
|
fclose ( $fp );
|
625
685
|
|
686
|
+
if ($_ENV['SPHINX_MOCK_RESPONSE']) {
|
687
|
+
echo $header;
|
688
|
+
echo $response;
|
689
|
+
}
|
690
|
+
|
626
691
|
// check response
|
627
692
|
$read = strlen ( $response );
|
628
693
|
if ( !$response || $read!=$len )
|
@@ -710,10 +775,12 @@ class SphinxClient
|
|
710
775
|
}
|
711
776
|
|
712
777
|
/// set ranking mode
|
713
|
-
function SetRankingMode ( $ranker )
|
778
|
+
function SetRankingMode ( $ranker, $rankexpr="" )
|
714
779
|
{
|
715
|
-
assert ( $ranker
|
780
|
+
assert ( $ranker===0 || $ranker>=1 && $ranker<SPH_RANK_TOTAL );
|
781
|
+
assert ( is_string($rankexpr) );
|
716
782
|
$this->_ranker = $ranker;
|
783
|
+
$this->_rankexpr = $rankexpr;
|
717
784
|
}
|
718
785
|
|
719
786
|
/// set matches sorting mode
|
@@ -892,7 +959,48 @@ class SphinxClient
|
|
892
959
|
assert ( is_string ( $select ) );
|
893
960
|
$this->_select = $select;
|
894
961
|
}
|
962
|
+
|
963
|
+
function SetQueryFlag ( $flag_name, $flag_value )
|
964
|
+
{
|
965
|
+
$known_names = array ( "reverse_scan", "sort_method", "max_predicted_time", "boolean_simplify", "idf" );
|
966
|
+
$flags = array (
|
967
|
+
"reverse_scan" => array ( 0, 1 ),
|
968
|
+
"sort_method" => array ( "pq", "kbuffer" ),
|
969
|
+
"max_predicted_time" => array ( 0 ),
|
970
|
+
"boolean_simplify" => array ( true, false ),
|
971
|
+
"idf" => array ("normalized", "plain" )
|
972
|
+
);
|
973
|
+
|
974
|
+
assert ( isset ( $flag_name, $known_names ) );
|
975
|
+
assert ( in_array( $flag_value, $flags[$flag_name], true ) || ( $flag_name=="max_predicted_time" && is_int ( $flag_value ) && $flag_value>=0 ) );
|
976
|
+
|
977
|
+
if ( $flag_name=="reverse_scan" ) $this->_query_flags = SetBit ( $this->_query_flags, 0, $flag_value==1 );
|
978
|
+
if ( $flag_name=="sort_method" ) $this->_query_flags = SetBit ( $this->_query_flags, 1, $flag_value=="kbuffer" );
|
979
|
+
if ( $flag_name=="max_predicted_time" )
|
980
|
+
{
|
981
|
+
$this->_query_flags = SetBit ( $this->_query_flags, 2, $flag_value>0 );
|
982
|
+
$this->_predictedtime = (int)$flag_value;
|
983
|
+
}
|
984
|
+
if ( $flag_name=="boolean_simplify" ) $this->_query_flags = SetBit ( $this->_query_flags, 3, $flag_value );
|
985
|
+
if ( $flag_name=="idf" ) $this->_query_flags = SetBit ( $this->_query_flags, 4, $flag_value=="plain" );
|
986
|
+
}
|
987
|
+
|
988
|
+
/// set outer order by parameters
|
989
|
+
function SetOuterSelect ( $orderby, $offset, $limit )
|
990
|
+
{
|
991
|
+
assert ( is_string($orderby) );
|
992
|
+
assert ( is_int($offset) );
|
993
|
+
assert ( is_int($limit) );
|
994
|
+
assert ( $offset>=0 );
|
995
|
+
assert ( $limit>0 );
|
895
996
|
|
997
|
+
$this->_outerorderby = $orderby;
|
998
|
+
$this->_outeroffset = $offset;
|
999
|
+
$this->_outerlimit = $limit;
|
1000
|
+
$this->_hasouter = true;
|
1001
|
+
}
|
1002
|
+
|
1003
|
+
|
896
1004
|
//////////////////////////////////////////////////////////////////////////////
|
897
1005
|
|
898
1006
|
/// clear all filters (for multi-queries)
|
@@ -916,6 +1024,20 @@ class SphinxClient
|
|
916
1024
|
{
|
917
1025
|
$this->_overrides = array ();
|
918
1026
|
}
|
1027
|
+
|
1028
|
+
function ResetQueryFlag ()
|
1029
|
+
{
|
1030
|
+
$this->_query_flags = 0;
|
1031
|
+
$this->_predictedtime = 0;
|
1032
|
+
}
|
1033
|
+
|
1034
|
+
function ResetOuterSelect ()
|
1035
|
+
{
|
1036
|
+
$this->_outerorderby = '';
|
1037
|
+
$this->_outeroffset = 0;
|
1038
|
+
$this->_outerlimit = 0;
|
1039
|
+
$this->_hasouter = false;
|
1040
|
+
}
|
919
1041
|
|
920
1042
|
//////////////////////////////////////////////////////////////////////////////
|
921
1043
|
|
@@ -956,7 +1078,10 @@ class SphinxClient
|
|
956
1078
|
$this->_MBPush ();
|
957
1079
|
|
958
1080
|
// build request
|
959
|
-
$req = pack ( "NNNNN", $this->
|
1081
|
+
$req = pack ( "NNNNN", $this->_query_flags, $this->_offset, $this->_limit, $this->_mode, $this->_ranker );
|
1082
|
+
if ( $this->_ranker==SPH_RANK_EXPR )
|
1083
|
+
$req .= pack ( "N", strlen($this->_rankexpr) ) . $this->_rankexpr;
|
1084
|
+
$req .= pack ( "N", $this->_sort ); // (deprecated) sort mode
|
960
1085
|
$req .= pack ( "N", strlen($this->_sortby) ) . $this->_sortby;
|
961
1086
|
$req .= pack ( "N", strlen($query) ) . $query; // query itself
|
962
1087
|
$req .= pack ( "N", count($this->_weights) ); // weights
|
@@ -1053,6 +1178,17 @@ class SphinxClient
|
|
1053
1178
|
|
1054
1179
|
// select-list
|
1055
1180
|
$req .= pack ( "N", strlen($this->_select) ) . $this->_select;
|
1181
|
+
|
1182
|
+
// max_predicted_time
|
1183
|
+
if ( $this->_predictedtime>0 )
|
1184
|
+
$req .= pack ( "N", (int)$this->_predictedtime );
|
1185
|
+
|
1186
|
+
$req .= pack ( "N", strlen($this->_outerorderby) ) . $this->_outerorderby;
|
1187
|
+
$req .= pack ( "NN", $this->_outeroffset, $this->_outerlimit );
|
1188
|
+
if ( $this->_hasouter )
|
1189
|
+
$req .= pack ( "N", 1 );
|
1190
|
+
else
|
1191
|
+
$req .= pack ( "N", 0 );
|
1056
1192
|
|
1057
1193
|
// mbstring workaround
|
1058
1194
|
$this->_MBPop ();
|
@@ -1083,8 +1219,8 @@ class SphinxClient
|
|
1083
1219
|
// send query, get response
|
1084
1220
|
$nreqs = count($this->_reqs);
|
1085
1221
|
$req = join ( "", $this->_reqs );
|
1086
|
-
$len =
|
1087
|
-
$req = pack ( "
|
1222
|
+
$len = 8+strlen($req);
|
1223
|
+
$req = pack ( "nnNNN", SEARCHD_COMMAND_SEARCH, VER_COMMAND_SEARCH, $len, 0, $nreqs ) . $req; // add header
|
1088
1224
|
|
1089
1225
|
if ( !( $this->_Send ( $fp, $req, $len+8 ) ) ||
|
1090
1226
|
!( $response = $this->_GetResponse ( $fp, VER_COMMAND_SEARCH ) ) )
|
@@ -1177,16 +1313,7 @@ class SphinxClient
|
|
1177
1313
|
list ( $doc, $weight ) = array_values ( unpack ( "N*N*",
|
1178
1314
|
substr ( $response, $p, 8 ) ) );
|
1179
1315
|
$p += 8;
|
1180
|
-
|
1181
|
-
if ( PHP_INT_SIZE>=8 )
|
1182
|
-
{
|
1183
|
-
// x64 route, workaround broken unpack() in 5.2.2+
|
1184
|
-
if ( $doc<0 ) $doc += (1<<32);
|
1185
|
-
} else
|
1186
|
-
{
|
1187
|
-
// x32 route, workaround php signed/unsigned braindamage
|
1188
|
-
$doc = sprintf ( "%u", $doc );
|
1189
|
-
}
|
1316
|
+
$doc = sphFixUint($doc);
|
1190
1317
|
}
|
1191
1318
|
$weight = sprintf ( "%u", $weight );
|
1192
1319
|
|
@@ -1218,22 +1345,35 @@ class SphinxClient
|
|
1218
1345
|
|
1219
1346
|
// handle everything else as unsigned ints
|
1220
1347
|
list(,$val) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
|
1221
|
-
if ( $type
|
1348
|
+
if ( $type==SPH_ATTR_MULTI )
|
1222
1349
|
{
|
1223
1350
|
$attrvals[$attr] = array ();
|
1224
1351
|
$nvalues = $val;
|
1225
1352
|
while ( $nvalues-->0 && $p<$max )
|
1226
1353
|
{
|
1227
1354
|
list(,$val) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
|
1228
|
-
$attrvals[$attr][] =
|
1355
|
+
$attrvals[$attr][] = sphFixUint($val);
|
1356
|
+
}
|
1357
|
+
} else if ( $type==SPH_ATTR_MULTI64 )
|
1358
|
+
{
|
1359
|
+
$attrvals[$attr] = array ();
|
1360
|
+
$nvalues = $val;
|
1361
|
+
while ( $nvalues>0 && $p<$max )
|
1362
|
+
{
|
1363
|
+
$attrvals[$attr][] = sphUnpackI64 ( substr ( $response, $p, 8 ) ); $p += 8;
|
1364
|
+
$nvalues -= 2;
|
1229
1365
|
}
|
1230
1366
|
} else if ( $type==SPH_ATTR_STRING )
|
1231
1367
|
{
|
1232
1368
|
$attrvals[$attr] = substr ( $response, $p, $val );
|
1233
1369
|
$p += $val;
|
1370
|
+
} else if ( $type==SPH_ATTR_FACTORS )
|
1371
|
+
{
|
1372
|
+
$attrvals[$attr] = substr ( $response, $p, $val-4 );
|
1373
|
+
$p += $val-4;
|
1234
1374
|
} else
|
1235
1375
|
{
|
1236
|
-
$attrvals[$attr] =
|
1376
|
+
$attrvals[$attr] = sphFixUint($val);
|
1237
1377
|
}
|
1238
1378
|
}
|
1239
1379
|
|
@@ -1295,24 +1435,40 @@ class SphinxClient
|
|
1295
1435
|
if ( !isset($opts["after_match"]) ) $opts["after_match"] = "</b>";
|
1296
1436
|
if ( !isset($opts["chunk_separator"]) ) $opts["chunk_separator"] = " ... ";
|
1297
1437
|
if ( !isset($opts["limit"]) ) $opts["limit"] = 256;
|
1438
|
+
if ( !isset($opts["limit_passages"]) ) $opts["limit_passages"] = 0;
|
1439
|
+
if ( !isset($opts["limit_words"]) ) $opts["limit_words"] = 0;
|
1298
1440
|
if ( !isset($opts["around"]) ) $opts["around"] = 5;
|
1299
1441
|
if ( !isset($opts["exact_phrase"]) ) $opts["exact_phrase"] = false;
|
1300
1442
|
if ( !isset($opts["single_passage"]) ) $opts["single_passage"] = false;
|
1301
1443
|
if ( !isset($opts["use_boundaries"]) ) $opts["use_boundaries"] = false;
|
1302
1444
|
if ( !isset($opts["weight_order"]) ) $opts["weight_order"] = false;
|
1303
1445
|
if ( !isset($opts["query_mode"]) ) $opts["query_mode"] = false;
|
1446
|
+
if ( !isset($opts["force_all_words"]) ) $opts["force_all_words"] = false;
|
1447
|
+
if ( !isset($opts["start_passage_id"]) ) $opts["start_passage_id"] = 1;
|
1448
|
+
if ( !isset($opts["load_files"]) ) $opts["load_files"] = false;
|
1449
|
+
if ( !isset($opts["html_strip_mode"]) ) $opts["html_strip_mode"] = "index";
|
1450
|
+
if ( !isset($opts["allow_empty"]) ) $opts["allow_empty"] = false;
|
1451
|
+
if ( !isset($opts["passage_boundary"]) ) $opts["passage_boundary"] = "none";
|
1452
|
+
if ( !isset($opts["emit_zones"]) ) $opts["emit_zones"] = false;
|
1453
|
+
if ( !isset($opts["load_files_scattered"]) ) $opts["load_files_scattered"] = false;
|
1454
|
+
|
1304
1455
|
|
1305
1456
|
/////////////////
|
1306
1457
|
// build request
|
1307
1458
|
/////////////////
|
1308
1459
|
|
1309
|
-
// v.1.
|
1460
|
+
// v.1.2 req
|
1310
1461
|
$flags = 1; // remove spaces
|
1311
1462
|
if ( $opts["exact_phrase"] ) $flags |= 2;
|
1312
1463
|
if ( $opts["single_passage"] ) $flags |= 4;
|
1313
1464
|
if ( $opts["use_boundaries"] ) $flags |= 8;
|
1314
1465
|
if ( $opts["weight_order"] ) $flags |= 16;
|
1315
1466
|
if ( $opts["query_mode"] ) $flags |= 32;
|
1467
|
+
if ( $opts["force_all_words"] ) $flags |= 64;
|
1468
|
+
if ( $opts["load_files"] ) $flags |= 128;
|
1469
|
+
if ( $opts["allow_empty"] ) $flags |= 256;
|
1470
|
+
if ( $opts["emit_zones"] ) $flags |= 512;
|
1471
|
+
if ( $opts["load_files_scattered"] ) $flags |= 1024;
|
1316
1472
|
$req = pack ( "NN", 0, $flags ); // mode=0, flags=$flags
|
1317
1473
|
$req .= pack ( "N", strlen($index) ) . $index; // req index
|
1318
1474
|
$req .= pack ( "N", strlen($words) ) . $words; // req words
|
@@ -1321,8 +1477,10 @@ class SphinxClient
|
|
1321
1477
|
$req .= pack ( "N", strlen($opts["before_match"]) ) . $opts["before_match"];
|
1322
1478
|
$req .= pack ( "N", strlen($opts["after_match"]) ) . $opts["after_match"];
|
1323
1479
|
$req .= pack ( "N", strlen($opts["chunk_separator"]) ) . $opts["chunk_separator"];
|
1324
|
-
$req .= pack ( "
|
1325
|
-
$req .= pack ( "
|
1480
|
+
$req .= pack ( "NN", (int)$opts["limit"], (int)$opts["around"] );
|
1481
|
+
$req .= pack ( "NNN", (int)$opts["limit_passages"], (int)$opts["limit_words"], (int)$opts["start_passage_id"] ); // v.1.2
|
1482
|
+
$req .= pack ( "N", strlen($opts["html_strip_mode"]) ) . $opts["html_strip_mode"];
|
1483
|
+
$req .= pack ( "N", strlen($opts["passage_boundary"]) ) . $opts["passage_boundary"];
|
1326
1484
|
|
1327
1485
|
// documents
|
1328
1486
|
$req .= pack ( "N", count($docs) );
|
@@ -1470,11 +1628,12 @@ class SphinxClient
|
|
1470
1628
|
|
1471
1629
|
/// batch update given attributes in given rows in given indexes
|
1472
1630
|
/// returns amount of updated documents (0 or more) on success, or -1 on failure
|
1473
|
-
function UpdateAttributes ( $index, $attrs, $values, $mva=false )
|
1631
|
+
function UpdateAttributes ( $index, $attrs, $values, $mva=false, $ignorenonexistent=false )
|
1474
1632
|
{
|
1475
1633
|
// verify everything
|
1476
1634
|
assert ( is_string($index) );
|
1477
1635
|
assert ( is_bool($mva) );
|
1636
|
+
assert ( is_bool($ignorenonexistent) );
|
1478
1637
|
|
1479
1638
|
assert ( is_array($attrs) );
|
1480
1639
|
foreach ( $attrs as $attr )
|
@@ -1499,9 +1658,11 @@ class SphinxClient
|
|
1499
1658
|
}
|
1500
1659
|
|
1501
1660
|
// build request
|
1661
|
+
$this->_MBPush ();
|
1502
1662
|
$req = pack ( "N", strlen($index) ) . $index;
|
1503
1663
|
|
1504
1664
|
$req .= pack ( "N", count($attrs) );
|
1665
|
+
$req .= pack ( "N", $ignorenonexistent ? 1 : 0 );
|
1505
1666
|
foreach ( $attrs as $attr )
|
1506
1667
|
{
|
1507
1668
|
$req .= pack ( "N", strlen($attr) ) . $attr;
|
@@ -1523,18 +1684,28 @@ class SphinxClient
|
|
1523
1684
|
|
1524
1685
|
// connect, send query, get response
|
1525
1686
|
if (!( $fp = $this->_Connect() ))
|
1687
|
+
{
|
1688
|
+
$this->_MBPop ();
|
1526
1689
|
return -1;
|
1690
|
+
}
|
1527
1691
|
|
1528
1692
|
$len = strlen($req);
|
1529
1693
|
$req = pack ( "nnN", SEARCHD_COMMAND_UPDATE, VER_COMMAND_UPDATE, $len ) . $req; // add header
|
1530
1694
|
if ( !$this->_Send ( $fp, $req, $len+8 ) )
|
1695
|
+
{
|
1696
|
+
$this->_MBPop ();
|
1531
1697
|
return -1;
|
1698
|
+
}
|
1532
1699
|
|
1533
1700
|
if (!( $response = $this->_GetResponse ( $fp, VER_COMMAND_UPDATE ) ))
|
1701
|
+
{
|
1702
|
+
$this->_MBPop ();
|
1534
1703
|
return -1;
|
1704
|
+
}
|
1535
1705
|
|
1536
1706
|
// parse response
|
1537
1707
|
list(,$updated) = unpack ( "N*", substr ( $response, 0, 4 ) );
|
1708
|
+
$this->_MBPop ();
|
1538
1709
|
return $updated;
|
1539
1710
|
}
|
1540
1711
|
|
@@ -1616,13 +1787,13 @@ class SphinxClient
|
|
1616
1787
|
// flush
|
1617
1788
|
//////////////////////////////////////////////////////////////////////////
|
1618
1789
|
|
1619
|
-
function
|
1790
|
+
function FlushAttributes ()
|
1620
1791
|
{
|
1621
1792
|
$this->_MBPush ();
|
1622
1793
|
if (!( $fp = $this->_Connect() ))
|
1623
1794
|
{
|
1624
1795
|
$this->_MBPop();
|
1625
|
-
return
|
1796
|
+
return -1;
|
1626
1797
|
}
|
1627
1798
|
|
1628
1799
|
$req = pack ( "nnN", SEARCHD_COMMAND_FLUSHATTRS, VER_COMMAND_FLUSHATTRS, 0 ); // len=0
|
@@ -1630,19 +1801,20 @@ class SphinxClient
|
|
1630
1801
|
!( $response = $this->_GetResponse ( $fp, VER_COMMAND_FLUSHATTRS ) ) )
|
1631
1802
|
{
|
1632
1803
|
$this->_MBPop ();
|
1633
|
-
return
|
1804
|
+
return -1;
|
1634
1805
|
}
|
1635
1806
|
|
1636
1807
|
$tag = -1;
|
1637
1808
|
if ( strlen($response)==4 )
|
1638
1809
|
list(,$tag) = unpack ( "N*", $response );
|
1810
|
+
else
|
1811
|
+
$this->_error = "unexpected response length";
|
1639
1812
|
|
1640
1813
|
$this->_MBPop ();
|
1641
1814
|
return $tag;
|
1642
1815
|
}
|
1643
|
-
|
1644
1816
|
}
|
1645
1817
|
|
1646
1818
|
//
|
1647
1819
|
// $Id$
|
1648
|
-
//
|
1820
|
+
//
|