U
    [h                     @  s   d dl mZ d dlZd dlZd dlZd dlZddlm	Z	 ej
rJddlmZ G dd dZG dd	 d	ZG d
d deZG dd deZdddddZdddddZG dd deeejjZdS )    )annotationsN   )Query)
SQLAlchemyc                   @  sR   e Zd ZdZejddddddZejddddd	dZd
dddddZdS )_QueryPropertyzRA class property that creates a query object for a model.

    :meta private:
    Noneztype[Model]r   )objclsreturnc                 C  s   d S N selfr   r	   r   r   :/tmp/pip-unpacked-wheel-pdy8nmv4/flask_sqlalchemy/model.py__get__   s    z_QueryProperty.__get__Modelc                 C  s   d S r   r   r   r   r   r   r      s    zModel | Nonec                 C  s   |j ||j dS )N)session)query_class__fsa__r   r   r   r   r   r      s     N)__name__
__module____qualname____doc__toverloadr   r   r   r   r   r      s   r   c                   @  sB   e Zd ZU dZded< eZded< e Zded< dd	d
dZ	dS )r   a  The base class of the :attr:`.SQLAlchemy.Model` declarative model class.

    To define models, subclass :attr:`db.Model <.SQLAlchemy.Model>`, not this. To
    customize ``db.Model``, subclass this and pass it as ``model_class`` to
    :class:`.SQLAlchemy`. To customize ``db.Model`` at the metaclass level, pass an
    already created declarative model class as ``model_class``.
    zt.ClassVar[SQLAlchemy]r   zt.ClassVar[type[Query]]r   zt.ClassVar[Query]querystr)r
   c                 C  sp   t | }|d k	st|jr.dt|  d}n*|jrFdt|  d}ndtt|j	}dt
| j d| dS )Nz(transient )z	(pending z, < >)sainspectAssertionErrorZ	transientidpendingjoinmapr   identitytyper   )r   statepkr   r   r   __repr__@   s    
zModel.__repr__N)
r   r   r   r   __annotations__r   r   r   r   r,   r   r   r   r   r   #   s
   
	r   c                      s@   e Zd ZU dZded< ded< dddd	d
d fddZ  ZS )BindMetaMixina  Metaclass mixin that sets a model's ``metadata`` based on its ``__bind_key__``.

    If the model sets ``metadata`` or ``__table__`` directly, ``__bind_key__`` is
    ignored. If the ``metadata`` is the same as the parent model, it will not be set
    directly on the child model.
    r   r   sa.MetaDatametadatar   tuple[type, ...]dict[str, t.Any]t.Anyr   namebasesdkwargsr
   c                   s^   d| j ksFd| j ksFt| dd }t| dd }| j|}||k	rF|| _t j|||f| d S )Nr0   	__table__Z__bind_key__)__dict__getattrr   Z_make_metadatar0   super__init__)r	   r5   r6   r7   r8   Zbind_keyZparent_metadatar0   	__class__r   r   r=   Y   s    zBindMetaMixin.__init__)r   r   r   r   r-   r=   __classcell__r   r   r>   r   r.   N   s   
r.   c                      sZ   e Zd ZU dZded< ded< ded< ddd	d
dd fddZd
d
ddddZ  ZS )NameMetaMixinaP  Metaclass mixin that sets a model's ``__tablename__`` by converting the
    ``CamelCase`` class name to ``snake_case``. A name is set for non-abstract models
    that do not otherwise define ``__tablename__``. If a model does not define a primary
    key, it will not generate a name or ``__table__``, for single-table inheritance.
    r/   r0   r   __tablename__zsa.Tabler9   r1   r2   r3   r   r4   c                   sR   t | rt| j| _t j|||f| d| jkrNd| jkrN| jd d krN| `d S )NrB   r9   )should_set_tablenamecamel_to_snake_caser   rB   r<   r=   r:   r9   )r	   r5   r6   r7   r8   r>   r   r   r=   r   s    zNameMetaMixin.__init__zsa.Table | None)argsr8   r
   c                 O  s   | d}|dkr|d }n| d|d  }|| jjkrFtj||S |D ]2}t|tjr`|jslt|tjrJtj||  S qJ| j	dd D ]}d|j
kr qqtj||S d| j
kr| `dS )	a  This is called by SQLAlchemy during mapper setup. It determines the final
        table object that the model will use.

        If no primary key is found, that indicates single-table inheritance, so no table
        will be created and ``__tablename__`` will be unset.
        schemaNr   .r   r9   rB   )getr0   Ztablesr!   ZTable
isinstanceZColumnZprimary_keyZPrimaryKeyConstraint__mro__r:   rB   )r	   rE   r8   rF   keyargbaser   r   r   __table_cls__   s&    

 

zNameMetaMixin.__table_cls__)r   r   r   r   r-   r=   rO   r@   r   r   r>   r   rA   g   s   
rA   r)   bool)r	   r
   c                 C  s   | j dds*tdd | jdd D s.dS | jD ]T}d|j krDq4t|j d tjjr^ dS || kp|j ddpt|tjj    S dS )	a  Determine whether ``__tablename__`` should be generated for a model.

    -   If no class in the MRO sets a name, one should be generated.
    -   If a declared attr is found, it should be used instead.
    -   If a name is found, it should be used if the class is a mixin, otherwise one
        should be generated.
    -   Abstract models should not have one generated.

    Later, ``__table_cls__`` will determine if the model looks like single or
    joined-table inheritance. If no primary key is found, the name will be unset.
    Z__abstract__Fc                 s  s   | ]}t |tjjV  qd S r   )rJ   r!   ormDeclarativeMeta).0br   r   r   	<genexpr>   s    z'should_set_tablename.<locals>.<genexpr>r   NrB   T)	r:   rI   anyrK   rJ   r!   rQ   Zdeclared_attrrR   )r	   rN   r   r   r   rC      s    

rC   r   )r5   r
   c                 C  s   t dd| } |  dS )z/Convert a ``CamelCase`` name to ``snake_case``.z(((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))z_\1_)resublowerlstrip)r5   r   r   r   rD      s    rD   c                   @  s   e Zd ZdZdS )DefaultMetazgSQLAlchemy declarative metaclass that provides ``__bind_key__`` and
    ``__tablename__`` support.
    N)r   r   r   r   r   r   r   r   r\      s   r\   )
__future__r   rX   typingr   Z
sqlalchemyr!   Zsqlalchemy.ormr   r   TYPE_CHECKING	extensionr   r   r   r)   r.   rA   rC   rD   rQ   rR   r\   r   r   r   r   <module>   s   +E!