Skip to content

Commit

Permalink
Improved streaming expression result and added graph query for GraphML (
Browse files Browse the repository at this point in the history
solariumphp#582)

Improved streaming expression result and added graph query for GraphML
  • Loading branch information
Markus Kalkbrenner authored Mar 19, 2018
1 parent 853b566 commit fa38360
Show file tree
Hide file tree
Showing 10 changed files with 358 additions and 32 deletions.
18 changes: 18 additions & 0 deletions src/Core/Client/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ class Client extends Configurable implements ClientInterface
*/
const QUERY_STREAM = 'stream';

/**
* Querytype graph.
*/
const QUERY_GRAPH = 'graph';

/**
* Querytype extract.
*/
Expand Down Expand Up @@ -130,6 +135,7 @@ class Client extends Configurable implements ClientInterface
self::QUERY_SPELLCHECK => 'Solarium\QueryType\Spellcheck\Query',
self::QUERY_SUGGESTER => 'Solarium\QueryType\Suggester\Query',
self::QUERY_STREAM => 'Solarium\QueryType\Stream\Query',
self::QUERY_GRAPH => 'Solarium\QueryType\Graph\Query',
self::QUERY_EXTRACT => 'Solarium\QueryType\Extract\Query',
self::QUERY_REALTIME_GET => 'Solarium\QueryType\RealtimeGet\Query',
];
Expand Down Expand Up @@ -1163,6 +1169,18 @@ public function createStream($options = null)
return $this->createQuery(self::QUERY_STREAM, $options);
}

/**
* Create a graph query instance.
*
* @param mixed $options
*
* @return \Solarium\QueryType\Graph\Query
*/
public function createGraph($options = null)
{
return $this->createQuery(self::QUERY_GRAPH, $options);
}

/**
* Create a RealtimeGet query instance.
*
Expand Down
10 changes: 10 additions & 0 deletions src/Exception/StreamException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Solarium\Exception;

/**
* StreamException exception for Solarium classes.
*/
class StreamException extends \UnexpectedValueException implements ExceptionInterface
{
}
72 changes: 72 additions & 0 deletions src/QueryType/Graph/Query.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

namespace Solarium\QueryType\Graph;

use Solarium\Core\Client\Client;
use Solarium\Core\Query\AbstractQuery;
use Solarium\QueryType\Stream\RequestBuilder;

/**
* Graph query.
*/
class Query extends AbstractQuery
{
/**
* Default options.
*
* @var array
*/
protected $options = [
'handler' => 'graph',
'resultclass' => 'Solarium\QueryType\Graph\Result',
];

/**
* Get type for this query.
*
* @return string
*/
public function getType()
{
return Client::QUERY_GRAPH;
}

/**
* Get a requestbuilder for this query.
*
* @return RequestBuilder
*/
public function getRequestBuilder()
{
return new RequestBuilder();
}

/**
* No response parser required since we pass through GraphML.
*/
public function getResponseParser()
{
}

/**
* Set the expression.
*
* @param string $expr
*
* @return self Provides fluent interface
*/
public function setExpression($expr)
{
return $this->setOption('expr', $expr);
}

/**
* Get the expression.
*
* @return string
*/
public function getExpression()
{
return $this->getOption('expr');
}
}
43 changes: 43 additions & 0 deletions src/QueryType/Graph/Result.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Solarium\QueryType\Graph;

use Solarium\Core\Query\Result\Result as BaseResult;

/**
* Graph query result.
*/
class Result extends BaseResult
{
/**
* Get Solr status code.
*
* @return int
*/
public function getStatusCode()
{
return $this->response->getStatusCode();
}

/**
* Get Solr response body.
*
* @return string The response body
*/
public function getData()
{
return $this->response->getBody();
}

/**
* Get Solr response data in GraphML format.
*
* More expressive convenience method that just call getData().
*
* @return string GraphML XML document
*/
public function getGraphML()
{
return $this->getData();
}
}
24 changes: 0 additions & 24 deletions src/QueryType/Select/Query/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -261,30 +261,6 @@ public function getStart()
return $this->getOption('start');
}

/**
* Set a custom resultclass.
*
* @param string $value classname
*
* @return self Provides fluent interface
*/
public function setResultClass($value)
{
return $this->setOption('resultclass', $value);
}

/**
* Get the current resultclass option.
*
* The value is a classname, not an instance
*
* @return string
*/
public function getResultClass()
{
return $this->getOption('resultclass');
}

/**
* Set a custom document class.
*
Expand Down
1 change: 0 additions & 1 deletion src/QueryType/Select/ResponseParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ class ResponseParser extends ResponseParserAbstract implements ResponseParserInt
/**
* Get result data for the response.
*
*
* @param Result $result
*
* @throws RuntimeException
Expand Down
40 changes: 35 additions & 5 deletions src/QueryType/Stream/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@
namespace Solarium\QueryType\Stream;

use Solarium\Core\Client\Client;
use Solarium\Core\Query\AbstractQuery as BaseQuery;
use Solarium\Core\Query\AbstractQuery;

/**
* Stream query.
**/
class Query extends BaseQuery
*/
class Query extends AbstractQuery
{
/**
* Default options.
*
* @var array
*/
protected $options = [
'resultclass' => 'Solarium\QueryType\Stream\Result',
'handler' => 'stream',
'resultclass' => 'Solarium\QueryType\Stream\Result',
'documentclass' => 'Solarium\QueryType\Select\Result\Document',
];

/**
Expand All @@ -41,10 +42,13 @@ public function getRequestBuilder()
}

/**
* The stream query has no response parser so we return a null value.
* Get a response parser for this query.
*
* @return ResponseParser
*/
public function getResponseParser()
{
return new ResponseParser();
}

/**
Expand All @@ -68,4 +72,30 @@ public function getExpression()
{
return $this->getOption('expr');
}

/**
* Set a custom document class.
*
* This class should implement the document interface
*
* @param string $value classname
*
* @return self Provides fluent interface
*/
public function setDocumentClass($value)
{
return $this->setOption('documentclass', $value);
}

/**
* Get the current documentclass option.
*
* The value is a classname, not an instance
*
* @return string
*/
public function getDocumentClass()
{
return $this->getOption('documentclass');
}
}
71 changes: 71 additions & 0 deletions src/QueryType/Stream/ResponseParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace Solarium\QueryType\Stream;

use Solarium\Core\Query\AbstractResponseParser as ResponseParserAbstract;
use Solarium\Core\Query\ResponseParserInterface as ResponseParserInterface;
use Solarium\Exception\RuntimeException;
use Solarium\Exception\StreamException;
use Solarium\QueryType\Select\Result\Result;

/**
* Parse streaming expression response data.
*/
class ResponseParser extends ResponseParserAbstract implements ResponseParserInterface
{
/**
* Get result data for the response.
*
* @param Result $result
*
* @throws RuntimeException
*
* @return array
*/
public function parse($result)
{
$data = $result->getData();

/*
* @var Query
*/
$query = $result->getQuery();

// create document instances
$documentClass = $query->getOption('documentclass');
$classes = class_implements($documentClass);
if (!in_array('Solarium\QueryType\Select\Result\DocumentInterface', $classes, true)) {
throw new RuntimeException('The result document class must implement a document interface');
}

$documents = [];
if (isset($data['result-set']['docs'])) {
foreach ($data['result-set']['docs'] as $doc) {
$fields = (array) $doc;
if (isset($fields['EXCEPTION'])) {
// Use Solr's exception as message.
throw new StreamException($fields['EXCEPTION']);
}
if (isset($fields['EOF'])) {
// End of stream.
break;
}
$documents[] = new $documentClass($fields);
}
if (!isset($fields['EOF'])) {
throw new StreamException('Streaming expression returned an incomplete result-set.');
}
$data['responseHeader']['QTime'] = $fields['RESPONSE_TIME'];
$data['responseHeader']['status'] = 0;
} else {
throw new StreamException('Streaming expression did not return a result-set.');
}

return $this->addHeaderInfo(
$data,
[
'documents' => $documents,
]
);
}
}
Loading

0 comments on commit fa38360

Please sign in to comment.