Skip to content

Commit

Permalink
Allow custom dbms pagination support through PaginatedQueryInterface
Browse files Browse the repository at this point in the history
  • Loading branch information
fab2s committed Aug 18, 2022
1 parent 2db56d3 commit a4d44da
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 73 deletions.
18 changes: 18 additions & 0 deletions src/Extractors/PaginatedQueryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* This file is part of YaEtl
* (c) Fabrice de Stefanis / https://github.com/fab2s/YaEtl
* This source file is licensed under the MIT license which you will
* find in the LICENSE file or at https://opensource.org/licenses/MIT
*/

namespace fab2s\YaEtl\Extractors;

interface PaginatedQueryInterface
{
/**
* @return string the paginated query with current offset and limit
*/
public function getPaginatedQuery(): string;
}
2 changes: 1 addition & 1 deletion src/Extractors/PdoExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public function __destruct()
*
* @return string the paginated query with current offset and limit
*/
protected function getPaginatedQuery(): string
public function getPaginatedQuery(): string
{
return $this->extractQuery . $this->getLimitOffsetBit();
}
Expand Down
6 changes: 3 additions & 3 deletions src/Extractors/PdoExtractorTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ public function configurePdo(\PDO $pdo)
$this->pdo = $pdo;
$this->dbDriverName = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);

if (!isset($this->supportedDrivers[$this->dbDriverName])) {
throw new YaEtlException('Pdo driver not supported, must be one of: ' . \implode(', ', \array_keys($this->supportedDrivers)));
if (!($this instanceof PaginatedQueryInterface) && !isset($this->supportedDrivers[$this->dbDriverName])) {
throw new YaEtlException(\get_class($this) . ' does not implement PaginatedQueryInterface and does not uses a supported Pdo driver, supported drivers are: ' . \implode(', ', \array_keys($this->supportedDrivers)));
}

if ($this->dbDriverName === 'mysql') {
Expand Down Expand Up @@ -127,5 +127,5 @@ public function fetchRecords(): bool
/**
* @return string the paginated query with current offset and limit
*/
abstract protected function getPaginatedQuery(): string;
abstract public function getPaginatedQuery(): string;
}
40 changes: 20 additions & 20 deletions src/Extractors/PdoUniqueKeyExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,26 @@ public function fetchRecords(): bool
return true;
}

/**
* This method sets offset and limit in the query
* WARNING : if you set an offset without limit,
* the limit will be set to $this->maxdefaultLimit
*
* @return string the paginated query with current offset and limit
*/
public function getPaginatedQuery(): string
{
if ($this->joinFrom) {
$this->queryBindings = array_values($this->uniqueKeyValues);

$whereOrAndStr = stripos($this->extractQuery, 'WHERE') !== false ? 'AND' : 'WHERE';

return $this->extractQuery . " $whereOrAndStr $this->uniqueKeyName IN (" . implode(',', array_fill(0, count($this->uniqueKeyValues), '?')) . ')';
}

return $this->extractQuery . $this->getLimitOffsetBit();
}

/**
* @return bool
*/
Expand All @@ -106,24 +126,4 @@ protected function fetchJoinedRecords(): bool

return !empty($this->joinedRecords);
}

/**
* This method sets offset and limit in the query
* WARNING : if you set an offset without limit,
* the limit will be set to $this->maxdefaultLimit
*
* @return string the paginated query with current offset and limit
*/
protected function getPaginatedQuery(): string
{
if ($this->joinFrom) {
$this->queryBindings = array_values($this->uniqueKeyValues);

$whereOrAndStr = stripos($this->extractQuery, 'WHERE') !== false ? 'AND' : 'WHERE';

return $this->extractQuery . " $whereOrAndStr $this->uniqueKeyName IN (" . implode(',', array_fill(0, count($this->uniqueKeyValues), '?')) . ')';
}

return $this->extractQuery . $this->getLimitOffsetBit();
}
}
31 changes: 5 additions & 26 deletions src/Laravel/Extractors/DbExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@
use fab2s\NodalFlow\NodalFlowException;
use fab2s\NodalFlow\YaEtlException;
use fab2s\YaEtl\Extractors\DbExtractorAbstract;
use fab2s\YaEtl\Extractors\PaginatedQueryInterface;
use fab2s\YaEtl\Extractors\PdoExtractor;
use Illuminate\Database\Query\Builder;

/**
* Class DbExtractor
*/
class DbExtractor extends PdoExtractor
class DbExtractor extends PdoExtractor implements PaginatedQueryInterface
{
use DelayedExtractQueryTrait;

/**
* The record collection structure
*
Expand Down Expand Up @@ -52,36 +55,12 @@ public function __construct(?Builder $extractQuery = null)
DbExtractorAbstract::__construct();
}

/**
* Set the extract query
*
* @param Builder $extractQuery
*
* @throws YaEtlException
*
* @return static
*/
public function setExtractQuery($extractQuery): DbExtractorAbstract
{
if (!($extractQuery instanceof Builder)) {
throw new YaEtlException('Argument 1 passed to ' . __METHOD__ . ' must be an instance of ' . Builder::class . ', ' . \gettype($extractQuery) . ' given');
}

if (!isset($this->pdo)) {
$this->configurePdo($extractQuery->getConnection()->getPdo());
}

parent::setExtractQuery($extractQuery);

return $this;
}

/**
* This method sets offset and limit in the query
*
* @return string the paginated query with current offset and limit
*/
protected function getPaginatedQuery(): string
public function getPaginatedQuery(): string
{
$extractQuery = $this->extractQuery
->offset($this->offset)
Expand Down
41 changes: 41 additions & 0 deletions src/Laravel/Extractors/DelayedExtractQueryTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

/*
* This file is part of YaEtl
* (c) Fabrice de Stefanis / https://github.com/fab2s/YaEtl
* This source file is licensed under the MIT license which you will
* find in the LICENSE file or at https://opensource.org/licenses/MIT
*/

namespace fab2s\YaEtl\Laravel\Extractors;

use fab2s\NodalFlow\YaEtlException;
use fab2s\YaEtl\Extractors\DbExtractorAbstract;
use Illuminate\Database\Query\Builder;

trait DelayedExtractQueryTrait
{
/**
* Set the extract query
*
* @param Builder $extractQuery
*
* @throws YaEtlException
*
* @return static
*/
public function setExtractQuery($extractQuery): DbExtractorAbstract
{
if (!($extractQuery instanceof Builder)) {
throw new YaEtlException('Argument 1 passed to ' . __METHOD__ . ' must be an instance of ' . Builder::class . ', ' . \gettype($extractQuery) . ' given');
}

if (!isset($this->pdo)) {
$this->configurePdo($extractQuery->getConnection()->getPdo());
}

parent::setExtractQuery($extractQuery);

return $this;
}
}
34 changes: 11 additions & 23 deletions src/Laravel/Extractors/UniqueKeyExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@

use fab2s\NodalFlow\NodalFlowException;
use fab2s\NodalFlow\YaEtlException;
use fab2s\YaEtl\Extractors\DbExtractorAbstract;
use fab2s\YaEtl\Extractors\PaginatedQueryInterface;
use fab2s\YaEtl\Extractors\PdoUniqueKeyExtractor;
use fab2s\YaEtl\Extractors\UniqueKeyExtractorAbstract;
use Illuminate\Database\Query\Builder;

/**
* Class UniqueKeyExtractor
*/
class UniqueKeyExtractor extends PdoUniqueKeyExtractor
class UniqueKeyExtractor extends PdoUniqueKeyExtractor implements PaginatedQueryInterface
{
use DelayedExtractQueryTrait;

/**
* Generic extraction from tables with unique (composite) key
*
Expand All @@ -39,37 +42,22 @@ class UniqueKeyExtractor extends PdoUniqueKeyExtractor
* @throws YaEtlException
* @throws NodalFlowException
*/
public function __construct(Builder $extractQuery, $uniqueKey = 'id')
public function __construct(?Builder $extractQuery = null, $uniqueKey = 'id')
{
parent::__construct($extractQuery->getConnection()->getPdo(), $extractQuery, $uniqueKey);
}

/**
* Set the extract query
*
* @param Builder $extractQuery
*
* @throws YaEtlException
*
* @return static
*/
public function setExtractQuery($extractQuery): DbExtractorAbstract
{
if (!($extractQuery instanceof Builder)) {
throw new YaEtlException('Argument 1 passed to ' . __METHOD__ . ' must be an instance of ' . Builder::class . ', ' . \gettype($extractQuery) . ' given');
if ($extractQuery !== null) {
$this->setExtractQuery($extractQuery);
}

parent::setExtractQuery($extractQuery);

return $this;
// delay configuring pdo to flow start
UniqueKeyExtractorAbstract::__construct(null, $uniqueKey);
}

/**
* This method sets offset and limit in the query
*
* @return string the paginated query with current offset and limit
*/
protected function getPaginatedQuery(): string
public function getPaginatedQuery(): string
{
if ($this->joinFrom) {
$extractQuery = $this->extractQuery
Expand Down

0 comments on commit a4d44da

Please sign in to comment.