
    恕f                     @   d dl Z d dlmZmZmZmZ 	 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 d d	lmZ d d
lmZmZ d dlmZmZmZ d Zd Zd Zd Zd Z d Z!d Z"d Z#ddZ$d Z%d Z&d Z'd Z(y# e$ r	 d dl	mZ Y gw xY w# e$ r d dlmZ ej                  ZY ww xY w)    N)tuple_or_and_inspect)_class_resolver)hybrid_property)ASSOCIATION_PROXY)AssociationProxyExtensionType)eq)
DBAPIError)InstrumentedAttribute)filter_liststring_types)
iterencode
iterdecodeescapec                 v    | j                  d      r
d| dd  z  }|S | j                  d      r| dd  }|S d| z  }|S )N^z%s%%   =z%%%s%%)
startswith)termstmts     ]/var/www/feuerwehr-webapp/venv/lib/python3.12/site-packages/flask_admin/contrib/sqla/tools.pyparse_like_termr      sU    sQR  K 
	ABx K $K    c                 "     t         fd|      S )z
        Return list of columns that belong to passed table.

        :param base_table: Table to check against
        :param columns: List of columns to filter
    c                 "    | j                   k(  S N)table)c
base_tables    r   <lambda>z(filter_foreign_columns.<locals>.<lambda>+   s    J!6 r   )r   )r"   columnss   ` r   filter_foreign_columnsr%   $   s     6@@r   c                     | j                   j                  }|j                  D cg c]  }|j                  |      j                   }}t        |      dk(  r|d   S t        |      dkD  rt        |      S yc c}w )z
        Return primary key name from a model. If the primary key consists of multiple columns,
        return the corresponding tuple

        :param model:
            Model class
    r   r   N)_sa_class_managermapperprimary_keyget_property_by_columnkeylentuple)modelr(   r!   pkss       r   get_primary_keyr0   .   sq     $$++F9?9K9K
LA6((+//
LC
L
3x1}1v	SASz Ms   "A6c                     t        | d      st        d      t        | j                  j                  j
                        dkD  S )zE
        Return True, if the model has more than one primary key
    r'   z'model must be a sqlalchemy mapped modelr   )hasattr	TypeErrorr,   r'   r(   r)   r.   s    r   has_multiple_pksr5   @   s=     5-.ABBu&&--99:Q>>r   c           	          g }|D ]U  }g }t        t        |             D ]#  }|j                  t        | |   ||                % |j                  t	        |        W t        |      dk\  rt        | S y)a  The tuple_ Operator only works on certain engines like MySQL or Postgresql. It does not work with sqlite.

    The function returns an or_ - operator, that containes and_ - operators for every single tuple in ids.

    Example::

      model_pk =  [ColumnA, ColumnB]
      ids = ((1,2), (1,3))

      tuple_operator(model_pk, ids) -> or_( and_( ColumnA == 1, ColumnB == 2), and_( ColumnA == 1, ColumnB == 3) )

    The returning operator can be used within a filter(), as it is just an or_ operator
    r   N)ranger,   appendr   r   r   )model_pkidsandsidkis         r   tuple_operator_inr?   J   sz     D s8}% 	-AHHRRU+,	-D!H	
 4yA~Dzr   c                    t        |      rs|D cg c]  }t        |       }}t        |      D cg c]  }t        ||       }}	 | j	                  t        | j                  |            }|j                          |S t        |t        |            }| j	                  |j                  |            }|S c c}w c c}w # t        $ r | j	                  t        ||            }Y |S w xY w)z
        Return a query object filtered by primary key values passed in `ids` argument.

        Unfortunately, it is not possible to use `in_` filter if model has more than one
        primary key.
    )
r5   r   r0   getattrfilterr   in_allr   r?   )
modelqueryr.   r:   vdecoded_idsnamer9   querys           r   get_query_for_idsrJ   d   s     .12z!}22 6EU5KLTGE4(LL	P%%fh&7&;&;K&HIE IIK L 5/%"89!!(,,s"34L! 3 M  	P%%&7+&NOE
 L	Ps   B6B;6C   $C('C(c                     | r8t        | d      r,t        | j                  d      r| j                  j                  st        d| z        | j                  j                  S )Npropertyr$   z0Invalid field %s: does not contains any columns.)r2   rL   r$   	Exception)fields    r   get_columns_for_fieldrO      sK    z*	2&&JURSS>>!!!r   c                 F    || j                   j                  j                  vS )z4
        Check if join to a table is necessary.
    )r'   r(   tables)r.   r    s     r   	need_joinrR      s!     //66====r   c                    g }t        |t              r| }d}|j                  d      D ]  }t        ||      }t	        |      r|j
                  }|r|j                  }n|g}|D ]X  }t        |      s|j                  j                  j                  }|j                  }	t        | |	      sH|j                  |       Z  |}
|
|fS |}
t        |
t              st	        |
      r]t        |
      }t!        |      dkD  rt#        d|z        |d   }t        | |j$                        r|j                  |j$                         |
|fS )z
        Resolve property by name and figure out its join path.

        Join path might contain both properties and tables.
    N.r   z!Can only handle one column for %sr   )
isinstancer   splitrA   is_association_proxyattrremote_attris_relationshiprL   r(   class_	__table__rR   r8   r   rO   r,   rM   r    )r.   rH   return_remote_proxy_attrpathcurrent_modelvalue	attributerelation_valuesrelation_valuer    rX   r$   columns                r   get_field_with_pathre      s@    D $%C 	4IM95E#E*"'**+!--E#('"1 4">2$2$;$;$B$B$I$IM)33E .N34	4" " :  d126J46P+D1G7|a Cd JKKQZF -FLL):r   c                 h    t        d t        |       j                  j                         D              S )Nc              3   J   K   | ]  \  }}t        |t              r||f  y wr   )rU   r   ).0r+   props      r   	<genexpr>z(get_hybrid_properties.<locals>.<genexpr>   s*      CdO, 
ds   !#)dictr   all_orm_descriptorsitemsr4   s    r   get_hybrid_propertiesrn      s/      ;;AAC  r   c                 f   t        |t              r
|j                  d      }| }t        t	        |      dz
        D ]  }t        |||         }t        |      r|j                  }|j                  j                  }t        |t              r! |j                  j                  |             }pt        |t              r| j                  |j                     }t        |t        j                  t        j                   f      s |       } |d   }|t#        |      v S |j$                  t#        |       v S )NrT   r   )rU   r   rV   r7   r,   rA   rW   rY   rL   argument_clsregistry_resolve_namer   _decl_class_registryargtypesFunctionType
MethodTypern   rH   )r.   	attr_namenames
last_modelr>   rX   	last_names          r   is_hybrid_propertyr|      s   )\*$
s5zA~& 
	*A:uQx0D#D)''//J*l3PT]]DDZPR
J8"77
G
J););U=M=M(NO'\

	* "I	1*===~~!6u!===r   c                 J    t        | d      xr t        | j                  d      S )NrL   	direction)r2   rL   rX   s    r   rZ   rZ      s    4$L)LLr   c                 t    t        | d      r| j                  } t        | d      xr | j                  t        k(  S )Nparentextension_type)r2   r   r   r	   r   s    r   rW   rW      s4    tX{{4)*Wt/B/BFW/WWr   )T))ru   
sqlalchemyr   r   r   r   sqlalchemy.orm.clsregistryr   ImportError&sqlalchemy.ext.declarative.clsregistrysqlalchemy.ext.hybridr   sqlalchemy.ext.associationproxyr	   r
   sqlalchemy.sql.operatorsr   sqlalchemy.excr   sqlalchemy.orm.attributesr   flask_admin._compatr   r   flask_admin.toolsr   r   r   r   r%   r0   r5   r?   rJ   rO   rR   re   rn   r|   rZ   rW    r   r   <module>r      s     1 1G: 2HA ( % ; 9 < <A$?48">0h>*MX  GFG  HM5GGHs"   A2 B 2B ?B BB