Skip to content

Commit

Permalink
update 修改语句解析方式 通过各自管理遍历的方式解析 为之后的操作符准备
Browse files Browse the repository at this point in the history
kvnZero committed Nov 10, 2021
1 parent 45ad7d9 commit ba3a01a
Showing 24 changed files with 333 additions and 247 deletions.
92 changes: 19 additions & 73 deletions app/ApiJson/Entity/ConditionEntity.php
Original file line number Diff line number Diff line change
@@ -2,61 +2,9 @@

namespace App\ApiJson\Entity;

use App\ApiJson\Handle\FunctionLimitHandle;
use App\ApiJson\Handle\FunctionOffsetHandle;
use App\ApiJson\Interface\QueryInterface;
use App\ApiJson\Handle\AbstractHandle;
use App\ApiJson\Handle\FunctionColumnHandle;
use App\ApiJson\Handle\FunctionGroupHandle;
use App\ApiJson\Handle\FunctionHavingHandle;
use App\ApiJson\Handle\FunctionOrderHandle;
use App\ApiJson\Handle\WhereBetweenHandle;
use App\ApiJson\Handle\WhereExistsHandle;
use App\ApiJson\Handle\WhereHandle;
use App\ApiJson\Handle\WhereInHandle;
use App\ApiJson\Handle\WhereJsonContainsHandle;
use App\ApiJson\Handle\WhereLikeHandle;
use App\ApiJson\Handle\WhereRawHandle;
use App\ApiJson\Handle\WhereRegexpHandle;
use App\ApiJson\Method\AbstractMethod;
use App\ApiJson\Replace\AbstractReplace;
use App\ApiJson\Replace\KeywordCountReplace;
use App\ApiJson\Replace\KeywordPageReplace;
use App\ApiJson\Replace\QuoteReplace;

class ConditionEntity
{
/**
* 替换规则
* @var AbstractReplace[]
*/
protected array $replaceRules = [
KeywordCountReplace::class,
KeywordPageReplace::class,
QuoteReplace::class,
];


/**
* 匹配规则 根据从上自下优先先匹先出
* @var AbstractHandle[]
*/
protected array $methodRules = [
FunctionColumnHandle::class,
FunctionHavingHandle::class,
FunctionOffsetHandle::class,
FunctionLimitHandle::class,
FunctionGroupHandle::class,
FunctionOrderHandle::class,
WhereJsonContainsHandle::class,
WhereBetweenHandle::class,
WhereExistsHandle::class,
WhereRegexpHandle::class,
WhereLikeHandle::class,
WhereRawHandle::class,
WhereInHandle::class,
WhereHandle::class,
];
protected array $changeLog = [];

/**
* @param array $condition 条件
@@ -65,29 +13,27 @@ public function __construct(protected array $condition, protected array $extendD
{
}

protected function replaceHandle($key, $value, array $condition = []): array
public function getExtendData(): array
{
foreach ($this->replaceRules as $rule) {
/** @var AbstractReplace $replaceRule */
$replaceRule = new $rule($key, $value, $condition, $this->extendData);
$response = $replaceRule->handle();
if (!is_null($response)) return $response;
}
return [$key, $value];
return $this->extendData;
}

/**
* 整理语句
*/
public function setQueryCondition(QueryInterface $query)
public function setCondition(array $condition)
{
$this->log($condition);
$this->condition = $condition;
}

public function getCondition(): array
{
return $this->condition;
}

protected function log(array $condition)
{
foreach ($this->condition as $key => $value) {
[$key, $value] = $this->replaceHandle($key, $value, $this->condition); //解决引用问题
/** @var AbstractMethod $rule */
foreach ($this->methodRules as $rule) {
$methodRule = new $rule($query, $key, $value);
if ($methodRule->handle()) break;
}
}
$this->changeLog[] = [
'old' => $this->condition,
'new' => $condition
];
}
}
31 changes: 24 additions & 7 deletions app/ApiJson/Handle/AbstractHandle.php
Original file line number Diff line number Diff line change
@@ -2,27 +2,44 @@

namespace App\ApiJson\Handle;

use App\ApiJson\Entity\ConditionEntity;
use App\ApiJson\Interface\QueryInterface;

abstract class AbstractHandle
{
/** @var string 清洗后的查询key */
protected string $sanitizeKey;

public function __construct(protected QueryInterface $query, protected string $key, protected $value)
/** @var string 关键字 */
protected string $keyWord;

protected array $unsetKey = [];

public function __construct(protected QueryInterface $query, protected ConditionEntity $condition)
{
preg_match('#(?<key>[a-zA-z0-9_]+)#', $this->key, $match);
$this->sanitizeKey = $match['key'] ?? $this->key;
}

public function handle(): bool
protected function sanitizeKey(string $key): string
{
preg_match('#(?<key>[a-zA-z0-9_]+)#', $key, $match);
return $match['key'] ?? $key;
}

public function handle()
{
if (!$this->validateCondition()) return false;
$this->buildModel();
return true;
$this->unsetKeySaveCondition();
}

abstract protected function validateCondition(): bool;
protected function unsetKeySaveCondition()
{
if (empty($this->unsetKey)) return;
$condition = $this->condition->getCondition();
foreach ($this->unsetKey as $key) {
unset($condition[$key]);
}
$this->condition->setCondition($condition);
}

abstract protected function buildModel();
}
20 changes: 13 additions & 7 deletions app/ApiJson/Handle/FunctionColumnHandle.php
Original file line number Diff line number Diff line change
@@ -4,14 +4,20 @@

class FunctionColumnHandle extends AbstractHandle
{
protected function validateCondition(): bool
{
return $this->key === '@column';
}
protected string $keyWord = '@column';

protected function buildModel()
public function buildModel()
{
$this->value = str_replace([';',':'], [',', ' AS '], $this->value);
$this->query->select(explode(',', $this->value));
if (!in_array($this->keyWord, array_keys($this->condition->getCondition()))) {
return;
}
foreach (array_filter($this->condition->getCondition(), function($key){
return $key == $this->keyWord;
}, ARRAY_FILTER_USE_KEY) as $key => $value)
{
$value = str_replace([';',':'], [',', ' AS '], $value);
$this->query->select(explode(',', $value));
$this->unsetKey[] = $this->keyWord;
}
}
}
20 changes: 13 additions & 7 deletions app/ApiJson/Handle/FunctionGroupHandle.php
Original file line number Diff line number Diff line change
@@ -4,14 +4,20 @@

class FunctionGroupHandle extends AbstractHandle
{
protected function validateCondition(): bool
{
return $this->key === '@group';
}
protected string $keyWord = '@group';

protected function buildModel()
public function buildModel()
{
$groupArr = explode(',', $this->value);
$this->query->groupBy($groupArr);
if (!in_array($this->keyWord, array_keys($this->condition->getCondition()))) {
return;
}
foreach (array_filter($this->condition->getCondition(), function($key){
return $key == $this->keyWord;
}, ARRAY_FILTER_USE_KEY) as $key => $value)
{
$groupArr = explode(',', $value);
$this->query->groupBy($groupArr);
$this->unsetKey[] = $this->keyWord;
}
}
}
22 changes: 14 additions & 8 deletions app/ApiJson/Handle/FunctionHavingHandle.php
Original file line number Diff line number Diff line change
@@ -4,16 +4,22 @@

class FunctionHavingHandle extends AbstractHandle
{
protected function validateCondition(): bool
{
return $this->key === '@having';
}
protected string $keyWord = '@having';

protected function buildModel()
public function buildModel()
{
$havingArr = explode(';', $this->value);
foreach ($havingArr as $having) {
$this->query->having($having);
if (!in_array($this->keyWord, array_keys($this->condition->getCondition()))) {
return;
}
foreach (array_filter($this->condition->getCondition(), function($key){
return $key == $this->keyWord;
}, ARRAY_FILTER_USE_KEY) as $key => $value)
{
$havingArr = explode(';', $value);
foreach ($havingArr as $having) {
$this->query->having($having);
}
$this->unsetKey[] = $this->keyWord;
}
}
}
16 changes: 11 additions & 5 deletions app/ApiJson/Handle/FunctionLimitHandle.php
Original file line number Diff line number Diff line change
@@ -4,13 +4,19 @@

class FunctionLimitHandle extends AbstractHandle
{
protected function validateCondition(): bool
{
return $this->key === '@limit';
}
protected string $keyWord = '@limit';

protected function buildModel()
{
$this->query->limit((int)$this->value);
if (!in_array($this->keyWord, array_keys($this->condition->getCondition()))) {
return;
}
foreach (array_filter($this->condition->getCondition(), function($key){
return $key == $this->keyWord;
}, ARRAY_FILTER_USE_KEY) as $key => $value)
{
$this->query->limit((int)$value);
$this->unsetKey[] = $this->keyWord;
}
}
}
16 changes: 11 additions & 5 deletions app/ApiJson/Handle/FunctionOffsetHandle.php
Original file line number Diff line number Diff line change
@@ -4,13 +4,19 @@

class FunctionOffsetHandle extends AbstractHandle
{
protected function validateCondition(): bool
{
return $this->key === '@offset';
}
protected string $keyWord = '@offset';

protected function buildModel()
{
$this->query->offset((int)$this->value);
if (!in_array($this->keyWord, array_keys($this->condition->getCondition()))) {
return;
}
foreach (array_filter($this->condition->getCondition(), function($key){
return $key == $this->keyWord;
}, ARRAY_FILTER_USE_KEY) as $key => $value)
{
$this->query->offset((int)$value);
$this->unsetKey[] = $this->keyWord;
}
}
}
22 changes: 14 additions & 8 deletions app/ApiJson/Handle/FunctionOrderHandle.php
Original file line number Diff line number Diff line change
@@ -4,16 +4,22 @@

class FunctionOrderHandle extends AbstractHandle
{
protected function validateCondition(): bool
{
return $this->key === '@order';
}
protected string $keyWord = '@order';

protected function buildModel()
public function buildModel()
{
$orderArr = explode(',', $this->value);
foreach ($orderArr as $order) {
$this->query->orderBy(str_replace(['-', '+'], '', $order), str_ends_with($order, '-') ? 'desc' : 'asc');
if (!in_array($this->keyWord, array_keys($this->condition->getCondition()))) {
return;
}
foreach (array_filter($this->condition->getCondition(), function($key){
return $key == $this->keyWord;
}, ARRAY_FILTER_USE_KEY) as $key => $value)
{
$orderArr = explode(',', $value);
foreach ($orderArr as $order) {
$this->query->orderBy(str_replace(['-', '+'], '', $order), str_ends_with($order, '-') ? 'desc' : 'asc');
}
$this->unsetKey[] = $this->keyWord;
}
}
}
23 changes: 12 additions & 11 deletions app/ApiJson/Handle/WhereBetweenHandle.php
Original file line number Diff line number Diff line change
@@ -4,19 +4,20 @@

class WhereBetweenHandle extends AbstractHandle
{
protected function validateCondition(): bool
{
return str_ends_with($this->key, '$');
}

protected function buildModel()
{
$value = !is_array($this->value) ? [$this->value] : $this->value;
$sql = [];
foreach ($value as $item) {
$itemArr = explode(',', $item);
$sql[] = sprintf("%s BETWEEN %s AND %s", $this->sanitizeKey, trim($itemArr[0]), trim($itemArr[1]));
foreach (array_filter($this->condition->getCondition(), function($key){
return str_ends_with($key, '$');
}, ARRAY_FILTER_USE_KEY) as $key => $value)
{
$value = !is_array($value) ? [$value] : $value;
$sql = [];
foreach ($value as $item) {
$itemArr = explode(',', $item);
$sql[] = sprintf("%s BETWEEN %s AND %s", $this->sanitizeKey($key), trim($itemArr[0]), trim($itemArr[1]));
}
$this->query->whereRaw(join(' OR ', $sql)); //3.2.3
$this->unsetKey[] = $key;
}
$this->query->whereRaw(join(' OR ', $sql)); //3.2.3
}
}
Loading
Oops, something went wrong.

0 comments on commit ba3a01a

Please sign in to comment.