|  | 
| 235 | 235 |     ]); | 
| 236 | 236 | echo "Updated age with modulo\n"; | 
| 237 | 237 | 
 | 
|  | 238 | +echo "\n9. Error Handling Examples\n"; | 
|  | 239 | +echo "---------------------------\n"; | 
|  | 240 | + | 
|  | 241 | +// Demonstrate exception handling | 
|  | 242 | +try { | 
|  | 243 | +    // This will work fine | 
|  | 244 | +    $users = $db->find()->from('users')->get(); | 
|  | 245 | +    echo "Successfully retrieved " . count($users) . " users\n"; | 
|  | 246 | +     | 
|  | 247 | +    // Try to insert duplicate email (will cause constraint violation) | 
|  | 248 | +    $db->find()->table('users')->insert([ | 
|  | 249 | +        'name' => 'Duplicate User', | 
|  | 250 | +        'email' => 'alice@example.com',  // This email already exists | 
|  | 251 | +        'age' => 25 | 
|  | 252 | +    ]); | 
|  | 253 | +} catch (\tommyknocker\pdodb\exceptions\ConstraintViolationException $e) { | 
|  | 254 | +    echo "Constraint violation caught: " . $e->getMessage() . "\n"; | 
|  | 255 | +    echo "Constraint: " . $e->getConstraintName() . "\n"; | 
|  | 256 | +    echo "Table: " . $e->getTableName() . "\n"; | 
|  | 257 | +    echo "Retryable: " . ($e->isRetryable() ? 'Yes' : 'No') . "\n"; | 
|  | 258 | +} catch (\tommyknocker\pdodb\exceptions\DatabaseException $e) { | 
|  | 259 | +    echo "Database error caught: " . $e->getMessage() . "\n"; | 
|  | 260 | +    echo "Driver: " . $e->getDriver() . "\n"; | 
|  | 261 | +    echo "Category: " . $e->getCategory() . "\n"; | 
|  | 262 | +} | 
|  | 263 | + | 
|  | 264 | +// Demonstrate error context | 
|  | 265 | +try { | 
|  | 266 | +    // Try invalid query | 
|  | 267 | +    $db->find()->from('nonexistent_table')->get(); | 
|  | 268 | +} catch (\tommyknocker\pdodb\exceptions\QueryException $e) { | 
|  | 269 | +    echo "Query error caught: " . $e->getMessage() . "\n"; | 
|  | 270 | +    echo "Query: " . $e->getQuery() . "\n"; | 
|  | 271 | +    echo "Context: " . json_encode($e->getContext()) . "\n"; | 
|  | 272 | +} | 
|  | 273 | + | 
|  | 274 | +echo "\n10. Advanced JSON Operations\n"; | 
|  | 275 | +echo "-----------------------------\n"; | 
|  | 276 | + | 
|  | 277 | +// JSON length and type | 
|  | 278 | +$jsonUsers = $db->find() | 
|  | 279 | +    ->from('users') | 
|  | 280 | +    ->select([ | 
|  | 281 | +        'id', | 
|  | 282 | +        'name', | 
|  | 283 | +        'tag_count' => Db::jsonLength('tags'), | 
|  | 284 | +        'tags_type' => Db::jsonType('tags') | 
|  | 285 | +    ]) | 
|  | 286 | +    ->where(Db::jsonLength('tags'), 2, '>') | 
|  | 287 | +    ->get(); | 
|  | 288 | +echo "Users with more than 2 tags: " . count($jsonUsers) . "\n"; | 
|  | 289 | + | 
|  | 290 | +// JSON ordering | 
|  | 291 | +$sortedByAge = $db->find() | 
|  | 292 | +    ->from('users') | 
|  | 293 | +    ->orderBy(Db::jsonGet('meta', ['age']), 'DESC') | 
|  | 294 | +    ->where(Db::jsonExists('meta', ['age'])) | 
|  | 295 | +    ->get(); | 
|  | 296 | +echo "Users sorted by JSON age: " . count($sortedByAge) . "\n"; | 
|  | 297 | + | 
|  | 298 | +echo "\n11. Query Analysis Examples\n"; | 
|  | 299 | +echo "---------------------------\n"; | 
|  | 300 | + | 
|  | 301 | +// Get SQL without execution | 
|  | 302 | +$query = $db->find() | 
|  | 303 | +    ->table('users') | 
|  | 304 | +    ->where('age', 25, '>') | 
|  | 305 | +    ->andWhere('status', 'active') | 
|  | 306 | +    ->toSQL(); | 
|  | 307 | +echo "Generated SQL: " . $query['sql'] . "\n"; | 
|  | 308 | +echo "Parameters: " . json_encode($query['params']) . "\n"; | 
|  | 309 | + | 
|  | 310 | +// Table structure analysis | 
|  | 311 | +$structure = $db->find()->table('users')->describe(); | 
|  | 312 | +echo "Table structure columns: " . count($structure) . "\n"; | 
|  | 313 | + | 
|  | 314 | +echo "\n12. Bulk Operations\n"; | 
|  | 315 | +echo "------------------\n"; | 
|  | 316 | + | 
|  | 317 | +// UPSERT example (works differently on SQLite) | 
|  | 318 | +try { | 
|  | 319 | +    $upsertResult = $db->find()->table('users')->onDuplicate([ | 
|  | 320 | +        'age' => Db::inc(), | 
|  | 321 | +        'updated_at' => Db::now() | 
|  | 322 | +    ])->insert([ | 
|  | 323 | +        'email' => 'upsert@example.com', | 
|  | 324 | +        'name' => 'Upsert User', | 
|  | 325 | +        'age' => 30 | 
|  | 326 | +    ]); | 
|  | 327 | +    echo "UPSERT result: " . $upsertResult . "\n"; | 
|  | 328 | +} catch (\Exception $e) { | 
|  | 329 | +    // SQLite doesn't support ON DUPLICATE KEY UPDATE, so we'll do a manual upsert | 
|  | 330 | +    $existing = $db->find() | 
|  | 331 | +        ->from('users') | 
|  | 332 | +        ->where('email', 'upsert@example.com') | 
|  | 333 | +        ->getOne(); | 
|  | 334 | +     | 
|  | 335 | +    if ($existing) { | 
|  | 336 | +        $db->find() | 
|  | 337 | +            ->table('users') | 
|  | 338 | +            ->where('email', 'upsert@example.com') | 
|  | 339 | +            ->update([ | 
|  | 340 | +                'age' => Db::inc(), | 
|  | 341 | +                'updated_at' => Db::now() | 
|  | 342 | +            ]); | 
|  | 343 | +        echo "Updated existing user\n"; | 
|  | 344 | +    } else { | 
|  | 345 | +        $db->find()->table('users')->insert([ | 
|  | 346 | +            'email' => 'upsert@example.com', | 
|  | 347 | +            'name' => 'Upsert User', | 
|  | 348 | +            'age' => 30 | 
|  | 349 | +        ]); | 
|  | 350 | +        echo "Inserted new user\n"; | 
|  | 351 | +    } | 
|  | 352 | +} | 
|  | 353 | + | 
|  | 354 | +// Check if user exists after upsert | 
|  | 355 | +$exists = $db->find() | 
|  | 356 | +    ->from('users') | 
|  | 357 | +    ->where('email', 'upsert@example.com') | 
|  | 358 | +    ->exists(); | 
|  | 359 | +echo "User exists after upsert: " . ($exists ? 'Yes' : 'No') . "\n"; | 
|  | 360 | + | 
| 238 | 361 | echo "\n=== Demo Complete ===\n"; | 
0 commit comments