Skip to content

Commit

Permalink
added support for mongodb
Browse files Browse the repository at this point in the history
  • Loading branch information
pyatachok committed Dec 4, 2019
1 parent e525fac commit 21b5ddc
Show file tree
Hide file tree
Showing 12 changed files with 521 additions and 5 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
All notable changes to this project will be documented in this file.

## [Unreleased]

## [1.0.2] - 2019-12-04
### Added
- support for mongodb 3.6

## [0.0.1] - 2019-12-01
## [1.0.1] - 2019-12-01
### Added
- support for elasticsearch6
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ Tests
```

[CHANGELOG]: ./CHANGELOG.md
[version-badge]: https://img.shields.io/badge/version-0.0.1-blue.svg
[version-badge]: https://img.shields.io/badge/version-1.0.2-blue.svg

2 changes: 1 addition & 1 deletion src/services/ConstructorService.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use micetm\conditionsBase\exceptions\AttributeNotFoundException;
use micetm\conditionsBase\models\constructor\conditions\Condition;
use micetm\conditionsBase\models\constructor\attributes\AbstractAttribute;
use micetm\conditionsBase\models\constructor\attributes\activeRecords\Attribute;
use micetm\conditionsBase\models\constructor\attributes\activeRecords\mongodb\Attribute;
use micetm\conditionsBase\models\constructor\attributes\activeRecords\AttributeInterface;
use micetm\conditionsBase\models\search\AttributeSearchInterface;
use yii\helpers\ArrayHelper;
Expand Down
73 changes: 72 additions & 1 deletion src/services/builders/mongodb/QueryBuilder.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,79 @@
<?php
namespace micetm\conditionsBase\services\builders\monbodb;
namespace micetm\conditionsBase\services\builders\mongodb;

use micetm\conditionsBase\exceptions\WrongComparison;
use micetm\conditionsBase\models\ConditionInterface;
use micetm\conditionsBase\services\BuilderInterface;
use micetm\conditionsBase\services\builders\mongodb\comparisons\ComparisonManager;

class QueryBuilder implements BuilderInterface
{
/** @var ComparisonManager */
public $comparisonManager;

const OPERATOR_AND = '$and';
const OPERATOR_OR = '$or';
const OPERATOR_NOT = '$not';

const CONDITIONS = [
ConditionInterface::OPERATOR_AND => self::OPERATOR_AND,
ConditionInterface::OPERATOR_OR => self::OPERATOR_OR,
ConditionInterface::OPERATOR_NOT => self::OPERATOR_NOT,
ConditionInterface::OPERATOR_STATEMENT => self::OPERATOR_OR,
];

public function __construct(ComparisonManager $comparisonManager)
{
$this->comparisonManager = $comparisonManager;
}

/**
* @param $conditions
* @return array
* @throws WrongComparison
*/
public function create($conditions):array
{
$query = [];

if ($conditions instanceof \ArrayObject || is_array($conditions)) {
foreach ($conditions as $condition) {
$query[] = $this->getQuery($condition);

}
}
$query = array_filter($query);

if (empty($query)) {
return [];
}
if (1 == count($query)) {
return array_shift($query);
}

return [
self::OPERATOR_OR => $query
];
}

/**
* @return array|null
* @throws WrongComparison
*/
protected function getQuery(ConditionInterface $condition)
{
if (count($condition->conditionModels)) {
$query = [];
foreach ($condition->conditionModels as $childCondition) {
if (!empty($filter = $this->getQuery($childCondition))) {
$query[self::CONDITIONS[$condition->operator]][] = $filter;
}
}
return $query;
} elseif ($condition->attribute) {
$comparison = $this->comparisonManager->getComparison($condition);
return $comparison->buildFilter($condition);
}
return;
}
}
34 changes: 34 additions & 0 deletions src/services/builders/mongodb/comparisons/ComparisonManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php
namespace micetm\conditionsBase\services\builders\mongodb\comparisons;

use micetm\conditionsBase\exceptions\WrongComparison;
use micetm\conditionsBase\models\ComparisonInterface;
use micetm\conditionsBase\models\ConditionInterface;
use micetm\conditionsBase\services\ComparisonManagerInterface;

class ComparisonManager implements ComparisonManagerInterface
{
const AVAILABLE_COMPARISONS = [
RangeComparison::class,
LikeComparison::class,
InComparison::class,
DefaultComparison::class,
EmbeddedComparison::class
];

/**
* @param ConditionInterface $condition
* @return ComparisonInterface
* @throws WrongComparison
*/
public function getComparison(ConditionInterface $condition): ComparisonInterface
{
foreach (self::AVAILABLE_COMPARISONS as $className) {
if ($className::isMaster($condition)) {
return new $className();
}
}

throw new WrongComparison();
}
}
37 changes: 37 additions & 0 deletions src/services/builders/mongodb/comparisons/DefaultComparison.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace micetm\conditionsBase\services\builders\mongodb\comparisons;

use micetm\conditionsBase\models\AttributeInterface;
use micetm\conditionsBase\models\ComparisonInterface;
use micetm\conditionsBase\models\ConditionInterface;
use micetm\conditionsBase\services\builders\mongodb\QueryBuilder;

class DefaultComparison implements ComparisonInterface
{
const RANGE_PARAMETER_GREATER_THAN_OR_EQUAL_TO = '$gte';
const RANGE_PARAMETER_GREATER_THAN = '$gt';
const RANGE_PARAMETER_LESS_THAN_OR_EQUAL_TO = '$lte';
const RANGE_PARAMETER_LESS_THAN = '$lt';
const IN_COMPARISON = '$in';

public static function isMaster(ConditionInterface $condition): bool
{
return AttributeInterface::EQUAL_TO_COMPARISON === $condition->comparison;
}

public function buildFilter(ConditionInterface $condition): array
{
if (is_array($condition->value)) {
return $this->buikdNestedFilter($condition);
}
$query[$condition->attribute] = $condition->value;
return $query;
}

protected function buikdNestedFilter(ConditionInterface $condition): array
{
$query[$condition->attribute][self::IN_COMPARISON] = array_values($condition->value);
return $query;
}
}
28 changes: 28 additions & 0 deletions src/services/builders/mongodb/comparisons/EmbeddedComparison.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace micetm\conditionsBase\services\builders\mongodb\comparisons;

use micetm\conditionsBase\models\AttributeInterface;
use micetm\conditionsBase\models\ComparisonInterface;
use micetm\conditionsBase\models\ConditionInterface;

class EmbeddedComparison extends DefaultComparison
{
public static function isMaster(ConditionInterface $condition): bool
{
return AttributeInterface::EMBEDDED_COMPARISON === $condition->comparison;
}

public function buildFilter(ConditionInterface $condition): array
{
if (!is_array($condition->value)) {
throw new \RuntimeException('Nested comparison should have value of type Array');
}

foreach ($condition->value as $key => $value) {
$query[$condition->attribute]['$elemMatch'][$key] = $value;
}

return $query;
}
}
21 changes: 21 additions & 0 deletions src/services/builders/mongodb/comparisons/InComparison.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace micetm\conditionsBase\services\builders\mongodb\comparisons;

use micetm\conditionsBase\models\AttributeInterface;
use micetm\conditionsBase\models\ComparisonInterface;
use micetm\conditionsBase\models\ConditionInterface;
use micetm\conditionsBase\services\builders\mongodb\QueryBuilder;

class InComparison extends DefaultComparison
{
public static function isMaster(ConditionInterface $condition): bool
{
return AttributeInterface::MORE_THAN_ONE_IN_COMPARISON === $condition->comparison;
}

public function buildFilter(ConditionInterface $condition): array
{
return parent::buikdNestedFilter($condition);
}
}
22 changes: 22 additions & 0 deletions src/services/builders/mongodb/comparisons/LikeComparison.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace micetm\conditionsBase\services\builders\mongodb\comparisons;

use micetm\conditionsBase\models\AttributeInterface;
use micetm\conditionsBase\models\ComparisonInterface;
use micetm\conditionsBase\models\ConditionInterface;
use micetm\conditionsBase\services\builders\mongodb\QueryBuilder;

class LikeComparison implements ComparisonInterface
{
public static function isMaster(ConditionInterface $condition): bool
{
return AttributeInterface::LIKE_COMPARISON === $condition->comparison;
}

public function buildFilter(ConditionInterface $condition): array
{
$query['$text']['$search'] = $condition->value;
return $query;
}
}
50 changes: 50 additions & 0 deletions src/services/builders/mongodb/comparisons/RangeComparison.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace micetm\conditionsBase\services\builders\mongodb\comparisons;

use micetm\conditionsBase\models\AttributeInterface;
use micetm\conditionsBase\models\ComparisonInterface;
use micetm\conditionsBase\models\ConditionInterface;
use micetm\conditionsBase\services\builders\mongodb\QueryBuilder;

class RangeComparison implements ComparisonInterface
{
public static function isMaster(ConditionInterface $condition): bool
{
return in_array(
$condition->comparison,
[
AttributeInterface::GREATER_THAN_COMPARISON,
AttributeInterface::LESS_THAN_COMPARISON,
AttributeInterface::GREATER_THAN_OR_EQUAL_TO_COMPARISON,
AttributeInterface::LESS_THAN_OR_EQUAL_TO_COMPARISON
]
);
}

public function buildFilter(ConditionInterface $condition): array
{
if (AttributeInterface::GREATER_THAN_COMPARISON === $condition->comparison) {
$query[$condition->attribute][DefaultComparison::RANGE_PARAMETER_GREATER_THAN]
= $condition->value;
return $query;
}
if (AttributeInterface::LESS_THAN_COMPARISON === $condition->comparison) {
$query[$condition->attribute][DefaultComparison::RANGE_PARAMETER_LESS_THAN]
= $condition->value;
return $query;
}
if (AttributeInterface::GREATER_THAN_OR_EQUAL_TO_COMPARISON === $condition->comparison) {
$query[$condition->attribute][DefaultComparison::RANGE_PARAMETER_GREATER_THAN_OR_EQUAL_TO]
= $condition->value;
return $query;
}
if (AttributeInterface::LESS_THAN_OR_EQUAL_TO_COMPARISON === $condition->comparison) {
$query[$condition->attribute][DefaultComparison::RANGE_PARAMETER_LESS_THAN_OR_EQUAL_TO]
= $condition->value;
return $query;
}

return [];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use micetm\conditionsBase\models\AttributeInterface;
use PHPUnit\Framework\TestCase;

class QueryBuilderTest extends TestCase
class ESQueryBuilderTest extends TestCase
{
/**
* @dataProvider providerUnarySuccess
Expand Down

0 comments on commit 21b5ddc

Please sign in to comment.