packages/ztd-query-core/src/Simulator/StatementSimulator.php
1<?php
2
3declare(strict_types=1);
4
5namespace ZtdQuery\Simulator;
6
7use ZtdQuery\Connection\StatementInterface;
8use ZtdQuery\Rewrite\QueryKind;
9use ZtdQuery\Session;
10
11/**
12 * Executes rewritten statements and applies shadow mutations for exec().
13 *
14 * Exception handling for unsupported SQL and unknown schema is now done in Session::rewrite(),
15 * so this class simply delegates to the session.
16 */
17final class StatementSimulator
18{
19 /**
20 * Session context for rewrite and mutation application.
21 *
22 * @var Session
23 */
24 private Session $session;
25
26 /**
27 * @param Session $session Current ZTD session.
28 */
29 public function __construct(Session $session)
30 {
31 $this->session = $session;
32 }
33
34 /**
35 * Simulate exec() by running result-select and updating shadow state.
36 *
37 * Session::rewrite() now handles exceptions for unsupported SQL and unknown schema
38 * based on config, so we no longer need to handle FORBIDDEN/UNKNOWN_SCHEMA here.
39 *
40 * @param callable(string): (StatementInterface|false) $executor
41 */
42 public function simulate(string $statement, callable $executor): int|false
43 {
44 $plan = $this->session->rewrite($statement);
45
46 if ($plan->kind() === QueryKind::SKIPPED) {
47 return 0;
48 }
49
50 if ($plan->kind() === QueryKind::READ) {
51 $stmt = $executor($plan->sql());
52 if ($stmt === false) {
53 return false;
54 }
55 return $stmt->rowCount();
56 }
57
58 $rows = $this->session->runResultSelectAndApplyShadow($plan, $executor);
59
60 return count($rows);
61 }
62}
63