U
    4Jeg                     @  sF  d Z ddlmZ ddlZddlZddlmZmZmZm	Z	m
Z
mZ ddlmZ ddlmZmZmZmZ ddlmZmZmZ dd	lmZmZmZ dd
l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) erddl*m+Z+ dZ,dZ-dZ.dZ/dZ0G dd dZ1G dd de1Z2G dd de1Z3G dd de1Z4G dd de4Z5dS )z,Implementation of the CRUD database objects.    )annotationsN)TYPE_CHECKINGAnyDictListOptionalUnion   )DbDoc)ER_NO_SUCH_TABLEER_TABLE_EXISTS_ERRORER_X_CMD_NUM_ARGUMENTSER_X_INVALID_ADMIN_COMMAND)NotSupportedErrorOperationalErrorProgrammingError)
deprecatedescapequote_identifier)	AddStatementCreateCollectionIndexStatementDeleteStatementFindStatementInsertStatementModifyStatementRemoveStatementSelectStatementUpdateStatement)ConnectionType
SchemaTypeSessionType
StrOrBytes)Resultz_SELECT COUNT(*) FROM information_schema.views WHERE table_schema = '{0}' AND table_name = '{1}'z`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '{0}' AND table_name = '{1}'zJSELECT COUNT(*) FROM information_schema.schemata WHERE schema_name = '{0}'zSELECT COUNT(*) FROM {0}.{1}zDROP TABLE IF EXISTS {0}.{1}c                   @  s   e Zd ZdZddddddZedd	d
dZedd	ddZedd	ddZdd	ddZ	dd	ddZ
dd	ddZdd	ddZdd	ddZedddd	dd Zedd!dd	d"d#Zd$S )%DatabaseObjectzProvides base functionality for database objects.

    Args:
        schema (mysqlx.Schema): The Schema object.
        name (str): The database object name.
    r   r!   None)schemanamereturnc                 C  s:   || _ t|tr| n|| _| j  | _| j | _d S N)	_schema
isinstancebytesdecode_nameget_session_sessionget_connection_connection)selfr%   r&    r3   //tmp/pip-unpacked-wheel-7_167w8m/mysqlx/crud.py__init__V   s    zDatabaseObject.__init__r    r'   c                 C  s   | j S )z,:class:`mysqlx.Session`: The Session object.r/   r2   r3   r3   r4   session\   s    zDatabaseObject.sessionc                 C  s   | j S )z*:class:`mysqlx.Schema`: The Schema object.r)   r8   r3   r3   r4   r%   a   s    zDatabaseObject.schemastrc                 C  s   | j S )z&str: The name of this database object.r-   r8   r3   r3   r4   r&   f   s    zDatabaseObject.namer   c                 C  s   | j S )z~Returns the underlying connection.

        Returns:
            mysqlx.connection.Connection: The connection object.
        )r1   r8   r3   r3   r4   r0   k   s    zDatabaseObject.get_connectionc                 C  s   | j S )zwReturns the session of this database object.

        Returns:
            mysqlx.Session: The Session object.
        r7   r8   r3   r3   r4   r.   s   s    zDatabaseObject.get_sessionc                 C  s   | j S )z{Returns the Schema object of this database object.

        Returns:
            mysqlx.Schema: The Schema object.
        r:   r8   r3   r3   r4   
get_schema{   s    zDatabaseObject.get_schemac                 C  s   | j S )zwReturns the name of this database object.

        Returns:
            str: The name of this database object.
        r<   r8   r3   r3   r4   get_name   s    zDatabaseObject.get_namer   c                 C  s   t dS )zVerifies if this object exists in the database.

        Returns:
            bool: `True` if object exists in database.

        Raises:
           NotImplementedError: This method must be implemented.
        N)NotImplementedErrorr8   r3   r3   r4   exists_in_database   s    	z!DatabaseObject.exists_in_databasez8.0.12z)Use 'exists_in_database()' method insteadc                 C  s   |   S )a+  Verifies if this object exists in the database.

        Returns:
            bool: `True` if object exists in database.

        Raises:
           NotImplementedError: This method must be implemented.

        .. deprecated:: 8.0.12
           Use ``exists_in_database()`` method instead.
        )r@   r8   r3   r3   r4   	am_i_real   s    zDatabaseObject.am_i_realzUse 'get_name()' method insteadc                 C  s   |   S )zReturns the name of this database object.

        Returns:
            str: The name of this database object.

        .. deprecated:: 8.0.12
           Use ``get_name()`` method instead.
        )r>   r8   r3   r3   r4   who_am_i   s    
zDatabaseObject.who_am_iN)__name__
__module____qualname____doc__r5   propertyr9   r%   r&   r0   r.   r=   r>   r@   r   rA   rB   r3   r3   r3   r4   r#   N   s"   r#   c                      s   e Zd ZdZdddd fddZdd	d
dZdd	ddZd+ddddddZdd	ddZd,ddddddZ	d-ddddddZ
d.ddddddZdddd d!Zd/ddd#d$dd%d&d'Zd0dd#dd(d)d*Z  ZS )1SchemazA client-side representation of a database schema. Provides access to
    the schema contents.

    Args:
        session (mysqlx.XSession): Session object.
        name (str): The Schema name.
    r    r;   r$   )r9   r&   r'   c                   s   || _ t | | d S r(   )r/   superr5   )r2   r9   r&   	__class__r3   r4   r5      s    zSchema.__init__boolr6   c                 C  s    t t| j}| j|dkS zVerifies if this object exists in the database.

        Returns:
            bool: `True` if object exists in database.
        r	   )_COUNT_SCHEMAS_QUERYformatr   r-   r1   execute_sql_scalarr2   sqlr3   r3   r4   r@      s    zSchema.exists_in_databasezList[Collection]c              	   C  s|   | j dd| ji}|  g }|D ]R}|d dkr6q$zt| |d }W n" tk
rj   t| |d }Y nX || q$|S )zyReturns a list of collections for this schema.

        Returns:
            `list`: List of Collection objects.
        list_objectsr%   typeZ
COLLECTION
TABLE_NAMEr&   )r1   get_row_resultr-   	fetch_all
Collection
ValueErrorappend)r2   rowscollectionsrow
collectionr3   r3   r4   get_collections   s    zSchema.get_collectionsFTable)r&   check_existencer'   c                 C  s   |  ||S )zuReturns a a table object for the given collection

        Returns:
            mysqlx.Table: Table object.

        )	get_table)r2   r&   ra   r3   r3   r4   get_collection_as_table   s    	zSchema.get_collection_as_tablezList[Table]c              	   C  s~   | j dd| ji}|  g }d}|D ]P}|d |kr(zt| |d }W n" tk
rl   t| |d }Y nX || q(|S )zoReturns a list of tables for this schema.

        Returns:
            `list`: List of Table objects.
        rS   r%   )ZTABLEZVIEWrT   rU   r&   )r1   rV   r-   rW   r`   rY   rZ   )r2   r[   ZtablesZobject_typesr]   tabler3   r3   r4   
get_tables   s    zSchema.get_tablesc                 C  s"   t | |}|r| std|S )zwReturns the table of the given name for this schema.

        Returns:
            mysqlx.Table: Table object.
        zTable does not exist)r`   r@   r   )r2   r&   ra   rd   r3   r3   r4   rb      s
    
zSchema.get_tableViewc                 C  s"   t | |}|r| std|S )ztReturns the view of the given name for this schema.

        Returns:
            mysqlx.View: View object.
        zView does not exist)rf   r@   r   )r2   r&   ra   viewr3   r3   r4   get_view  s
    
zSchema.get_viewrX   c                 C  s"   t | |}|r| std|S )zReturns the collection of the given name for this schema.

        Returns:
            mysqlx.Collection: Collection object.
        zCollection does not exist)rX   r@   r   )r2   r&   ra   r^   r3   r3   r4   get_collection  s
    
zSchema.get_collection)r&   r'   c                 C  s&   | j dtt| jt|d dS )zmDrops a collection.

        Args:
            name (str): The name of the collection to be dropped.
        rR   FN)r1   execute_nonquery_DROP_TABLE_QUERYrO   r   r-   )r2   r&   r3   r3   r4   drop_collection   s     zSchema.drop_collectionNz%Optional[Dict[str, Union[str, Dict]]]r   )r&   reuse_existing
validationkwargsr'   c              
   K  s  |st dd|kr(tdt |d }t| |}| j|d}|dk	r
t|trV|s^t dd}|D ]}||krft d| qfg }	d	|kr|d	 }
t|
tst d
|		d	|
f d|kr|d }t|ttfst d|		dt|trt
|n|f d|	f|d< z| jddd| W np tk
r } zP|jtkrJtd||jtkrp|st d| d|nt |j|j|W 5 d}~X Y nX |S )aJ  Creates in the current schema a new collection with the specified
        name and retrieves an object representing the new collection created.

        Args:
            name (str): The name of the collection.
            reuse_existing (bool): `True` to reuse an existing collection.
            validation (Optional[dict]): A dict, containing the keys `level`
                                         with the validation level and `schema`
                                         with a dict or a string representation
                                         of a JSON schema specification.

        Returns:
            mysqlx.Collection: Collection object.

        Raises:
            :class:`mysqlx.ProgrammingError`: If ``reuse_existing`` is False
                                              and collection exists or the
                                              collection name is invalid.
            :class:`mysqlx.NotSupportedError`: If schema validation is not
                                               supported by the server.

        .. versionchanged:: 8.0.21
        Collection name is invalidZreusezG'reuse' is deprecated since 8.0.21. Please use 'reuse_existing' instead)r%   r&   NInvalid value for 'validation'levelr%    Invalid option in 'validation': rs   Invalid value for 'level'r%   Invalid value for 'schema'rn   optionsmysqlxcreate_collectionTlYour MySQL server does not support the requested operation. Please update to MySQL 8.0.19 or a later versionCollection 'z' already exists)r   warningswarnDeprecationWarningrX   r-   r*   dictr;   rZ   jsondumpsr1   rj   r   errnor   r   r   msg)r2   r&   rm   rn   ro   r^   fieldsvalid_optionsoptionrw   rs   r%   errr3   r3   r4   ry   .  sp    


   
"zSchema.create_collection)r&   rn   r'   c           
   
   C  s:  |st dt|tr|s"t dd}|D ]}||kr*t d| q*g }d|krz|d }t|tslt d|d|f d|kr|d }t|ttfst d|dt|trt|n|f | j|d	|fd
}z| j	ddd| W nJ t
k
r4 }	 z*|	jtkrtd|	t |	j|	j|	W 5 d}	~	X Y nX dS )a
  Modifies a collection using a JSON schema validation.

        Args:
            name (str): The name of the collection.
            validation (Optional[dict]): A dict, containing the keys `level`
                                         with the validation level and `schema`
                                         with a dict or a string representation
                                         of a JSON schema specification.

        Raises:
            :class:`mysqlx.ProgrammingError`: If the collection name or
                                              validation is invalid.
            :class:`mysqlx.NotSupportedError`: If schema validation is not
                                               supported by the server.

        .. versionadded:: 8.0.21
        rp   rq   rr   rt   rs   ru   r%   rv   rn   )r%   r&   rw   rx   Zmodify_collection_optionsTrz   N)r   r*   r   r;   rZ   r   r   r-   r1   rj   r   r   r   r   r   )
r2   r&   rn   r   r   rw   rs   r%   r   r   r3   r3   r4   modify_collection  sT    
   zSchema.modify_collection)F)F)F)F)FN)N)rC   rD   rE   rF   r5   r@   r_   rc   re   rb   rh   ri   rl   ry   r   __classcell__r3   r3   rJ   r4   rH      s    	   ` rH   c                   @  s   e Zd ZdZddddZd0ddd	d
dZdddddZddd	ddZddd	ddZddddZ	ddddddZ
dd d!d"d#Zdd$d%d&d'd(Zdd$d%d&d)d*Zddd+d,d-Zdd%d+d.d/ZdS )1rX   zRepresents a collection of documents on a schema.

    Args:
        schema (mysqlx.Schema): The Schema object.
        name (str): The collection name.
    rL   r6   c                 C  s*   t t| jjt| j}| j|dkS rM   _COUNT_TABLES_QUERYrO   r   r)   r&   r-   r1   rP   rQ   r3   r3   r4   r@     s    zCollection.exists_in_databaseNzOptional[str]r   )	conditionr'   c                 C  s   t | |}| j |_|S )zRetrieves documents from a collection.

        Args:
            condition (Optional[str]): The string with the filter expression of
                                       the documents to be retrieved.
        )r   r1   get_next_statement_idstmt_idr2   r   stmtr3   r3   r4   find  s    
zCollection.findr
   r   )valuesr'   c                 G  s   t | j| S )zAdds a list of documents to a collection.

        Args:
            *values: The document list to be added into the collection.

        Returns:
            mysqlx.AddStatement: AddStatement object.
        )r   add)r2   r   r3   r3   r4   r     s    	zCollection.addr;   r   c                 C  s   t | |}| j |_|S )ap  Removes documents based on the ``condition``.

        Args:
            condition (str): The string with the filter expression of the
                             documents to be removed.

        Returns:
            mysqlx.RemoveStatement: RemoveStatement object.

        .. versionchanged:: 8.0.12
           The ``condition`` parameter is now mandatory.
        )r   r1   r   r   r   r3   r3   r4   remove  s    
zCollection.remover   c                 C  s   t | |}| j |_|S )ar  Modifies documents based on the ``condition``.

        Args:
            condition (str): The string with the filter expression of the
                             documents to be modified.

        Returns:
            mysqlx.ModifyStatement: ModifyStatement object.

        .. versionchanged:: 8.0.12
           The ``condition`` parameter is now mandatory.
        )r   r1   r   r   r   r3   r3   r4   modify
  s    
zCollection.modifyintc              
   C  s|   t t| jjt| j}z| j|}W nL tk
rv } z.|j	t
krdtd| j d| jj d| W 5 d}~X Y nX |S )z}Counts the documents in the collection.

        Returns:
            int: The total of documents in the collection.
        r{   ' does not exist in schema ''N_COUNT_QUERYrO   r   r)   r&   r-   r1   rP   r   r   r   r2   rR   resr   r3   r3   r4   count  s    
 
zCollection.countzDict[str, Any]r   )
index_namefields_descr'   c                 C  s   t | ||S )ab  Creates a collection index.

        Args:
            index_name (str): Index name.
            fields_desc (dict): A dictionary containing the fields members that
                                constraints the index to be created. It must
                                have the form as shown in the following::

                                   {"fields": [{"field": member_path,
                                                "type": member_type,
                                                "required": member_required,
                                                "array": array,
                                                "collation": collation,
                                                "options": options,
                                                "srid": srid},
                                                # {... more members,
                                                #      repeated as many times
                                                #      as needed}
                                                ],
                                    "type": type}
        )r   )r2   r   r   r3   r3   r4   create_index/  s    zCollection.create_indexr$   )r   r'   c              	   C  s$   | j ddd| jj| j|d dS )z[Drops a collection index.

        Args:
            index_name (str): Index name.
        rx   Zdrop_collection_indexF)r%   r^   r&   N)r1   rj   r)   r&   r-   )r2   r   r3   r3   r4   
drop_indexI  s    zCollection.drop_indexzUnion[Dict, DbDoc]z'Result')doc_iddocr'   c                 C  s:   d|kr|d |krt d| dd|d| S )zReplaces the Document matching the document ID with a new document
        provided.

        Args:
            doc_id (str): Document ID
            doc (:class:`mysqlx.DbDoc` or `dict`): New Document
        _idKReplacement document has an _id that is different than the matched document	_id = :id$id)r   r   setbindexecuter2   r   r   r3   r3   r4   replace_oneZ  s
    zCollection.replace_onec                 C  sH   d|kr|d |krt dt|ts.t|}| ||d S )zUpserts the Document matching the document ID with a new document
        provided.

        Args:
            doc_id (str): Document ID
            doc (:class:`mysqlx.DbDoc` or dict): New Document
        r   r   T)r   r*   r
   r   copyZupsertr   r   r3   r3   r4   add_or_replace_onei  s    
zCollection.add_or_replace_one)r   r'   c                 C  s,   |  dd| }| }| j  |S )zReturns a Document matching the Document ID.

        Args:
            doc_id (str): Document ID

        Returns:
            mysqlx.DbDoc: The Document matching the Document ID.
        r   r   )r   r   r   Z	fetch_oner1   Zfetch_active_result)r2   r   resultr   r3   r3   r4   get_onez  s    	
zCollection.get_onec                 C  s   |  dd| S )zRemoves a Document matching the Document ID.

        Args:
            doc_id (str): Document ID

        Returns:
            mysqlx.Result: Result object.
        r   r   )r   r   r   )r2   r   r3   r3   r4   
remove_one  s    	zCollection.remove_one)N)rC   rD   rE   rF   r@   r   r   r   r   r   r   r   r   r   r   r   r3   r3   r3   r4   rX     s   	rX   c                   @  sv   e Zd ZdZddddZdddd	d
ZdddddZddddZddddZddddZ	ddddZ
dS )r`   zRepresents a database table on a schema.

    Provides access to the table through standard INSERT/SELECT/UPDATE/DELETE
    statements.

    Args:
        schema (mysqlx.Schema): The Schema object.
        name (str): The table name.
    rL   r6   c                 C  s*   t t| jjt| j}| j|dkS rM   r   rQ   r3   r3   r4   r@     s    zTable.exists_in_databaser;   r   )r   r'   c                 G  s   t | f| }| j |_|S )zCreates a new :class:`mysqlx.SelectStatement` object.

        Args:
            *fields: The fields to be retrieved.

        Returns:
            mysqlx.SelectStatement: SelectStatement object
        )r   r1   r   r   r2   r   r   r3   r3   r4   select  s    	zTable.selectr   r   c                 G  s   t | f| }| j |_|S )zCreates a new :class:`mysqlx.InsertStatement` object.

        Args:
            *fields: The fields to be inserted.

        Returns:
            mysqlx.InsertStatement: InsertStatement object
        )r   r1   r   r   r   r3   r3   r4   insert  s    	zTable.insertr   c                 C  s   t | }| j |_|S )zCreates a new :class:`mysqlx.UpdateStatement` object.

        Returns:
            mysqlx.UpdateStatement: UpdateStatement object
        )r   r1   r   r   r2   r   r3   r3   r4   update  s    zTable.updater   c                 C  s   t | }| j |_|S )zCreates a new :class:`mysqlx.DeleteStatement` object.

        Returns:
            mysqlx.DeleteStatement: DeleteStatement object

        .. versionchanged:: 8.0.12
           The ``condition`` parameter was removed.
        )r   r1   r   r   r   r3   r3   r4   delete  s    	zTable.deleter   c              
   C  s|   t t| jjt| j}z| j|}W nL tk
rv } z.|j	t
krdtd| j d| jj d| W 5 d}~X Y nX |S )ziCounts the rows in the table.

        Returns:
            int: The total of rows in the table.
        zTable 'r   r   Nr   r   r3   r3   r4   r     s    
 
zTable.countc                 C  s*   t t| jjt| j}| j|dkS )zDetermine if the underlying object is a view or not.

        Returns:
            bool: `True` if the underlying object is a view.
        r	   _COUNT_VIEWS_QUERYrO   r   r)   r&   r-   r1   rP   rQ   r3   r3   r4   is_view  s    zTable.is_viewN)rC   rD   rE   rF   r@   r   r   r   r   r   r   r3   r3   r3   r4   r`     s   
	
r`   c                   @  s   e Zd ZdZddddZdS )rf   zRepresents a database view on a schema.

    Provides a mechanism for creating, alter and drop views.

    Args:
        schema (mysqlx.Schema): The Schema object.
        name (str): The table name.
    rL   r6   c                 C  s*   t t| jjt| j}| j|dkS rM   r   rQ   r3   r3   r4   r@     s    zView.exists_in_databaseN)rC   rD   rE   rF   r@   r3   r3   r3   r4   rf     s   	rf   )6rF   
__future__r   r   r|   typingr   r   r   r   r   r   Zdbdocr
   	errorcoder   r   r   r   errorsr   r   r   Zhelpersr   r   r   Z	statementr   r   r   r   r   r   r   r   r   typesr   r   r    r!   r   r"   r   r   rN   r   rk   r#   rH   rX   r`   rf   r3   r3   r3   r4   <module>   s8    ,d  " Cc