Package · cdo

Updating & deleting

Both update() and delete() are driven by a Qb condition for the WHERE clause and return an affected-row count. The condition and the new values are all bound — nothing is interpolated into SQL.

Update rows

Pass the table, the new values, and a Qb condition. The return value is the number of rows changed.

php
use Flytachi\Winter\Cdo\Qb;

$affected = $cdo->update('users',
  ['name' => 'Alice Smith', 'updated_at' => date('Y-m-d H:i:s')],
  Qb::eq('id', 1)
);

echo $affected; // number of rows updated

The new values become SET name = :S_name, ... with typed binds, and the Qb fragment becomes the WHERE. Both sets of placeholders are distinct, so a column can appear in both the SET and the condition without collision.

No condition means no WHERE guard

update() and delete() always emit the Qb fragment as the WHERE. If you build a condition that turns out empty (for example every optional filter was skipped), you can produce an UPDATE/DELETE without a WHERE and touch every row. Guard against an empty Qb before calling — see dynamic filters.

Update with a compound condition

Any Qb composition works as the WHERE:

php
$affected = $cdo->update('users',
  ['status' => 'inactive'],
  Qb::and(
      Qb::lt('last_login', '2024-01-01'),
      Qb::eq('status', 'active'),
  )
);

Delete rows

delete() takes a table and a Qb condition, and returns the deleted-row count:

php
// by id
$deleted = $cdo->delete('users', Qb::eq('id', 1));

// by a set of ids
$deleted = $cdo->delete('users', Qb::in('id', [1, 2, 3]));

// by a compound condition
$deleted = $cdo->delete('sessions',
  Qb::and(
      Qb::lt('expires_at', date('Y-m-d H:i:s')),
      Qb::eq('is_active', false),
  )
);

Values are bound, including in SET

Update values go through the same type-aware binder as everything else: an array becomes JSON, an int binds as an integer, a DateTimeInterface becomes Y-m-d H:i:s. You can pass rich values directly:

php
$cdo->update('products',
  ['attributes' => ['color' => 'red', 'size' => 'M']], // bound as JSON
  Qb::eq('id', 42)
);

See Parameter binding for the full type map.