Transactions & Raw SQL

Transactions — inTransaction()

Wrap multiple statements in a single database transaction. Piql rolls back on any throwable.

$saved = null;

table('system_user')->inTransaction(function ($porm) use (&$saved, $payload) {
    $saved = $porm->save($payload);
    table('audit_log')->save([
        'user_id' => $porm->lastSaved(),
        'action'  => 'register',
    ]);
});

The callback receives the same Porm instance; $porm->database is swapped to the transactional Piql handle for the duration of the closure.

Use a use (&$var) reference when you need values after the transaction completes.

Full raw queries — raw()

$stats = table('orders')->raw(
    'SELECT status, COUNT(*) AS c FROM orders GROUP BY status',
);

$one = table('orders')->raw(
    'SELECT * FROM orders WHERE id = :id LIMIT 1',
    ['id' => 42],
);
  • One row → object
  • Multiple rows → array
  • Always use bound parameters for user input

SQL fragments — Piql::raw()

Embed safe literal SQL inside WHERE arrays:

use Pionia\Porm\Core\Piql;

table('posts')->filter([
    'published_at[<=]' => Piql::raw('CURRENT_TIMESTAMP'),
])->all();

Raw values are not escaped — only use for trusted SQL expressions, never for concatenated user input.

Low-level Piql

$porm->getDatabase() returns Pionia\Porm\Core\Piql with Medoo-compatible methods (select, insert, update, delete, query, action, etc.). Prefer table() for application code; Piql is for debugging and framework extensions.

$piql = table('users')->getDatabase();
$piql->debug();  // echo generated SQL
$piql->log();    // return query log array

Exceptions

Database errors surface as Pionia\Porm\Exceptions\BaseDatabaseException or Pionia\Exceptions\DatabaseException. Uncaught errors in HTTP apps flow through the exception pipeline.

Related: Making queries · WHERE DSL.