All three were missing the transient-connection retry that sql_update and
run_sql_select already had. On OperationalError (stale/dropped connection),
each now retries once with a fresh engine.connect() without disposing the pool.
IntegrityError (duplicate key, FK violation, NOT NULL) continues to return
None without retrying — the same data would fail again and None signals a
data conflict to callers, distinct from False (error) or an int (success).
sql_insert_or_update retry is safe because ON DUPLICATE KEY UPDATE is idempotent.
sql_insert retry is safe because OperationalError means MariaDB rolled back.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On OperationalError, sql_update and run_sql_select were calling
sql_connect() → reconnect_db() which disposes the entire connection
pool mid-flight, killing other in-flight connections under concurrency.
Removed the sql_connect() calls; the existing retry blocks already open
a fresh engine.connect() context manager, and pool_pre_ping=True handles
stale connection detection. Also drops the now-unused sql_connect import.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Updated sql_select, sql_update, and sql_delete to use explicit 'is not None' checks for record_id. This prevents falsy ID values (like 0) from triggering generic table scans or failing to filter, which was causing the config bootstrap to accidentally load record ID 1 when ID 0 was requested.
- Modify sql_select to return False on database exceptions instead of an empty result
- Update V3 Search endpoint to catch False results and return a 500 Internal Server Error
- Enhances error visibility for frontend developers and prevents misleading 200 OK responses during SQL errors
- Refactor SQL CRUD to use engine.connect() context managers for thread safety
- Optimize connection pooling in lib_sql_core
- Clean up app/routers/api.py to fix duplicate definitions and OpenAPI KeyError
- Add 'default_qry_str' to searchable_fields for Event, Session, Presentation, Presenter, Badge, and Journal
- Add 'event_location_name' to searchable_fields for Event Session
- Verified 20/20 E2E success via repro_intermittent_errors.py
- Update sql_connect to refresh global db object via reconnect_db
- Add returns_rows check and safe fetch block in sql_select
- Prevents 500 errors during transient database connection issues