Skip to content

Commit

Permalink
Provide option to return a cursor for table row results (#129)
Browse files Browse the repository at this point in the history
* Give option to return a cursor rather than array

* Give option to pass in custom cursor

* Get the verbiage correct: we're manipulating the documents

* Expose $options parameter on Driver->getTableRows()

* Need to abstract out getConfigInstance() for testing downstream

* Add the same behavior to the constructor

* Add tests

* consistent uri
  • Loading branch information
rsinger authored Sep 7, 2018
1 parent 77abf3e commit 8d8106d
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 26 deletions.
12 changes: 10 additions & 2 deletions src/IDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,17 @@ public function select($filter,$fields,$sortBy=null,$limit=null,$context=null);
* @param array $sortBy
* @param int $offset
* @param int $limit
* @param array $options
* @return array
*/
public function getTableRows($tableType,$filter=array(),$sortBy=array(),$offset=0,$limit=10);
public function getTableRows(
$tableType,
array $filter = [],
array $sortBy = [],
$offset = 0,
$limit = 10,
array $options = []
);

/**
* todo: work out what this does
Expand Down Expand Up @@ -181,4 +189,4 @@ public function removeInertLocks($transaction_id, $reason);

/* END Deprecated methods that will be removed in 1.x.x */

}
}
19 changes: 16 additions & 3 deletions src/mongo/Driver.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,22 @@ public function getViews(Array $filter, $viewType)
* @param int $limit
* @return array
*/
public function getTableRows($tableType, $filter = array(), $sortBy = array(), $offset = 0, $limit = 10)
{
return $this->getTripodTables()->getTableRows($tableType,$filter,$sortBy,$offset,$limit);
public function getTableRows(
$tableType,
array $filter = [],
array $sortBy = [],
$offset = 0,
$limit = 10,
array $options = []
) {
return $this->getTripodTables()->getTableRows(
$tableType,
$filter,
$sortBy,
$offset,
$limit,
$options
);
}

/**
Expand Down
69 changes: 48 additions & 21 deletions src/mongo/delegates/Tables.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,45 +233,72 @@ public function getOperationType()
* @param array $sortBy
* @param int $offset
* @param int $limit
* @param array $options Table query options
* @return array
*/
public function getTableRows($tableSpecId,$filter=[],$sortBy=[],$offset=0,$limit=10)
{
public function getTableRows(
$tableSpecId,
array $filter = [],
array $sortBy = [],
$offset = 0,
$limit = 10,
array $options = []
) {
$t = new \Tripod\Timer();
$t->start();

$filter["_id." . _ID_TYPE] = $tableSpecId;
$options = array_merge(
[
'returnCursor' => false,
'includeCount' => true,
'documentType' => '\Tripod\Mongo\Documents\Tables'
],
$options
);

$collection = $this->config->getCollectionForTable($this->storeName, $tableSpecId, $this->readPreference);
$filter['_id.' . _ID_TYPE] = $tableSpecId;

$collection = $this->getConfigInstance()->getCollectionForTable(
$this->storeName,
$tableSpecId,
$this->readPreference
);

$findOptions = [];
if (!empty($limit)) {
$findOptions['skip'] = (int) $offset;
$findOptions['limit'] = (int) $limit;
$findOptions['skip'] = (int) $offset;
$findOptions['limit'] = (int) $limit;
}
if (isset($sortBy)) {
$findOptions['sort'] = $sortBy;
}

$results = $collection->find($filter, $findOptions);

$rows = [];
foreach ($results as $doc)
{
if (array_key_exists(_IMPACT_INDEX,$doc['value'])) unset($doc['value'][_IMPACT_INDEX]); // remove impact index from client
$rows[] = $doc['value'];
if ($options['includeCount']) {
$count = $collection->count($filter);
} else {
$count = -1;
}

$t->stop();
$this->timingLog(MONGO_TABLE_ROWS, array('duration'=>$t->result(), 'query'=>$filter, 'collection'=>TABLE_ROWS_COLLECTION));
$this->getStat()->timer(MONGO_TABLE_ROWS.".$tableSpecId",$t->result());

return array(
"head"=>array(
"count" => $collection->count($filter),
"offset"=>$offset,
"limit"=>$limit
),
"results"=>$rows);
$results->setTypeMap(['root' => $options['documentType'], 'document' => 'array', 'array' => 'array']);

$t->stop();
$this->timingLog(
MONGO_TABLE_ROWS,
['duration' => $t->result(), 'query' => $filter, 'collection' => TABLE_ROWS_COLLECTION]
);
$this->getStat()->timer(MONGO_TABLE_ROWS . ".$tableSpecId", $t->result());

return [
'head' => [
'count' => $count,
'offset' => $offset,
'limit' => $limit
],
'results' => $options['returnCursor'] ? $results : $results->toArray()
];
}

/**
Expand Down
36 changes: 36 additions & 0 deletions src/mongo/documents/Tables.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Tripod\Mongo\Documents;

class Tables extends \MongoDB\Model\BSONDocument
{
public function __construct(array $input = [])
{
parent::__construct($this->toTableRow($input));
}
/**
* Sets the array value to the modeled table row value
*
* @param array $data DB document array
* @return void
*/
public function bsonUnserialize(array $data)
{
$this->exchangeArray($this->toTableRow($data));
}

/**
* Models the table row from the source data
*
* @param array $doc Database document
* @return array
*/
protected function toTableRow(array $doc)
{
$result = isset($doc['value']) ? $doc['value'] : [];
if (isset($result[_IMPACT_INDEX])) {
unset($result[_IMPACT_INDEX]);
}
return $result;
}
}
66 changes: 66 additions & 0 deletions test/unit/mongo/MongoTripodTablesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1839,4 +1839,70 @@ public function testDeleteTableRowsByTableIdWithTimestamp()

$this->assertEquals(11, $tables->deleteTableRowsByTableId('t_source_count', $timestamp));
}

public function testTablesDocuments()
{
$dbDoc = [
'_id' => [
'r' => 'http://talis.com/modules/xmen-004',
'c' => 'tenantContexts:DefaultGraph',
'type' => 't_report_hierarchy'
],
'_cts' => new \MongoDB\BSON\UTCDateTime(1535454036),
'value' => [
'_id' => [
'r' => 'http://talis.com/modules/xmen-004',
'c' => 'tenantContexts:DefaultGraph'
],
'_impactIndex' => [
[ 'r' => 'http://talis.com/modules/xmen-004', 'c' => 'tenantContexts:DefaultGraph' ],
[ 'r' => 'http://talis.com/schools/xmen-001', 'c' => 'tenantContexts:DefaultGraph' ]
],
'code' => 'XMEN-004',
'nodeUrl' => 'http://talis.com/modules/xmen-004',
'name' => 'Psychology: Living with The Voices',
'description' => 'Professor Deadpool will attempt to give you the ability to embrace your mental disorder and use it to your advantage. Whether you suffer from Schizophrenia, Dissociative Identity Disorder or plain old Comic Awareness, Wade Wilson has probably suffered through it himself. And while Deadpool can\'t solve your problem, he can teach you how to make it one of your most marketable qualities.',
'parentCode' => 'XMEN-001',
'parentNodeUrl' => 'http://talis.com/schools/xmen-001',
'listCount' => 0,
'type' => 'Module',
'hasLinkedLists' => 'false'
]
];
$doc = new \Tripod\Mongo\Documents\Tables();
$this->assertInstanceOf('MongoDB\Model\BSONDocument', $doc);
$this->assertEquals([], $doc->getArrayCopy());
$doc = new \Tripod\Mongo\Documents\Tables($dbDoc);
$this->assertEquals('XMEN-004', $doc['code']);
$this->assertEquals('http://talis.com/modules/xmen-004', $doc['_id']['r']);
$this->assertArrayNotHasKey('_cts', $doc);
$this->assertArrayNotHasKey('_impactIndex', $doc);
$this->assertArrayNotHasKey('type', $doc['_id']);
}

public function testGetTableRowsNoCount()
{
$this->tripodTables->generateTableRows('t_resource');

$tableRows = $this->tripodTables->getTableRows('t_resource', [], [], 0, 1, ['includeCount' => false]);

$this->assertCount(1, $tableRows['results']);
$this->assertEquals(-1, $tableRows['head']['count']);
}

public function testGetTableRowsReturnCursor()
{
$this->tripodTables->generateTableRows('t_resource');

$tableRows = $this->tripodTables->getTableRows('t_resource', [], [], 0, 1, ['returnCursor' => true]);

$this->assertInstanceOf('\MongoDB\Driver\Cursor', $tableRows['results']);
$count = 0;
foreach ($tableRows['results'] as $result) {
$this->assertInstanceOf('\Tripod\Mongo\Documents\Tables', $result);
$count++;
}
$this->assertEquals(1, $count);
$this->assertGreaterThan(1, $tableRows['head']['count']);
}
}

0 comments on commit 8d8106d

Please sign in to comment.