src/PHPixie/Database/Driver/Mongo/Parser.php
<?php
namespace PHPixie\Database\Driver\Mongo;
class Parser extends \PHPixie\Database\Parser
{
protected $conditionsParser;
/**
* Parser constructor.
*
* @param $database
* @param $driver
* @param $config
* @param $conditionsParser
*/
public function __construct($database, $driver, $config, $conditionsParser)
{
parent::__construct($database, $driver, $config);
$this->conditionsParser = $conditionsParser;
}
/**
* @param \PHPixie\Database\Query $query
*
* @return mixed
* @throws \PHPixie\Database\Exception\Parser
*/
public function parse($query)
{
$runner = $this->driver->runner();;
switch ($query->type()) {
case 'select':
return $this->selectQuery($query, $runner);
case 'selectSingle':
return $this->selectSingleQuery($query, $runner);
case 'insert':
return $this->insertQuery($query, $runner);
case 'update':
return $this->updateQuery($query, $runner);
case 'delete':
return $this->deleteQuery($query, $runner);
case 'count':
return $this->countQuery($query, $runner);
default:
throw new \PHPixie\Database\Exception\Parser("Query type '{$query->type()}' is not supported");
}
}
/**
* @param $query
* @param $runner
*
* @return mixed
* @throws \PHPixie\Database\Exception\Parser
*/
protected function selectQuery($query, $runner)
{
$this->chainCollection($query, $runner);
$conditions = $this->conditionsParser->parse($query->getWhereConditions());
$options = array();
if(($limit = $query->getLimit()) !== null) {
$options['limit'] = $limit;
}
if(($offset = $query->getOffset()) !== null) {
$options['skip'] = $offset;
}
if(count($fields = $query->getFields()) !== 0) {
$options['projection'] = $this->fieldKeys($fields);
}
$order = $query->getOrderBy();
if (!empty($order)) {
$ordering = array();
foreach ($order as $orderBy) {
$ordering[$orderBy->field()] = $orderBy->direction() === 'asc' ? 1 : -1;
}
$options['sort'] = $ordering;
}
$runner->chainMethod('find', array($conditions, $options));
return $runner;
}
/**
* @param $fields
*
* @return array
*/
protected function fieldKeys($fields)
{
return array_fill_keys($fields, 1);
}
/**
* @param $query
* @param $runner
*
* @return mixed
* @throws \PHPixie\Database\Exception\Parser
*/
protected function selectSingleQuery($query, $runner)
{
$this->chainCollection($query, $runner);
$conditions = $this->conditionsParser->parse($query->getWhereConditions());
$options = array();
if(count($fields = $query->getFields()) !== 0) {
$options['projection'] = $this->fieldKeys($fields);
}
$runner->chainMethod('findOne', array($conditions, $options));
return $runner;
}
/**
* @param $query
* @param $runner
*
* @return mixed
* @throws \PHPixie\Database\Exception\Parser
*/
protected function insertQuery($query, $runner)
{
$this->chainCollection($query, $runner);
if (($data = $query->getBatchData()) !== null) {
$runner->chainMethod('insertMany', array($data));
} elseif (($data = $query->getData()) !== null) {
$runner->chainMethod('insertOne', array($data));
}else
throw new \PHPixie\Database\Exception\Parser("No data set for insertion");
return $runner;
}
/**
* @param $query
* @param $runner
*
* @return mixed
* @throws \PHPixie\Database\Exception\Parser
*/
protected function updateQuery($query, $runner)
{
$this->chainCollection($query, $runner);
$modifiers = array(
'$set' => $query->getSet(),
'$unset' => $this->fieldKeys($query->getUnset()),
'$inc' => $query->getIncrement()
);
$data = array();
foreach ($modifiers as $key=>$value) {
if(!empty($value))
$data[$key] = $value;
}
if (empty($data))
throw new \PHPixie\Database\Exception\Parser("No modifiers specified for update");
$conditions = $this->conditionsParser->parse($query->getWhereConditions());
$runner->chainMethod('updateMany', array($conditions, $data));
return $runner;
}
/**
* @param $query
* @param $runner
*
* @return mixed
* @throws \PHPixie\Database\Exception\Parser
*/
protected function deleteQuery($query, $runner)
{
$this->chainCollection($query, $runner);
$conditions = $this->conditionsParser->parse($query->getWhereConditions());
$runner->chainMethod('deleteMany', array($conditions));
return $runner;
}
/**
* @param $query
* @param $runner
*
* @return mixed
* @throws \PHPixie\Database\Exception\Parser
*/
protected function countQuery($query, $runner)
{
$this->chainCollection($query, $runner);
$conditions = $this->conditionsParser->parse($query->getWhereConditions());
$runner->chainMethod('count', array($conditions));
return $runner;
}
/**
* @param $query
* @param $runner
*
* @throws \PHPixie\Database\Exception\Parser
*/
protected function chainCollection($query, $runner)
{
if (($collection = $query->getCollection()) !== null) {
$runner->chainProperty($collection);
}else
throw new \PHPixie\Database\Exception\Parser("You must specify a collection for this query.");
}
}