{"id":15608885,"url":"https://github.com/borislavv/symfony-clickhouse-adapter","last_synced_at":"2026-04-29T17:40:06.737Z","repository":{"id":61165431,"uuid":"548858809","full_name":"Borislavv/symfony-clickhouse-adapter","owner":"Borislavv","description":"ClickHouse implementation for PHP projects","archived":false,"fork":false,"pushed_at":"2022-10-10T09:46:27.000Z","size":23,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T08:31:57.305Z","etag":null,"topics":["adapter","clickhouse","library","php","repository","symfony"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Borislavv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-10-10T09:44:15.000Z","updated_at":"2024-01-13T07:32:47.000Z","dependencies_parsed_at":"2022-10-12T02:04:32.436Z","dependency_job_id":null,"html_url":"https://github.com/Borislavv/symfony-clickhouse-adapter","commit_stats":null,"previous_names":["borislavv/phpclickhouseadapter","borislavv/symfony-clickhouse-adapter","borislavv/php-clickhouse-adapter"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Borislavv%2Fsymfony-clickhouse-adapter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Borislavv%2Fsymfony-clickhouse-adapter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Borislavv%2Fsymfony-clickhouse-adapter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Borislavv%2Fsymfony-clickhouse-adapter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Borislavv","download_url":"https://codeload.github.com/Borislavv/symfony-clickhouse-adapter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246195046,"owners_count":20738791,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adapter","clickhouse","library","php","repository","symfony"],"created_at":"2024-10-03T05:40:24.109Z","updated_at":"2026-04-29T17:40:06.683Z","avatar_url":"https://github.com/Borislavv.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ClickHouse\n\n1. **Сущность/Entity**\n\n    1. Каждая сущность = отдельная таблица\n\n    2. Название сущности = inTheLowerCase(название таблицы)\n\n    3. Название свойств сущности = название столбцов\n\n    4. Каждая сущность, которая работает через ClickHouse, должна имплементировать интерфейс [ClickHouseEntityInterface](./src/Entity/Interfaces/ClickHouseEntityInterface.php) (_необходимо для нормализации и денормализации_).\n\n\n2. **Репозиторий/Repository**\n   \n   1. Каждый репозиторий должен наследоваться от [ClickHouseRepository](./src/ClickHouseRepository.php) (_является базовым репозиторием и имеет дефолтный функционал_) \n      и интерфейс репозитория, аналогично, должен быть унаследован от [ClickHouseRepositoryInterface](./src/Repository/Interfaces/ClickHouseRepositoryInterface.php).\n   2. (Perhaps) _Конструктор базового/абстрактного репозитория принимает 3 аргумента: `normalizer, denormalizer, entityClass`. Если в процессе работы возникают ошибки при записи, возможно, вам стоит изменить формат данных или же проверить, как ваша сущность выглядит в нормализованном виде и правильно ли она маппится на таблицу. При необходимости, смотреть в [ClickHouseEntityNormalizer](./src/Serializer/Normalizer/ClickHouseEntityNormalizer.php)._\n\n\n3. **Клиент/Adapter**\n\n   1. Паттер адаптер, который закрывает взаимодствеие с ClickHouse через [интерфейс](./src/Client/Adapter/Interfaces/ClickHouseClientAdapterInterface.php) с методами select, insert, query и ping. \n      Реализует прямой доступ к HTTP интерфейсу ClickHouse. \n      \n   2. **!!!Важно**: в коде, мы должны везде закрываться не реализацией, т.е. типом самого [класса адаптера](./src/Client/Adapter/ClickHouseClientAdapter.php), а его [интерфейсом](./src/Client/Adapter/Interfaces/ClickHouseClientAdapterInterface.php), для возможности подмены реализации.\n\n   3. **!!!Важно**: в частности, [ClickHouseClientAdapter](./src/Client/Adapter/ClickHouseClientAdapter.php) реализует метод `query`, который третьим аргументом(`isAwaitableQuery`) принимает логическое значение и если оно истинно, то добавляет в запрос уникальный ключ и возвращает как результат инстас [ClickHouseSyncResponse](./src/Client/Response/ClickHouseSyncResponse.php) (подробнее о Response|SyncResponse в следующем пункте #4). \n\n\n4. **Ответ/Response**\n\n   Из любого метода адаптера, кроме метода `ping` мы получаем экземпляр класса [ClickHouseResponse](./src/Client/Response/ClickHouseResponse.php) или же [ClickHouseSyncResponse](./src/Client/Response/ClickHouseSyncResponse.php).\n   1. [ClickHouseSyncResponse](./src/Client/Response/ClickHouseSyncResponse.php) - обертка для класса [Statement](./vendor/smi2/phpclickhouse/src/Statement.php), реализующая дополнительный функционал по ожиданию запросов (`ALTER TABLE t DELETE|UPDATE` - в ClickHouse выполняются в background-e, т.е. операция полностью не завершена, но ответ уже пришел).\n      Данный класс позволяет вам с помощью методов `await` и `isDone` явно дождаться ответа и фиксации данных.\n      1. `await` - ожидает, пока запрос не завершится, залипает в цикле, максимум на 10 минут (_конфигурируется через параметр_). \n      2. `isDone` - единоразовая проверка без залипания, полезно, если ждем фиксацию + выполняем какую-то доп. обработку или т.п..\n   2. [ClickHouseResponse](./src/Client/Response/ClickHouseResponse.php) - простая обертка для ответа из ClickHouse, является родителем для ClickHouseSyncResponse (советуется использовать метод `isSyncable` для определения, является ли экземляр сихронизируемым).\n      Простой proxy-класс скрывающий реализацию.\n\n\n6. **Примесь/Trait**\n\n   1. [ClickHouseClientTrait](./src/Traits/ClickHouseClientTrait.php) - единственный функционал, который позволяет получить вышеописанный [Adapter](./src/Client/Adapter/ClickHouseClientAdapter.php) для работы с ClickHouse.\n\n   2. Требования для использования trait-a:\n   \n      1. Класс, в котором подключается trait, должен имплементировать интерфейс [ClickHouseClientTraitInterface](./src/Traits/Interfaces/ClickHouseClientTraitInterface.php), либо же вы получите соответствующее [исклчюение](./src/Exception/ClickHouseNotImplementedException.php).\n\n\n6. **Миграция/Migration**\n   \n   1. Должна имплементировать [ClickHouseMigrationInterface](./src/Migrations/Interfaces/ClickHouseMigrationInterface.php) и \n      использовать вышеописанный trait явно (`$this-\u003eclickhouse()-\u003e(select|insert|query|ping)(...);`).\n\n\n7. **Тест/Test**\n\n   1. Если тест нуждается/взаимодействует с ClickHouse, то данный тест нужно унаследовать от [ClickHouseSetUpTestCase](./tests/_support/ClickHouseSetupTestCase.php), \n   далее, использовать по усмотрению, явно через trait или же через репозиторий, который можно получить черзе EntityManager в любом тесте.  \n\n   2. **!!!Важно:** если вы переопределяете методы `setUp` или `tearDown`, нужно вызвать родительский метод (`parent::(tearDown|setUp)();`), либо явно очистить таблицы в тестовой БД в ClickHouse (`$this-\u003eclearTables();`). **!!!Важно:** очистка таблиц не произойдет и будет выброшено [исключение](./src/Exception/ClickHouseBadRequestException.php), если вы пытаетесь использовать этот метод не в тестовой среде.\n\n   3. На данный момент для сущностей, которые работают с ClickHouse нельзя создать фикстуры (в дальнейшем, возможно, этот функционал будет реализован). Загрузку данных, можно реализовать явно, создав отдельный метод в тесте.\n\n\n8. **Исключение/Exception**\n\n   1. [Все исключения](./src/Exception), которые возникают при работе с ClickHouse, имплементируют [ClickHouseExceptionInterface](./src/Exception/Interfaces/ClickHouseExceptionInterface.php) и наследуются от [ClickHouseException](./src/Exception/ClickHouseException.php).\n      Соответственно, могут быть перехвачены базовым интефейсом `\\Throwable`.\n\n\n9. **Запрос/Request (only syncable)**\n   \n   1. В данном кейсе нужно отметить, что если вы попытаетесь отправить запрос типа `Sync`, т.е. указав `isAwaitableQuery` параметр в значение `true` и в переданом SQL-e не будет условия `WHERE`, то получите соотвествующее [исклчюение](./src/Exception/ClickHouseBadRequestException.php) и том, что запросы данного вида не разрешены. Вы должны всегда явно указывать `WHERE {condition}` для запросов типа `Sync`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fborislavv%2Fsymfony-clickhouse-adapter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fborislavv%2Fsymfony-clickhouse-adapter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fborislavv%2Fsymfony-clickhouse-adapter/lists"}