Skip to content

Commit c2f838c

Browse files
author
Bennett Thompson
committed
Have added batched statements so it's possible to process large result sets without running out of memory
1 parent 08daeb1 commit c2f838c

File tree

4 files changed

+78
-10
lines changed

4 files changed

+78
-10
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
namespace triagens\ArangoDb;
3+
class BatchedCursor extends Cursor
4+
{
5+
6+
private $_processed = 0;
7+
public function setResults( array $data )
8+
{
9+
$this->_result=[];
10+
$this->add( $data );
11+
$this->rewind();
12+
$this->updateLength();
13+
}
14+
15+
public function fetchNextBatch()
16+
{
17+
// continuation
18+
$this->_processed += $this->_length;
19+
$response = $this->_connection->put($this->url() . '/' . $this->_id, '', array());
20+
++$this->_fetches;
21+
22+
$data = $response->getJson();
23+
24+
$this->_hasMore = (bool) $data[Cursor::ENTRY_HASMORE];
25+
$this->setResults($data[Cursor::ENTRY_RESULT]);
26+
27+
if (!$this->_hasMore) {
28+
// we have fetched the complete result set and can unset the id now
29+
$this->_id = null;
30+
}
31+
return $this->_result;
32+
}
33+
34+
public function next()
35+
{
36+
parent::next();
37+
if( $this->key() >= $this->_length && $this->_hasMore )
38+
{
39+
$this->fetchNextBatch();
40+
}
41+
}
42+
43+
public function fullKey()
44+
{
45+
return $this->_processed + $this->key();
46+
}
47+
}
48+
?>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: Bennett.Thompson
5+
* Date: 25/10/2016
6+
* Time: 11:48 AM
7+
*/
8+
9+
namespace triagens\ArangoDb;
10+
class BatchedStatement extends Statement
11+
{
12+
protected static function getCursor( $connection, $json, $options )
13+
{
14+
return new BatchedCursor( $connection, $json, $options );
15+
}
16+
}

lib/triagens/ArangoDb/Cursor.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Cursor implements
3131
*
3232
* @var Connection
3333
*/
34-
private $_connection;
34+
protected $_connection;
3535
/**
3636
* Cursor options
3737
*
@@ -51,21 +51,21 @@ class Cursor implements
5151
*
5252
* @var array
5353
*/
54-
private $_result;
54+
protected $_result;
5555

5656
/**
5757
* "has more" indicator - if true, the server has more results
5858
*
5959
* @var bool
6060
*/
61-
private $_hasMore;
61+
protected $_hasMore;
6262

6363
/**
6464
* cursor id - might be NULL if cursor does not have an id
6565
*
6666
* @var mixed
6767
*/
68-
private $_id;
68+
protected $_id;
6969

7070
/**
7171
* current position in result set iteration (zero-based)
@@ -79,7 +79,7 @@ class Cursor implements
7979
*
8080
* @var int
8181
*/
82-
private $_length;
82+
protected $_length;
8383

8484
/**
8585
* full count of the result set (ignoring the outermost LIMIT)
@@ -98,7 +98,7 @@ class Cursor implements
9898
/**
9999
* number of HTTP calls that were made to build the cursor result
100100
*/
101-
private $_fetches = 1;
101+
protected $_fetches = 1;
102102

103103
/**
104104
* whether or not the query result was served from the AQL query result cache
@@ -378,7 +378,7 @@ public function valid()
378378
*
379379
* @return void
380380
*/
381-
private function add(array $data)
381+
protected function add(array $data)
382382
{
383383
foreach ($this->sanitize($data) as $row) {
384384
if (!is_array($row) || (isset($this->_options[self::ENTRY_FLAT]) && $this->_options[self::ENTRY_FLAT])) {
@@ -672,7 +672,7 @@ private function fetchOutstanding()
672672
*
673673
* @return void
674674
*/
675-
private function updateLength()
675+
protected function updateLength()
676676
{
677677
$this->_length = count($this->_result);
678678
}
@@ -683,7 +683,7 @@ private function updateLength()
683683
*
684684
* @return string
685685
*/
686-
private function url()
686+
protected function url()
687687
{
688688
if (isset($this->_options[self::ENTRY_BASEURL])) {
689689
return $this->_options[self::ENTRY_BASEURL];

lib/triagens/ArangoDb/Statement.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ public function execute()
250250
while (true) {
251251
try {
252252
$response = $this->_connection->post(Urls::URL_CURSOR, $this->getConnection()->json_encode_wrapper($data), array());
253-
return new Cursor($this->_connection, $response->getJson(), $this->getCursorOptions());
253+
return static::getCursor($this->_connection, $response->getJson(), $this->getCursorOptions());
254254
} catch (ServerException $e) {
255255
if ($tries++ >= $this->_retries) {
256256
throw $e;
@@ -264,6 +264,10 @@ public function execute()
264264
}
265265
}
266266

267+
protected static function getCursor($connection, $json, $options)
268+
{
269+
return new Cursor( $connection, $json, $options );
270+
}
267271

268272
/**
269273
* Explain the statement's execution plan

0 commit comments

Comments
 (0)