Skip to content

Commit b57694e

Browse files
committed
add 存储过程支持 && 通过class_map使查询后执行事件进行转JSON处理
通过上面的方式删掉了上下文存储statement导致执行查询后无法进行存储过程问题
1 parent 11b09c6 commit b57694e

File tree

12 files changed

+249
-57
lines changed

12 files changed

+249
-57
lines changed

app/ApiJson/Entity/ConditionEntity.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class ConditionEntity
1717
protected array $group = [];
1818
protected array $order = [];
1919
protected array $having = [];
20+
protected string $procedure = "";
2021

2122
/**
2223
* @param array $condition 条件
@@ -155,6 +156,22 @@ public function getOrder(): array
155156
return $this->order;
156157
}
157158

159+
/**
160+
* @param string $procedure
161+
*/
162+
public function setProcedure(string $procedure): void
163+
{
164+
$this->procedure = $procedure;
165+
}
166+
167+
/**
168+
* @return string
169+
*/
170+
public function getProcedure(): string
171+
{
172+
return $this->procedure;
173+
}
174+
158175
protected function log(array $condition)
159176
{
160177
$this->changeLog[] = [
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace App\ApiJson\Handle;
4+
5+
class FunctionProcedureHandle extends AbstractHandle
6+
{
7+
protected string $keyWord = '@procedure()';
8+
9+
public function buildModel()
10+
{
11+
if (!in_array($this->keyWord, array_keys($this->condition->getCondition()))) {
12+
return;
13+
}
14+
15+
foreach (array_filter($this->condition->getCondition(), function($key){
16+
return $key == $this->keyWord;
17+
}, ARRAY_FILTER_USE_KEY) as $key => $value)
18+
{
19+
$this->condition->setProcedure($value);
20+
$this->unsetKey[] = $this->keyWord;
21+
}
22+
}
23+
}

app/ApiJson/Method/GetMethod.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,32 @@ protected function validateCondition(): bool
1818

1919
protected function process()
2020
{
21-
$handle = new Handle($this->tableEntity->getConditionEntity(), $this->tableEntity);
22-
$handle->build();
23-
2421
$queryMany = $this->isQueryMany();
2522
if (!$queryMany) {
2623
$this->tableEntity->getConditionEntity()->setLimit(1);
2724
}
2825

26+
$handle = new Handle($this->tableEntity->getConditionEntity(), $this->tableEntity);
27+
$handle->build();
28+
2929
//该事件鼓励是做语句缓存或者事件触发 不赞成修改语句做法 修改语句应在更上层的QueryHandle事件
3030
$event = new QueryExecuteBefore($this->query->toSql(), $this->method);
3131
ApplicationContext::getContainer()->get(EventDispatcherInterface::class)->dispatch($event);
3232

3333
if(is_null($event->result)) {
3434
$result = $this->query->all();
3535

36-
$queryEvent = new QueryResult($result);
36+
$queryEvent = new QueryResult($result, $this->query->toSql());
3737
ApplicationContext::getContainer()->get(EventDispatcherInterface::class)->dispatch($queryEvent);
3838

3939
$result = $queryEvent->result;
40+
41+
if (!empty($this->tableEntity->getConditionEntity()->getProcedure())) {
42+
foreach ($result as $i => $item) {
43+
$result[$i]['procedure'] = $this->query->callProcedure($item);
44+
}
45+
}
46+
4047
} else {
4148
$result = $event->result;
4249
}

app/ApiJson/Model/MysqlQuery.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,50 @@ public function getBindings(): array
8787
return $this->db->getBindings();
8888
}
8989

90+
public function callProcedure(array $dataItem, bool $query = true): array
91+
{
92+
if (empty($this->conditionEntity->getProcedure())) {
93+
return [];
94+
}
95+
$count = -1;
96+
$list = []; //默认值
97+
98+
$procedure = $this->conditionEntity->getProcedure();
99+
$rule = '/(?<functionName>.+)\((?<args>.+?)\)/';
100+
preg_match($rule, $procedure, $match);
101+
if (empty($match['functionName'])) {
102+
return [];
103+
}
104+
$args = array_map('trim', explode(',', $match['args']));
105+
106+
$callArgs = [];
107+
foreach ($args as $arg) {
108+
if (in_array($arg, array_keys($dataItem))) {
109+
$callArgs[] = $dataItem[$arg];
110+
} else if ($arg == '@limit') {
111+
$callArgs[] = $this->conditionEntity->getLimit();
112+
} else if ($arg == '@offset') {
113+
$callArgs[] = $this->conditionEntity->getOffset();
114+
} else {
115+
$callArgs[] = $arg;
116+
}
117+
}
118+
119+
$sql = sprintf("CALL %s(%s)", $match['functionName'], join(',', $callArgs));
120+
121+
if ($query) {
122+
$list = Db::select($sql);
123+
} else {
124+
$count = Db::affectingStatement($sql);
125+
}
126+
127+
return [
128+
'count' => $count,
129+
'update' => !$query,
130+
'list' => $list,
131+
];
132+
}
133+
90134
protected function buildQuery(bool $query = true)
91135
{
92136
if ($this->build) return;

app/ApiJson/Parse/Handle.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use App\ApiJson\Handle\FunctionLimitHandle;
2121
use App\ApiJson\Handle\FunctionOffsetHandle;
2222
use App\ApiJson\Handle\FunctionOrderHandle;
23+
use App\ApiJson\Handle\FunctionProcedureHandle;
2324
use App\ApiJson\Handle\WhereBetweenHandle;
2425
use App\ApiJson\Handle\WhereExistsHandle;
2526
use App\ApiJson\Handle\WhereHandle;
@@ -54,6 +55,7 @@ class Handle
5455
* @var AbstractHandle[]
5556
*/
5657
protected array $methodRules = [
58+
FunctionProcedureHandle::class,
5759
FunctionColumnHandle::class,
5860
FunctionHavingHandle::class,
5961
FunctionOffsetHandle::class,

app/ApiJson/Parse/Parse.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ class Parse
1515
{
1616
protected array $tagColumn = [
1717
'tag' => null,
18-
'debug' => false
18+
'debug' => false,
19+
'other' => []
1920
];
2021

2122
protected array $globalKey = [

app/Event/ApiJson/QueryResult.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010
class QueryResult
1111
{
12-
public function __construct(public array $result)
12+
public function __construct(public array $result, public string $sql)
1313
{
1414
}
1515
}

app/Event/StatementComplete.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ class StatementComplete
1919
*/
2020
public $connection;
2121

22+
/**
23+
* The query result
24+
*
25+
* @var array|false
26+
*/
27+
public $result;
28+
2229
/**
2330
* The PDO statement.
2431
*
@@ -30,11 +37,13 @@ class StatementComplete
3037
* Create a new event instance.
3138
*
3239
* @param \Hyperf\Database\Connection $connection
40+
* @param array|false $result
3341
* @param \PDOStatement $statement
3442
*/
35-
public function __construct($connection, $statement)
43+
public function __construct($connection, $result, $statement)
3644
{
3745
$this->statement = $statement;
46+
$this->result = $result;
3847
$this->connection = $connection;
3948
}
4049
}

app/Listener/DbPreparedListener.php

Lines changed: 0 additions & 30 deletions
This file was deleted.

app/Listener/QueryResultTryToJsonListener.php

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33

44
namespace App\Listener;
55

6-
use App\Constants\ConfigCode;
7-
use App\Event\ApiJson\QueryResult;
6+
use App\Event\StatementComplete;
87
use Hyperf\Event\Annotation\Listener;
98
use Hyperf\Event\Contract\ListenerInterface;
10-
use Hyperf\Utils\Context;
119

1210
/**
1311
* @Listener
@@ -17,18 +15,15 @@ class QueryResultTryToJsonListener implements ListenerInterface
1715
public function listen(): array
1816
{
1917
return [
20-
QueryResult::class,
18+
StatementComplete::class,
2119
];
2220
}
2321

2422
public function process(object $event)
2523
{
26-
if (!$event instanceof QueryResult) return;
27-
28-
$statement = Context::get(ConfigCode::DB_QUERY_STATEMENT);
29-
if (empty($statement)) {
30-
return;
31-
}
24+
if (!$event instanceof StatementComplete) return;
25+
if (empty($event->result)) return;
26+
$statement = $event->statement;
3227

3328
$columnCount = count(array_keys(current($event->result)));
3429
$columnMeta = [];

class_map/Hyperf/Database/Connection.php

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -286,11 +286,9 @@ public function select(string $query, array $bindings = [], bool $useReadPdo = t
286286

287287
$statement->execute();
288288

289-
$response = $statement->fetchAll();
289+
$result = $statement->fetchAll();
290290

291-
$this->complete($statement);
292-
293-
return $response;
291+
return $this->complete($result, $statement);
294292
});
295293
}
296294

@@ -318,9 +316,9 @@ public function cursor(string $query, array $bindings = [], bool $useReadPdo = t
318316
// Next, we'll execute the query against the database and return the statement
319317
// so we can return the cursor. The cursor will use a PHP generator to give
320318
// back one row at a time without using a bunch of memory to render them.
321-
$statement->execute();
319+
$result = $statement->execute();
322320

323-
$this->complete($statement);
321+
$this->complete($result, $statement);
324322

325323
return $statement;
326324
});
@@ -990,12 +988,15 @@ protected function prepared(PDOStatement $statement)
990988
return $statement;
991989
}
992990

993-
protected function complete(PDOStatement $statement)
991+
protected function complete($result, PDOStatement $statement)
994992
{
995-
$this->event(new StatementComplete(
993+
$event = new StatementComplete(
996994
$this,
995+
$result,
997996
$statement
998-
));
997+
);
998+
$this->event($event);
999+
return $event->result;
9991000
}
10001001

10011002
/**

0 commit comments

Comments
 (0)