
    @i                    `   d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZ d dl	m
Z
 d dlmZ d dlZd dlmZ d dlZd dlmZ d dlmZ dd	lmZ i Zd d
Zd Zd Zd Zd dZd Zd dZd Zd Z  G d d      Z! G d d      Z" G d de"      Z# G d de"      Z$d!dZ% G d d      Z& G d d      Z'y)"    N)defaultdict
namedtuple)deepcopy)List)g)fields)config   )	BaseModelc                 >   ddl mm ddl m  ddlm} 	 t        | |      r/| | j                  j                  j                  }| j                  } n|| j                  j                  } G fdd|j                         ||       j                  |       S )Nr   )date	timedelta)datetime)Queryc                   :     e Zd Z	 	 ddZd Z fdZ xZS )%render_query.<locals>.LiteralCompilerc                 N    | j                  |j                  |j                        S N)render_literal_valuevaluetype)self	bindparamwithin_columns_clauseliteral_bindskwargss        ./cmf/data_providers/base.pyvisit_bindparamz5render_query.<locals>.LiteralCompiler.visit_bindparam.   s    ,,Y__innMM    c           
          t        |t              r2ddj                  |D cg c]  }| j                  ||       c}      z  S | j	                  ||      S c c}w )Nz{%s},)
isinstancelistjoinrender_array_valuer   )r   val	item_typexs       r   r%   z8render_query.<locals>.LiteralCompiler.render_array_value2   sS    #t$Y\)]TU$*A*A!Y*O)] ^^^,,S)<< *^s   A
c           
         t        |t              rt        |      S t        |f      rd|j                  d      z  S t        |      rdt	        |      j                  dd      z  S t        |t              r<ddj                  |D cg c]  }| j                  ||j                          c}      z  S t        | /  ||      S c c}w )Nz'%s'z%Y-%m-%d %H:%M:%S'z''z'{%s}'r!   )r"   intreprstrftimestrreplacer#   r$   r%   r'   superr   )	r   r   type_r(   LiteralCompiler	__class__r   r   r   s	       r   r   z:render_query.<locals>.LiteralCompiler.render_literal_value7   s    %%E{"ED(#34/B CCCE9-E
 2 23 ===E4(388bg,h]^T-D-DQ-X,h#ijj$DUERR -is   	#C
)FF)__name__
__module____qualname__r   r%   r   __classcell__)r3   r2   r   r   r   s   @r   r2   r   ,   s     CH*/	N	=

	S 
	Sr   r2   )r   r   r   sqlalchemy.ormr   r"   sessionbinddialect	statementstatement_compilerprocess)r<   r;   r   r2   r   r   r   s      @@@@r   render_queryr?      s    (!$ )U#?'',,44G''		..((S S'44 S. 7I.66yAAr   c                 ,    t         j                  |       S )uK   Вернём драйвер по имени источника данных)ds_registryget)ds_names    r   get_ddrD   F   s    ??7##r   c                      t         rt        d      d} t        j                  j	                         D ]<  \  }}|j                  d      dk(  r| ddlm} |} | |d<   t        ||      t         |<   > y)uY   Инициализация всех источников данных из конфигаuZ   Источники данных нельзя инициализировать дваждыNzsqlalchemy.poolclass	QueuePoolr   )rF   )name)	rA   	Exceptionr	   data_sourcesitemsrB   sqlalchemy.poolrF   new_dd)
queue_poolrC   	ds_configrF   s       r   init_dsrO   K   sw    tuuJ$11779 ?==/0K?!5&
0:I,-  &ig>G?r   c                      t         j                         D ]$  \  } }t        d|         	 |j                          & y# t        $ r t        d       Y >w xY w)u=   Инициализация, миграция схемы БД.zInit DB u        не реализовано.N)rA   rJ   printinit_dbNotImplementedError)rC   ds_dds     r   rR   rR   [   sU    %++- 7	"#	7MMO7 # 	746	7s   =AAc                     | j                  d      }|s| j                  d      }|dk(  rd}|st        d||       |j                  dd      \  }}t        j                  |      }t        ||      } || |	      S )
Nclassr   
sqlalchemyz2cmf.data_providers.sqlalchemy:SQLAlchemyDataDriverzDYou must specify valid "type" or "class" in datasource configuration:   )maxsplitrN   rG   )rB   
ValueErrorsplit	importlibimport_modulegetattr)rN   rG   dd_mod_classdd_typedd_module_namedd_class_name	dd_moduledd_classs           r   rL   rL   f   s    ==)L--'l"OL_bfhqrr$0$6$6sQ$6$G!NM''7Iy-0Hid33r   c                  V    t         j                         D ]  } | j                           y r   )rA   valuesbefore_requestdds    r   ri   ri   u   s&      " 
r   c                     | r%t        t        d      rt        j                  d       t        j	                         D ]%  }| r|j                          |j                          ' y )NdebugROLLBACK)hasattrr   rm   rA   rh   rollbackcommit)	exceptionrk   s     r   commit_all_dsrs   {   sL    1gGGJ  "  KKM IIKr   c                      t         j                         D ]*  } t        j                  d|         | j	                          , y )Nz	ROLLBACK )rA   rh   r   rm   rp   rj   s    r   rollback_all_dsru      s6      " 	)B4 !
r   c                  d    ddl m}  t        j                         D ]  }|j	                  |         y)zmake_models hookr   modelsN)cmf.includerx   rA   rh   make_models)rx   rk   s     r   rz   rz      s)    "  " 
vr   c                   ~    e Zd ZdZddddZd Zd Zd Zd Zd	 Z	d
 Z
d Zd Zd Zd Zd Zd Zd Zd Zd Zd Zy)BaseDataDriver Nr[   c                     || _         || _        y r   )r	   rG   )r   rN   rG   _args_kwargss        r   __init__zBaseDataDriver.__init__   s    	r   c                      y r    r   modelargsr   s       r   rB   zBaseDataDriver.get       r   c                      y r   r   r   instancer   r   s       r   createzBaseDataDriver.create   r   r   c                      y r   r   r   s       r   deletezBaseDataDriver.delete   r   r   c                      y r   r   r   s       r   updatezBaseDataDriver.update   r   r   c                      y r   r   r   s       r   r#   zBaseDataDriver.list   r   r   c                      y r   r   r   s       r   countzBaseDataDriver.count   r   r   c                      y r   r   r   s    r   rq   zBaseDataDriver.commit   r   r   c                      y r   r   r   s    r   rp   zBaseDataDriver.rollback   r   r   c                      y r   r   r   s    r   ri   zBaseDataDriver.before_request   r   r   c                      y r   r   )r   	cmf_models     r   dp_modelzBaseDataDriver.dp_model   r   r   c                      y r   r   )r   sa_models     r   r   zBaseDataDriver.cmf_model   r   r   c                      y r   r   )r   dp_instances     r   is_instancezBaseDataDriver.is_instance   r   r   c                      y r   r   )r   models_s     r   rz   zBaseDataDriver.make_models   r   r   c                      y)u,   Вернём кастомный запросNr   r   r   r   s      r   query_deprecatedzBaseDataDriver.query_deprecated       r   c                     t         )u2   Создание/миграция схемы БД.rS   r   s    r   rR   zBaseDataDriver.init_db   s    !!r   c                      y)u8   Закрываем текущие подключенияNr   r   s    r   close_all_sessionsz!BaseDataDriver.close_all_sessions   s    r   )r4   r5   r6   __doc__r   rB   r   r   r   r#   r   rq   rp   ri   r   r   r   rz   r   rR   r   r   r   r   r|   r|      s_    
)-D ;"r   r|   c                   @    e Zd Zd ZddZd Zd Zd	dZed	d       Z	y)

BaseMapperc                      y)u  
        Вызывать по завершению маппинга всех объектов в запросе, постобработка.
        Обычно должен вызывать тот, кто создал экземпляр маппера.
        Nr   r   s    r   post_mapping_hookzBaseMapper.post_mapping_hook   r   r   Nc                     t         r   r   )r   obj
cmf_entityr   
model_namefull_fields_loads         r   object_to_cmfzBaseMapper.object_to_cmf       !!r   c                     t         r   r   )r   r   r   s      r   cmf_to_objectzBaseMapper.cmf_to_object   r   r   c           	         |sy|j                   D ci c]:  }|j                  | d      r$dj                  |j                  d      dd       d< }}t	        dt
        f|      }|j                         |_         |j                   D ]Q  }|j                  | d      sdj                  |j                  d      dd       }t        ||t        ||             S |S c c}w )u  
        TODO: создание промежуточного объекта плохо для производительности, нужно маппить напрямую из ResultSet
          да и в целом можно зарефакторить
        N_sub__rY   CmfObj)	_fields
startswithr$   r]   r   objectkeyssetattrr`   )r   result_query
field_namefield
obj_fieldsresattnames          r   obj_from_result_queryz BaseMapper.obj_from_result_query   s    
  &--6:,d 34 IIekk$'+,d26
 6 8fZ4 oo'!)) 	DE:,d 34))EKK$5ab$9:WglE&BC	D 
6s   ?Cc                 P    |D cg c]  }| j                  |||       c}S c c}w )Nr   r   )r   )r   lstr   r   r   s        r   list_to_cmfzBaseMapper.list_to_cmf   s*    cfg\_""3eFV"Wgggs   #c                     |s
t               S |dk(  r
t               S t        |t              r|S t	        |t              r |       S t        d      )u   
        :param mapper: тип маппера
        :type mapper: None, str, Mapper subclass, Mapper instance
        :return: экземпляр маппера
        :rtype:  Mapper
        simplezInvalid mapper)MapperSimpleMapperr"   r   
issubclassr\   )clsmappers     r   
get_mapperzBaseMapper.get_mapper   sJ     8OX>!fj)Mfj)8O)**r   NNNNr   )
r4   r5   r6   r   r   r   r   r   classmethodr   r   r   r   r   r      s0    ""(h + +r   r   c                        e Zd ZdZ ej
                          G d d             Z edg d      Z fdZ	d Z
d	dZ xZS )
r   u   
    Dataclass as model, для лёгкой сериализации в json
    fill class_name
    TODO fill meta для api, но вероятно это драйвер будет делать, там дешевле
    c                   "    e Zd ZU dZeed<   d Zy)SimpleMapper.SimpleModelNidc                     t        | d      r)| j                   d| j                   d| j                   dS | j                   dt	        | dd        dS )NrG   (z: )r   )ro   
class_namecoderG   r`   r   s    r   __repr__z!SimpleMapper.SimpleModel.__repr__  sT    tV$//*!DII;b1EEoo&adD(A'B!DDr   )r4   r5   r6   r   r.   __annotations__r   r   r   r   SimpleModelr     s     C	Er   r   VirtualInitDatar   r   
field_listc                 0    t         |           g | _        y r   )r0   r   _virtual_init_list)r   r3   s    r   r   zSimpleMapper.__init__  s    "$r   c                    i }t        | j                        D ]  }|j                  |j                  j                        }|r|j
                  |_        n5|j                  |j
                        }|||j                  j                  <   |j                  D ]J  }t        ||j                        }d|_	        t        |j
                  |j                  |j                         L  g | _        y)uN   Вычислим все запрошенные виртуальные поля)simple_objectN)reversedr   rB   r   r   r   r   r   r`   _valuer   r   )r   cmf_instances	init_datacmf_wrapper	field_clsvirtual_fields         r   r   zSimpleMapper.post_mapping_hook#  s     "$"9"9: 	UI'++IOO,F,FGK,5,<,<)'ooI<L<LoM<Gioo889&11 U	 'Y5I5I J'+$	(()*>*>@S@STU	U #%r   c           
         ddl m} |s,|s|j                  j                  d      d   }t	        ||      }|s&t
        j                         }|j                  |_        nt        d||      g }|xs |j                  D ]A  }d|v rt        ||t	        ||d             !|j                  j                  |      }	|	s?|	j                  r"|s|	j                  dv r|j                  |	       mt        |	t        j                   t        j"                  f      rtt	        ||	j%                         d      }
|
du r|
d}n|xr |j                  |      }|r6t	        || d	d      $| j'                  | j)                  ||      |
      }nL	t        |	t        j*                  t        j,                  t        j.                  f      rFt	        ||d      }|du rYt        |	t        j0                        r>| j3                  ||xr |j                  |      t	        ||	j                  d               }nt        |	t        j4                        r9|r7|j6                  s\|j9                  t:        j<                  j>                        }n1t        |	t        j@                        r|rtC        jD                  |      }t        |||       D |r1| jF                  j                  t
        jI                  |||             |S )u  
        отображение obj -> simple_model
        если cmf_entity не указан, то создадим новый на основе модели cmf_model или её имени model_name
        возвращаем simple_model
        r   rw   rX   uI   Передан cmf_entity в SimpleMapper, вероятно это багr   .)defaultalwaysN_sub__id)r   tzinfor   )%ry   rx   r   r]   r`   r   r   r   r\   r   r   rB   virtual	load_modeappendr   CmfRelationCmfGenericRelationid_fieldnamer   r   
CmfM2MBaseCmfBackrefBaseCmfDateRangeCmfObjectListr   CmfDateTimer   r/   r   timezoneutcCmfJsonujsonloadsr   r   )r   r   r   r   r   r   rx   virtual_fieldsr   r   obj_related_idfield_valuesub_ffls                r   r   zSimpleMapper.object_to_cmf6  s    	'  VV\\#.q1
FJ/E%113J$)$4$4J!hjtvyzz*:ell 6	9Jz!
JZ0MN((4I  &6):M:MQf:f%%i0)f&8&8&:S:S%TU!(i.D.D.F!L!S(!)"&K.S3C3G3G
3SG #3:,h(?FR*.*<*< $ : :3
 K18 += +:K % I(9(96;P;PRXReRe'fg%c:s;c!)V%9%9:"..!1!V6F6J6J:6VFI$4$4Q$78: Iv'9'9:{"))"-"5"5X=N=N=R=R"5"SKIv~~6;#kk+6J
K8m6	9p ##**,,JeXf,gir   r   )r4   r5   r6   r   dataclasses	dataclassr   r   r   r   r   r   r7   )r3   s   @r   r   r     sO    
 [
E 
E 
E !!24UVO%
%&Pr   r   c                       e Zd ZddZd Zy)r   Nc           
      P   ddl m} |s:|s,|s|j                  j                  d      d   }t	        ||      } |d      }d}nd}|st        |      }|}|r|}	n|j                  j                         }	|	D ]  }
|j                  j                  |
      x}s"|j                  r,|s|j                  dk(  rt	        ||
      }d|_        d|_        Zt        |t        j                  t        j                  t        j                   f      rt	        ||
d	      }t        |t        j"                        rB|d	u r| j%                  ||xr |j                  |
      t	        ||j                  d               }t        |t        j&                  t        j(                  f      rt	        ||j+                         d	      }|d	u rH|d}n|xr |j                  |
      }|rt	        ||
 d
d      dk7  rt	        ||
 d
      rqt        |t        j(                        r|j                  d      d   n|j,                  }t	        ||d      }|r%| j/                  | j1                  ||
      ||      }nd}n|d	u rt        |t        j2                        r8|r6|j4                  s*|j7                  t8        j:                  j<                        }t        |t        j>                        r|jA                  |      }n1t        |t        jB                        r|rtE        jF                  |      }t        |t        jH                        rh|
jK                  d      rW|
dd |	vrPtM        ||
dd       rA|jO                  |      }|r||
dd    j                  d	u r|||
dd    _        |||
dd    _        t	        ||
      }|r|j                  d	u rBtQ        |tR        tT        tV        t        d      tX        f      r||_        nt[        |      |_        ||_         d|_.        |j_                          |S )u  
        отображение obj -> cmf_entity
        если cmf_entity не указан, то создадим новый на основе модели cmf_model или её имени model_name
        возвращаем ссылку на cmf_entity
        r   rw   rX   T)emptyFr   N.r   r   r   _id)0ry   rx   r   r]   r`   r   r   r   rB   r   r   r   _oldr   r   r   r   r   r   r   r   r   r   r   r   r   r   r/   r   r   r  CmfIPv4NetworkListdb_castr  jsonr  CmfTUUIDendswithro   make_ellipsis_idobjr"   r.   r+   floatboolr   is_newmark_exists_in_db)r   r   r   r   r   r   rx   cmf_is_existsr   r   kr   r   r  r  r  	model_subelipsis_obj	field_objs                      r   r   zMapper.object_to_cmf  s    	'!!$c!21!5J
3T*J!M M$E#D<<$$&D W	+A!&!1!1!!44I4  &6):M:MQY:Y
A.#!
 )f&7&79N9NPVPcPc%de!#q#.K)V%9%9:#%"..!1!M6F6J6J16MwW]_h_o_opq_rOsu )f&8&8&:S:S%TU!(i.D.D.F!L!S(!)"&K.J3C3G3G3JG"<A3hDJwWchigjjresOtIST]_e_x_xIy)=)=c)B1)E%.__ '(/
D(II  ).2.@.@$($>$>|Q$O*3g /A /O /3$  c!)V%7%78["))"-"5"5X=N=N=R=R"5"SK)V%>%>?'//<Iv~~6;"jj5 )V__5 ::e$3Bt);
TUVYWYTZ@[","@"@"MK(Jq"v,>,C,Cs,J2=
1Sb6*/0;Jq"v&-  
A.I !INNc$9kCeT$Z+NO%0IN%-k%:IN*IoW	+r "
$$&r   c           	          t        |      }|j                  j                         D ]T  \  }}t        |t        j                        r"t        |t        j
                        r=t        |t        j                        rXt        |t        j                        rst        |t        j                        rt        |t        j                        rt        |t        j                        rt        ||      }t        |t        j                        rF|j                  du s|j                  r|j                   s|j"                  s |j%                         }|du rt'        d| d| d|       t)        |||       W |S )N.u%   Попытка update field=Ellipsis  )r   r   rJ   r   r   r   CmfM2MCmfGenericM2M
CmfBackrefr   CmfGenericBackrefr`   r"   CmfTyper   r   
is_changed	orm_dirty	db_formatrH   r   )r   r   r   r   r  vvvs          r   r   zMapper.cmf_to_object   s:   Z LL&&( 	 DAq!V//0!V667!V]]+!V112!V../!V001!V556Q'B"fnn-99#rzz
 }}R\\\\^Sy"G
|STUVTWWXY[X\ ]^^CB=	 > 
r   r   )r4   r5   r6   r   r   r   r   r   r   r     s    tl!r   r   c                    	 dt         vrt        t              t         _        t         j                  j                  dt        t                     t         j                  d   j                  | d       t         j                  d   | xx   dz  cc<   t         j                  d   j                  dd       t         j                  d   dxx   dz  cc<   y# t        $ r
}Y d}~yd}~ww xY w)uK   
    Глобальный счетчик запросов
    :return:
    profiler_dataNselect_countr   rY   total)r   r   dictr.  rH   
setdefault)actiones     r   inc_select_countr5  $  s    !#)$/AO OO~{4/@AOON#..vq9OON#F+q0+OON#..w:OON#G,1,  s    C 	C% C%c                       e Zd ZdZ ej
                  d      ZddZed        Z	ddddddZ
d	d
dZd Zd Zd ZdddZd Zd Zd Zd ZddZd ZddddddZdddddZdddZy)DataProvideruV   Объект, связывающий модель с источником данныхz"\b(?P<table>\w+)\.(?P<field>\w+)\bNc                 D    || _         || _        d | _        t        | _        y r   )r   data_source_ddr   
mapper_cls)r   r9  r   s      r   r   zDataProvider.__init__;  s    
& r   c                 f    | j                   st        | j                        | _         | j                   S r   )r:  rD   r9  r   s    r   data_driverzDataProvider.data_driverA  s$    xxd../DHxxr   F)no_cacheTECHCOM_nocache
for_updatecache_inmemoryc                   |rt        d      | j                  j                  xsW |xsS t        j                  xsA |xs= t
        j                  j                  j                  | j                  j                        }| j                  | j                  |      |d<   fdt        j                  r	 t        j                  j                  j                  | j                  j                   dg|d|i|}|rd}	n+t
        j                  j                  j                  ||      }	t                |	dk(  rFt
        j                  j!                  t
        j                  j                  j"                  d	|        y|	Gt
        j                  j!                  t
        j                  j                  j"                  d
|        |	S t
        j                  j!                  t
        j                  j                  j"                  d|         | j$                  j                  | j                  g|d|i|}
| j$                  j&                  dk(  r|
S |r	|
rd|
_        |r|
S t
        j                  j                  j+                  ||
| j                  j                   | j-                  | j                  |d   |j                  d      |j                  d            |       |
S )zF
        :param args:
        :param kwargs:
        :return:
        8   no_cache запрещен и будет удален osvfilterc                 z    |j                         D ]'  \  }}|| vr	||   | |<   | |   |k7  s | |   |       ) y r   )rJ   )_fields_grow_cache_full_fields_loadr  r+  _grow_merges       r   rH  z%DataProvider.get.<locals>._grow_merge[  sU    )//1 >1..,=a,@&q))!,1#$6q$91=>r   Nz.getrA  rA  EmptyzDP: get() cache Empty zDP: get() cache zDP: get() NOcache r@  rdiskTorder_bygroup_byquery_paramsrA  )rH   r   TEXKOM_no_cacher   import_modecmfapp	CMF_CACHEcache_is_lockedr4   _get_filterTEXCOM_ENABLE_GROWCACHE_HACKtexcom_growcache_hack_cacherB   hashr5  print_debugDEBUGr=  rG   readonlyadd_query_params)r   r>  r?  r@  rA  r   r   fields_grow_cachekeycachedb_resrH  s              @r   rB   zDataProvider.getG  sn    VWW::-- M MAMM MU_ Mgg''77

8K8KL 	  ++DJJ?x	> ))e gg$$

(;(;'<D%ArDrYgrkqrEGG%%))#n)MEGGG 1 1 7 7;QRUQV9WXGG 1 1 7 7;KC59QRLGG 1 1 7 7;McU9ST)T%%))$**]t]
]V\]F $$/&"& GG!!V

 3 34!//

F8<LfjjYcNdflfpfpq{f|}- " 
 Mr   T)
invalidatec                H   t        d        | j                  j                  |g|i |}| j                  j                  dk(  r|S |s|S |+t        j
                  j                  j                  |d       y t        j
                  j                  j                  |d       |S )NinsertrK  r   )r5  r=  r   rG   rR  rS  rT  rc  )r   r   rc  r   r   r   s         r   r   zDataProvider.create  s    "%d%%h@@@   G+JJ;GG((8<$$S(3
r   c                 T    t        d        | j                  j                  |i |}|S )Nr   )r5  r=  bulk_deleter   r   r   r   s       r   rg  zDataProvider.bulk_delete  s,    "*d**D;F;
r   c                     t        d       t        j                  d| d| d|         | j                  j                  |g|i |}t        j                  d       |S )Nre  zbulk_insert start model= args= kwargs=zbulk_insert end)r5  r   rm   r=  bulk_insert)r   r   r   r   r   s        r   rl  zDataProvider.bulk_insert  s]    "	*5'vXfXNO*d**5B4B6B	/#
r   c           	         dd l }ddlm} dd l}t	        d       t        j                  d| d| d|         | j                  j                  |g|i |}t        j                  d       |j                  s |j                          }t        |      dkD  r5t        j                  j                  j                  |j                  d        n6|r4t        j                  j                  j                  |j                  |        |j                          |z
  dz  }	|j!                  d	t        |       d
| d|	dd       |	dkD  r |d|	dd       |S )Nr   	cmf_alertr   zbulk_update start model=rj  rk  zbulk_update endi  u)   Инвалидировали кеш по u$    обьектам у таблицы u    за z.2fu    мс   u2   DEV: Инвалидация кэша заняла )timery   ro  loggingr5  r   rm   r=  bulk_updaterP  lenrR  rS  rT  invalidate_idsr   warning)
r   r   r   r   rq  ro  rr  r   
start_timeelapsed_times
             r   rs  zDataProvider.bulk_update  sJ   )"	*5'vXfXNO*d**5B4B6B	/#$$"J3x$!!001A1A4H!!001A1A3G%DIIK*4<LOOGCzQuv{u|  }C  DP  QT  CU  UZ  [  \c!N|\_N``efg
r   )r>  c                    t        d       | j                  j                  s"t        j                  d|j
                           | j                  j                  |g|i |}| j                  j                  s"t        j                  d|j
                          |rt        d      | j                  j                  }| j                  j                  dk(  r|S |s|j                  dd      rd}d|j                  v r&|j                  j                  r|j                  rd	nd
}|j                  rd
}t        j                   j"                  j%                  ||       t        j                  d|j
                          |S )Nr   z+Run self.data_driver.update(), instance_id=z+End self.data_driver.update(), instance_id=rC  rK  rc  Tcmf_deletedr   r   z0End cmf.app.CMF_CACHE.invalidate(), instance_id=)r5  r   rP  r   rm   r   r=  r   rH   rG   rB   r   rz  r(  r  rR  rS  rT  rc  )r   r   r>  r   r   r   r3  s          r   r   zDataProvider.update  s0   "zz))GGA(++OP%d%%h@@@zz))GGA(++OPVWW::--   G+JFJJ|T:F/H4H4H4S4S%-%9%9x!GG((f5GGFx{{mTU
r   c                 >     | j                   j                  |i |}|S r   )r=  rq   )r   r   r   rets       r   rq   zDataProvider.commit  s$    %d%%t6v6
r   c                 :     | j                   j                  |i |S r   )r=  rp   r   s      r   rp   zDataProvider.rollback  s     (t(($9&99r   c                      | j                   j                  |i |}| j                   j                  dk(  r|S t        j                  j
                  j                  |d       |S )u   
        Logical delete. Реализация в провайдере или в модели?
        self.deleted = 1
        self.update()
        rK  r   )r=  r   rG   rR  rS  rT  rc  rh  s       r   r   zDataProvider.delete  s[     &d%%t6v6   G+J$$S(3
r   c                   
 ddl mmmmmmmm ddl	m
 ddlm}m}m}m} dddddfd	dfd	dfd		dfd
	dfd	dfd	dfd	dfd	d
ddddddddddd

|j                  dg       }|g }|j                  d      si t!        |t"              rt%        j&                  |      }|r|g}|j)                         j+                         D ]Q  \  }}	||j,                  v s||= t!        |	t,        j.                        r|	j0                  }	|j3                  |d|	g       S fd
fddt"        ffdfd |      }|S )u   
        Преобразуем обычные kwargs в продвинутый фильтр для однообразной логики фильтрования
        :param model:
        :param kwargs:
        :return:
        r   )start_of_day
end_of_daystart_of_weekend_of_weekstart_of_monthend_of_monthstart_of_yearend_of_year)str_to_timedelta)r   r   rq  r   c                 ,    t        j                  |       S r   )r   nowoffsets    r   <lambda>z*DataProvider._get_filter.<locals>.<lambda>  s    AEE&M r   c                 ,    t        j                  |       S r   )r   r   r  s    r   r  z*DataProvider._get_filter.<locals>.<lambda>  s    AFF6N r   c                      |       S r   r   )r  r  s    r   r  z*DataProvider._get_filter.<locals>.<lambda>      L4H r   c                      |       S r   r   )r  r  s    r   r  z*DataProvider._get_filter.<locals>.<lambda>  s    Jv4F r   c                      |       S r   r   )r  r  s    r   r  z*DataProvider._get_filter.<locals>.<lambda>      M&4I r   c                      |       S r   r   )r  r  s    r   r  z*DataProvider._get_filter.<locals>.<lambda>      K4G r   c                      |       S r   r   )r  r  s    r   r  z*DataProvider._get_filter.<locals>.<lambda>	  s    N64J r   c                      |       S r   r   )r  r  s    r   r  z*DataProvider._get_filter.<locals>.<lambda>
  r  r   c                      |       S r   r   )r  r  s    r   r  z*DataProvider._get_filter.<locals>.<lambda>  r  r   c                      |       S r   r   )r  r  s    r   r  z*DataProvider._get_filter.<locals>.<lambda>  r  r   )
__G_NOW__G_DATE__START_OF_DAY__END_OF_DAY__START_OF_WEEK__END_OF_WEEK__START_OF_MONTH__END_OF_MONTH__START_OF_YEAR__END_OF_YEARdwMy)
r  r  r  r  r  r  r  r  r  r  rD  filter_context==c                     t        | t              r| vry| dk(  rd}n
| dk(  rd}nd}|r6t        t        dd      s|nt	        t        j
                  |      t        _         |           S )z plain '__G_NOW' / '__G_DATE' Nr  ,  r  ip  jscache_timelife)r"   r.   r`   r   minr  )sttl_TIME_BASE_FUNCSs     r   _maybe_time_plain_stringz:DataProvider._get_filter.<locals>._maybe_time_plain_string-  so    a%2B)BI~j!07;Mt0TSZ]^_^p^pruZv"&#A&((r   c                    dt         dt        fd}t        | t              r| sy| d   }t        |t               r|vryt	        |       dk(  r
 |          S | d   }t        |t               s$t        d| dt        |      j                          ||      rj                  |      }|r| | }|j                         s
 |          S  |   |      S )	u!    ['KEY'] или ['KEY','offset'] r  returnc                     | xs dj                         } t        |       xr | j                  d      j                         S )Nr}   z+-)stripr  lstripisdigit)r  s    r   _is_plain_intzIDataProvider._get_filter.<locals>._maybe_time_list.<locals>._is_plain_int>  s2    W"OO%Aw;188D>#9#9#;;r   Nr   rY   u   Offset для u9    должен быть строкой, получено: )
r.   r  r"   r#   rt  r\   r   r4   rB   r  )noder  r`  r  unit_NATURAL_UNITr  s        r   _maybe_time_listz2DataProvider._get_filter.<locals>._maybe_time_list<  s   < < < dD)q'Cc3'36F+F4yA~,',..!WFfc* >#6optu{p|  qF  qF  pG  "H  I  IV$$((- &xv.F<<>,',..(#C(00r   r  c                 <   t        | t              sy t        j                  dt        j                        }|j                  | j                               }|sy d}t        t        dd       s|nt        t        j                  |      t        _
        dd l}|j                  j                         j                         }|j                  d      xs d}|j                         s%|j                  |j                  j                         S t        j                  d      }d}|}	|j#                  |      D ]E  \  }
}}|
xs |}
|
}|sd	}|j%                         }|d
k(  rd}n
|dk(  rd}n|}|	 |
 | |       z  }	G |	j                  |j                  j                         S )NzE^\s*now\(\)\s*(?P<tail>(?:\s*[+-]?\s*\d+\s*(?:y|M|min|[wdhms]))*)\s*$r  r  r   tailr}   z([+-]?)\s*(\d+)\s*([A-Za-z]+)?+r  r  mr  )r"   r.   recompileI	fullmatchr  r`   r   r  r  r   r  
astimezonegroupr   r  findalllower)r  _NOW_CALL_POSTFIX_REr  r  _dt
base_localr  token_re	last_sign	base_calcsignnumr  ulnormr  s                  r   _maybe_time_call_stringz9DataProvider._get_filter.<locals>._maybe_time_call_stringY  s~   a%#%::X$  %..qwwy9A C,3A7I4,PVYZ[ZlZlnqVrA #))+668J776?(bD::<!,,S\\-=-=>>zz"CDHI"I#+#3#3D#9 Dc4(y 	DZZ\;D3YDD-seD6.BCC	D" ''(8(899r   c                     |       }||S t        | t              r| D cg c]
  } |       c}S  |       }||S  |       }||S t        | t              r#| j                  d      rdfd	 | dd        S t        | t              r)| dk(  r$t        j
                  j                  j                  S | S c c}w )Nz__SELF.c                 t    | j                  d      \  }}}|t        ||d       }n|   }|r
 ||      }|S )N.)r   )	partitionr`   )pathr   headsepr  r  get_ctx_attrs        r   r  zQDataProvider._get_filter.<locals>._recursive_params_replace.<locals>.get_ctx_attr  sI    &*nnS&9OD#t( 'tT : .t 4 ,T ? Lr   r
   __G_CURRENT_USERr   )r"   r#   r.   r   r   current_userr   r   )	rD  r+  ir  r  r  r  _recursive_params_replacer  s	      @r   r  z;DataProvider._get_filter.<locals>._recursive_params_replace  s     (A} &$'>DE1!4EE )0A} (/A} &#&6+<+<Y+G! $F12J//&#&65G+G~~((...M9 Fs   B;r   )ry   r  r  r  r  r  r  r  r  cmf.util.cmfutilr  r   r   rq  r   rB   r"   r.   r  r  copyrJ   r   r'  r   r   )r   r   r   r   r   rq  r   smart_filterr  r+  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  s             @@@@@@@@@@@@@@@@r   rV  zDataProvider._get_filter  sR    	I  	I  	I5<< A B H F I G J H I G
  "3"S #s"S
 zz(B/L$45NlC(::l3L(+LKKM'') 	2DAqELL 1Ia0A##QaL1	2	)	1:+	:s +	:`$	 $	L 1>r   c                 H   ddl m} ddl m} t        g g i       }|rm|D ]h  }	|	dk(  r	|	j	                  d      r|	d d |j
                  v r|	d d }	|	j                  d      r|	d	d  }	|d
   j                  |j                   d|	        j |rQ|D ]L  }
|
j	                  d      r|
d d |j
                  v r|
d d }
|d
   j                  |j                   d|
        N |s|S t        |d   t              ra|D ]Z  }| j                  |||      j                         D ]3  \  }}|dk(  r||   j                  |        ||   j                  |       5 \ |S |d   dv r`| j                  ||d	d  |d         j                         D ]3  \  }}|dk(  r||   j                  |        ||   j                  |       5 |S |d   dk(  r|t        |      dk7  s|d	   dvrt!        d      |d   D ]R  }	|	dk(  r	|	j	                  d      r|	d d |j
                  v r|	d d }	|d
   j                  |j                   d|	        T |S t        |      dk(  rEd }|d   j#                  d      }|d	   j#                  d      }d }d }|d   dk(  r|S |d   dk(  rd|d<   |d   |j
                  v r0|d	   }|j
                  |d      }|d   }t        |      d	kD  rF|d	   }n@|d   |j
                  v r/|d   }|j
                  |d      }|d   }t        |      d	kD  r|d	   }d}|j	                  d      r|d d |j
                  v r|d d }d}|r>|j	                  d      r-|j%                         }|r|d d |d   j
                  v r|d d }d}|r|sdv r|dk7  r|d   }t        |t&              rt        |      }t        |t              s|g}g }|D ]q  }t)        t+        |      t
        j,                        r|j.                  }t)        t+        |      t0              r|j2                  j.                  }|j                  |       s |dk(  r$|d   j5                  |g       j                  |       ||j6                  v r$|d   j5                  |g       j                  |       |dk7  rvt)        |t
        j8                        r\d}|D ]Q  }t        |t:              r=|j=                  d      d	k(  r)t;        |      j#                  d      d   t?        |      v rPd}S |rd}t)        |t
        j@                        r;|j                  dk7  r,|j
                  jC                  |j                  d d       xs |}t)        |t
        j8                        ra|dk7  r\|j%                         D ]I  }|s|d   j                  |j                          |s'|d
   j                  |j                   d|        K t)        |t
        j8                        rsdk(  rn|j%                         D ][  }| j                  ||d         j                         D ]3  \  }}|dk(  r||   j                  |        ||   j                  |       5 ] |d
   j                  |j                   d|        |S  |d| d d!       |S )"Nr   rn  rw   )rx   r   cache_clustersr   r  r  -rY   r   r  )parent_operr  )ANDORrL     )=r  ut   Операция order_by в фильтре должна быть в формате: ["order_by", "=", [поля..]]r
   rz  ANYtextFT)r  r  INr  parentrX   rx   EXISTSuP   Ошибка  при выполнении UBQL - неверный запрос. uM    Проверьте правильность введенных данных.)abort)"ry   ro  rx   r1  r  r   r   r   r   r"   r#   r^  rJ   r   extendrt  rH   r]   related_modelssetr   r   r'  r   r   r   r2  cache_cluster_fields
CmfRelBaser.   r   varsr  rB   )r   r   
obj_filterobj_order_byobj_group_byr  ro  rx   r   rL  rM  filt_lsr`  r&   r   obj_filter0obj_filter1field__field_namer   operfield_is_tuuid
_relmodelsrule_values_dirtyrule_valuesrvmaybe_field_is_tuuid_vrmodels                               r   r^  zDataProvider._query_params  sX   
 	*&"R;( Gt#$$U+"0M'}H&&s+'|HH$$(8(8'98*%EFG ( G$$U+"0M'}HH$$(8(8'98*%EFG
 JjmT*% - $ 2 25'{ 2 [ a a c -HC..C,C,--` 
S ]m+ ..ujnR\]^R_.`ffh )S**HOOC(HOOC()N 
C ]j(:!#z!}K'G  !W  X  X 'qM Gt#$$U+"0M'}HH$$(8(8'98*%EFGv 
i _!E$Q---c2K$Q---c2K $J 1~.
1~& "(A1~-!!}[^4(^
{#A%(3A%Q5<</!!}[^4(^
{#A%(3A%"N""5)j"o.M'_
!% %6%?%?%F"113
!%6s%;z!}?S?S%S(9#2(>%%)N(T5F-F;Z^K^(21%!"3S9,01B,C)%&7>->,?)"$K/ /%d2h?!#B%d2h	:!#B#**2./ "X-,-88RHOOP[\!U%?%??,-88RHOOP[\* "X-*UFDUDU2V/3,"- =B$.r3$7BHHSMQ<NSVWYSZS`S`adSefgShlpqwlxSx7< 4= 0-1NeV__5%:J:Jd:R!LL,,U-=-=cr-BCLuEeV%6%67 "X-&+&:&:&< aF#1 #H 4 48I8I7J L0 #H 4 48I8I7J!L]K^5_ `	a
 eV%6%67DH<L"'"6"6"8 5(,(:(:6:a=(Q(W(W(Y 5HC"&66 #C 4 #C 455 H$$(8(8'9:,%GH 
 hisht  uB  C  KO  P
r   c                    ddg dg dggdgg dg g g dgg ddgd	gg g d
gdgg dg dgg g g dgg ddgddgg g g dgg dg dgg ddgg g g dgg dgg dgg g g dgg dgg dgg g g dgg dgg dgg g g dgg dgdgddgg g g dgg dgg ddgg g g dgg dgdgddgg g g dgg dg d gg dd!gg g g dgg d"gg dgg g g dgg d#gdgdgg g g dgg}d$d%l m} |D ]f  \  }}|j                  j                  j	                  |j                  |      }||k7  s<t        d&| d'       t        d(|        t        d)|        h y*)+ug   
        Тестирование
        Запуск: models.CmfTask.dp._test_query_params()
        listsr  )cache_status_typer  IN_PROGRESS)logic_prefixr  zlist.agile_sprintCmfList)zCmfList.cache_status_typezCmfList.logic_prefixCmfTask.lists)rx   r   parentsr  r  )r  r  {   r  r  )rG   r  qwezCmfTask.name)zcmf_owner.idr  zCmfPerson:12312321	CmfPersonzCmfPerson.idzCmfTask.cmf_ownerzCmfTask.cache_status_typezCmfTask.logic_prefix)ext_idLIKEz
%::qwe::%%zCmfTask.ext_id)r  r  ::qwe::)zparent.ext_idr  r  zCmfTask.parent)zstatus.ext_idr  r  	CmfStatuszCmfStatus.ext_idzCmfTask.status)zstatus.status_code_idr  12345zCmfStatus.status_code)zstatus.status_coder  r  )rG   r  r  )r   r  	qweqweqwez
CmfTask.id)zparent.project.namer  r  )statusr  r  r   rw   uC   Ошибка в результате _query_params(models.CmfTask, r   u   Факт:        u   Должно быть: N)ry   rx   CmfTaskdpr^  rQ   )r   f_listrx   fres_origr   s         r   _test_query_paramszDataProvider._test_query_paramsc  s    h!JLv wx!{.t  BD  XZ  eg  h	

 !!{.?Bbdpsotu
 "n%5"XZegh
 9#}AT0Ubdxz  FH  I
 78bc&ACY%Zgi}  KM  N
 .. &6%7BZ\gij
 (( &6%7BZ\gij
 //&6%7BZ\gij
 // $}1CEU0Vcey{  GI  J
 55&=?O%P]_su  AC  D
 22#}1HJZ0[hj  A  LN  O
 "#;<nl%CPRfhsuv
 11&6%7BZ\gij	
 $$#}1A0Bregrtu
s=
@ 	'! 	<KAx..##11&..!DCh[\][^^_`a)#/0/z:;	< 	r   c                   |rt        d      | j                  j                  xsW |xsS t        j                  xsA |xs= t
        j                  j                  j                  | j                  j                        }t                | j                  | j                  |      |d<   t        j                  j                  j                  | j                  j                   dg|d|i|}|rd}nt        j                         }	t
        j                  j                  j                  ||      }t        j                         |	z
  dkD  r-t        j                  dt        j                         |	z
          |d	k(  rGt
        j                  j!                  t
        j                  j                  j"                  d
|        g S |Gt
        j                  j!                  t
        j                  j                  j"                  d|        |S t
        j                  j!                  t
        j                  j                  j"                  d|        t        j                         }	 | j$                  j&                  | j                  g|d|i|}
t        j                         |	z
  dkD  r-t        j                  dt        j                         |	z
          | j$                  j(                  dk(  r|
S |r|
D ]	  }d|_         |st        j                         }	| j-                  | j                  |d   |j                  d      |j                  d            }t
        j                  j                  j/                  ||
| j                  j                   ||       t        j                         |	z
  dkD  r-t        j                  dt        j                         |	z
          |
S )u   
        Пробросили сюда relation_load и relation_load_only для реализации join и подселектов в будущем
        :param args:
        :param kwargs:
        :return:
        rC  rD  z.listrA  NrI  g333333?z%PROF DataProvider.list cache.get got rJ  zlist() From cache  Empty zlist() From cache zDP: list() From NOcache r@  g      ?z1PROF DataProvider.list self.data_driver.list got rK  TrL  rM  rN  z%PROF DataProvider.list cache.add got )rH   r   rP  r   rQ  rR  rS  rT  rU  r4   r5  rV  rY  rq  rB   rm   rZ  r[  r=  r#   rG   r\  r^  r]  )r   r>  r?  r@  rA  r   r   r`  ra  prof_strb  r  rO  s                r   r#   zDataProvider.list  s'    VWW::-- M MAMM MV` Mgg''77

8K8KL 	++DJJ?xgg$$

(;(;'<E%BsTsZhslrsEiikGGG%%))#n)MEyy{W$s*?		g@U?VWXGGG 1 1 7 7;TUXTY9Z[IGG 1 1 7 7;McU9STLGG 1 1 7 7;STWSX9YZiikG*T%%**4::^^^W]^Fyy{W$s*KDIIKZaLaKbcd $$/ &A!%AJ& ))+#11$**fX>NPVPZPZ[ePfhnhrhrs}h~!!%%c6djj6I6I5JZf  xF%  G99;(3.GGCDIIKRYDYCZ[\Mr   )r>  r?  rA  c                   |rt        d      | j                  j                  xsS |xsO t        j                  xs= t
        j                  j                  j                  | j                  j                        }t                | j                  | j                  |      |d<   t        j                  j                  j                  | j                  j                   dg|d|i|}|rd }n+t
        j                  j                  j                  ||      }|dk(  rPt
        j                  j                  t
        j                  j                  j                  d|        t!        d      |Gt
        j                  j                  t
        j                  j                  j                  d	|        |S t                 | j"                  j$                  | j                  g|i |}|s| j'                  | j                  |d   |j                  d
      |j                  d            }	t
        j                  j                  j)                  ||| j                  j                   |	|       |S )NrC  rD  z.countrA  rI  rJ  zcount() From cache Empty z$BUG: count() cache can not be empty!zcount() From cache rL  rM  rN  )rH   r   rP  r   rQ  rR  rS  rT  rU  r4   r5  rV  rY  rB   rZ  r[  r\   r=  r   r^  r]  )
r   r>  r?  rA  r   r   r`  ra  rb  rO  s
             r   r   zDataProvider.count  s   VWW::-- M MAMM Mgg''77

8K8KL 	++DJJ?xgg$$

(;(;'<F%Ctdt[itmstEGG%%))#n)MEGGG 1 1 7 7;TUXTY9Z[CDDGG 1 1 7 7;Nse9TUL+T%%++DJJHHHF#11$**fX>NPVPZPZ[ePfhnhrhrs}h~!!%%c6djj6I6I5JZf  xF%  Gr   )r   c                |    t         | j                  j                  |i || j                  | j                  |      S Nrk   r   r   )
QueryProxyr=  queryr   )r   r   r   r   s       r   r   zDataProvider.query_deprecated  s@    "D""D3F38H8HPTPZPZcik 	kr   )NN)NNr  )r4   r5   r6   r   r  r  TABLE_FIELD_REr   propertyr=  rB   r   rg  rl  rs  r   rq   rp   r   rV  r^  r  r#   r   r   r   r   r   r7  r7  7  s    `RZZ EFN!  
 #(%`e HT 26 &. 05 2
:yxn`L^ $)$5af 4l %*4PU 4 .2 kr   r7  c                   `    e Zd ZdZddZd ZddZd Zd Zd Z	d	 Z
d
 Zd Zed        Zd Zy)r%  u   
    Оборачиваем кастомный запрос и добавляем возможность извлекать данные с автомаппингом.
    TODO: Проверить слайсы query[a:b]
    Nc                     || _         || _        || _        t        |t               | _        t        j                  |      | _        y r   )_queryr:  r   r"   r   _mapper_is_myr   _mapper)r   r&  rk   r   r   s        r   r   zQueryProxy.__init__  s;    
!+FJ!??!,,V4r   c                       fd}|S )u   Обёртка для методов, которые возвращают новый запрос на основании текущего.c                       t        j                        | i |}t        |j                  j                  j
                        S r#  )r`   r+  r%  r:  r   r-  )r   r   	new_queryitemr   s      r   method_proxyz,QueryProxy.__getattr__.<locals>.method_proxy  s<    2T2DCFCIiDHHDJJt||\\r   r   )r   r1  r2  s   `` r   __getattr__zQueryProxy.__getattr__  s    	] r   c                     | j                   j                  | j                  | j                  |||      }t	        || j                   | j                  | j
                        S )uR   
        Логика сортировки на основе модели
        )r   rL  sliceaggregate_selectr$  )r:  order_queryr+  r   r%  r-  )r   rL  r5  r6  r0  s        r   r7  zQueryProxy.order_query  sO     HH((KKtzzHE\l ) n	)

4<<XXr   c                     | j                   rZ| j                   j                  |      r?| j                  j                  || j                   j	                  t        |                  }|S )u6   Автоконвертация объектов в CMF)r   )r:  r   r-  r   r   r   )r   r   s     r   
_map_valuezQueryProxy._map_value#  sL    88,,U3LL..uDHH<N<NtTY{<[.\Er   c                 n     t        |t              rt         fd|D              S  j                  |      S )Nc              3   @   K   | ]  }j                  |        y wr   )r9  ).0colr   s     r   	<genexpr>z&QueryProxy._map_row.<locals>.<genexpr>,  s     =#-=s   )r"   tupler9  )r   rows   ` r   _map_rowzQueryProxy._map_row)  s-    c5!====??3''r   c                 H   t        | j                        }d}t        j                  j                  j                  ||      }t        j                  j                  j                  | j                  j                        rd}n)t        j                  j                  j                  |      }t                |dk(  rGt        j                  j                  t        j                  j                  j                  d|        g S |Gt        j                  j                  t        j                  j                  j                  d|        |S t        j                  j                  t        j                  j                  j                  d|        | j                  D cg c]  }| j                  |       }}t        j                  j                  j                  ||| j                  j                          | j                  r| j                   j#                          |S c c}w )uo   Метод извлечения всех данных из текущего запрос с маппингом.
custom_allNrJ  zall() From cache Empty zall() From cache zDP: all() From NOcache )r?   r+  rR  rS  rT  rY  rU  r   r4   rB   r5  rZ  r[  rA  r]  r,  r-  r   r   sql_kr`  ra  r@  rb  s          r   allzQueryProxy.all0  s   4;;'gg$$R- 77,,TZZ-@-@AEGG%%))#.EGGG 1 1 7 7;RSVRW9XYIGG 1 1 7 7;LSE9RSLGG 1 1 7 7;RSVRW9XY48KK@SdmmC(@F@GG!!#v$**2E2E1FH!!..0M	 As   Hc                 B   t        | j                        }d}t        j                  j                  j                  ||      }t        j                  j                  j                  | j                  j                        rd}n)t        j                  j                  j                  |      }t                |dk(  rFt        j                  j                  t        j                  j                  j                  d|        y|Gt        j                  j                  t        j                  j                  j                  d|        |S t        j                  j                  t        j                  j                  j                  d|        | j                  j                         }| j                  |      }t        j                  j                  j                  ||| j                  j                          | j                   r| j"                  j%                          |S )uP   Метод извлечения первой строки с маппингом.custom_firstNrJ  zDP: first() From cache Empty zDP: first() From cache zDP: first() From NOcache )r?   r+  rR  rS  rT  rY  rU  r   r4   rB   r5  rZ  r[  firstrA  r]  r,  r-  r   rD  s          r   rJ  zQueryProxy.firstK  s   4;;'gg$$R- 77,,TZZ-@-@AEGG%%))#.EGGG 1 1 7 7;XY\X]9^_GG 1 1 7 7;RSVRW9XYLGG 1 1 7 7;TUXTY9Z[++##%C]]3'FGG!!#v$**2E2E1FH!!..0Mr   c                    t                t        | j                        }d}t        j                  j
                  j                  ||      }t        j                  j
                  j                  | j                  j                        rd }n)t        j                  j
                  j                  |      }t                |dk(  rFt        j                  j                  t        j                  j
                  j                  d|        y |Gt        j                  j                  t        j                  j
                  j                  d|        |S t        j                  j                  t        j                  j
                  j                  d       | j                  j                         }t        j                  j
                  j                  ||| j                  j                          |S )Ncustom_countrJ  zDP: count() From cache Empty zDP: count() From cache zDP: count() From NOcache TODO)r5  r?   r+  rR  rS  rT  rY  rU  r   r4   rB   rZ  r[  r   r]  )r   rE  rF  r`  ra  rb  s         r   r   zQueryProxy.countg  sW   4;;'gg$$R- 77,,TZZ-@-@AEGG%%))#.EGWW  !2!2!8!8<YZ]Y^:_`WW  !2!2!8!8<STWSX:YZ\GG 1 1 7 7;XZ[[&&(FGG!!#v$**2E2E1FHr   c                 >     | j                   j                  |i |}|S r   )r+  r   )r   r   r   rb  s       r   r   zQueryProxy.delete  s"    ###T4V4r   c                     | j                   S r   )r+  r   s    r   dd_queryzQueryProxy.dd_query  s    {{r   c                 4    t        | j                               S )u+   Чтение строк из запроса)iterrG  r   s    r   __iter__zQueryProxy.__iter__  s    DHHJr   )NNN)r4   r5   r6   r   r   r3  r7  r9  rA  rG  rJ  r   r   r(  rO  rR  r   r   r   r%  r%    sN    5Y(684
   r   r%  r   )select)(r   r^   r  r	  r  rq  collectionsr   r   r  r   typingr   r  flaskr   cmf.apprR  r   ry   r	   models.base_modelr   rA   r?   rD   rO   rR   rL   ri   rs   ru   rz   r|   r   r   r   r5  r7  r%  r   r   r   <module>rY     s        	  /        ) *BZ$
? 746 6r4+ 4+n~: ~BXZ Xv2&Mk MkbD  D r   