





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


_lowerCamelCase							=     datasets.utils.logging.get_logger(__name__)




@dataclass
class 					UpperCamelCase_    (       datasets.BuilderConfig      ):
							lowerCamelCase_          =   None
							lowerCamelCase_          =   None
							lowerCamelCase_          =   None
							lowerCamelCase_          =   True
							lowerCamelCase_          =   None
							lowerCamelCase_          =   None
							lowerCamelCase_          =   None
							lowerCamelCase_          =   1_00_00
							lowerCamelCase_          =   None


							def        _snake_case					(							self      :Tuple						)				->				str:



									"""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        _snake_case					(							self      :Dict							,			__A      :dict							,			__A      :Optional[datasets.Features] = None							,			)				->				str:



									"""simple docstring"""



									SCREAMING_SNAKE_CASE__								= 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
									SCREAMING_SNAKE_CASE__								= config_kwargs["""sql"""]
									if not isinstance(__A							,			__A						):
											if datasets.config.SQLALCHEMY_AVAILABLE and "sqlalchemy" in sys.modules:
													import sqlalchemy

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

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


							@property
							def        _snake_case					(							self      :Tuple						)				->				Tuple:



									"""simple docstring"""



									SCREAMING_SNAKE_CASE__								= {
									    """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 					UpperCamelCase_    (       datasets.ArrowBasedBuilder      ):
							lowerCamelCase_          =   SqlConfig


							def        _snake_case					(							self      :List[str]						)				->				Optional[Any]:



									"""simple docstring"""



									return datasets.DatasetInfo(features=self.config.features						)


							def        _snake_case					(							self      :List[Any]							,			__A      :List[Any]						)				->				List[Any]:



									"""simple docstring"""



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


							def        _snake_case					(							self      :List[str]							,			__A      :pa.Table						)				->				pa.Table:



									"""simple docstring"""



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


							def        _snake_case					(							self      :List[str]						)				->				Any:



									"""simple docstring"""



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






from typing import Callable






def 			SCREAMING_SNAKE_CASE__							(    UpperCamelCase__:							Callable      ):

		def wrapper(UpperCamelCase__:							List[Any]      ):
				SCREAMING_SNAKE_CASE__								= function_with_docstring.__doc__
				return target_function

		return wrapper