






import sys
from dataclasses import dataclass
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union

import pandas as pd
import pyarrow as pa

import datasets
import datasets.config
from datasets.features.features import require_storage_cast
from datasets.table import table_cast


if TYPE_CHECKING:
					import sqlitea

					import sqlalchemy


__snake_case     :     List[str]       =  datasets.utils.logging.get_logger(__name__)


@dataclass
class      __SCREAMING_SNAKE_CASE       ( datasets.BuilderConfig):
						_SCREAMING_SNAKE_CASE						:							Union[str, "sqlalchemy.sql.Selectable"]				=       None
						_SCREAMING_SNAKE_CASE						:							Union[str, "sqlalchemy.engine.Connection", "sqlalchemy.engine.Engine", "sqlite3.Connection"]				=       None
						_SCREAMING_SNAKE_CASE						:							Optional[Union[str, List[str]]]				=       None
						_SCREAMING_SNAKE_CASE						:							bool				=       True
						_SCREAMING_SNAKE_CASE						:							Optional[Union[List, Tuple, Dict]]				=       None
						_SCREAMING_SNAKE_CASE						:							Optional[Union[List, Dict]]				=       None
						_SCREAMING_SNAKE_CASE						:							Optional[List[str]]				=       None
						_SCREAMING_SNAKE_CASE						:							Optional[int]				=       10000
						_SCREAMING_SNAKE_CASE						:							Optional[datasets.Features]				=       None






						def    UpperCamelCase__   (						self ):






												"""simple docstring"""
												if self.sql is None:
																		raise ValueError('sql must be specified' )
												if self.con is None:
																		raise ValueError('con must be specified' )






						def    UpperCamelCase__   (						self  ,    _UpperCamelCase  ,    _UpperCamelCase = None  ,    ):






												"""simple docstring"""
												lowerCAmelCase__         =    config_kwargs.copy()
												# We need to stringify the Selectable object to make its hash deterministic

												# The process of stringifying is explained here: http://docs.sqlalchemy.org/en/latest/faq/sqlexpressions.html
												lowerCAmelCase__         =    config_kwargs['sql']
												if not isinstance(_UpperCamelCase  ,    _UpperCamelCase ):
																		if datasets.config.SQLALCHEMY_AVAILABLE and "sqlalchemy" in sys.modules:
																								import sqlalchemy

																								if isinstance(_UpperCamelCase  ,    sqlalchemy.sql.Selectable ):
																														lowerCAmelCase__         =    sqlalchemy.create_engine(config_kwargs['con'].split('://' )[0] + '://' )
																														lowerCAmelCase__         =    str(sql.compile(dialect=engine.dialect ) )
																														lowerCAmelCase__         =    sql_str
																								else:
																														raise TypeError(
																														    F"Supported types for 'sql' are string and sqlalchemy.sql.Selectable but got {type(_UpperCamelCase )}: {sql}" )
																		else:
																								raise TypeError(
																								    F"Supported types for 'sql' are string and sqlalchemy.sql.Selectable but got {type(_UpperCamelCase )}: {sql}" )
												lowerCAmelCase__         =    config_kwargs['con']
												if not isinstance(_UpperCamelCase  ,    _UpperCamelCase ):
																		lowerCAmelCase__         =    id(_UpperCamelCase )
																		logger.info(
																		    F"SQL connection 'con' of type {type(_UpperCamelCase )} couldn't be hashed properly. To enable hashing, specify 'con' as URI string instead." )

												return super().create_config_id(_UpperCamelCase  ,    custom_features=_UpperCamelCase )







						@property
						def    UpperCamelCase__   (						self ):






												"""simple docstring"""
												lowerCAmelCase__         =    {
												    'index_col': self.index_col,
												    'columns': self.columns,
												    'params': self.params,
												    'coerce_float': self.coerce_float,
												    'parse_dates': self.parse_dates,
												}
												return pd_read_sql_kwargs




class      __SCREAMING_SNAKE_CASE       ( datasets.ArrowBasedBuilder):
						_SCREAMING_SNAKE_CASE						:							Dict				=       SqlConfig






						def    UpperCamelCase__   (						self ):






												"""simple docstring"""
												return datasets.DatasetInfo(features=self.config.features )






						def    UpperCamelCase__   (						self  ,    _UpperCamelCase ):






												"""simple docstring"""
												return [datasets.SplitGenerator(name=datasets.Split.TRAIN  ,    gen_kwargs={} )]






						def    UpperCamelCase__   (						self  ,    _UpperCamelCase ):






												"""simple docstring"""
												if self.config.features is not None:
																		lowerCAmelCase__         =    self.config.features.arrow_schema
																		if all(not require_storage_cast(_UpperCamelCase ) for feature in self.config.features.values() ):
																								# cheaper cast
																								lowerCAmelCase__         =    pa.Table.from_arrays([pa_table[field.name] for field in schema]  ,    schema=_UpperCamelCase )
																		else:
																								# more expensive cast; allows str <-> int/float or str to Audio for example
																								lowerCAmelCase__         =    table_cast(_UpperCamelCase  ,    _UpperCamelCase )
												return pa_table







						def    UpperCamelCase__   (						self ):






												"""simple docstring"""
												lowerCAmelCase__         =    self.config.chunksize
												lowerCAmelCase__         =    pd.read_sql(
												    self.config.sql  ,    self.config.con  ,    chunksize=_UpperCamelCase  ,    **self.config.pd_read_sql_kwargs )
												lowerCAmelCase__         =    [sql_reader] if chunksize is None else sql_reader
												for chunk_idx, df in enumerate(_UpperCamelCase ):
																		lowerCAmelCase__         =    pa.Table.from_pandas(_UpperCamelCase )
																		yield chunk_idx, self._cast_table(_UpperCamelCase )













from __future__ import annotations

from collections.abc import Iterable, Iterator
from typing import Any, Generic, TypeVar

__snake_case     :     str       =  TypeVar("""T""", bound=bool)


class      __SCREAMING_SNAKE_CASE       ( Generic[T]):






						def __init__(						self  ,    _UpperCamelCase ):






												"""simple docstring"""
												lowerCAmelCase__         =    value
												lowerCAmelCase__         =    None
												lowerCAmelCase__         =    None






						@property
						def    UpperCamelCase__   (						self ):






												"""simple docstring"""
												return self._value







						@staticmethod
						def    UpperCamelCase__   (						_UpperCamelCase  ,    _UpperCamelCase ):






												"""simple docstring"""
												if not roota:
																		return roota

												if not roota:
																		return roota

												if roota.value > roota.value:
																		lowerCAmelCase__    ,							lowerCAmelCase__         =    roota, roota

												lowerCAmelCase__         =    roota
												lowerCAmelCase__         =    roota.right
												lowerCAmelCase__         =    roota.left
												lowerCAmelCase__         =    SkewNode.merge(_UpperCamelCase  ,    _UpperCamelCase )

												return result




class      __SCREAMING_SNAKE_CASE       ( Generic[T]):






						def __init__(						self  ,    _UpperCamelCase = () ):






												"""simple docstring"""
												lowerCAmelCase__         =    None
												if data:
																		for item in data:
																								self.insert(_UpperCamelCase )






						def __bool__(						self ):






												"""simple docstring"""
												return self._root is not None






						def __iter__(						self ):






												"""simple docstring"""
												lowerCAmelCase__         =    []
												while self:
																		result.append(self.pop() )

												# Pushing items back to the heap not to clear it.
												for item in result:
																		self.insert(_UpperCamelCase )

												return iter(_UpperCamelCase )






						def    UpperCamelCase__   (						self  ,    _UpperCamelCase ):






												"""simple docstring"""
												lowerCAmelCase__         =    SkewNode.merge(self._root  ,    SkewNode(_UpperCamelCase ) )






						def    UpperCamelCase__   (						self ):






												"""simple docstring"""
												lowerCAmelCase__         =    self.top()
												lowerCAmelCase__         =    (
												    SkewNode.merge(self._root.left  ,    self._root.right ) if self._root else None
												)

												return result






						def    UpperCamelCase__   (						self ):






												"""simple docstring"""
												if not self._root:
																		raise IndexError('Can\'t get top element for the empty heap.' )
												return self._root.value







						def    UpperCamelCase__   (						self ):






												"""simple docstring"""
												lowerCAmelCase__         =    None


if __name__ == "__main__":
					import doctest

					doctest.testmod()





