
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
U
    SW                     @   s   d Z ddlT 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	 Z
i ZG dd	 d	eZG d
d deeeZdd ZG dd deZG dd deZG dd deZdS )a  
Provide a "Generic ForeignKey", similar to Django.  A "GFK" is composed of two
columns: an object ID and an object type identifier.  The object types are
collected in a global registry (all_models), so all you need to do is subclass
``gfk.Model`` and your model will be added to the registry.

Example:

class Tag(Model):
    tag = CharField()
    object_type = CharField(null=True)
    object_id = IntegerField(null=True)
    object = GFKField('object_type', 'object_id')

class Blog(Model):
    tags = ReverseGFK(Tag, 'object_type', 'object_id')

class Photo(Model):
    tags = ReverseGFK(Tag, 'object_type', 'object_id')

tag.object -> a blog or photo
blog.tags -> select query of tags for ``blog`` instance
Blog.tags -> select query of all tags for Blog instances
    )*)	BaseModel)Model)SelectQuery)UpdateQuery)with_metaclassc                       s   e Zd Z fddZ  ZS )r   c                    s,   t t| | |||} |dkr(t|  | S )N)_metaclass_helper_r   )superr   __new__
all_modelsadd)clsnamebasesattrs	__class__ @/opt/alt/python38/lib64/python3.8/site-packages/playhouse/gfk.pyr
   '   s    
zBaseModel.__new__)__name__
__module____qualname__r
   __classcell__r   r   r   r   r   &   s   r   c                   @   s   e Zd ZdS )r   N)r   r   r   r   r   r   r   r   -   s   r   c                 C   s4   | t kr*tD ]}|jj| kr|t | <  q*qt | S N)table_cacher   _metadb_tableget)tbl_namemodelr   r   r   	get_model0   s    r    c                   @   s@   e Zd ZdZdd Zedd Zedd Zdd	 Zd
d Z	dS )BoundGFKFieldmodel_class	gfk_fieldc                 C   s   || _ || _d S r   r"   )selfr#   r$   r   r   r   __init__;   s    zBoundGFKField.__init__c                 C   sB   | j jj}t| jj| jjf}|D ]\}}|t| s" dS q"dS NTF)r#   r   indexessetr$   model_type_fieldmodel_id_field)r%   r(   fieldsZindexed_columns	is_uniquer   r   r   unique?   s    
zBoundGFKField.uniquec                 C   s>   | j jj}t|tr:t| jj| jjf}|t|j	 s:dS dS r'   )
r#   r   primary_key
isinstanceCompositeKeyr)   r$   r*   r+   field_names)r%   pkr,   r   r   r   r/   I   s    

zBoundGFKField.primary_keyc                 C   s<   | j j}|j| jj }|j| jj }||jjk|| k@ S r   )r#   r   r,   r$   r*   r+   r   _get_pk_value)r%   othermeta
type_fieldid_fieldr   r   r   __eq__S   s    

zBoundGFKField.__eq__c                 C   s@   t |}|jj| jj }|jj| jj }||jjk|| k@ S r   )typer   r,   r$   r*   r+   r   r4   )r%   r5   Z	other_clsr7   r8   r   r   r   __ne__[   s    

zBoundGFKField.__ne__N)
r   r   r   	__slots__r&   propertyr.   r/   r9   r;   r   r   r   r   r!   8   s   
	
	r!   c                   @   s0   e Zd ZdddZdd Zddd	Zd
d ZdS )GFKFieldobject_type	object_idc                 C   s$   || _ || _d| j | jf| _d S )N.)r*   r+   joinatt_name)r%   r*   r+   r   r   r   r&   e   s    zGFKField.__init__c                 C   sh   |j }|| jrd|| jrd|| j }t|}|s@td| | |jj	|| j k}| S d S )Nz-Model for table "%s" not found in GFK lookup.)
_datar   r*   r+   r    AttributeErrorselectwherer   r/   )r%   instancedatar   r#   queryr   r   r   get_objk   s    
zGFKField.get_objNc                 C   sB   |r8| j |jkr*| |}|r*||j| j < |j| j S t|| S r   )rC   
_obj_cacherK   r   r!   )r%   rH   instance_typeZrel_objr   r   r   __get__w   s    
zGFKField.__get__c                 C   s0   ||j | j< |jj|j| j< | |j| j< d S r   )rL   rC   r   r   rD   r*   r4   r+   )r%   rH   valuer   r   r   __set__   s    zGFKField.__set__)r?   r@   )N)r   r   r   r&   rK   rN   rP   r   r   r   r   r>   d   s     

	r>   c                   @   s(   e Zd Zd
ddZdddZdd	 ZdS )
ReverseGFKr?   r@   c                 C   s&   || _ |jj| | _|jj| | _d S r   )r#   r   r,   r*   r+   )r%   r   r*   r+   r   r   r   r&      s    zReverseGFK.__init__Nc                 C   sJ   |r,| j  | j|jjk| j| k@ S | j  | j|jjkS d S r   )r#   rF   rG   r*   r   r   r+   r4   )r%   rH   rM   r   r   r   rN      s    

zReverseGFK.__get__c                    s   |j j}| }t|trL|j jkrLt j j| j|i	|j
  nVtt fdd|r|D ],}t| jj| t| jj| |  qfntd| d S )Nc                    s   t |  jS r   )r0   r#   )ir%   r   r   <lambda>       z$ReverseGFK.__set__.<locals>.<lambda>z&ReverseGFK field unable to handle "%s")r   r   r4   r0   r   r#   r   r*   r+   rG   _whereexecuteallmapsetattrr   save
ValueError)r%   rH   rO   ZmtvZmivobjr   rS   r   rP      s&    

  
zReverseGFK.__set__)r?   r@   )N)r   r   r   r&   rN   rP   r   r   r   r   rQ      s
     

rQ   N)__doc__peeweer   Z
_BaseModelr   Z_Modelr   r   r   r)   r   r   r    objectr!   r>   rQ   r   r   r   r   <module>   s   ,"