o
    b1}                     @   sB  d Z ddlZddlZddlZddlZddlmZmZmZ zddl	m
Z
 W n ey/   eZ
Y nw ddlmZmZ ddlmZmZmZmZmZmZ ddlmZmZmZmZ dd	lmZ dd
lmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z) ddl*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2 ddl3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZB ddlCmDZC eEdZFeEdejGZHeEdejGZIeEdZJg dZKeKg d ZLeMeNOeP  dZQdZRdZSg dZdZTeUedrejVrdZTdd ZWdd ZXdd  ZYd0d!d"ZZd#d$ Z[d%d& Z\d'd( Z]d)d* Z^d+d, Z_d-d. Z`g d/ZadS )1z$MySQL X DevAPI Python implementation    N)	parse_qslunquoteurlparse)JSONDecodeError   )ClientSession)AuthLockContentionOPENSSL_CS_NAMESSSLModeTLS_VERSIONSTLS_CIPHER_SUITES)Schema
CollectionTableView)DbDoc)ErrorInterfaceErrorDatabaseErrorNotSupportedError	DataErrorIntegrityErrorProgrammingErrorOperationalErrorInternalError	PoolErrorTimeoutError)ColumnRowResultBufferingResult	RowResult	SqlResult	DocResult
ColumnType)	StatementFilterableStatementSqlStatementFindStatementAddStatementRemoveStatementModifyStatementSelectStatementInsertStatementDeleteStatementUpdateStatementCreateCollectionIndexStatementExprReadStatementWriteStatement)
ExprParserz,(?![^\(\)]*\))z!^\(address=(.+),priority=(\d+)\)$z^\(address=(.+)[,]*\)$z"^([a-zA-Z][a-zA-Z0-9+\-.]+)://(.*))ssl-certssl-cassl-keyssl-crltls-versionstls-ciphersuites)userpasswordschemahostportrouterssocketssl-modeauthzuse-pureconnect-timeoutconnection-attributescompressioncompression-algorithmsdns-srvzVThe '{list}' list must not contain repeated values, the value '{value}' is duplicated.zdThe given tls-version: '{}' is not recognized as a valid TLS protocol version (should be one of {}).zINo supported TLS protocol version found in the 'tls-versions' list '{}'. )TLSv1zTLSv1.1zTLSv1.2TLSv1.3FHAS_TLSv1_3Tc           	      C   sp  |  dd} d| vo| ddko| ddk o"| do"| d}g }t|r/| dd n| }d	}|D ]d}i }t|}|rT|d}t	|d
|d< |d7 }nt
|}|rd|d}d|d< td|}|jsutd|z|j|j|jd W n ty } ztd|dd}~ww || q6d	|  k rt|k rn ntdd|rd|iS |d	 S )zParses a list of host, port pairs

    Args:
        path: String containing a list of routers or just router

    Returns:
        Returns a dict with parsed values of host, port and priority if
        specified.
      ,:r   []r      priorityd   z//{0}zInvalid address: {0})r@   rA   zInvalid URI: {0}i  Nz\You must either assign no priority to any of the routers or give a priority for every routeri  rB   )replacecount
startswithendswith	_SPLIT_REsplit_PRIORITY_REmatchgroupint
_ROUTER_REr   formathostnamer   updaterA   
ValueErrorr   appendlen)	patharrayrB   Zaddress_listZpriority_countaddressrouterr_   err rn   N/var/www/secure340b-portal/env/lib/python3.10/site-packages/mysqlx/__init__.py_parse_address_list]   sJ   





rp   c                 C   s  ddi}t | }|r| nd| f\}} |dvr td||dkr(d|d< | d	d
d
d \}}|dd
d
d \}}|d}||d
 ddkr^|dkr^|dd\}|d< |	d}|rk|rkd|vrrtd| |
dd\}	}
t|	t|
|d< |d< |drt||d< n|drtd|t| d}t|dD ]J\}}|dd }||v rtd|||v rtd||tv rt|	d||< q| }|d v rd||< q|d!v rd"||< q|||< q|S )#a  Parses the connection string and returns a dictionary with the
    connection settings.

    Args:
        uri: mysqlx URI scheme to connect to a MySQL server/farm.

    Returns:
        Returns a dict with parsed values of credentials and address of the
        MySQL server/farm.

    Raises:
        :class:`mysqlx.InterfaceError`: If contains a duplicate option or
                                        URI scheme is not valid.
    r?   rO   mysqlx)rq   
mysqlx+srvzScheme '{0}' is not validrr   TrJ   @NrU   ?/)rT   r   r   z()rQ   zMalformed URI '{0}'r=   r>   )ru   z...rC   z\.zWindows Pipe is not supported)r=   r>   rJ   _-zInvalid option: '{0}'zDuplicate option: '{0}')1true)0falseF)_URI_SCHEME_REr_   groupsr   rc   	partitionrfindfindrsplitstripr]   r   rZ   re   rp   r   rX   lower	_SSL_OPTS)urisettingsr_   schemeuserinfotmpr@   Z	query_strposr=   r>   Zinvalid_optionskeyvaloptZval_strrn   rn   ro   _parse_connection_uri   sL   







r   c              	      s  t   t}|rtdd|d v r& d D ]}t|d qnd v r.t  d v rlz d   d< t	
 d  W n ttfyU   td d w  d t	jkrlt fdd	tD rltd
d v rxd vrxtdd v rd vrtdd vr dt	jt	jfv rtdd v r dt	jt	jfvrtdd v rz d   d< t
 d  W n ttfy   td d w d v r d   }|dvrtd d | d< d v r/t d tr d  d}|r|d d< nd d< nt d ttfs#td ddkr/d d< d v r8t  d v rmz#t d trNt d  d< t d tr] d d k r_tW n tyl   td!w d" v rt d" ts~td# d$rtd% d&rtd' drtd(nd v r d&sd d&< d) v rt  d* v rt  dS dS )+an  Validates the settings to be passed to a Session object
    the port values are converted to int if specified or set to 33060
    otherwise. The priority values for each router is converted to int
    if specified.

    Args:
        settings: dict containing connection settings.

    Raises:
        :class:`mysqlx.InterfaceError`: On any configuration issue.
    zInvalid option(s): '{0}'z', 'rB   i$  r@   rD   zInvalid SSL Mode '{0}'c                 3   s    | ]}| v V  qd S Nrn   ).0r   r   rn   ro   	<genexpr>   s    z%_validate_settings.<locals>.<genexpr>z)SSL options used with ssl-mode 'disabled'r:   r8   zCA Certificate not providedr9   r7   zClient Certificate not providedzCannot verify Server without CAz$Must verify Server if CA is providedrE   zInvalid Auth '{0}'rH   )	preferredrequireddisabledzThe connection property 'compression' acceptable values are: 'preferred', 'required', or 'disabled'. The value '{0}' is not acceptablerI   z[]rP   Nz@Invalid type of the connection property 'compression-algorithms'r   rG   rF   r   zEThe connection timeout value must be a positive integer (including 0)rJ   z(The value of 'dns-srv' must be a booleanrC   z<Using Unix domain sockets with DNS SRV lookup is not allowedrA   z;Specifying a port number with DNS SRV lookup is not allowedzASpecifying multiple hostnames with DNS SRV look up is not allowedr;   r<   ) setkeys
difference
_SESS_OPTSr   rc   join_validate_hostsr   r   indexAttributeErrorrf   ZDISABLEDanyr   getZVERIFY_IDENTITYZ	VERIFY_CAr	   r   
isinstancestrr]   listtuple_validate_connection_attributesra   	TypeErrorbool_validate_tls_versions_validate_tls_ciphersuites)r   Zinvalid_optsrl   rH   Zcompression_algorithmsrn   r   ro   _validate_settings   s   











r   c                 C   s   d| v r@| d r@zt | d | d< | d dk s| d dkr"tddW n ty/   tdd ty?   td| d dw d| v r_| d r_zt | d | d< W dS  ty^   td	w d
| v rk|rm|| d< dS dS dS )zValidate hosts.

    Args:
        settings (dict): Settings dictionary.
        default_port (int): Default connection port.

    Raises:
        :class:`mysqlx.InterfaceError`: If priority or port are invalid.
    rV   r   rW   z1Invalid priority value, must be between 0 and 100i  zInvalid priorityzInvalid priority: {}rA   zInvalid portr@   N)ra   r   	NameErrorrf   rc   r   )r   default_portrn   rn   ro   r   C  s0   

r   c           	      C   s  i }d| vrdS | d }t |tr||dkri | d< dS |dr%|ds0|dvr0td||dv rD|dv r>d	| d< dS i | d< dS |d
d d}|D ]+}|dkrVqO|d}|d }t|d
kri|d
 nd}||v rvtd||||< qOnt |tr|D ]}|| }t |tst	|}|||< qnft |t
s|dv r|ri | d< dS d	| d< dS t |tr|D ]}d||< qn@t |tr|D ]+}|dkrq|d}|d }t|d
kr|d
 nd}||v rtd||||< qnt |t
std||rP|D ]L}|| }t |tstd|t|dkr$td||dr1td|t |ts?td||t|dkrNtd||q|| d< dS )zValidate connection-attributes.

    Args:
        settings (dict): Settings dictionary.

    Raises:
        :class:`mysqlx.InterfaceError`: If attribute name or value exceeds size.
    rG   NrO   rR   rS   )Falser}   Truer{   z`The value of 'connection-attributes' must be a boolean or a list of key-value pairs, found: '{}')r   r}   Fr   rT   rP   =r   z0Duplicate key '{}' used in connection-attributes)r   r   zOconnection-attributes must be Boolean or a list of key-value pairs, found: '{}'z(Attribute name '{}' must be a stringtype    z4Attribute name '{}' exceeds 32 characters limit sizerx   zEKey names in connection-attributes cannot start with '_', found: '{}'z0Attribute '{}' value: '{}' must be a string typei   z=Attribute '{}' value: '{}' exceeds 1024 characters limit size)r   r   rZ   r[   r   rc   r]   rh   dictreprr   r   r   )	r   
attributesZ
conn_attrsZconn_attributesattrZattr_name_val	attr_nameZattr_val
attr_valuern   rn   ro   r   b  s   	











r   c                 C   s  g }d| vrdS | d }t |trX|dr|ds"td||dd d}|D ])}| }|d	kr8q-|tvrDtt	|t||v rQtt
jd
|d|| q-nVt |tr|sctd|D ] }|tvrstt	|t||v rtt
jd
|d|| qen't |tr|D ]}|tvrtt	|t|| qntddt||std|dgkrtstt|t|| d< dS )zValidate tls-versions.

    Args:
        settings (dict): Settings dictionary.

    Raises:
        :class:`mysqlx.InterfaceError`: If tls-versions name is not valid.
    r;   NrR   rS   z(tls-versions must be a list, found: '{}'r   rT   rP   rO   tls_versionsr   valuezKAt least one TLS protocol version must be specified in 'tls-versions' list.zMtls-versions should be a list with one or more of versions in {}. found: '{}'z, rL   )r   r   rZ   r[   r   rc   r]   r   r   TLS_VERSION_ERRORDUPLICATED_IN_LIST_ERRORrg   r   r   r   TLS_V1_3_SUPPORTEDTLS_VER_NO_SUPPORTED)r   r   Ztls_versions_settingsZtls_verstls_verZtls_versionrn   rn   ro   r     s|   	




r   c                 C   s  g }d| vrdS | d }t |trD|dr|ds"td||dd d}|s1td	|D ]}|  }|rB|	| q3n&t |t
rQd
d |D }nt |trc|D ]	}|ra|	| qXntd|| dddu rxtdd n| d dd }|jdd |d }g }i }g }	tdt|d  D ]}
|t|
  |	t|
  q|D ]1}d|v r||	v r|	| q||v r|| }||v rttjd|d|	| qtd||std	|| d< dS )zValidate tls-ciphersuites.

    Args:
        settings (dict): Settings dictionary.

    Raises:
        :class:`mysqlx.InterfaceError`: If tls-ciphersuites name is not valid.
    r<   NrR   rS   z,tls-ciphersuites must be a list, found: '{}'r   rT   rP   z;No valid cipher suite found in the 'tls-ciphersuites' list.c                 S   s   g | ]}|r|qS rn   rn   )r   tls_csrn   rn   ro   
<listcomp>6  s    
z._validate_tls_ciphersuites.<locals>.<listcomp>zLtls-ciphersuites should be a list with one or more ciphersuites. Found: '{}'r;   T)reverser   ry   tls_ciphersuitesr   z;The value '{}' in cipher suites is not a valid cipher suite)r   r   rZ   r[   r   rc   r]   r   upperrg   r   r   r   r   sortr   re   r   extendr   r   r   )r   r   Ztls_ciphersuites_settingsZtls_cssr   r   Znewer_tls_verZtranslated_namesZiani_cipher_suites_namesZossl_cipher_suites_namesr   nameZtranslated_namern   rn   ro   r     s~   	






r   c                  O   s   i }| r-t | d trt| d }n.t | d tr,| d  D ]\}}|||dd< qn|r@| D ]\}}|||dd< q3|sFtdt| |S )aZ  Parses the connection string and returns a dictionary with the
    connection settings.

    Args:
        *args: Variable length argument list with the connection data used
               to connect to the database. It can be a dictionary or a
               connection string.
        **kwargs: Arbitrary keyword arguments with connection data used to
                  connect to the database.

    Returns:
        mysqlx.Session: Session object.

    Raises:
        TypeError: If connection timeout is not a positive integer.
        :class:`mysqlx.InterfaceError`: If settings not provided.
    r   rx   ry   zSettings not provided)r   r   r   r   itemsrX   r   r   )argskwargsr   r   r   rn   rn   ro   _get_connection_settingsk  s   r   c                  O   s   t | i |}t|S )a  Creates a Session instance using the provided connection data.

    Args:
        *args: Variable length argument list with the connection data used
               to connect to a MySQL server. It can be a dictionary or a
               connection string.
        **kwargs: Arbitrary keyword arguments with connection data used to
                  connect to the database.

    Returns:
        mysqlx.Session: Session object.
    )r   r   )r   r   r   rn   rn   ro   get_session  s   r   c                 C   sF  t | ttfstdt| }t |ttfstdt |tr2zt|}W n ty1   tdw i }| D ]\}}|||	dd< q8t |tsNtdi }d|v r|
d}t |tsbtd|
dd	|d< |
d
d|d
< |
dd|d< |
dd|d< t|dkrtd|t|dkrtd| t||S )a8  Creates a Client instance with the provided connection data and settings.

    Args:
        connection_string: A string or a dict type object to indicate the             connection data used to connect to a MySQL server.

            The string must have the following uri format::

                cnx_str = 'mysqlx://{user}:{pwd}@{host}:{port}'
                cnx_str = ('mysqlx://{user}:{pwd}@['
                           '    (address={host}:{port}, priority=n),'
                           '    (address={host}:{port}, priority=n), ...]'
                           '       ?[option=value]')

            And the dictionary::

                cnx_dict = {
                    'host': 'The host where the MySQL product is running',
                    'port': '(int) the port number configured for X protocol',
                    'user': 'The user name account',
                    'password': 'The password for the given user account',
                    'ssl-mode': 'The flags for ssl mode in mysqlx.SSLMode.FLAG',
                    'ssl-ca': 'The path to the ca.cert'
                    "connect-timeout": '(int) milliseconds to wait on timeout'
                }

        options_string: A string in the form of a document or a dictionary             type with configuration for the client.

            Current options include::

                options = {
                    'pooling': {
                        'enabled': (bool), # [True | False], True by default
                        'max_size': (int), # Maximum connections per pool
                        "max_idle_time": (int), # milliseconds that a
                            # connection will remain active while not in use.
                            # By default 0, means infinite.
                        "queue_timeout": (int), # milliseconds a request will
                            # wait for a connection to become available.
                            # By default 0, means infinite.
                    }
                }

    Returns:
        mysqlx.Client: Client object.

    .. versionadded:: 8.0.13
    z(connection_data must be a string or dictz+connection_options must be a string or dictzA'pooling' options must be given in the form of a document or dictry   rx   Zpoolingz<'pooling' options must be given in the form document or dictenabledTmax_size   Zmax_idle_timer   Zqueue_timeoutz Unrecognized pooling options: {}z#Unrecognized connection options: {})r   r   r   r   r   jsonloadsr   r   rX   poprh   rc   r   r   )Zconnection_stringZoptions_stringZsettings_dictZoptions_dictr   r   Zpooling_options_dictZpooling_optionsrn   rn   ro   
get_client  sH   2







r   )/r   r   r   r   exprr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r4   r5   r2   r3   r   )b__doc__rer   loggingsslurllib.parser   r   r   Zjson.decoderr   ImportErrorrf   
connectionr   r   	constantsr	   r
   r   r   r   r   Zcrudr   r   r   r   Zdbdocr   errorsr   r   r   r   r   r   r   r   r   r   r   resultr   r    r!   r"   r#   r$   r%   r&   Z	statementr'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r   r6   compiler\   VERBOSEr^   rb   r~   r   r   	getLogger__name__
addHandlerNullHandlerr   r   r   r   hasattrrM   rp   r   r   r   r   r   r   r   r   r   __all__rn   rn   rn   ro   <module>   sZ    4(D

3B
qmIS$b