sphinx 0.9.10.2122 → 2.1.1.3711
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
//
|