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   ):



 '''simple docstring'''




 __A           = None
 __A           = None
 __A           = None
 __A           = True
 __A           = None
 __A           = None
 __A           = None
 __A           = 10_000
 __A           = None







 def 						__UpperCAmelCase							(						self							:					int)		->     Dict:


   """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							:					Optional[Any]				,      lowercase_							:					Any				,      lowercase_							:					Union[str, Any] = None				,      )		->     Union[str, Any]:


   """simple docstring"""







   _UpperCamelCase				=  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
   _UpperCamelCase				=  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):
         _UpperCamelCase				=  sqlalchemy.create_engine(config_kwargs["con"].split("://")[0] + "://")
         _UpperCamelCase				=  str(sql.compile(dialect=engine.dialect))
         _UpperCamelCase				=  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}')
   _UpperCamelCase				=  config_kwargs["con"]
   if not isinstance(a__				,      a__):
     _UpperCamelCase				=  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 						__UpperCAmelCase							(						self							:					Tuple)		->     Dict:


   """simple docstring"""







   _UpperCamelCase				=  {
       "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   ):



 '''simple docstring'''




 __A           = SqlConfig







 def 						__UpperCAmelCase							(						self							:					str)		->     Tuple:


   """simple docstring"""







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







 def 						__UpperCAmelCase							(						self							:					List[Any]				,      lowercase_							:					str)		->     List[Any]:


   """simple docstring"""







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







 def 						__UpperCAmelCase							(						self							:					List[str]				,      lowercase_							:					Dict)		->     Tuple:


   """simple docstring"""







   if self.config.features is not None:
     _UpperCamelCase				=  self.config.features.arrow_schema
     if all(not require_storage_cast(a__) for feature in self.config.features.values()):
       # cheaper cast
       _UpperCamelCase				=  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
       _UpperCamelCase				=  table_cast(a__				,      a__)
   return pa_table







 def 						__UpperCAmelCase							(						self							:					str)		->     str:


   """simple docstring"""







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











"""simple docstring"""


import random
from typing import List, Optional, Union

import numpy as np
import torch

from ..state import AcceleratorState
from .constants import CUDA_DISTRIBUTED_TYPES
from .dataclasses import DistributedType, RNGType
from .imports import is_npu_available, is_tpu_available, is_xpu_available


if is_tpu_available(check_device=False):
      import torch_xla.core.xla_model as xm





def SCREAMING_SNAKE_CASE_   (       snake_case   :					int						,  snake_case   :					bool = False		)->		Any:
       if device_specific:
              seed += AcceleratorState().process_index
       random.seed(snake_case		)
       np.random.seed(snake_case		)
       torch.manual_seed(snake_case		)
       if is_xpu_available():
              torch.xpu.manual_seed_all(snake_case		)
       elif is_npu_available():
              torch.npu.manual_seed_all(snake_case		)
       else:
              torch.cuda.manual_seed_all(snake_case		)
       # ^^ safe to call this function even if cuda is not available
       if is_tpu_available():
              xm.set_rng_state(snake_case		)





def SCREAMING_SNAKE_CASE_   (       snake_case   :					Optional[RNGType] = None						,  snake_case   :					Optional[torch.Generator] = None		)->		str:
       # Get the proper rng state
       if rng_type == RNGType.TORCH:
              _lowerCamelCase    	=					torch.get_rng_state()
       elif rng_type == RNGType.CUDA:
              _lowerCamelCase    	=					torch.cuda.get_rng_state()
       elif rng_type == RNGType.XLA:
              assert is_tpu_available(), "Can't synchronize XLA seeds on an environment without TPUs."
              _lowerCamelCase    	=					torch.tensor(xm.get_rng_state()		)
       elif rng_type == RNGType.NPU:
              assert is_npu_available(), "Can't synchronize NPU seeds on an environment without NPUs."
              _lowerCamelCase    	=					torch.npu.get_rng_state()
       elif rng_type == RNGType.XPU:
              assert is_xpu_available(), "Can't synchronize XPU seeds on an environment without XPUs."
              _lowerCamelCase    	=					torch.xpu.get_rng_state()
       elif rng_type == RNGType.GENERATOR:
              assert generator is not None, "Need a generator to synchronize its seed."
              _lowerCamelCase    	=					generator.get_state()

       # Broadcast the rng state from device 0 to other devices
       _lowerCamelCase    	=					AcceleratorState()
       if state.distributed_type == DistributedType.TPU:
              _lowerCamelCase    	=					rng_state.to(xm.xla_device()		)
              xm.collective_broadcast([rng_state]		)
              xm.mark_step()
              _lowerCamelCase    	=					rng_state.cpu()
       elif (
           state.distributed_type in CUDA_DISTRIBUTED_TYPES
           or state.distributed_type == DistributedType.MULTI_NPU
           or state.distributed_type == DistributedType.MULTI_XPU
       ):
              _lowerCamelCase    	=					rng_state.to(state.device		)
              torch.distributed.broadcast(snake_case						,  0		)
              _lowerCamelCase    	=					rng_state.cpu()
       elif state.distributed_type == DistributedType.MULTI_CPU:
              torch.distributed.broadcast(snake_case						,  0		)

       # Set the broadcast rng state
       if rng_type == RNGType.TORCH:
              torch.set_rng_state(snake_case		)
       elif rng_type == RNGType.CUDA:
              torch.cuda.set_rng_state(snake_case		)
       elif rng_type == RNGType.NPU:
              torch.npu.set_rng_state(snake_case		)
       elif rng_type == RNGType.XPU:
              torch.xpu.set_rng_state(snake_case		)
       elif rng_type == RNGType.XLA:
              xm.set_rng_state(rng_state.item()		)
       elif rng_type == RNGType.GENERATOR:
              generator.set_state(snake_case		)





def SCREAMING_SNAKE_CASE_   (       snake_case   :					List[Union[str, RNGType]]						,  snake_case   :					Optional[torch.Generator] = None		)->		int:
       for rng_type in rng_types:
              synchronize_rng_state(RNGType(snake_case		)						,  generator=snake_case		)






