code: def _connect(
      connection_factory: Callable[[], Connection]
  ) -> Iterator[Cursor]:
      connection = connection_factory()
      _check_connection_is_dbapi2_compliant(connection)
  
      try:
          cursor = connection.cursor()
          _check_cursor_is_dbapi2_compliant(cursor)
          yield cursor
          connection.commit()
      except Exception:
          # `rollback` is optional since not all databases provide transaction support.
          try:
              connection.rollback()
          except Exception as e:
              # Each connector implements its own `NotSupportError` class, so we check
              # the exception's name instead of using `isinstance`.
              if (
                  isinstance(e, AttributeError)
                  or e.__class__.__name__ == "NotSupportedError"
              ):
                  pass
          raise
      finally:
          connection.close()
  
file_path: ray/python/ray/data/datasource/sql_datasource.py
imports: import math
  from contextlib import contextmanager
  from typing import Any, Callable, Iterable, Iterator, List, Optional
  from ray.data.block import Block, BlockAccessor, BlockMetadata
  from ray.data.datasource.datasource import Datasource, ReadTask
  from ray.util.annotations import PublicAPI
label_desc: Use image node_id 4 for calling a global function with example usage: _connect(connection_factory) without return types