Skip to content

Commit d710fc4

Browse files
authored
feat: add Client::insertPayload() and slightly refactor sql logging (#279)
1 parent 7c553f6 commit d710fc4

17 files changed

+284
-138
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ jobs:
4444

4545
- name: "Install dependencies with Composer"
4646
uses: "ramsey/composer-install@v3"
47+
env:
48+
COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.COMPOSER_AUTH }}"}}'
4749
with:
4850
composer-options: "${{ matrix.composer-options }}"
4951
dependency-versions: "${{ matrix.dependency-versions }}"
@@ -93,6 +95,8 @@ jobs:
9395

9496
- name: "Install dependencies with Composer"
9597
uses: "ramsey/composer-install@v3"
98+
env:
99+
COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.COMPOSER_AUTH }}"}}'
96100
with:
97101
dependency-versions: "${{ matrix.dependency-versions }}"
98102

.github/workflows/coding-standards.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ jobs:
3030

3131
- name: "Install dependencies with Composer"
3232
uses: "ramsey/composer-install@v3"
33+
env:
34+
COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.COMPOSER_AUTH }}"}}'
3335

3436
- name: "Run PHP_CodeSniffer"
3537
run: "vendor/bin/phpcs -q --no-colors --report=checkstyle | cs2pr"

.github/workflows/static-analysis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ jobs:
3030

3131
- name: "Install dependencies with Composer"
3232
uses: "ramsey/composer-install@v3"
33+
env:
34+
COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.COMPOSER_AUTH }}"}}'
3335

3436
- name: "Run a static analysis with phpstan/phpstan"
3537
run: "vendor/bin/phpstan analyse --error-format=checkstyle | cs2pr"

README.md

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ $clickHouseClient = new PsrClickHouseClient(
6060
$psr17Factory,
6161
$psr17Factory
6262
),
63+
new LoggerChain(),
6364
[],
6465
new DateTimeZone('UTC')
6566
);
@@ -84,41 +85,6 @@ framework:
8485
database: '%clickhouse.database%'
8586
```
8687
87-
### Logging
88-
89-
`SimPod\ClickHouseClient\Client\Http\LoggerPlugin` is available to be used with [HTTPlug PluginClient](http://docs.php-http.org/en/latest/plugins/index.html).
90-
91-
This is the
92-
93-
```php
94-
<?php
95-
96-
declare(strict_types=1);
97-
98-
namespace Cdn77\Mon\Core\Infrastructure\Symfony\Service\ClickHouse;
99-
100-
use Http\Client\Common\PluginClient;
101-
use SimPod\ClickHouseClient\Client\Http\LoggerPlugin;
102-
use SimPod\ClickHouseClient\Logger\SqlLogger;
103-
use Symfony\Component\HttpClient\HttplugClient;
104-
use Symfony\Contracts\HttpClient\HttpClientInterface;
105-
106-
final class HttpClientFactory
107-
{
108-
public function __construct(private HttpClientInterface $clickHouseClient, private SqlLogger $sqlLogger)
109-
{
110-
}
111-
112-
public function create() : PluginClient
113-
{
114-
return new PluginClient(
115-
new HttplugClient($this->clickHouseClient),
116-
[new LoggerPlugin($this->sqlLogger)]
117-
);
118-
}
119-
}
120-
```
121-
12288
### Time Zones
12389
12490
ClickHouse does not have date times with timezones.

composer.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"require-dev": {
4040
"cdn77/coding-standard": "^7.0",
4141
"infection/infection": "^0.29.0",
42+
"kafkiansky/phpclick": "dev-bump",
4243
"nyholm/psr7": "^1.2",
4344
"php-http/message-factory": "^1.1",
4445
"phpstan/extension-installer": "^1.1",
@@ -58,5 +59,9 @@
5859
"psr-4": {
5960
"SimPod\\ClickHouseClient\\Tests\\": "tests/"
6061
}
61-
}
62+
},
63+
"repositories": [{
64+
"type": "vcs",
65+
"url": "https://github.com/simPod/PHPClick"
66+
}]
6267
}

src/Client/ClickHouseClient.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace SimPod\ClickHouseClient\Client;
66

77
use Psr\Http\Client\ClientExceptionInterface;
8+
use Psr\Http\Message\StreamInterface;
89
use SimPod\ClickHouseClient\Exception\CannotInsert;
910
use SimPod\ClickHouseClient\Exception\ServerError;
1011
use SimPod\ClickHouseClient\Exception\UnsupportedParamType;
@@ -85,4 +86,21 @@ public function insert(string $table, array $values, array|null $columns = null,
8586
* @template O of Output
8687
*/
8788
public function insertWithFormat(string $table, Format $inputFormat, string $data, array $settings = []): void;
89+
90+
/**
91+
* @param array<string, float|int|string> $settings
92+
* @param list<string> $columns
93+
* @param Format<Output<mixed>> $inputFormat
94+
*
95+
* @throws ClientExceptionInterface
96+
* @throws CannotInsert
97+
* @throws ServerError
98+
*/
99+
public function insertPayload(
100+
string $table,
101+
Format $inputFormat,
102+
StreamInterface $payload,
103+
array $columns = [],
104+
array $settings = [],
105+
): void;
88106
}

src/Client/Http/LoggerPlugin.php

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

src/Client/Http/RequestFactory.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,13 @@ public function __construct(
4949
$this->uri = $uri;
5050
}
5151

52-
/** @throws UnsupportedParamType */
53-
public function prepareRequest(RequestOptions $requestOptions): RequestInterface
54-
{
52+
/** @param array<string, mixed> $additionalOptions */
53+
public function initRequest(
54+
RequestSettings $requestSettings,
55+
array $additionalOptions = [],
56+
): RequestInterface {
5557
$query = http_build_query(
56-
$requestOptions->settings,
58+
$requestSettings->settings + $additionalOptions,
5759
'',
5860
'&',
5961
PHP_QUERY_RFC3986,
@@ -70,11 +72,20 @@ public function prepareRequest(RequestOptions $requestOptions): RequestInterface
7072
}
7173
}
7274

73-
$request = $this->requestFactory->createRequest('POST', $uri);
75+
return $this->requestFactory->createRequest('POST', $uri);
76+
}
7477

75-
preg_match_all('~\{([a-zA-Z\d]+):([a-zA-Z\d ]+(\(.+\))?)}~', $requestOptions->sql, $matches);
78+
/** @throws UnsupportedParamType */
79+
public function prepareSqlRequest(
80+
string $sql,
81+
RequestSettings $requestSettings,
82+
RequestOptions $requestOptions,
83+
): RequestInterface {
84+
$request = $this->initRequest($requestSettings);
85+
86+
preg_match_all('~\{([a-zA-Z\d]+):([a-zA-Z\d ]+(\(.+\))?)}~', $sql, $matches);
7687
if ($matches[0] === []) {
77-
$body = $this->streamFactory->createStream($requestOptions->sql);
88+
$body = $this->streamFactory->createStream($sql);
7889
try {
7990
return $request->withBody($body);
8091
} catch (InvalidArgumentException) {
@@ -93,7 +104,7 @@ static function (array $acc, string|int $k) use ($matches) {
93104
[],
94105
);
95106

96-
$streamElements = [['name' => 'query', 'contents' => $requestOptions->sql]];
107+
$streamElements = [['name' => 'query', 'contents' => $sql]];
97108
foreach ($requestOptions->params as $name => $value) {
98109
$type = $paramToType[$name] ?? null;
99110
if ($type === null) {

src/Client/Http/RequestOptions.php

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,9 @@
66

77
final class RequestOptions
88
{
9-
/** @var array<string, float|int|string> */
10-
public array $settings;
11-
12-
/**
13-
* @param array<string, mixed> $params
14-
* @param array<string, float|int|string> $defaultSettings
15-
* @param array<string, float|int|string> $querySettings
16-
*/
9+
/** @param array<string, mixed> $params */
1710
public function __construct(
18-
public string $sql,
1911
public array $params,
20-
array $defaultSettings,
21-
array $querySettings,
2212
) {
23-
$this->settings = $querySettings + $defaultSettings;
2413
}
2514
}

src/Client/Http/RequestSettings.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimPod\ClickHouseClient\Client\Http;
6+
7+
final class RequestSettings
8+
{
9+
/** @var array<string, float|int|string> */
10+
public array $settings;
11+
12+
/**
13+
* @param array<string, float|int|string> $defaultSettings
14+
* @param array<string, float|int|string> $querySettings
15+
*/
16+
public function __construct(
17+
array $defaultSettings,
18+
array $querySettings,
19+
) {
20+
$this->settings = $querySettings + $defaultSettings;
21+
}
22+
}

src/Client/PsrClickHouseAsyncClient.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@
1212
use Psr\Http\Message\ResponseInterface;
1313
use SimPod\ClickHouseClient\Client\Http\RequestFactory;
1414
use SimPod\ClickHouseClient\Client\Http\RequestOptions;
15+
use SimPod\ClickHouseClient\Client\Http\RequestSettings;
1516
use SimPod\ClickHouseClient\Exception\ServerError;
1617
use SimPod\ClickHouseClient\Format\Format;
18+
use SimPod\ClickHouseClient\Logger\SqlLogger;
1719
use SimPod\ClickHouseClient\Output\Output;
1820
use SimPod\ClickHouseClient\Sql\SqlFactory;
1921
use SimPod\ClickHouseClient\Sql\ValueFormatter;
2022

23+
use function uniqid;
24+
2125
class PsrClickHouseAsyncClient implements ClickHouseAsyncClient
2226
{
2327
private SqlFactory $sqlFactory;
@@ -26,6 +30,7 @@ class PsrClickHouseAsyncClient implements ClickHouseAsyncClient
2630
public function __construct(
2731
private HttpAsyncClient $asyncClient,
2832
private RequestFactory $requestFactory,
33+
private SqlLogger|null $sqlLogger = null,
2934
private array $defaultSettings = [],
3035
DateTimeZone|null $clickHouseTimeZone = null,
3136
) {
@@ -83,20 +88,27 @@ private function executeRequest(
8388
array $settings = [],
8489
callable|null $processResponse = null,
8590
): PromiseInterface {
86-
$request = $this->requestFactory->prepareRequest(
87-
new RequestOptions(
88-
$sql,
89-
$params,
91+
$request = $this->requestFactory->prepareSqlRequest(
92+
$sql,
93+
new RequestSettings(
9094
$this->defaultSettings,
9195
$settings,
9296
),
97+
new RequestOptions(
98+
$params,
99+
),
93100
);
94101

102+
$id = uniqid('', true);
103+
$this->sqlLogger?->startQuery($id, $sql);
104+
95105
return Create::promiseFor(
96106
$this->asyncClient->sendAsyncRequest($request),
97107
)
98108
->then(
99-
static function (ResponseInterface $response) use ($processResponse) {
109+
function (ResponseInterface $response) use ($id, $processResponse) {
110+
$this->sqlLogger?->stopQuery($id);
111+
100112
if ($response->getStatusCode() !== 200) {
101113
throw ServerError::fromResponse($response);
102114
}
@@ -107,6 +119,7 @@ static function (ResponseInterface $response) use ($processResponse) {
107119

108120
return $processResponse($response);
109121
},
122+
fn () => $this->sqlLogger?->stopQuery($id),
110123
);
111124
}
112125
}

0 commit comments

Comments
 (0)