Пакет · cdo

API CDO

CDO extends PDO, добавляя методы DML ниже. Всё остальное — query, prepare, fetch*, транзакции, атрибуты — унаследовано от PDO без изменений. Каждый метод здесь бросает CDOException при сбое, оборачивая исходный PDOException.

Идентификаторы квотируются, значения привязываются

Значения привязываются как параметры подготовленного запроса. Имена таблиц и колонок — которые привязать нельзя — квотируются символами кавычек драйвера ("…" для PostgreSQL/SQLite/Oracle, `…` для MySQL/MariaDB), поэтому эти методы DML безопасны даже с динамически собранными именами. Поскольку квотированные идентификаторы в PostgreSQL регистрозависимы, передавайте имена ровно так, как они существуют в схеме (users, а не Users). Это квотирование действует только в методах CDO — имена колонок, переданные в Qb, не квотируются.

Создание

Вы редко создаёте CDO напрямую — за вас это делает ConnectionPool. Конструктор:

php
public function __construct(
  DbConfigInterface $config,
  int $timeout = 5,
  bool $debug = false
)
Параметр Тип По умолчанию Описание
config DbConfigInterface Конфиг соединения (учётные данные, драйвер, логгер)
timeout int 5 Тайм-аут соединения в секундах (PDO::ATTR_TIMEOUT)
debug bool false При true устанавливает PDO::ERRMODE_EXCEPTION

getDriverName

php
public function getDriverName(): string

Возвращает нормализованный драйвер: 'pgsql', 'mysql', 'mariadb', 'sqlite' или 'oci'. В отличие от PDO::ATTR_DRIVER_NAME, различает MariaDB и MySQL — см. Определение драйвера.

insert

php
final public function insert(string $table, object|array $entity): mixed

Вставляет одну строку и возвращает сгенерированный первичный ключ.

Параметр Тип Описание
table string Имя таблицы
entity `object\ array`
  • Возвращает первичный ключ — значение первого ключа сущности, прочитанное через RETURNING (PostgreSQL/MariaDB) или lastInsertId() (MySQL/SQLite/Oracle). Возвращает null, когда нет сгенерированного id для сообщения.
  • Значения null в entity исключаются из INSERT.
  • Бросает CDOException при сбое запроса.

insertBatch

php
final public function insertBatch(
  string $table,
  iterable $entities,
  int $chunkSize = 1000
): int

Пакетно вставляет много строк как чанкованные многострочные INSERT.

Параметр Тип По умолчанию Описание
table string Имя таблицы
entities iterable Массив или генератор массивов/объектов
chunkSize int 1000 Строк на один INSERT
  • Возвращает общее число вставленных строк — для обычного INSERT этот счётчик одинаково сообщается на PostgreSQL/MySQL/MariaDB/SQLite. Пустой массив entities — no-op, возвращающий 0.
  • Строки группируются по сигнатуре колонок (набору ненулевых колонок) перед чанкованием, поэтому строки одинаковой формы батчатся вместе, а смешанные формы больше не ломают многострочный список VALUES.
  • Значения null в отдельных строках исключаются. Бросает CDOException при сбое либо если у строки нет ни одной ненулевой колонки.

upsert

php
final public function upsert(
  string $table,
  object|array $entity,
  array $conflictColumns,
  ?array $updateColumns = null
): mixed

Вставляет строку либо обновляет/игнорирует её при уникальном конфликте.

Параметр Тип По умолчанию Описание
table string Имя таблицы
entity `object\ array`
conflictColumns array Колонка(и), определяющие уникальность
updateColumns `array\ null` null
  • Возвращает первичный ключ на PostgreSQL (через RETURNING); на MySQL/MariaDB/SQLite возвращает lastInsertId() (null, если новая строка не была вставлена).
  • Синтаксис конфликта подстраивается под драйвер: PostgreSQL и SQLite используют ON CONFLICT, тогда как MySQL/MariaDB используют INSERT IGNORE / ON DUPLICATE KEY UPDATE.
  • Бросает CDOException, если conflictColumns пуст, или при сбое запроса.
  • Токены выражений :new / :current — см. Плейсхолдеры апсерта.

upsertBatch

php
final public function upsertBatch(
  string $table,
  iterable $entities,
  array $conflictColumns,
  ?array $updateColumns = null,
  int $chunkSize = 500
): void

Пакетный апсерт с чанкованием.

Параметр Тип По умолчанию Описание
table string Имя таблицы
entities iterable Массив или генератор массивов/объектов
conflictColumns array Колонка(и), определяющие уникальность
updateColumns `array\ null` null
chunkSize int 500 Строк на запрос
  • Возвращает ничего — void by design: число затронутых строк апсерта несопоставимо между драйверами, поэтому стабильного значения для возврата нет. Пустой entities ⇒ no-op; пустой conflictColumns ⇒ бросает исключение.

update

php
final public function update(string $table, object|array $entity, Qb $qb): int

Обновляет строки, соответствующие условию Qb.

Параметр Тип Описание
table string Имя таблицы
entity `object\ array`
qb Qb Условие для секции WHERE
  • Возвращает число затронутых строк (rowCount()).
  • Бросает CDOException при сбое.

delete

php
final public function delete(string $table, Qb $qb): int

Удаляет строки, соответствующие условию Qb.

Параметр Тип Описание
table string Имя таблицы
qb Qb Условие для секции WHERE
  • Возвращает число удалённых строк. Бросает CDOException при сбое.

transaction

php
public function transaction(Closure $callback): void

Выполняет $callback внутри транзакции: начинает её, вызывает колбэк и коммитит при успехе. Если колбэк бросает исключение, транзакция откатывается, а исключение пробрасывается повторно.

  • Откат защищён проверкой inTransaction(), а его собственный сбой логируется (не бросается), поэтому всегда пробрасывается исходное исключение колбэка — неудавшийся откат никогда его не маскирует.
  • Бросает то, что бросил колбэк (после попытки отката).

Поведение по базам данных

Работает на всех драйверах, но с оговорками: на MySQL откатываются только таблицы InnoDB (MyISAM — нет). DDL внутри транзакции транзакционен на PostgreSQL/SQLite, но на MySQL/MariaDB/Oracle DDL-оператор вызывает неявный коммит и не может быть откачен. Вложенность не поддерживается — PDO не поддерживает вложенные транзакции.

applyDatabaseTimezone

php
public function applyDatabaseTimezone(mixed $driver, string $tz): void

Устанавливает часовой пояс сессии в соответствие с PHP. Вызывается автоматически при подключении; открыт как публичный, чтобы можно было переприменить его после сброса на уровне драйвера. Поведение по драйверам описано в Определении драйвера.

Только запись; чтение остаётся PDO

Здесь намеренно нет select / find. Читайте унаследованными методами PDO и фрагментом Qb для WHERE.

Связанное