|
3 | 3 | namespace Teto\SQL\Replacer;
|
4 | 4 |
|
5 | 5 | use Teto\SQL\ProcessorInterface;
|
| 6 | +use Teto\SQL\ReplacerInterface; |
6 | 7 |
|
7 | 8 | use DomainException;
|
8 | 9 |
|
|
12 | 13 | * @copyright 2016 pixiv Inc.
|
13 | 14 | * @license https://github.com/BaguettePHP/TetoSQL/blob/master/LICENSE MPL-2.0
|
14 | 15 | */
|
15 |
| -class ForBlock implements ProcessorInterface |
| 16 | +class ForBlock implements ReplacerInterface |
16 | 17 | {
|
17 |
| - const FOR_PATTERN = '/ |
18 |
| -^\s*%for\s*(?:\[(?<glue>[^\]]*)\])?\s+(?<name>:[a-zA-Z0-9_]+\s*$) # first line |
19 |
| -(?<block>\s[\s\S]*?\s) # block, includes %else |
20 |
| -^\s*%endfor$ # block termination |
21 |
| -/mx'; |
| 18 | + const FOR_PATTERN = '(?:^|\s)%for\s*(?:\[(?<forGlue>[^\]]*)\])?\s+(?<forName>:[a-zA-Z0-9_]+\s) # first line |
| 19 | +(?<forBlock>\s[\s\S]*?)\s # block, includes %else |
| 20 | +(?:^|\s*)%endfor(?:\s|$) # block termination |
| 21 | +'; |
22 | 22 |
|
23 |
| - /** @var DynamicPlaceholder */ |
24 |
| - private $placeholder_replacer; |
| 23 | + /** @phpstan-var list<ProcessorInterface> */ |
| 24 | + private $processors; |
25 | 25 |
|
26 |
| - public function __construct(DynamicPlaceholder $placeholder_replacer) |
| 26 | + /** |
| 27 | + * @phpstan-param list<ProcessorInterface> $processors |
| 28 | + */ |
| 29 | + public function __construct(array $processors) |
27 | 30 | {
|
28 |
| - $this->placeholder_replacer = $placeholder_replacer; |
| 31 | + $this->processors = $processors; |
29 | 32 | }
|
30 | 33 |
|
31 |
| - public function processQuery($pdo, $sql, array $params, array &$bind_values) |
| 34 | + public function getKey() |
32 | 35 | {
|
33 |
| - $built_sql = preg_replace_callback(self::FOR_PATTERN, function (array $matches) use ( |
34 |
| - $pdo, $params, &$bind_values |
35 |
| - ) { |
36 |
| - $glue = $matches['glue']; |
37 |
| - $name = rtrim($matches['name']); |
38 |
| - if (!isset($params[$name])) { |
39 |
| - throw new DomainException(sprintf('Must be assigned parameter %s.', $name)); |
40 |
| - } |
41 |
| - if (!is_array($params[$name])) { |
42 |
| - throw new DomainException(sprintf('Parameter %s must be an array.', $name)); |
43 |
| - } |
| 36 | + return 'for'; |
| 37 | + } |
44 | 38 |
|
45 |
| - /** @phpstan-var array<non-empty-string, array<non-empty-string, mixed>> $array */ |
46 |
| - $array = $params[$name]; |
| 39 | + public function getPattern() |
| 40 | + { |
| 41 | + return self::FOR_PATTERN; |
| 42 | + } |
47 | 43 |
|
48 |
| - $block = rtrim($matches['block'], "\n"); |
49 |
| - if (strpos($block, '%for') !== false) { |
50 |
| - throw new DomainException('Nested %for is not supported.'); |
51 |
| - } |
| 44 | + public function replaceQuery($pdo, array $matches, array $params, array &$bind_values) |
| 45 | + { |
| 46 | + $glue = $matches['forGlue']; |
| 47 | + if ($glue === '') { |
| 48 | + $glue = ','; |
| 49 | + } |
| 50 | + $name = rtrim($matches['forName']); |
| 51 | + if (!isset($params[$name])) { |
| 52 | + throw new DomainException(sprintf('Must be assigned parameter %s.', $name)); |
| 53 | + } |
| 54 | + if (!is_array($params[$name])) { |
| 55 | + throw new DomainException(sprintf('Parameter %s must be an array.', $name)); |
| 56 | + } |
52 | 57 |
|
53 |
| - $replaced = []; |
54 |
| - foreach ($array as $row) { |
55 |
| - $replaced[] = $this->placeholder_replacer->processQuery($pdo, $block, $row, $bind_values); |
56 |
| - } |
| 58 | + /** @phpstan-var array<non-empty-string, array<non-empty-string, mixed>> $array */ |
| 59 | + $array = $params[$name]; |
57 | 60 |
|
58 |
| - return implode($glue, $replaced); |
59 |
| - }, $sql); |
| 61 | + $block = $matches['forBlock']; |
| 62 | + if (strpos($block, '%for') !== false) { |
| 63 | + throw new DomainException('Nested %for is not supported.'); |
| 64 | + } |
60 | 65 |
|
61 |
| - assert($built_sql !== null); |
| 66 | + $replaced = []; |
| 67 | + foreach ($array as $row) { |
| 68 | + $new = $block; |
| 69 | + foreach ($this->processors as $processor) { |
| 70 | + $new = $processor->processQuery($pdo, $new, $row, $bind_values); |
| 71 | + } |
| 72 | + $replaced[] = \ltrim($new); |
| 73 | + } |
62 | 74 |
|
63 |
| - return $built_sql; |
| 75 | + return implode($glue, $replaced); |
64 | 76 | }
|
65 | 77 | }
|
0 commit comments