


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


__UpperCamelCase					:	Optional[Any]          =				datasets.utils.logging.get_logger(__name__)





@dataclass
class 			lowerCAmelCase__(     datasets.BuilderConfig    ):






    '''simple docstring'''





    A_	:  Union[str, "sqlalchemy.sql.Selectable"]								=			None
    A_	:  Union[str, "sqlalchemy.engine.Connection", "sqlalchemy.engine.Engine", "sqlite3.Connection"]								=			None
    A_	:  Optional[Union[str, List[str]]]								=			None
    A_	:  bool								=			True
    A_	:  Optional[Union[List, Tuple, Dict]]								=			None
    A_	:  Optional[Union[List, Dict]]								=			None
    A_	:  Optional[List[str]]								=			None
    A_	:  Optional[int]								=			1_0_0_0_0
    A_	:  Optional[datasets.Features]								=			None





    def        _lowerCamelCase			(						self					: Tuple						):





       '''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        _lowerCamelCase			(						self					: Dict							, __snake_case					: dict							, __snake_case					: Optional[datasets.Features] = None							, ):





       '''simple docstring'''
       UpperCAmelCase_				:   Tuple							= 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_				:   Union[str, Any]							= config_kwargs['''sql''']
       if not isinstance(__snake_case							, __snake_case						):
          if datasets.config.SQLALCHEMY_AVAILABLE and "sqlalchemy" in sys.modules:
             import sqlalchemy

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

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





    @property
    def        _lowerCamelCase			(						self					: str						):





       '''simple docstring'''
       UpperCAmelCase_				:   Optional[Any]							= {
           '''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 			lowerCAmelCase__(     datasets.ArrowBasedBuilder    ):






    '''simple docstring'''





    A_	:  Union[str, Any]								=			SqlConfig





    def        _lowerCamelCase			(						self					: Dict						):





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





    def        _lowerCamelCase			(						self					: Union[str, Any]							, __snake_case					: Optional[int]						):





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





    def        _lowerCamelCase			(						self					: List[str]							, __snake_case					: pa.Table						):





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





    def        _lowerCamelCase			(						self					: List[str]						):





       '''simple docstring'''
       UpperCAmelCase_				:   str							= self.config.chunksize
       UpperCAmelCase_				:   Union[str, Any]							= pd.read_sql(
           self.config.sql							, self.config.con							, chunksize=__snake_case							, **self.config.pd_read_sql_kwargs						)
       UpperCAmelCase_				:   List[str]							= [sql_reader] if chunksize is None else sql_reader
       for chunk_idx, df in enumerate(__snake_case						):
          UpperCAmelCase_				:   Dict							= pa.Table.from_pandas(__snake_case						)
          yield chunk_idx, self._cast_table(__snake_case						)



def   snake_case_    (			__lowercase      ,							__lowercase      ,							__lowercase      ,							__lowercase							):
   UpperCAmelCase_				:   Optional[int]							= int((lower_bound + upper_bound) // 2							)
   if array[r] == value:
      return r
   if lower_bound >= upper_bound:
      return -1
   if array[r] < value:
      return binary_search(__lowercase      ,							r + 1      ,							__lowercase      ,							__lowercase							)
   else:
      return binary_search(__lowercase      ,							__lowercase      ,							r - 1      ,							__lowercase							)
def   snake_case_    (			__lowercase      ,							__lowercase							):
   UpperCAmelCase_				:   Union[str, Any]							= 0
   if matrix[index][0] == value:
      return [index, 0]
   while index < len(__lowercase							) and matrix[index][0] < value:
      UpperCAmelCase_				:   str							= binary_search(matrix[index]      ,							0      ,							len(matrix[index]							) - 1      ,							__lowercase							)
      if r != -1:
         return [index, r]
      index += 1
   return [-1, -1]


if __name__ == "__main__":
       import doctest

       doctest.testmod()