Skip to content

Commit

Permalink
Support Request Headers (#137)
Browse files Browse the repository at this point in the history
- rename `ClickHouseClient::selectWithParameters()` to `ClickHouseClient::selectWithParams()` (same for `ClickHouseAsyncClient`)
- `$requestQueryParameters` renamed to `$requestQueryParams`
  • Loading branch information
simPod authored Jan 12, 2022
1 parent 6952a02 commit 923a65a
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 96 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
- "21.1"
- "21.2"
- "21.3"
- "21.4"
# - "21.4" It does not support header auth
- "21.5"
- "21.6"
- "21.7"
Expand Down
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Naming used here is the same as in ClickHouse docs.
- [PSR Factories who?](#psr-factories-who)
- [Sync API](#sync-api)
- [Select](#select)
- [Select With Parameters](#select-with-parameters)
- [Select With Params](#select-with-params)
- [Insert](#insert)
- [Async API](#async-api)
- [Select](#select-1)
Expand Down Expand Up @@ -57,10 +57,10 @@ $clickHouseClient = new PsrClickHouseClient(
),
'https://localhost:8123',
[
'database' => 'dbname',
'user' => 'username',
'password' => 'secret',
‘X-ClickHouse-User' => 'username',
'X-ClickHouse-Key' => 'secret',
],
['database' => 'dbname'],
new DateTimeZone('UTC')
);
```
Expand Down Expand Up @@ -117,13 +117,14 @@ use SimPod\ClickHouseClient\Output;
$output = $client->select(
'SELECT * FROM table',
new JsonEachRow(),
[],
['force_primary_key' => 1]
);
```

### Select With Parameters
### Select With Params

`ClickHouseClient::selectWithParameters()`
`ClickHouseClient::selectWithParams()`

Same as `ClickHouseClient::select()` except it also allows [parameter binding](#parameters-binding).

Expand All @@ -136,10 +137,11 @@ use SimPod\ClickHouseClient\Output;

/** @var ClickHouseClient $client */
/** @var Output\JsonEachRow $output */
$output = $client->selectWithParameters(
$output = $client->selectWithParams(
'SELECT * FROM :table',
['table' => 'table_name'],
new JsonEachRow(),
[],
['force_primary_key' => 1]
);
```
Expand Down
27 changes: 17 additions & 10 deletions src/Client/ClickHouseAsyncClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,36 @@
use SimPod\ClickHouseClient\Format\Format;
use SimPod\ClickHouseClient\Output\Output;

/** @see Output hack for IDE to preserve `use` */
interface ClickHouseAsyncClient
{
/**
* @see Output hack for IDE to preserve `use`
*
* @param array<string, float|int|string> $requestParameters
* @param array<string, string|array<string>> $requestHeaders
* @param array<string, float|int|string> $requestQueryParams
* @psalm-param Format<O> $outputFormat
*
* @template O of Output
*/
public function select(string $sql, Format $outputFormat, array $requestParameters = []) : PromiseInterface;
public function select(
string $sql,
Format $outputFormat,
array $requestHeaders = [],
array $requestQueryParams = []
) : PromiseInterface;

/**
* @param array<string, float|int|string> $requestParameters
* @param array<string, mixed> $queryParameters
* @param array<string, mixed> $statementParams
* @param array<string, string|array<string>> $requestHeaders
* @param array<string, float|int|string> $requestQueryParams
* @psalm-param Format<O> $outputFormat
*
* @template O of Output
*/
public function selectWithParameters(
string $query,
array $queryParameters,
public function selectWithParams(
string $sql,
array $statementParams,
Format $outputFormat,
array $requestParameters = []
array $requestHeaders = [],
array $requestQueryParams = []
) : PromiseInterface;
}
41 changes: 29 additions & 12 deletions src/Client/ClickHouseClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,56 @@

interface ClickHouseClient
{
/** @param array<string, float|int|string> $requestParameters */
public function executeQuery(string $query, array $requestParameters = []) : void;
/**
* @param array<string, string|array<string>> $requestHeaders
* @param array<string, float|int|string> $requestQueryParams
*/
public function executeQuery(string $query, array $requestHeaders = [], array $requestQueryParams = []) : void;

/**
* @param array<string, mixed> $queryParameters
* @param array<string, float|int|string> $requestParameters
* @param array<string, mixed> $statementParams
* @param array<string, string|array<string>> $requestHeaders
* @param array<string, float|int|string> $requestQueryParams
*/
public function executeQueryWithParameters(string $query, array $queryParameters, array $requestParameters = []) : void;
public function executeQueryWithParameters(
string $query,
array $statementParams,
array $requestHeaders = [],
array $requestQueryParams = []
) : void;

/**
* @param array<string, float|int|string> $requestParameters
* @param array<string, string|array<string>> $requestHeaders
* @param array<string, float|int|string> $requestQueryParams
* @psalm-param Format<O> $outputFormat
*
* @psalm-return O
*
* @template O of Output
*/
public function select(string $query, Format $outputFormat, array $requestParameters = []) : Output;
public function select(
string $query,
Format $outputFormat,
array $requestHeaders = [],
array $requestQueryParams = []
) : Output;

/**
* @param array<string, float|int|string> $requestParameters
* @param array<string, mixed> $queryParameters
* @param array<string, string|array<string>> $requestHeaders
* @param array<string, float|int|string> $requestQueryParams
* @param array<string, mixed> $statementParams
* @psalm-param Format<O> $outputFormat
*
* @psalm-return O
*
* @template O of Output
*/
public function selectWithParameters(
public function selectWithParams(
string $query,
array $queryParameters,
array $statementParams,
Format $outputFormat,
array $requestParameters = []
array $requestHeaders = [],
array $requestQueryParams = []
) : Output;

/**
Expand Down
9 changes: 6 additions & 3 deletions src/Client/Http/RequestFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,20 @@ public function prepareRequest(string $endpoint, RequestOptions $requestOptions)
$uri = $this->uriFactory->createUri($endpoint);
$uri = $uri->withQuery(
http_build_query(
$requestOptions->parameters,
$requestOptions->queryParams,
'',
'&',
PHP_QUERY_RFC3986
)
);

$body = $this->streamFactory->createStream($requestOptions->sql);

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

foreach ($requestOptions->headers as $name => $value) {
$request = $request->withHeader($name, $value);
}

$body = $this->streamFactory->createStream($requestOptions->sql);
$request = $request->withBody($body);

return $request;
Expand Down
25 changes: 18 additions & 7 deletions src/Client/Http/RequestOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,27 @@ final class RequestOptions
{
public string $sql;

/** @var array<string, string|array<string>> */
public array $headers;

/** @var array<string, float|int|string> */
public array $parameters;
public array $queryParams;

/**
* @param array<string, float|int|string> $defaultParameters
* @param array<string, float|int|string> $requestParameters
* @param array<string, string|array<string>> $defaultHeaders
* @param array<string, string|array<string>> $requestHeaders
* @param array<string, float|int|string> $defaultQueryParams
* @param array<string, float|int|string> $requestParams
*/
public function __construct(string $sql, array $defaultParameters, array $requestParameters)
{
$this->sql = $sql;
$this->parameters = $defaultParameters + $requestParameters;
public function __construct(
string $sql,
array $defaultHeaders,
array $requestHeaders,
array $defaultQueryParams,
array $requestParams
) {
$this->sql = $sql;
$this->headers = $defaultHeaders + $requestHeaders;
$this->queryParams = $defaultQueryParams + $requestParams;
}
}
61 changes: 42 additions & 19 deletions src/Client/PsrClickHouseAsyncClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,38 +25,51 @@ class PsrClickHouseAsyncClient implements ClickHouseAsyncClient

private string $endpoint;

/** @var array<string, string|array<string>> */
private array $defaultHeaders;

/** @var array<string, float|int|string> */
private array $defaultParameters;
private array $defaultQueryParams;

private SqlFactory $sqlFactory;

/** @param array<string, float|int|string> $defaultParameters */
/**
* @param array<string, string|array<string>> $defaultHeaders
* @param array<string, float|int|string> $defaultQueryParams
*/
public function __construct(
HttpAsyncClient $asyncClient,
RequestFactory $requestFactory,
string $endpoint,
array $defaultParameters = [],
array $defaultHeaders = [],
array $defaultQueryParams = [],
?DateTimeZone $clickHouseTimeZone = null
) {
$this->asyncClient = $asyncClient;
$this->requestFactory = $requestFactory;
$this->endpoint = $endpoint;
$this->defaultParameters = $defaultParameters;
$this->sqlFactory = new SqlFactory(new ValueFormatter($clickHouseTimeZone));
$this->asyncClient = $asyncClient;
$this->requestFactory = $requestFactory;
$this->endpoint = $endpoint;
$this->defaultHeaders = $defaultHeaders;
$this->defaultQueryParams = $defaultQueryParams;
$this->sqlFactory = new SqlFactory(new ValueFormatter($clickHouseTimeZone));
}

/**
* {@inheritDoc}
*/
public function select(string $sql, Format $outputFormat, array $requestParameters = []) : PromiseInterface
{
public function select(
string $sql,
Format $outputFormat,
array $requestHeaders = [],
array $requestParameters = []
) : PromiseInterface {
$formatClause = $outputFormat::toSql();

return $this->executeRequest(
<<<CLICKHOUSE
$sql
$formatClause
CLICKHOUSE,
$requestHeaders,
$requestParameters,
static function (ResponseInterface $response) use ($outputFormat) : Output {
return $outputFormat::output((string) $response->getBody());
Expand All @@ -67,30 +80,40 @@ static function (ResponseInterface $response) use ($outputFormat) : Output {
/**
* {@inheritDoc}
*/
public function selectWithParameters(string $query, array $queryParameters, Format $outputFormat, array $requestParameters = []) : PromiseInterface
{
public function selectWithParams(
string $sql,
array $statementParams,
Format $outputFormat,
array $requestHeaders = [],
array $requestQueryParams = []
) : PromiseInterface {
return $this->select(
$this->sqlFactory->createWithParameters($query, $queryParameters),
$this->sqlFactory->createWithParameters($sql, $statementParams),
$outputFormat,
$requestParameters
$requestHeaders,
$requestQueryParams
);
}

/**
* @param array<string, float|int|string> $requestParameters
* @param callable(ResponseInterface):mixed|null $processResponse
* @param array<string, string|array<string>> $requestHeaders
* @param array<string, float|int|string> $requestQueryParams
* @param (callable(ResponseInterface):mixed)|null $processResponse
*/
private function executeRequest(
string $sql,
array $requestParameters = [],
array $requestHeaders = [],
array $requestQueryParams = [],
?callable $processResponse = null
) : PromiseInterface {
$request = $this->requestFactory->prepareRequest(
$this->endpoint,
new RequestOptions(
$sql,
$this->defaultParameters,
$requestParameters
$this->defaultHeaders,
$requestHeaders,
$this->defaultQueryParams,
$requestQueryParams
)
);

Expand Down
Loading

0 comments on commit 923a65a

Please sign in to comment.