-
Notifications
You must be signed in to change notification settings - Fork 49
Expand file tree
/
Copy path01-event-dispatcher.php
More file actions
181 lines (157 loc) · 5.31 KB
/
01-event-dispatcher.php
File metadata and controls
181 lines (157 loc) · 5.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
<?php
/**
* Example: PSR-14 Event Dispatcher Integration
*
* This example demonstrates how to use the PSR-14 Event Dispatcher
* to listen to database events like query execution, transactions, and errors.
*
* Requires: symfony/event-dispatcher or any other PSR-14 compatible implementation
*/
require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/../helpers.php';
use Psr\EventDispatcher\EventDispatcherInterface;
use tommyknocker\pdodb\PdoDb;
use tommyknocker\pdodb\events\ConnectionOpenedEvent;
use tommyknocker\pdodb\events\QueryExecutedEvent;
use tommyknocker\pdodb\events\QueryErrorEvent;
use tommyknocker\pdodb\events\TransactionCommittedEvent;
use tommyknocker\pdodb\events\TransactionRolledBackEvent;
use tommyknocker\pdodb\events\TransactionStartedEvent;
// Simple event dispatcher implementation (or use Symfony EventDispatcher)
class SimpleEventDispatcher implements EventDispatcherInterface
{
/** @var array<string, array<callable>> */
protected array $listeners = [];
/**
* Register a listener for a specific event class.
*
* @param string $eventClass Event class name
* @param callable $listener Listener callback
*/
public function listen(string $eventClass, callable $listener): void
{
$this->listeners[$eventClass][] = $listener;
}
/**
* Dispatch an event.
*
* @param object $event
*
* @return object
*/
public function dispatch(object $event): object
{
$eventClass = $event::class;
if (isset($this->listeners[$eventClass])) {
foreach ($this->listeners[$eventClass] as $listener) {
$listener($event);
}
}
return $event;
}
}
// Create event dispatcher
$dispatcher = new SimpleEventDispatcher();
// Listen to connection opened events
$dispatcher->listen(ConnectionOpenedEvent::class, function (ConnectionOpenedEvent $event) {
echo sprintf(
"✓ Connection opened: %s (DSN: %s)\n",
$event->getDriver(),
substr($event->getDsn(), 0, 50)
);
});
// Listen to query executed events
$dispatcher->listen(QueryExecutedEvent::class, function (QueryExecutedEvent $event) {
$sqlPreview = substr($event->getSql(), 0, 60);
if (strlen($event->getSql()) > 60) {
$sqlPreview .= '...';
}
echo sprintf(
" Query executed: %s (%.2f ms, %d rows, driver: %s)\n",
$sqlPreview,
$event->getExecutionTime(),
$event->getRowsAffected(),
$event->getDriver()
);
});
// Listen to transaction events
$dispatcher->listen(TransactionStartedEvent::class, function (TransactionStartedEvent $event) {
echo sprintf(" → Transaction started on %s\n", $event->getDriver());
});
$dispatcher->listen(TransactionCommittedEvent::class, function (TransactionCommittedEvent $event) {
echo sprintf(
" ✓ Transaction committed on %s (duration: %.2f ms)\n",
$event->getDriver(),
$event->getDuration()
);
});
$dispatcher->listen(TransactionRolledBackEvent::class, function (TransactionRolledBackEvent $event) {
echo sprintf(
" ✗ Transaction rolled back on %s (duration: %.2f ms)\n",
$event->getDriver(),
$event->getDuration()
);
});
// Listen to error events
$dispatcher->listen(QueryErrorEvent::class, function (QueryErrorEvent $event) {
echo sprintf(
" ✗ Query error: %s - %s\n",
substr($event->getSql(), 0, 40),
$event->getException()->getMessage()
);
});
// Create database with event dispatcher
$config = getExampleConfig();
$driver = $config['driver'];
unset($config['driver']);
$db = new PdoDb($driver, $config);
$db->setEventDispatcher($dispatcher);
echo "=== PSR-14 Event Dispatcher Example ===\n\n";
// Create table (will trigger connection opened and query executed events)
echo "1. Creating table...\n";
$driver = getCurrentDriver($db);
$autoIncrement = $driver === 'mysql' ? 'INT AUTO_INCREMENT PRIMARY KEY' :
($driver === 'pgsql' ? 'SERIAL PRIMARY KEY' : 'INTEGER PRIMARY KEY AUTOINCREMENT');
$db->rawQuery("DROP TABLE IF EXISTS users");
$db->rawQuery("CREATE TABLE users (
id $autoIncrement,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)");
// Insert data (will trigger query executed events)
echo "\n2. Inserting data...\n";
$db->find()->table('users')->insert([
'name' => 'Alice',
'email' => 'alice@example.com',
]);
$db->find()->table('users')->insert([
'name' => 'Bob',
'email' => 'bob@example.com',
]);
// Transaction example (will trigger transaction events)
echo "\n3. Transaction example...\n";
$db->startTransaction();
try {
$db->find()->table('users')->insert([
'name' => 'Charlie',
'email' => 'charlie@example.com',
]);
$db->commit();
echo " Transaction completed successfully.\n";
} catch (Exception $e) {
$db->rollback();
echo " Transaction rolled back.\n";
}
// Query data
echo "\n4. Querying data...\n";
$users = $db->find()->table('users')->get();
echo sprintf(" Found %d users\n", count($users));
// Error example (will trigger query error event)
echo "\n5. Error example...\n";
try {
$db->rawQuery('SELECT * FROM nonexistent_table');
} catch (Exception $e) {
// Error event was already dispatched
}
echo "\n=== Example completed ===\n";