o
    Åîï]V  ã                
   @   sê   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ ed	g d
¢ƒedƒŽ ZejejfZG dd„ deƒZejejejejejejejejejejiZdd„ Zdd„ Zdd„ Z dd„ Z!dd„ Z"dd„ Z#dS )z*Represent a deployment of MongoDB servers.é    )Ú
namedtuple)Úcommon)ÚConfigurationError)ÚReadPreference©ÚServerDescription)Ú	Selection)ÚSERVER_TYPEÚTopologyType)ÚSingleÚReplicaSetNoPrimaryÚReplicaSetWithPrimaryÚShardedÚUnknowné   c                   @   sà   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Ze	dd„ ƒZ
e	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd „ ƒZe	d!d"„ ƒZd*d$d%„Zejfd&d'„Zd(d)„ Zd#S )+ÚTopologyDescriptionc                 C   s  || _ || _|| _|| _|| _|| _d| _| j ¡ D ]G}|js q|j	duo*|j	t
jk}|jduo5|jt
jk }	|rJd|jd |jd |j	t
jf | _q|	rad|jd |jd |jt
jt
jf | _ nq| j}
|
sld| _dS tdd„ |
D ƒƒrzd| _dS tdd„ |
D ƒƒ| _dS )	aê  Representation of a deployment of MongoDB servers.

        :Parameters:
          - `topology_type`: initial type
          - `server_descriptions`: dict of (address, ServerDescription) for
            all seeds
          - `replica_set_name`: replica set name or None
          - `max_set_version`: greatest setVersion seen from a primary, or None
          - `max_election_id`: greatest electionId seen from a primary, or None
          - `topology_settings`: a TopologySettings
        Nz]Server at %s:%d requires wire version %d, but this version of PyMongo only supports up to %d.r   é   zgServer at %s:%d reports wire version %d, but this version of PyMongo requires at least %d (MongoDB %s).c                 s   s   � | ]}|j d u V  qd S ©N©Úlogical_session_timeout_minutes©Ú.0Ús© r   úN/var/www/html/env/lib/python3.10/site-packages/pymongo/topology_description.pyÚ	<genexpr>o   s   € ÿz/TopologyDescription.__init__.<locals>.<genexpr>c                 s   ó   � | ]}|j V  qd S r   r   r   r   r   r   r   s   s   € ÿ)Ú_topology_typeÚ_replica_set_nameÚ_server_descriptionsÚ_max_set_versionÚ_max_election_idÚ_topology_settingsÚ_incompatible_errÚvaluesÚis_server_type_knownÚmin_wire_versionr   ÚMAX_SUPPORTED_WIRE_VERSIONÚmax_wire_versionÚMIN_SUPPORTED_WIRE_VERSIONÚaddressÚMIN_SUPPORTED_SERVER_VERSIONÚreadable_serversÚ_ls_timeout_minutesÚanyÚmin)ÚselfÚtopology_typeÚserver_descriptionsÚreplica_set_nameÚmax_set_versionÚmax_election_idÚtopology_settingsr   Úserver_too_newÚserver_too_oldr,   r   r   r   Ú__init__%   sX   

ý

ýÿþÿýþÿ÷
ÿ
ÿzTopologyDescription.__init__c                 C   s   | j rt| j ƒ‚dS )z®Raise ConfigurationError if any server is incompatible.

        A server is incompatible if its wire protocol version range does not
        overlap with PyMongo's.
        N)r#   r   ©r0   r   r   r   Úcheck_compatiblev   s   
ÿz$TopologyDescription.check_compatiblec                 C   s
   || j v S r   )r   ©r0   r*   r   r   r   Ú
has_server   s   
zTopologyDescription.has_serverc                 C   s   t | t|ƒƒS )z;A copy of this description, with one server marked Unknown.)Úupdated_topology_descriptionr   r<   r   r   r   Úreset_server‚   s   z TopologyDescription.reset_serverc                 C   sH   | j tjkr
tj}n| j }tdd„ | jD ƒƒ}t||| j| j| j	| j
ƒS )z<A copy of this description, with all servers marked Unknown.c                 s   s   � | ]	}|t |ƒfV  qd S r   r   )r   r*   r   r   r   r   Ž   s   € ÿz,TopologyDescription.reset.<locals>.<genexpr>)r   ÚTOPOLOGY_TYPEr   r   Údictr   r   r   r    r!   r"   )r0   r1   Úsdsr   r   r   Úreset†   s   ÿúzTopologyDescription.resetc                 C   s
   | j  ¡ S )zRDict of (address,
        :class:`~pymongo.server_description.ServerDescription`).)r   Úcopyr:   r   r   r   r2   ™   s   
z'TopologyDescription.server_descriptionsc                 C   ó   | j S )zThe type of this topology.)r   r:   r   r   r   r1   ž   ó   z!TopologyDescription.topology_typec                 C   s   t j| j S )zUThe topology type as a human readable string.

        .. versionadded:: 3.4
        )r@   Ú_fieldsr   r:   r   r   r   Útopology_type_name£   s   z&TopologyDescription.topology_type_namec                 C   rE   )zThe replica set name.)r   r:   r   r   r   r3   «   rF   z$TopologyDescription.replica_set_namec                 C   rE   )z1Greatest setVersion seen from a primary, or None.)r    r:   r   r   r   r4   °   rF   z#TopologyDescription.max_set_versionc                 C   rE   )z1Greatest electionId seen from a primary, or None.)r!   r:   r   r   r   r5   µ   rF   z#TopologyDescription.max_election_idc                 C   rE   )z)Minimum logical session timeout, or None.)r-   r:   r   r   r   r   º   rF   z3TopologyDescription.logical_session_timeout_minutesc                 C   ó   dd„ | j  ¡ D ƒS )z)List of Servers of types besides Unknown.c                 S   ó   g | ]}|j r|‘qS r   ©r%   r   r   r   r   Ú
<listcomp>Â   s    
ÿz5TopologyDescription.known_servers.<locals>.<listcomp>©r   r$   r:   r   r   r   Úknown_servers¿   ó   z!TopologyDescription.known_serversc                 C   s   t dd„ | j ¡ D ƒƒS )z7Whether there are any Servers of types besides Unknown.c                 s   s   � | ]}|j r|V  qd S r   rK   r   r   r   r   r   È   s   € ÿz8TopologyDescription.has_known_servers.<locals>.<genexpr>)r.   r   r$   r:   r   r   r   Úhas_known_serversÅ   s   z%TopologyDescription.has_known_serversc                 C   rI   )zList of readable Servers.c                 S   rJ   r   )Úis_readabler   r   r   r   rL   Î   s    z8TopologyDescription.readable_servers.<locals>.<listcomp>rM   r:   r   r   r   r,   Ë   rO   z$TopologyDescription.readable_serversc                 C   s"   | j }|rtdd„ | j D ƒƒS dS )z3Minimum of all servers' max wire versions, or None.c                 s   r   r   )r(   r   r   r   r   r   Õ   s   € z:TopologyDescription.common_wire_version.<locals>.<genexpr>N)rN   r/   )r0   Úserversr   r   r   Úcommon_wire_versionÐ   s   z'TopologyDescription.common_wire_versionc                 C   s   | j jS r   )r"   Úheartbeat_frequencyr:   r   r   r   rT   Ù   s   z'TopologyDescription.heartbeat_frequencyNc                    s¼   ‡ fdd„}t |ddƒr ˆ j}|r ||jk r td||j|f ƒ‚ˆ jtjkr)ˆ jS |r9ˆ  ¡  	|¡}|r7|gS g S ˆ jtj
krEt ˆ ¡}n|t ˆ ¡ƒ}|d urZ|rZ| ||jƒ¡}||ƒS )Nc                    sB   | sg S ˆj }tdd„ | jD ƒƒ‰ |jd ‰‡ ‡fdd„| jD ƒS )Nc                 s   r   r   ©Úround_trip_timer   r   r   r   r   æ   s   € 
ÿzTTopologyDescription.apply_selector.<locals>.apply_local_threshold.<locals>.<genexpr>g     @�@c                    s   g | ]}|j ˆ  ˆkr|‘qS r   rU   r   ©ÚfastestÚ	thresholdr   r   rL   é   s    ÿzUTopologyDescription.apply_selector.<locals>.apply_local_threshold.<locals>.<listcomp>)r"   r/   r2   Úlocal_threshold_ms)Ú	selectionÚsettingsr:   rW   r   Úapply_local_thresholdß   s   ÿ
zATopologyDescription.apply_selector.<locals>.apply_local_thresholdr&   r   zF%s requires min wire version %d, but topology's min wire version is %d)ÚgetattrrS   r&   r   r1   r@   r   rN   r2   Úgetr   r   Úfrom_topology_descriptionÚwith_server_descriptions)r0   Úselectorr*   Úcustom_selectorr]   Ú	common_wvÚdescriptionr[   r   r:   r   Úapply_selectorÝ   s2   þÿÿÿz"TopologyDescription.apply_selectorc                 C   s   t  d|¡ t|  |d¡ƒS )aÒ  Does this topology have any readable servers available matching the
        given read preference?

        :Parameters:
          - `read_preference`: an instance of a read preference from
            :mod:`~pymongo.read_preferences`. Defaults to
            :attr:`~pymongo.read_preferences.ReadPreference.PRIMARY`.

        .. note:: When connected directly to a single server this method
          always returns ``True``.

        .. versionadded:: 3.4
        Úread_preferenceN)r   Úvalidate_read_preferencer.   rf   )r0   rg   r   r   r   Úhas_readable_server  s   z'TopologyDescription.has_readable_serverc                 C   s   |   tj¡S )zÉDoes this topology have a writable server available?

        .. note:: When connected directly to a single server this method
          always returns ``True``.

        .. versionadded:: 3.4
        )ri   r   ÚPRIMARYr:   r   r   r   Úhas_writable_server  s   z'TopologyDescription.has_writable_serverr   )Ú__name__Ú
__module__Ú__qualname__r9   r;   r=   r?   rC   r2   Úpropertyr1   rH   r3   r4   r5   r   rN   rP   r,   rS   rT   rf   r   rj   ri   rk   r   r   r   r   r   $   s@    Q	











+r   c           	      C   s²  |j }| j}| j}| j}| j}|j}|  ¡ }|||< |tjkr*t	tj||||| j
ƒS |tjkrF|tjkr:| |¡ n|tjtjfvrFt| }|tjkrY|tjtjfvrX| |¡ nv|tjkr‘|tjtjfv rl| |¡ nc|tjkr~t|||||ƒ\}}}}nQ|tjtjtjfv r�t|||ƒ\}}n>|tjkrÏ|tjtjfv r¨| |¡ t|ƒ}n'|tjkrºt|||||ƒ\}}}}n|tjtjtjfv rËt|||ƒ}nt|ƒ}t	|||||| j
ƒS )a„  Return an updated copy of a TopologyDescription.

    :Parameters:
      - `topology_description`: the current TopologyDescription
      - `server_description`: a new ServerDescription that resulted from
        an ismaster call

    Called after attempting (successfully or not) to call ismaster on the
    server at server_description.address. Does not modify topology_description.
    )r*   r1   r3   r4   r5   Úserver_typer2   r@   r   r   r"   r   r	   Ú
StandaloneÚpopÚRSGhostÚ_SERVER_TYPE_TO_TOPOLOGY_TYPEr   ÚMongosr   Ú	RSPrimaryÚ_update_rs_from_primaryÚRSSecondaryÚ	RSArbiterÚRSOtherÚ!_update_rs_no_primary_from_memberr   Ú_check_has_primaryÚ#_update_rs_with_primary_from_member)	Útopology_descriptionÚserver_descriptionr*   r1   Úset_namer4   r5   rp   rB   r   r   r   r>   /  s    
ú



€

üýýÿ€



üýýÿûr>   c                 C   s~   |   ¡ }t| ¡ ƒt|ƒkr| S |D ]}||vrt|ƒ||< qt| ¡ ƒD ]}||vr0| |¡ q%t| j|| j| j	| j
| jƒS )zñReturn an updated copy of a TopologyDescription.

    :Parameters:
      - `topology_description`: the current TopologyDescription
      - `seedlist`: a list of new seeds new ServerDescription that resulted from
        an ismaster call
    )r2   ÚsetÚkeysr   Úlistrr   r   r1   r3   r4   r5   r"   )r~   ÚseedlistrB   r*   r   r   r   Ú)_updated_topology_description_srv_polling—  s&   	€
€úr…   c           
      C   s,  |du r|j }n||j kr|  |j¡ t| ƒ|||fS ||f}d|jvrAd|vr>||jkr>|j}t|ƒ| |< t| ƒ|||fS |j}|jdurR|du sO|j|krR|j}|  ¡ D ]}|j	t
ju rn|j|jkrnt|jƒ| |j<  nqV|jD ]}|| vr~t|ƒ| |< qrt| ƒ|j D ]}	|  |	¡ q†t| ƒ|||fS )aj  Update topology description from a primary's ismaster response.

    Pass in a dict of ServerDescriptions, current replica set name, the
    ServerDescription we are processing, and the TopologyDescription's
    max_set_version and max_election_id if any.

    Returns (new topology type, new replica_set_name, new max_set_version,
    new max_election_id).
    N)r3   rr   r*   r|   Úelection_tupler   Úelection_idÚset_versionr$   rp   r	   rv   Ú	all_hostsr�   )
rB   r3   r   r4   r5   Úmax_election_tupler*   ÚserverÚnew_addressÚaddrr   r   r   rw   ¹  sT   
ý

ý

€
€ýrw   c                 C   sP   |dusJ ‚||j kr|  |j¡ t| ƒS |jr$|j|jkr$|  |j¡ t| ƒS )zØRS with known primary. Process a response from a non-primary.

    Pass in a dict of ServerDescriptions, current replica set name, and the
    ServerDescription we are processing.

    Returns new topology type.
    N)r3   rr   r*   Úmer|   )rB   r3   r   r   r   r   r}     s   
ûr}   c                 C   sz   t j}|du r|j}n||jkr|  |j¡ ||fS |jD ]}|| vr)t|ƒ| |< q|jr9|j|jkr9|  |j¡ ||fS )zòRS without known primary. Update from a non-primary's response.

    Pass in a dict of ServerDescriptions, current replica set name, and the
    ServerDescription we are processing.

    Returns (new topology type, new replica_set_name).
    N)r@   r   r3   rr   r*   r‰   r   rŽ   )rB   r3   r   r1   r*   r   r   r   r{     s   

€r{   c                 C   s*   |   ¡ D ]}|jtjkrtj  S qtjS )z—Current topology type is ReplicaSetWithPrimary. Is primary still known?

    Pass in a dict of ServerDescriptions.

    Returns new topology type.
    )r$   rp   r	   rv   r@   r   r   )rB   r   r   r   r   r|   <  s
   
ÿr|   N)$Ú__doc__Úcollectionsr   Úpymongor   Úpymongo.errorsr   Úpymongo.read_preferencesr   Úpymongo.server_descriptionr   Úpymongo.server_selectorsr   Úpymongo.server_typer	   Úranger@   r   r   ÚSRV_POLLING_TOPOLOGIESÚobjectr   ru   rv   r   rx   r   ry   rz   rt   r>   r…   rw   r}   r{   r|   r   r   r   r   Ú<module>   s6   þ  û	h"L 