3
(hb                 @   s   d Z ddlZddlZddl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
ZdZdZ dZ!dZ"G dd de#Z$G dd de$Z%G dd de$Z&G dd de$Z'G dd de'Z(dS )z,Implementation of the CRUD database objects.    N   )DbDoc)STRING_TYPES)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)	FindStatementAddStatementRemoveStatementModifyStatementSelectStatementInsertStatementDeleteStatementUpdateStatementCreateCollectionIndexStatementz_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 Zedd Zedd Zedd	 Zd
d Z	dd Z
dd Zdd Zdd Zedddd Ze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.
    c             C   s(   || _ || _| j j | _| jj | _d S )N)_schema_nameget_session_sessionget_connection_connection)selfschemaname r"   ?/tmp/pip-install-q3hcpn_q/mysql-connector-python/mysqlx/crud.py__init__?   s    zDatabaseObject.__init__c             C   s   | j S )z5:class:`mysqlx.Session`: The Session object.
        )r   )r   r"   r"   r#   sessionE   s    zDatabaseObject.sessionc             C   s   | j S )z3:class:`mysqlx.Schema`: The Schema object.
        )r   )r   r"   r"   r#   r    K   s    zDatabaseObject.schemac             C   s   | j S )z/str: The name of this database object.
        )r   )r   r"   r"   r#   r!   Q   s    zDatabaseObject.namec             C   s   | j S )z~Returns the underlying connection.

        Returns:
            mysqlx.connection.Connection: The connection object.
        )r   )r   r"   r"   r#   r   W   s    zDatabaseObject.get_connectionc             C   s   | j S )zwReturns the session of this database object.

        Returns:
            mysqlx.Session: The Session object.
        )r   )r   r"   r"   r#   r   _   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   )r   r"   r"   r#   
get_schemag   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   )r   r"   r"   r#   get_nameo   s    zDatabaseObject.get_namec             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)NotImplementedError)r   r"   r"   r#   exists_in_databasew   s    	z!DatabaseObject.exists_in_databasez8.0.12z)Use 'exists_in_database()' method insteadc             C   s   | j  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)   )r   r"   r"   r#   	am_i_real   s    zDatabaseObject.am_i_realzUse 'get_name()' method insteadc             C   s   | j  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'   )r   r"   r"   r#   who_am_i   s    
zDatabaseObject.who_am_iN)__name__
__module____qualname____doc__r$   propertyr%   r    r!   r   r   r&   r'   r)   r   r*   r+   r"   r"   r"   r#   r   8   s   r   c                   s|   e Zd ZdZ fddZdd Zdd Zdd	d
Zdd ZdddZ	dddZ
dddZdd ZdddZdddZ  ZS ) 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.
    c                s   || _ tt| j| | d S )N)r   superr1   r$   )r   r%   r!   )	__class__r"   r#   r$      s    zSchema.__init__c             C   s    t jt| j}| 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   r   execute_sql_scalar)r   sqlr"   r"   r#   r)      s    zSchema.exists_in_databasec             C   s   | j jdd| ji}|j  g }xZ|D ]R}|d dkr8q&yt| |d }W n" tk
rl   t| |d }Y nX |j| q&W |S )zyReturns a list of collections for this schema.

        Returns:
            `list`: List of Collection objects.
        list_objectsr    typeZ
COLLECTION
TABLE_NAMEr!   )r   get_row_resultr   	fetch_all
Collection
ValueErrorappend)r   rowscollectionsrow
collectionr"   r"   r#   get_collections   s    
zSchema.get_collectionsFc             C   s   | j ||S )zuReturns a a table object for the given collection

        Returns:
            mysqlx.Table: Table object.

        )	get_table)r   r!   check_existencer"   r"   r#   get_collection_as_table   s    zSchema.get_collection_as_tablec             C   s   | j jdd| ji}|j  g }d}xX|D ]P}|d |kr*yt| |d }W n" tk
rn   t| |d }Y nX |j| q*W |S )	zoReturns a list of tables for this schema.

        Returns:
            `list`: List of Table objects.
        r8   r    TABLEVIEWr9   r:   r!   )rH   rI   )r   r;   r   r<   Tabler>   r?   )r   r@   tablesZobject_typesrB   tabler"   r"   r#   
get_tables   s    
zSchema.get_tablesc             C   s"   t | |}|r|j std|S )zwReturns the table of the given name for this schema.

        Returns:
            mysqlx.Table: Table object.
        zTable does not exist)rJ   r)   r   )r   r!   rF   rL   r"   r"   r#   rE      s
    
zSchema.get_tablec             C   s"   t | |}|r|j std|S )ztReturns the view of the given name for this schema.

        Returns:
            mysqlx.View: View object.
        zView does not exist)Viewr)   r   )r   r!   rF   viewr"   r"   r#   get_view   s
    
zSchema.get_viewc             C   s"   t | |}|r|j std|S )zReturns the collection of the given name for this schema.

        Returns:
            mysqlx.Collection: Collection object.
        zCollection does not exist)r=   r)   r   )r   r!   rF   rC   r"   r"   r#   get_collection   s
    
zSchema.get_collectionc             C   s&   | j jdtjt| jt|d dS )zmDrops a collection.

        Args:
            name (str): The name of the collection to be dropped.
        r7   FN)r   execute_nonquery_DROP_TABLE_QUERYr5   r   r   )r   r!   r"   r"   r#   drop_collection  s    zSchema.drop_collectionNc             K   s  |st dd|kr(tjdt |d }t| |}| j|d}|dk	rt|t sZ| rbt dd}x"|D ]}||krlt d	j|qlW g }	d|kr|d }
t|
t	st d
|	j
d|
f d|kr
|d }t|t	tfst d|	j
dt|trtj|n|f d|	f|d< y| jjddd| W nh tk
r } zJ|jtkrTtd|jtkrv|st dj|nt |j|jW Y dd}~X 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
        zCollection name is invalidZreusezG'reuse' is deprecated since 8.0.21. Please use 'reuse_existing' instead)r    r!   NzInvalid value for 'validation'levelr    z"Invalid option in 'validation': {}zInvalid value for 'level'zInvalid value for 'schema'
validationoptionsmysqlxcreate_collectionTzlYour MySQL server does not support the requested operation. Please update to MySQL 8.0.19 or a later versionzCollection '{}' already exists)rU   r    )r   warningswarnDeprecationWarningr=   r   
isinstancedictr5   strr?   jsondumpsr   rR   r
   errnor   r	   r   msg)r   r!   Zreuse_existingrV   kwargsrC   fieldsvalid_optionsoptionrW   rU   r    errr"   r"   r#   rY     sV    




 zSchema.create_collectionc       
      C   s>  |st dt|t s| r&t dd}x"|D ]}||kr0t dj|q0W g }d|kr|d }t|tstt d|jd|f d|kr|d }t|ttfst d|jdt|trtj|n|f | j|d|fd	}y| j	j
d
dd| W nF tk
r8 }	 z(|	jtkrtdt |	j|	jW Y dd}	~	X 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
        zCollection name is invalidzInvalid value for 'validation'rU   r    z"Invalid option in 'validation': {}zInvalid value for 'level'zInvalid value for 'schema'rV   )r    r!   rW   rX   Zmodify_collection_optionsTzlYour MySQL server does not support the requested operation. Please update to MySQL 8.0.19 or a later versionN)rU   r    )r   r]   r^   r5   r_   r?   r`   ra   r   r   rR   r
   rb   r   r	   rc   )
r   r!   rV   rf   rg   rW   rU   r    re   rh   r"   r"   r#   modify_collectione  sB    

zSchema.modify_collection)F)F)F)F)FN)N)r,   r-   r.   r/   r$   r)   rD   rG   rM   rE   rP   rQ   rT   rY   ri   __classcell__r"   r"   )r3   r#   r1      s   	
	




Sr1   c               @   sr   e Zd ZdZdd ZdddZdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd ZdS )r=   zRepresents a collection of documents on a schema.

    Args:
        schema (mysqlx.Schema): The Schema object.
        name (str): The collection name.
    c             C   s*   t jt| jjt| j}| jj|dkS )zVerifies if this object exists in the database.

        Returns:
            bool: `True` if object exists in database.
        r   )_COUNT_TABLES_QUERYr5   r   r   r!   r   r   r6   )r   r7   r"   r"   r#   r)     s    zCollection.exists_in_databaseNc             C   s   t | |}| jj |_|S )zRetrieves documents from a collection.

        Args:
            condition (Optional[str]): The string with the filter expression of
                                       the documents to be retrieved.
        )r   r   get_next_statement_idstmt_id)r   	conditionstmtr"   r"   r#   find  s    
zCollection.findc             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)r   valuesr"   r"   r#   rq     s    	zCollection.addc             C   s   t | |}| j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   r   rl   rm   )r   rn   ro   r"   r"   r#   remove  s    
zCollection.removec             C   s   t | |}| j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   r   rl   rm   )r   rn   ro   r"   r"   r#   modify  s    
zCollection.modifyc             C   st   t jt| jjt| j}y| jj|}W nD tk
rn } z(|j	t
kr\tdj| j| jj W Y dd}~X nX |S )z}Counts the documents in the collection.

        Returns:
            int: The total of documents in the collection.
        z-Collection '{}' does not exist in schema '{}'N)_COUNT_QUERYr5   r   r   r!   r   r   r6   r
   rb   r   )r   r7   resrh   r"   r"   r#   count  s    
zCollection.countc             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   )r   
index_nameZfields_descr"   r"   r#   create_index   s    zCollection.create_indexc             C   s$   | j 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    rC   r!   N)r   rR   r   r!   r   )r   rx   r"   r"   r#   
drop_index  s    
zCollection.drop_indexc             C   s   | j djd|jd|j 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
        z	_id = :id$id)rt   setbindexecute)r   doc_iddocr"   r"   r#   replace_one#  s    zCollection.replace_onec             C   s,   t |tst|}| j|j|jdj 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
        T)r]   r   rq   copyZupsertr   )r   r   r   r"   r"   r#   add_or_replace_one.  s    
zCollection.add_or_replace_onec             C   s,   | j djd|j }|j }| jj  |S )zReturns a Document matching the Document ID.

        Args:
            doc_id (str): Document ID

        Returns:
            mysqlx.DbDoc: The Document matching the Document ID.
        z	_id = :idr|   )rp   r~   r   Z	fetch_oner   Zfetch_active_result)r   r   resultr   r"   r"   r#   get_one:  s    	
zCollection.get_onec             C   s   | j djd|j S )zRemoves a Document matching the Document ID.

        Args:
            doc_id (str): Document ID

        Returns:
            mysqlx.Result: Result object.
        z	_id = :idr|   )rs   r~   r   )r   r   r"   r"   r#   
remove_oneH  s    	zCollection.remove_one)N)r,   r-   r.   r/   r)   rp   rq   rs   rt   rw   ry   rz   r   r   r   r   r"   r"   r"   r#   r=     s   

r=   c               @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )rJ   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.
    c             C   s*   t jt| jjt| j}| jj|dkS )zVerifies if this object exists in the database.

        Returns:
            bool: `True` if object exists in database.
        r   )rk   r5   r   r   r!   r   r   r6   )r   r7   r"   r"   r#   r)   _  s    zTable.exists_in_databasec             G   s   t | f| }| jj |_|S )zCreates a new :class:`mysqlx.SelectStatement` object.

        Args:
            *fields: The fields to be retrieved.

        Returns:
            mysqlx.SelectStatement: SelectStatement object
        )r   r   rl   rm   )r   re   ro   r"   r"   r#   selecti  s    	zTable.selectc             G   s   t | f| }| jj |_|S )zCreates a new :class:`mysqlx.InsertStatement` object.

        Args:
            *fields: The fields to be inserted.

        Returns:
            mysqlx.InsertStatement: InsertStatement object
        )r   r   rl   rm   )r   re   ro   r"   r"   r#   insertv  s    	zTable.insertc             C   s   t | }| jj |_|S )zCreates a new :class:`mysqlx.UpdateStatement` object.

        Returns:
            mysqlx.UpdateStatement: UpdateStatement object
        )r   r   rl   rm   )r   ro   r"   r"   r#   update  s    zTable.updatec             C   s   t | }| jj |_|S )zCreates a new :class:`mysqlx.DeleteStatement` object.

        Returns:
            mysqlx.DeleteStatement: DeleteStatement object

        .. versionchanged:: 8.0.12
           The ``condition`` parameter was removed.
        )r   r   rl   rm   )r   ro   r"   r"   r#   delete  s    	zTable.deletec             C   st   t jt| jjt| j}y| jj|}W nD tk
rn } z(|j	t
kr\tdj| j| jj W Y dd}~X nX |S )ziCounts the rows in the table.

        Returns:
            int: The total of rows in the table.
        z(Table '{}' does not exist in schema '{}'N)ru   r5   r   r   r!   r   r   r6   r
   rb   r   )r   r7   rv   rh   r"   r"   r#   rw     s    
zTable.countc             C   s*   t jt| jjt| j}| 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_QUERYr5   r   r   r!   r   r   r6   )r   r7   r"   r"   r#   is_view  s    zTable.is_viewN)r,   r-   r.   r/   r)   r   r   r   r   rw   r   r"   r"   r"   r#   rJ   T  s   	

rJ   c               @   s   e Zd ZdZdd ZdS )rN   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.
    c             C   s*   t jt| jjt| j}| jj|dkS )zVerifies if this object exists in the database.

        Returns:
            bool: `True` if object exists in database.
        r   )r   r5   r   r   r!   r   r   r6   )r   r7   r"   r"   r#   r)     s    zView.exists_in_databaseN)r,   r-   r.   r/   r)   r"   r"   r"   r#   rN     s   rN   ))r/   r`   rZ   Zdbdocr   compatr   	errorcoder   r   r   r   errorsr	   r
   r   helpersr   r   r   Z	statementr   r   r   r   r   r   r   r   r   r   rk   r4   ru   rS   objectr   r1   r=   rJ   rN   r"   r"   r"   r#   <module>   s*   ,f   1c