Skip to content

Commit

Permalink
feat: add Client::insertPayload() and slightly refactor sql logging (
Browse files Browse the repository at this point in the history
  • Loading branch information
simPod authored Jan 22, 2025
1 parent 7c553f6 commit d710fc4
Show file tree
Hide file tree
Showing 17 changed files with 284 additions and 138 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ jobs:

- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v3"
env:
COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.COMPOSER_AUTH }}"}}'
with:
composer-options: "${{ matrix.composer-options }}"
dependency-versions: "${{ matrix.dependency-versions }}"
Expand Down Expand Up @@ -93,6 +95,8 @@ jobs:

- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v3"
env:
COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.COMPOSER_AUTH }}"}}'
with:
dependency-versions: "${{ matrix.dependency-versions }}"

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/coding-standards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ jobs:

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

- name: "Run PHP_CodeSniffer"
run: "vendor/bin/phpcs -q --no-colors --report=checkstyle | cs2pr"
2 changes: 2 additions & 0 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ jobs:

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

- name: "Run a static analysis with phpstan/phpstan"
run: "vendor/bin/phpstan analyse --error-format=checkstyle | cs2pr"
36 changes: 1 addition & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ $clickHouseClient = new PsrClickHouseClient(
$psr17Factory,
$psr17Factory
),
new LoggerChain(),
[],
new DateTimeZone('UTC')
);
Expand All @@ -84,41 +85,6 @@ framework:
database: '%clickhouse.database%'
```
### Logging
`SimPod\ClickHouseClient\Client\Http\LoggerPlugin` is available to be used with [HTTPlug PluginClient](http://docs.php-http.org/en/latest/plugins/index.html).

This is the

```php
<?php
declare(strict_types=1);
namespace Cdn77\Mon\Core\Infrastructure\Symfony\Service\ClickHouse;
use Http\Client\Common\PluginClient;
use SimPod\ClickHouseClient\Client\Http\LoggerPlugin;
use SimPod\ClickHouseClient\Logger\SqlLogger;
use Symfony\Component\HttpClient\HttplugClient;
use Symfony\Contracts\HttpClient\HttpClientInterface;
final class HttpClientFactory
{
public function __construct(private HttpClientInterface $clickHouseClient, private SqlLogger $sqlLogger)
{
}
public function create() : PluginClient
{
return new PluginClient(
new HttplugClient($this->clickHouseClient),
[new LoggerPlugin($this->sqlLogger)]
);
}
}
```

### Time Zones
ClickHouse does not have date times with timezones.
Expand Down
7 changes: 6 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"require-dev": {
"cdn77/coding-standard": "^7.0",
"infection/infection": "^0.29.0",
"kafkiansky/phpclick": "dev-bump",
"nyholm/psr7": "^1.2",
"php-http/message-factory": "^1.1",
"phpstan/extension-installer": "^1.1",
Expand All @@ -58,5 +59,9 @@
"psr-4": {
"SimPod\\ClickHouseClient\\Tests\\": "tests/"
}
}
},
"repositories": [{
"type": "vcs",
"url": "https://github.com/simPod/PHPClick"
}]
}
18 changes: 18 additions & 0 deletions src/Client/ClickHouseClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace SimPod\ClickHouseClient\Client;

use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\StreamInterface;
use SimPod\ClickHouseClient\Exception\CannotInsert;
use SimPod\ClickHouseClient\Exception\ServerError;
use SimPod\ClickHouseClient\Exception\UnsupportedParamType;
Expand Down Expand Up @@ -85,4 +86,21 @@ public function insert(string $table, array $values, array|null $columns = null,
* @template O of Output
*/
public function insertWithFormat(string $table, Format $inputFormat, string $data, array $settings = []): void;

/**
* @param array<string, float|int|string> $settings
* @param list<string> $columns
* @param Format<Output<mixed>> $inputFormat
*
* @throws ClientExceptionInterface
* @throws CannotInsert
* @throws ServerError
*/
public function insertPayload(
string $table,
Format $inputFormat,
StreamInterface $payload,
array $columns = [],
array $settings = [],
): void;
}
40 changes: 0 additions & 40 deletions src/Client/Http/LoggerPlugin.php

This file was deleted.

27 changes: 19 additions & 8 deletions src/Client/Http/RequestFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@ public function __construct(
$this->uri = $uri;
}

/** @throws UnsupportedParamType */
public function prepareRequest(RequestOptions $requestOptions): RequestInterface
{
/** @param array<string, mixed> $additionalOptions */
public function initRequest(
RequestSettings $requestSettings,
array $additionalOptions = [],
): RequestInterface {
$query = http_build_query(
$requestOptions->settings,
$requestSettings->settings + $additionalOptions,
'',
'&',
PHP_QUERY_RFC3986,
Expand All @@ -70,11 +72,20 @@ public function prepareRequest(RequestOptions $requestOptions): RequestInterface
}
}

$request = $this->requestFactory->createRequest('POST', $uri);
return $this->requestFactory->createRequest('POST', $uri);
}

preg_match_all('~\{([a-zA-Z\d]+):([a-zA-Z\d ]+(\(.+\))?)}~', $requestOptions->sql, $matches);
/** @throws UnsupportedParamType */
public function prepareSqlRequest(
string $sql,
RequestSettings $requestSettings,
RequestOptions $requestOptions,
): RequestInterface {
$request = $this->initRequest($requestSettings);

preg_match_all('~\{([a-zA-Z\d]+):([a-zA-Z\d ]+(\(.+\))?)}~', $sql, $matches);
if ($matches[0] === []) {
$body = $this->streamFactory->createStream($requestOptions->sql);
$body = $this->streamFactory->createStream($sql);
try {
return $request->withBody($body);
} catch (InvalidArgumentException) {
Expand All @@ -93,7 +104,7 @@ static function (array $acc, string|int $k) use ($matches) {
[],
);

$streamElements = [['name' => 'query', 'contents' => $requestOptions->sql]];
$streamElements = [['name' => 'query', 'contents' => $sql]];
foreach ($requestOptions->params as $name => $value) {
$type = $paramToType[$name] ?? null;
if ($type === null) {
Expand Down
13 changes: 1 addition & 12 deletions src/Client/Http/RequestOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,9 @@

final class RequestOptions
{
/** @var array<string, float|int|string> */
public array $settings;

/**
* @param array<string, mixed> $params
* @param array<string, float|int|string> $defaultSettings
* @param array<string, float|int|string> $querySettings
*/
/** @param array<string, mixed> $params */
public function __construct(
public string $sql,
public array $params,
array $defaultSettings,
array $querySettings,
) {
$this->settings = $querySettings + $defaultSettings;
}
}
22 changes: 22 additions & 0 deletions src/Client/Http/RequestSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace SimPod\ClickHouseClient\Client\Http;

final class RequestSettings
{
/** @var array<string, float|int|string> */
public array $settings;

/**
* @param array<string, float|int|string> $defaultSettings
* @param array<string, float|int|string> $querySettings
*/
public function __construct(
array $defaultSettings,
array $querySettings,
) {
$this->settings = $querySettings + $defaultSettings;
}
}
23 changes: 18 additions & 5 deletions src/Client/PsrClickHouseAsyncClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@
use Psr\Http\Message\ResponseInterface;
use SimPod\ClickHouseClient\Client\Http\RequestFactory;
use SimPod\ClickHouseClient\Client\Http\RequestOptions;
use SimPod\ClickHouseClient\Client\Http\RequestSettings;
use SimPod\ClickHouseClient\Exception\ServerError;
use SimPod\ClickHouseClient\Format\Format;
use SimPod\ClickHouseClient\Logger\SqlLogger;
use SimPod\ClickHouseClient\Output\Output;
use SimPod\ClickHouseClient\Sql\SqlFactory;
use SimPod\ClickHouseClient\Sql\ValueFormatter;

use function uniqid;

class PsrClickHouseAsyncClient implements ClickHouseAsyncClient
{
private SqlFactory $sqlFactory;
Expand All @@ -26,6 +30,7 @@ class PsrClickHouseAsyncClient implements ClickHouseAsyncClient
public function __construct(
private HttpAsyncClient $asyncClient,
private RequestFactory $requestFactory,
private SqlLogger|null $sqlLogger = null,
private array $defaultSettings = [],
DateTimeZone|null $clickHouseTimeZone = null,
) {
Expand Down Expand Up @@ -83,20 +88,27 @@ private function executeRequest(
array $settings = [],
callable|null $processResponse = null,
): PromiseInterface {
$request = $this->requestFactory->prepareRequest(
new RequestOptions(
$sql,
$params,
$request = $this->requestFactory->prepareSqlRequest(
$sql,
new RequestSettings(
$this->defaultSettings,
$settings,
),
new RequestOptions(
$params,
),
);

$id = uniqid('', true);
$this->sqlLogger?->startQuery($id, $sql);

return Create::promiseFor(
$this->asyncClient->sendAsyncRequest($request),
)
->then(
static function (ResponseInterface $response) use ($processResponse) {
function (ResponseInterface $response) use ($id, $processResponse) {
$this->sqlLogger?->stopQuery($id);

if ($response->getStatusCode() !== 200) {
throw ServerError::fromResponse($response);
}
Expand All @@ -107,6 +119,7 @@ static function (ResponseInterface $response) use ($processResponse) {

return $processResponse($response);
},
fn () => $this->sqlLogger?->stopQuery($id),

Check warning on line 122 in src/Client/PsrClickHouseAsyncClient.php

View workflow job for this annotation

GitHub Actions / Infection

Escaped Mutant for Mutator "NullSafeMethodCall": @@ @@ return $response; } return $processResponse($response); - }, fn() => $this->sqlLogger?->stopQuery($id)); + }, fn() => $this->sqlLogger->stopQuery($id)); } }
);
}
}
Loading

0 comments on commit d710fc4

Please sign in to comment.