Skip to content

Commit d5cda3c

Browse files
committed
add SqlServer parser
1 parent 18e9f06 commit d5cda3c

3 files changed

Lines changed: 405 additions & 0 deletions

File tree

src/SqlServerMultiQueryParser.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Nextras\MultiQueryParser;
4+
5+
use Iterator;
6+
use Nextras\MultiQueryParser\Exception\RuntimeException;
7+
use function file_get_contents;
8+
use function preg_match;
9+
use function strlen;
10+
11+
12+
class SqlServerMultiQueryParser implements IMultiQueryParser
13+
{
14+
public function parseFile(string $path): Iterator
15+
{
16+
$content = @file_get_contents($path);
17+
if ($content === false) {
18+
throw new RuntimeException("Cannot open file '$path'.");
19+
}
20+
21+
$offset = 0;
22+
$pattern = $this->getQueryPattern();
23+
var_dump($pattern);
24+
25+
while (preg_match($pattern, $content, $match, 0, $offset)) {
26+
$offset += strlen($match[0]);
27+
28+
if (isset($match['query']) && $match['query'] !== '') {
29+
yield $match['query'];
30+
} else {
31+
break;
32+
}
33+
}
34+
35+
if ($offset !== strlen($content)) {
36+
throw new RuntimeException("Failed to parse file '$path', please report an issue.");
37+
}
38+
}
39+
40+
41+
private function getQueryPattern(): string
42+
{
43+
$simpleQuery = /** @lang PhpRegExp */ '~
44+
(?:
45+
\\s
46+
| /\\* (?: [^*]++ | \\*(?!/) )*+ \\*/
47+
| -- [^\\n]*+
48+
)*+
49+
(?<simplequery>
50+
(?:
51+
[^;\'"[/-]++
52+
| \' (?: [^\'] )*+ \'
53+
| " (?: [^"] )*+ "
54+
| /\\* (?: [^*]++ | \\*(?!/) )*+ \\*/
55+
| -- [^\\n]*+
56+
| (?!;) .
57+
)++
58+
)
59+
;
60+
~x';
61+
return /** @lang PhpRegExp */ '~
62+
(?:
63+
\\s
64+
| /\\* (?: [^*]++ | \\*(?!/) )*+ \\*/
65+
| -- [^\\n]*+
66+
)*+
67+
68+
(?:
69+
(?:
70+
(?<query>
71+
(?:
72+
[^B;\'"[/-]++
73+
| \' (?: [^\'] )*+ \'
74+
| " (?: [^"] )*+ "
75+
| /\\* (?: [^*]++ | \\*(?!/) )*+ \\*/
76+
| BEGIN (?: \s*END\s*| ' . substr($simpleQuery, 1, -2) . ')*
77+
| -- [^\\n]*+
78+
| (?!;) .
79+
)++
80+
)
81+
(?: ; | \\z )
82+
)
83+
|
84+
(?:
85+
\\z
86+
)
87+
)
88+
~xsAS';
89+
}
90+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php declare(strict_types = 1);
2+
3+
/**
4+
* @testCase
5+
*/
6+
7+
namespace Nextras\MultiQueryParser;
8+
9+
use Tester\Assert;
10+
use Tester\TestCase;
11+
12+
13+
require_once __DIR__ . '/../bootstrap.php';
14+
15+
16+
class SqlServerMultiQueryParserTest extends TestCase
17+
{
18+
public function testFile()
19+
{
20+
$parser = new SqlServerMultiQueryParser();
21+
$queries = iterator_to_array($parser->parseFile(__DIR__ . '/data/sqlserver.sql'));
22+
Assert::count(69, $queries);
23+
Assert::same(<<<SQL
24+
CREATE TRIGGER mydatabase.trigger_book_stats
25+
ON yourtable.books
26+
AFTER INSERT, DELETE
27+
AS
28+
BEGIN
29+
SET NOCOUNT ON;
30+
INSERT INTO yourtable.book_stats(
31+
book_id,
32+
string_value
33+
)
34+
SELECT
35+
i.book_id,
36+
'INS'
37+
FROM
38+
inserted i
39+
UNION ALL
40+
SELECT
41+
d.book_id,
42+
'DEL'
43+
FROM
44+
deleted d;
45+
END
46+
SQL, $queries[67]);
47+
}
48+
}
49+
50+
51+
(new SqlServerMultiQueryParserTest())->run();

0 commit comments

Comments
 (0)