o
    ba                     @   s   d Z ddlZddl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)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 | _d S N)_schema_nameget_session_sessionget_connection_connection)selfschemaname r"   J/var/www/secure340b-portal/env/lib/python3.10/site-packages/mysqlx/crud.py__init__>   s   zDatabaseObject.__init__c                 C      | j S )z5:class:`mysqlx.Session`: The Session object.
        r   r   r"   r"   r#   sessionD      zDatabaseObject.sessionc                 C   r%   )z3:class:`mysqlx.Schema`: The Schema object.
        r   r'   r"   r"   r#   r    J   r)   zDatabaseObject.schemac                 C   r%   )z/str: The name of this database object.
        r   r'   r"   r"   r#   r!   P   r)   zDatabaseObject.namec                 C   r%   )z~Returns the underlying connection.

        Returns:
            mysqlx.connection.Connection: The connection object.
        )r   r'   r"   r"   r#   r   V      zDatabaseObject.get_connectionc                 C   r%   )zwReturns the session of this database object.

        Returns:
            mysqlx.Session: The Session object.
        r&   r'   r"   r"   r#   r   ^   r,   zDatabaseObject.get_sessionc                 C   r%   )z{Returns the Schema object of this database object.

        Returns:
            mysqlx.Schema: The Schema object.
        r*   r'   r"   r"   r#   
get_schemaf   r,   zDatabaseObject.get_schemac                 C   r%   )zwReturns the name of this database object.

        Returns:
            str: The name of this database object.
        r+   r'   r"   r"   r#   get_namen   r,   zDatabaseObject.get_namec                 C   s   t )zVerifies if this object exists in the database.

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

        Raises:
           NotImplementedError: This method must be implemented.
        )NotImplementedErrorr'   r"   r"   r#   exists_in_databasev   s   	z!DatabaseObject.exists_in_databasez8.0.12z)Use 'exists_in_database()' method insteadc                 C      |   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.
        )r0   r'   r"   r"   r#   	am_i_real   s   zDatabaseObject.am_i_realzUse 'get_name()' method insteadc                 C   r1   )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.   r0   r   r2   r3   r"   r"   r"   r#   r   7   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| | | d S r   )r   superr9   r$   )r   r(   r!   	__class__r"   r#   r$      s   zSchema.__init__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   r   execute_sql_scalarr   sqlr"   r"   r#   r0      s   zSchema.exists_in_databasec              	   C   sz   | j dd| ji}|  g }|D ](}|d dkrqz	t| |d }W n ty4   t| |d }Y nw || q|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   |  ||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 dd| ji}|  g }d}|D ]'}|d |v r;z	t| |d }W n ty5   t| |d }Y nw || q|S )zoReturns a list of tables for this schema.

        Returns:
            `list`: List of Table objects.
        rC   r    )ZTABLEZVIEWrD   rE   r!   )r   rF   r   rG   TablerI   rJ   )r   rK   ZtablesZobject_typesrM   tabler"   r"   r#   
get_tables   s    
zSchema.get_tablesc                 C   "   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)rS   r0   r
   )r   r!   rQ   rT   r"   r"   r#   rP      
   
zSchema.get_tablec                 C   rV   )ztReturns the view of the given name for this schema.

        Returns:
            mysqlx.View: View object.
        zView does not exist)Viewr0   r
   )r   r!   rQ   viewr"   r"   r#   get_view   rW   zSchema.get_viewc                 C   rV   )zReturns the collection of the given name for this schema.

        Returns:
            mysqlx.Collection: Collection object.
        zCollection does not exist)rH   r0   r
   )r   r!   rQ   rN   r"   r"   r#   get_collection   rW   zSchema.get_collectionc                 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.
        rB   FN)r   execute_nonquery_DROP_TABLE_QUERYr?   r   r   )r   r!   r"   r"   r#   drop_collection  s   zSchema.drop_collectionNc              
   K   s  |st dd|v rtdt |d }t| |}| j|d}|durt|tr*|s.t dd}|D ]}||vr?t d|q2g }	d	|v rZ|d	 }
t|
t	sSt d
|	
d	|
f d|v r~|d }t|t	tfsmt d|	
dt|trzt|n|f d|	f|d< z| jddd| W |S  ty } z&|jtkrtd|jtkr|st d|nt |j|jW Y d}~|S d}~ww )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': {}rb   Invalid value for 'level'r    Invalid value for 'schema'
validationoptionsmysqlxcreate_collectionTlYour MySQL server does not support the requested operation. Please update to MySQL 8.0.19 or a later versionzCollection '{}' already exists)r
   warningswarnDeprecationWarningrH   r   
isinstancedictr?   strrJ   jsondumpsr   r\   r	   errnor   r   r   msg)r   r!   Zreuse_existingrf   kwargsrN   fieldsvalid_optionsoptionrg   rb   r    errr"   r"   r#   ri     st   




zSchema.create_collectionc           
   
   C   s&  |st dt|tr|st dd}|D ]}||vr"t d|qg }d|v r=|d }t|ts6t d|d|f d|v ra|d }t|ttfsPt d|dt|tr]t|n|f | j|d	|fd
}z| j	
ddd| W dS  ty }	 z|	jtkrtdt |	j|	jd}	~	ww )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
        r_   r`   ra   rc   rb   rd   r    re   rf   )r    r!   rg   rh   Zmodify_collection_optionsTrj   N)r
   rn   ro   r?   rp   rJ   rq   rr   r   r   r\   r	   rs   r   r   rt   )
r   r!   rf   rw   rx   rg   rb   r    rv   ry   r"   r"   r#   modify_collectiond  sX   


zSchema.modify_collection)F)FNr   )r4   r5   r6   r7   r$   r0   rO   rR   rU   rP   rZ   r[   r^   ri   rz   __classcell__r"   r"   r;   r#   r9      s    	
	




Sr9   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 )rH   zRepresents a collection of documents on a schema.

    Args:
        schema (mysqlx.Schema): The Schema object.
        name (str): The collection name.
    c                 C   *   t t| jjt| j}| j|dkS r=   _COUNT_TABLES_QUERYr?   r   r   r!   r   r   r@   rA   r"   r"   r#   r0        zCollection.exists_in_databaseNc                 C      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   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#   r     s   	zCollection.addc                 C   r   )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   r   r   r   r"   r"   r#   remove     
zCollection.removec                 C   r   )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   r   r   r   r"   r"   r#   modify  r   zCollection.modifyc              
   C   h   t t| jjt| j}z	| j|}W |S  ty3 } z|j	t
kr.td| j| jj d}~ww )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_QUERYr?   r   r   r!   r   r   r@   r	   rs   r   r   rB   resry   r"   r"   r#   count     
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 ddd| jj| j|d dS )z[Drops a collection index.

        Args:
            index_name (str): Index name.
        rh   Zdrop_collection_indexF)r    rN   r!   N)r   r\   r   r!   r   )r   r   r"   r"   r#   
drop_index  s   
zCollection.drop_indexc                 C   s   |  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
        	_id = :id$id)r   setbindexecuter   doc_iddocr"   r"   r#   replace_one"  s   zCollection.replace_onec                 C   s,   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
        T)rn   r   r   copyZupsertr   r   r"   r"   r#   add_or_replace_one-  s   
zCollection.add_or_replace_onec                 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_oner   Zfetch_active_result)r   r   resultr   r"   r"   r#   get_one9  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   )r   r   r"   r"   r#   
remove_oneG  s   	zCollection.remove_oner   )r4   r5   r6   r7   r0   r   r   r   r   r   r   r   r   r   r   r   r"   r"   r"   r#   rH     s    

rH   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 )rS   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   r|   r=   r}   rA   r"   r"   r#   r0   ^  r   zTable.exists_in_databasec                 G       t | g|R  }| j |_|S )zCreates a new :class:`mysqlx.SelectStatement` object.

        Args:
            *fields: The fields to be retrieved.

        Returns:
            mysqlx.SelectStatement: SelectStatement object
        )r   r   r   r   r   rv   r   r"   r"   r#   selecth     	zTable.selectc                 G   r   )zCreates a new :class:`mysqlx.InsertStatement` object.

        Args:
            *fields: The fields to be inserted.

        Returns:
            mysqlx.InsertStatement: InsertStatement object
        )r   r   r   r   r   r"   r"   r#   insertu  r   zTable.insertc                 C      t | }| j |_|S )zCreates a new :class:`mysqlx.UpdateStatement` object.

        Returns:
            mysqlx.UpdateStatement: UpdateStatement object
        )r   r   r   r   r   r   r"   r"   r#   update  s   zTable.updatec                 C   r   )zCreates a new :class:`mysqlx.DeleteStatement` object.

        Returns:
            mysqlx.DeleteStatement: DeleteStatement object

        .. versionchanged:: 8.0.12
           The ``condition`` parameter was removed.
        )r   r   r   r   r   r"   r"   r#   delete  s   	zTable.deletec              
   C   r   )ziCounts the rows in the table.

        Returns:
            int: The total of rows in the table.
        z(Table '{}' does not exist in schema '{}'Nr   r   r"   r"   r#   r     r   zTable.countc                 C   r|   )zDetermine if the underlying object is a view or not.

        Returns:
            bool: `True` if the underlying object is a view.
        r   _COUNT_VIEWS_QUERYr?   r   r   r!   r   r   r@   rA   r"   r"   r#   is_view  r   zTable.is_viewN)r4   r5   r6   r7   r0   r   r   r   r   r   r   r"   r"   r"   r#   rS   S  s    


rS   c                   @   s   e Zd ZdZdd ZdS )rX   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   r|   r=   r   rA   r"   r"   r#   r0     r   zView.exists_in_databaseN)r4   r5   r6   r7   r0   r"   r"   r"   r#   rX     s    	rX   )'r7   rq   rk   Zdbdocr   	errorcoder   r   r   r   errorsr   r	   r
   helpersr   r   r   Z	statementr   r   r   r   r   r   r   r   r   r   r~   r>   r   r]   objectr   r9   rH   rS   rX   r"   r"   r"   r#   <module>   s*   ,f   1c