U eM@sxdZddlZddlZddlmZddlmZmZmZddl m Z m Z m Z ddl mZGdd d eZGd d d eZdS) z"Converting MySQL and Python types N)Decimal) FieldType FieldFlag CharacterSet)PY2 NUMERIC_TYPES struct_unpack) HexLiteralc@sLeZdZdZdddZddZddd Zd d Zd d ZddZ ddZ dS)MySQLConverterBasezBase class for conversion classes All class dealing with converting to and from MySQL data types must be a subclass of this class. utf8TcCs<d|_d|_d|_d|_d|_||||i|_dS)Nr)Z python_typesZ mysql_typescharset charset_id use_unicode set_charset set_unicode_cache_field_typesselfr rro/opt/hc_python/lib64/python3.8/site-packages/../../../lib/python3.8/site-packages/mysql/connector/conversion.py__init__+s  zMySQLConverterBase.__init__cCs8|dkr d}|dk r||_nd|_t|jd|_dS)zSet character setZutf8mb4r Nr)r rget_charset_infor)rr rrrr5s zMySQLConverterBase.set_charsetcCs ||_dS)zSet whether to use UnicodeN)rrvaluerrrr@szMySQLConverterBase.set_unicodecCs@|jj}zt|d||WStk r:|YSXdS)!Convert Python data type to MySQL _{0}_to_mysqlN) __class____name__lowergetattrformatAttributeErrorrr type_namerrrto_mysqlDs  zMySQLConverterBase.to_mysqlc Cs|dks|dkr"|dtjkr"dS|jsvi|_tjD]<\}}zt|d||j|d<Wq8tk rrYq8Xq8z|j|d||WStk r|YSXdS)!Convert MySQL data type to PythonNr_{0}_to_pythonr) rBITrdescitemsr r!r"KeyError)rvtypernameinforrr to_pythonLs zMySQLConverterBase.to_pythoncCs|S)z"Escape buffer for sending to MySQLrrbufrrrescapebszMySQLConverterBase.escapecCst|S)z!Quote buffer for sending to MySQLstrr1rrrquotefszMySQLConverterBase.quoteN)r T)T) r __module__ __qualname____doc__rrrr%r0r3r6rrrrr $s  r c@sfeZdZdZdFddZddZdd Zd d Zd d ZddZ ddZ ddZ ddZ ddZ ddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-ZdGd.d/ZeZdHd0d1ZeZeZeZeZeZ dId2d3Z!e!Z"dJd4d5Z#dKd6d7Z$dLd8d9Z%e%Z&dMd:d;Z'dNdd?Z*dPd@dAZ+dQdBdCZ,e,Z-dRdDdEZ.e.Z/e.Z0e.Z1dS)SMySQLConverteraDefault conversion class for MySQL Connector/Python. o escape method: for escaping values send to MySQL o quoting method: for quoting values send to MySQL in statements o conversion mapping: maps Python and MySQL data types to function for converting them. Whenever one needs to convert values differently, a converter_class argument can be given while instantiating a new connection like cnx.connect(converter_class=CustomMySQLConverterClass). NTcCst|||i|_dS)N)r rrrrrrryszMySQLConverter.__init__cCs|dkr |St|tr|St|ttfrr|dd}|dd}|dd}|dd }|d d }|d d }nH|dd}|dd}|dd}|dd}|dd}|dd}|S)z Escapes special characters as they are expected to by when MySQL receives them. As found in MySQL source mysys/charset.c Returns the value if not a string, or the escaped string. N\s\\ s\n s\r's\'"s\"s\\z\\ z\n z\r'z\'"z\"z\) isinstancerbytes bytearrayreplacerrrrr3}s$            zMySQLConverter.escapecCsdt|tr:tr*t|tr t|St|Sq`t|dSn&t|tdrPtdStd|dSdS)a  Quote the parameters for commands. General rules: o numbers are returns as bytes using ascii codec o None is returned as bytearray(b'NULL') o Everything else is single quoted '' Returns a bytearray object. asciiNsNULLr>) rGrrfloatreprr5encodetyperIr1rrrr6s   zMySQLConverter.quotecCsJ|jj}zt|d||WStk rDtd|YnXdS)rrz0Python '{0}' cannot be converted to a MySQL typeN)rrrr r!r" TypeErrorr#rrrr%s zMySQLConverter.to_mysqlc CsP|dkr|dtjkrdS|dkr&dS|jszi|_tjD]<\}}zt|d||j|d<Wq<tk rvYq}zt d||dfW5d}~XYnYnXdS)r&rrNr(utf-8z %s (field %s)) rr)rr*r+r r!r"r,decodeUnicodeDecodeError ValueErrorrP)rr-rr.r/errrrrr0s6$$zMySQLConverter.to_pythoncCst|SzConvert value to intintrrrr _int_to_mysqlszMySQLConverter._int_to_mysqlcCst|SrVrWrrrr_long_to_mysqlszMySQLConverter._long_to_mysqlcCst|S)zConvert value to floatrLrrrr_float_to_mysqlszMySQLConverter._float_to_mysqlcCstr t|S||S)zConvert value to string)rr5_unicode_to_mysqlrrrr _str_to_mysqlszMySQLConverter._str_to_mysqlcCsP|j}|j}|dkr&d}t|d}||}|tjkrLd|krLt||S|S)zConvert unicodebinaryr rr;)r rrrrNZslash_charsetsr )rrr rencodedrrrr]s   z MySQLConverter._unicode_to_mysqlcCs|SzConvert value to bytesrrrrr_bytes_to_mysqlszMySQLConverter._bytes_to_mysqlcCst|Sra)rHrrrr_bytearray_to_mysqlsz"MySQLConverter._bytearray_to_mysqlcCs|rdSdSdS)zConvert value to booleanrrNrrrrr_bool_to_mysqlszMySQLConverter._bool_to_mysqlcCsdS)z This would return what None would be in MySQL, but instead we leave it None and return it right away. The actual conversion from None to NULL happens in the quoting functionality. Return None. Nrrrrr_nonetype_to_mysqlsz!MySQLConverter._nonetype_to_mysqlc Cs^|jr4d}||j|j|j|j|j|j|jdSd}||j|j|j|j|j|jdS)z Converts a datetime instance to a string suitable for MySQL. The returned string has format: %Y-%m-%d %H:%M:%S[.%f] If the instance isn't a datetime.datetime type, it return None. Returns a bytes. z5{0:d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}.{6:06d}rKz-{0:d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}) microsecondr!yearmonthdayhourminutesecondrN)rrfmtrrr_datetime_to_mysqls0 z!MySQLConverter._datetime_to_mysqlcCsd|j|j|jdS)z Converts a date instance to a string suitable for MySQL. The returned string has format: %Y-%m-%d If the instance isn't a datetime.date type, it return None. Returns a bytes. z{0:d}-{1:02d}-{2:02d}rK)r!rgrhrirNrrrr_date_to_mysql&s zMySQLConverter._date_to_mysqlcCs&|jr|ddS|ddS)z Converts a time instance to a string suitable for MySQL. The returned string has format: %H:%M:%S[.%f] If the instance isn't a datetime.time type, it return None. Returns a bytes. z %H:%M:%S.%frKz%H:%M:%S)rfstrftimerNrrrr_time_to_mysql2s zMySQLConverter._time_to_mysqlcCstd|dS)z Converts a time.struct_time sequence to a string suitable for MySQL. The returned string has format: %Y-%m-%d %H:%M:%S Returns a bytes or None when not valid. z%Y-%m-%d %H:%M:%SrK)timerprNrrrr_struct_time_to_mysql?sz$MySQLConverter._struct_time_to_mysqlc Cst|jd|j}|jrDd}|jdkrQr)rr )rrdscZint_valrrr_BIT_to_pythons zMySQLConverter._BIT_to_pythoncCsNz2|d}tt|dt|dt|dWStk rHYdSXdS)zA Returns DATE column type as datetime.date type. -rrN)splitdatetimedaterXrT)rrrpartsrrr_DATE_to_pythons  (zMySQLConverter._DATE_to_pythonc Csd}z"|d\}}t|dd}Wntk rB|}d}YnXz^dd|dD\}}}|dd ksx|dd kr| | | }}}tj||||d }Wn"tk rtd |YnX|SdS) zA Returns TIME column type as datetime.time type. N.0rcSsg|] }t|qSrrW).0drrr sz2MySQLConverter._TIME_to_python..:-rt)r|minutesrxryz2Could not convert {0} to python datetime.timedelta)rrXljustrTr timedeltar!) rrrZtime_valhmsr{r|r~rrrr_TIME_to_pythons,   zMySQLConverter._TIME_to_pythonc Csd}z~|d\}}t|dkr@|d\}}t|dd}n|}d}dd |d Dd d |d D|g}tj|}Wntk rd}YnX|S) zI Returns DATETIME column type as datetime.datetime type. N rrrrrcSsg|] }t|qSrrWrrrrrrsz6MySQLConverter._DATETIME_to_python..rcSsg|] }t|qSrrWrrrrrsr)rrrXrrrT) rrrZ datetime_valZdate_Ztime_rr{Zdtvalrrr_DATETIME_to_pythons"  z"MySQLConverter._DATETIME_to_pythoncCs2z t|}Wn tk r,td|YnX|S)z#Returns YEAR column type as integerz"Failed converting YEAR to int (%s))rXrT)rrr*rgrrr_YEAR_to_python s  zMySQLConverter._YEAR_to_pythoncCsRd}||j}|stSzt|d}Wn tk rLtd|YnX|S)zReturns SET column type as set Actually, MySQL protocol sees a SET as a string type field. So this code isn't called directly, but used by STRING_to_python() method. Returns SET column type as a set. N,z'Could not convert set %s to a sequence.)rRr setrrT)rrrset_typerrrr_SET_to_pythons zMySQLConverter._SET_to_pythoncCsf|dk r4|dtj@r"|||S|dtj@r4|S|jdkrB|St|ttfrb|jrb| |jS|S)z Note that a SET is a string too, but using the FieldFlag we can see whether we have to split it. Returns string typed columns as string type. Nr_) rZSETrBINARYr rGrHrIrrRrrrrrr_STRING_to_python&s   z MySQLConverter._STRING_to_pythoncCs2|dk r&|dtj@r&tr|St|S|||S)z Convert BLOB data type to PythonNr)rrrrHrrrrr_BLOB_to_python=s zMySQLConverter._BLOB_to_python)NT)N)N)N)N)N)N)N)N)N)N)N)N)2rr7r8r9rr3r6r%r0rYrZr\r^r]rbrcrdrernrorqrsrrrrZ_DOUBLE_to_pythonrZ_TINY_to_pythonZ_SHORT_to_pythonZ_INT24_to_pythonZ_LONG_to_pythonZ_LONGLONG_to_pythonrZ_NEWDECIMAL_to_pythonrrrZ_NEWDATE_to_pythonrrZ_TIMESTAMP_to_pythonrrrZ_VAR_STRING_to_pythonrZ_LONG_BLOB_to_pythonZ_MEDIUM_BLOB_to_pythonZ_TINY_BLOB_to_pythonrrrrr:ks^  !     # .           r:)r9rrrdecimalr constantsrrrZcatch23rrr Z custom_typesr objectr r:rrrrs  G