Skip to content

Commit

Permalink
Merge pull request #3 from Larium/feature/mongodb-support
Browse files Browse the repository at this point in the history
Feature/mongodb support
  • Loading branch information
akDeveloper authored Nov 8, 2024
2 parents 41f8cca + 35711c2 commit 96d3951
Show file tree
Hide file tree
Showing 18 changed files with 476 additions and 34 deletions.
34 changes: 34 additions & 0 deletions .docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
FROM php:8.3-cli

WORKDIR "/opt/php"

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
libcurl4-openssl-dev \
libssl-dev \
libzip-dev \
zlib1g-dev \
unzip \
git \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean -y

RUN yes | pecl install xdebug

RUN pecl channel-update pecl.php.net && \
pecl install mongodb && \
docker-php-ext-enable mongodb && \
docker-php-source delete && \
rm -r /tmp/* /var/cache/*

RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php composer-setup.php \
&& php -r "unlink('composer-setup.php');" \
&& chmod +x composer.phar \
&& mv composer.phar /usr/local/bin/composer

RUN curl -L https://cs.symfony.com/download/php-cs-fixer-v3.phar -o php-cs-fixer \
&& chmod a+x php-cs-fixer \
&& mv php-cs-fixer /usr/bin/php-cs-fixer
15 changes: 15 additions & 0 deletions .docker/mongo/init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
set -e

user=$MONGO_INITDB_USER
password=$MONGO_INITDB_PWD
db=$MONGO_INITDB_DATABASE

mongosh -u $MONGO_INITDB_ROOT_USERNAME -p $MONGO_INITDB_ROOT_PASSWORD <<EOF
use ${db}
db = db.getSiblingDB("${db}")
db.createUser({
user: "${user}",
pwd: "${password}",
roles: [{ role: "readWrite", db: "${db}"}],
})
EOF
8 changes: 8 additions & 0 deletions .docker/xdebug.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
zend_extension=xdebug.so
xdebug.mode=develop,coverage,debug,profile
xdebug.idekey=docker
xdebug.start_with_request=no
xdebug.log=/dev/stdout
xdebug.log_level=0
xdebug.client_port=9003
xdebug.client_host=host.docker.internal
6 changes: 6 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
MONGO_ROOT_USERNAME=root
MONGO_ROOT_PASSWORD=s3cr3t
MONGODB=test
MONGODB_USER=admin
MONGODB_PASSWORD=s3cr3t
MONGODB_HOST=mongo-server
6 changes: 6 additions & 0 deletions .env.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
MONGO_ROOT_USERNAME=root
MONGO_ROOT_PASSWORD=
MONGODB=test
MONGODB_USER=admin
MONGODB_PASSWORD=
MONGODB_HOST=mongo-server
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ build
vendor
.DS_Store
.phpunit.result.cache
.phpunit.cache
composer.lock
.vscode
18 changes: 18 additions & 0 deletions .php-cs-fixer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

$finder = PhpCsFixer\Finder::create()
->in(__DIR__)
;

return (new PhpCsFixer\Config())
->setUsingCache(false)
->setRules([
'@PSR12' => true,
'ordered_imports' => ['sort_algorithm' => 'length', 'imports_order' => ['const', 'class', 'function']],
'array_syntax' => ['syntax' => 'short'],
'concat_space' => ['spacing' => 'one'],
'blank_line_between_import_groups' => true,
])->setFinder($finder)
;
7 changes: 5 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"keywords": ["http search", "search", "filtering", "criteria"],
"type": "library",
"license": "MIT",
"version": "1.0.0",
"authors": [
{
"name": "Andreas Kollaros",
Expand All @@ -14,9 +15,11 @@
"php": ">=8.1"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"phpunit/phpunit": "^10.0",
"doctrine/dbal": "^3.6",
"pagerfanta/pagerfanta": "^4.0"
"pagerfanta/pagerfanta": "^4.0",
"mongodb/mongodb": "^1.20",
"vlucas/phpdotenv": "^5.6"
},
"autoload": {
"psr-4": {
Expand Down
34 changes: 34 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
version: "3.1"
services:
php-cli:
build: .docker
container_name: larium-search
image: larium-search:latest
working_dir: /opt/php
tty: true
stdin_open: true
volumes:
- .:/opt/php
- ./.docker/xdebug.ini:/usr/local/etc/php/conf.d/15-xdebug.ini
networks:
- search-network
mongo-server:
image: mongo:latest
environment:
- MONGO_INITDB_ROOT_USERNAME=${MONGO_ROOT_USERNAME}
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_ROOT_PASSWORD}
- MONGO_INITDB_DATABASE=${MONGODB}
- MONGO_INITDB_USER=${MONGODB_USER}
- MONGO_INITDB_PWD=${MONGODB_PASSWORD}
ports:
- "27022:27017"
volumes:
- ./.docker/mongo/init.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro
- mongo-data:/data/db
networks:
- search-network
volumes:
mongo-data:
networks:
search-network:
driver: bridge
46 changes: 23 additions & 23 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>

<!-- http://www.phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit
backupGlobals = "false"
backupStaticAttributes = "false"
colors = "true"
verbose = "true"
convertErrorsToExceptions = "true"
convertNoticesToExceptions = "true"
convertWarningsToExceptions = "true"
processIsolation = "false"
stopOnFailure = "false"
bootstrap = "vendor/autoload.php">
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
backupGlobals="false"
colors="true"
processIsolation="false"
stopOnFailure="false"
testdox="true"
bootstrap="vendor/autoload.php"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.3/phpunit.xsd"
cacheDirectory=".phpunit.cache"
backupStaticProperties="false">
<coverage>
<report>
<clover outputFile="build/logs/clover.xml"/>
<html outputDirectory="build/coverage"/>
<text outputFile="build/coverage.txt"/>
</report>
</coverage>
<logging>
<log type="tap" target="build/report.tap"/>
<log type="junit" target="build/report.junit.xml"/>
<log type="coverage-html" target="build/coverage" />
<log type="coverage-text" target="build/coverage.txt"/>
<log type="coverage-clover" target="build/logs/clover.xml"/>
<junit outputFile="build/report.junit.xml"/>
</logging>
<source>
<include>
<directory suffix=".php">src/</directory>
</include>
</source>
<php>
<ini name="date.timezone" value="UTC"/>
</php>
Expand Down
20 changes: 20 additions & 0 deletions src/MongoDb/Builder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Larium\Search\MongoDb;

use Larium\Search\Criteria;

interface Builder
{
/**
* Checks if current builder supports given criteria.
*/
public function supports(Criteria $criteria): bool;

/**
* Apply criteria to given filter builder.
*/
public function build(Criteria $criteria, FilterBuilder $filterBuilder): void;
}
11 changes: 11 additions & 0 deletions src/MongoDb/FilterBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Larium\Search\MongoDb;

use ArrayObject;

class FilterBuilder extends ArrayObject
{
}
60 changes: 60 additions & 0 deletions src/MongoDb/MongoDbResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace Larium\Search\MongoDb;

use MongoDB\Collection;
use Larium\Search\Result;

class MongoDbResult implements Result
{
private array $filter = [];

public function __construct(
private readonly FilterBuilder $filterBuilder,
private readonly Collection $collection,
) {

}

public function fetch(int $offset, int $limit): array
{
$filter = $this->normalizeFilter();
$iterator = $this->collection->find($filter, ['skip' => $offset, 'limit' => $limit]);

return iterator_to_array($iterator);
}

public function getCountField(): ?string
{
return null;
}

public function setCountField(string $countField): void
{
}

public function setCountCallable(callable $function): void
{
}

public function count(): int
{
return $this->collection->countDocuments($this->normalizeFilter());
}

private function normalizeFilter(): array
{
if (!empty($this->filter)) {
return $this->filter;
}

$this->filter = array_reduce($this->filterBuilder->getArrayCopy(), function (array $result, array $item) {
$result = array_merge($result, $item);
return $result;
}, []);

return $this->filter;
}
}
39 changes: 39 additions & 0 deletions src/MongoDb/MongoDbSearchEngine.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace Larium\Search\MongoDb;

use MongoDB\Collection;
use Larium\Search\Result;
use Larium\Search\Criteria;
use Larium\Search\SearchEngine;

class MongoDbSearchEngine implements SearchEngine
{
private $builders = [];

public function __construct(
private readonly FilterBuilder $filterBuilder,
private readonly Collection $collection,
) {
}

public function match(Criteria $criteria): Result
{
foreach ($this->builders as $builder) {
if ($builder->supports($criteria)) {
$builder->build($criteria, $this->filterBuilder);
}
}

return new MongoDbResult($this->filterBuilder, $this->collection);
}

public function add(Builder $builder): self
{
$this->builders[] = $builder;

return $this;
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
<?php

declare(strict_types = 1);
declare(strict_types=1);

namespace Larium\Search\Doctrine\Dbal;
namespace Larium\Search;

use Larium\Search\Criteria\Paginating;
use Larium\Search\Paginator;
use Larium\Search\Result;
use ArrayIterator;
use Traversable;
use function intval;
use ArrayIterator;
use Larium\Search\Result;
use Larium\Search\Paginator;
use Larium\Search\Criteria\Paginating;

use function ceil;
use function intval;

class DoctrineDbalPaginator implements Paginator
class ResultPaginator implements Paginator
{
private $result;

Expand Down Expand Up @@ -76,7 +77,7 @@ public function getNextPage(): ?int
public function getPreviousPage(): ?int
{
return $this->paginating->currentPage > 1
? $this->paginating->currentPage - 1
? $this->paginating->currentPage - 1
: null;
}
}
Loading

0 comments on commit 96d3951

Please sign in to comment.