# Source code for geoalchemy2.admin.dialects.common

    """This module defines functions used by several dialects."""

    import sqlalchemy
    from packaging import version
    from sqlalchemy import Column
    from sqlalchemy import String
    from sqlalchemy.sql import expression
    from sqlalchemy.types import TypeDecorator

    from geoalchemy2.elements import WKBElement
    from geoalchemy2.types import Geometry

    _SQLALCHEMY_VERSION_BEFORE_14 = version.parse(sqlalchemy.__version__) < version.parse("1.4")

    def _spatial_idx_name(table_name, column_name):
        return f"idx_{table_name}_{column_name}"

    def _format_select_args(*args):
        if _SQLALCHEMY_VERSION_BEFORE_14:
            return [args]
        else:
            return args

    def check_management(*args):
        """Default function to check management (always True by default)."""
        return True

    def _get_gis_cols(table, spatial_types, dialect, check_col_management=None):
        func = check_col_management if check_col_management is not None else check_management
        return [
            col
            for col in table.columns
            if (
                isinstance(col, Column)
                and _check_spatial_type(col.type, spatial_types, dialect)
                and func(col)
            )
        ]

    def _check_spatial_type(tested_type, spatial_types, dialect=None):
        return isinstance(tested_type, spatial_types) or (
            isinstance(tested_type, TypeDecorator)
            and isinstance(tested_type.load_dialect_impl(dialect), spatial_types)
        )

    def _get_dispatch_info(table, bind, check_col_management=None):
        """Get info required for dispatch events."""
        dialect = bind.dialect

        # Filter Geometry columns from the table
        # Note: Geography and PostGIS >= 2.0 don't need this
        gis_cols = _get_gis_cols(table, Geometry, dialect, check_col_management=check_col_management)

        # Find all other columns that are not managed Geometries
        regular_cols = [x for x in table.columns if x not in gis_cols]

        return dialect, gis_cols, regular_cols

    def _update_table_for_dispatch(table, regular_cols):
        """Update the table before dispatch events."""
        # Save original table column list for later
        table.info["_saved_columns"] = table.columns

        # Temporarily patch a set of columns not including the
        # managed Geometry columns
        column_collection = expression.ColumnCollection()
        for col in regular_cols:
            column_collection.add(col)
        table.columns = column_collection

    def setup_create_drop(table, bind, check_col_management=None):
        """Prepare the table for before_create and before_drop events."""
        dialect, gis_cols, regular_cols = _get_dispatch_info(table, bind, check_col_management)
        _update_table_for_dispatch(table, regular_cols)
        return dialect, gis_cols, regular_cols

    def reflect_geometry_column(inspector, table, column_info):
        return  # pragma: no cover

    def before_create(table, bind, **kw):
        return  # pragma: no cover

    def after_create(table, bind, **kw):
        return  # pragma: no cover

    def before_drop(table, bind, **kw):
        return  # pragma: no cover

    def after_drop(table, bind, **kw):
        return  # pragma: no cover

    def compile_bin_literal(wkb_clause):
        """Compile a binary literal for WKBElement."""
        wkb_data = wkb_clause.value
        if isinstance(wkb_data, bytes | memoryview | WKBElement):
            if isinstance(wkb_data, memoryview):
                wkb_data = wkb_data.tobytes()
            if isinstance(wkb_data, bytes):
                wkb_data = WKBElement._wkb_to_hex(wkb_data)
            elif isinstance(wkb_data, WKBElement):
                wkb_data = wkb_data.desc

            wkb_clause = expression.bindparam(
                key=wkb_clause.key,
                value=wkb_data,
                type_=String(),
                unique=True,
            )
        return wkb_clause