
    qi$T                         S r SSKrSSKrSSKrSSKJr  SSKrSSKJr  SSK	J
r
JrJr  SSKJrJr  Sr\R"                  " \5      r " S S	\5      r " S
 S\5      rg)ao  
Implementation of a WebDAV provider that provides a very basic, read-only
resource layer emulation of a MySQL database.

This module is specific to the WsgiDAV application. It provides a
classes ``MySQLBrowserProvider``.

Usage::

    (see docs/sample_wsgidav.yaml)
    MySQLBrowserProvider(host, user, passwd, db)

    host - host of database server
    user - user_name to access database
    passwd - passwd to access database
    db - name of database on database server

The ``MySQLBrowserProvider`` provides a very basic, read-only
resource layer emulation of a MySQL database.
It provides the following interface:

    - the root collection shared consists of collections that correspond to
      table names

    - in each table collection, there is a resource called "_ENTIRE_CONTENTS".
      This is a non-collection resource that returns a csv representation of the
      entire table

    - if the table has a single primary key, each table record will also appear
      as a non-collection resource in the table collection using the primary key
      value as its name. This resource returns a csv representation of the record
      and will also include the record attributes as live properties with
      attribute name as property name and table name suffixed with colon as the
      property namespace


This is a very basic interface and below is a by no means thorough summary of
its limitations:

    - Really only supports having numbers or strings as primary keys. The code uses
      a numeric or string comparison that may not hold up if the primary key is
      a date or some other datatype.

    - There is no handling for cases like BLOBs as primary keys or such. Well, there is
      no handling for BLOBs in general.

    - When returning contents, it buffers the entire contents! A bad way to return
      large tables. Ideally you would have a FileMixin that reads the database even
      as the application reads the file object....

    - It takes too many database queries to return information.
      Ideally there should be some sort of caching for metadata at least, to avoid
      unnecessary queries to the database.

    N)StringIO)util)HTTP_FORBIDDENDAVError#PRECONDITION_CODE_ProtectedProperty)DAVProvider_DAVResourcereStructuredTextc                      ^  \ rS rSrSrU 4S jrS rS rS rS r	S r
S	 rS
 rS rS rS rS rU 4S jrU 4S jrSS jrSrU =r$ )MySQLBrowserResourceO   zdRepresents a single existing DAV resource instance.

See also DAVResource and MySQLBrowserProvider.
c                 4   > [         TU ]  X#U5        S U l        g N)super__init___cache)selfproviderpathis_collectionenviron	__class__s        W/home/kali/flask_env/lib/python3.13/site-packages/wsgidav/samples/mysql_dav_provider.pyr   MySQLBrowserResource.__init__U   s    g6    c           
      Z   U R                   =R                  S-  sl        U R                   R                  U R                  5      u  pSnSnSnUc  SnOUc  SnOSnUS	:X  a  S
nSnOSnSnUSL nSU[        R                  " 5       U R
                  [        R                  " 5       R                  U R                  5      R                  5       SSX4S.S.U l
        U(       d"  [        R                  " 5       U R                  S'   [        R                  SU R                   R                  -  5        g)zXRead resource information into self._cache, for cached access.

See DAVResource._init()
   Unknown z	text/htmlNDatabasezDatabase Tableztext/csv_ENTIRE_CONTENTSzDatabase Table Contentsz$CSV Representation of Table ContentszDatabase Recordz"Attributes available as propertiesF)typetypeComment)content_lengthcontentTypecreateddisplay_nameetagmodifiedsupport_rangesdisplay_infor)   z---> _init, nc=%s)r   _count_get_resource_inst_init_split_pathr   timenamehashlibmd5update	hexdigestr   _loggerdebug_count_initConnection)r   	tableNameprimKeydisplay_typedisplayTypeCommentr%   r   s          r   _initMySQLBrowserResource._initY   s    	33q83!]]66tyyA	 ! %L_+L$K,,8%K"0%I"  4 #&yy{ IIKKM((3==?#%1U

 &*iikDKK
#)DMM,O,OOPr   c                 r    U R                   c  U R                  5         U R                   R                  U5      $ r   )r   r;   get)r   infos     r   	_get_infoMySQLBrowserResource._get_info   s(    ;;JJL{{t$$r   c                 $    U R                  S5      $ )Nr$   r@   r   s    r   get_content_length'MySQLBrowserResource.get_content_length   s    ~~.//r   c                 $    U R                  S5      $ )Nr%   rC   rD   s    r   get_content_type%MySQLBrowserResource.get_content_type   s    ~~m,,r   c                 $    U R                  S5      $ )Nr&   rC   rD   s    r   get_creation_date&MySQLBrowserResource.get_creation_date   s    ~~i((r   c                     U R                   $ r   )r/   rD   s    r   get_display_name%MySQLBrowserResource.get_display_name   s    yyr   c                 $    U R                  S5      $ )Nr+   rC   rD   s    r   get_display_info%MySQLBrowserResource.get_display_info   s    ~~n--r   c                 $    U R                  S5      $ )Nr(   rC   rD   s    r   get_etagMySQLBrowserResource.get_etag   s    ~~f%%r   c                 $    U R                  S5      $ )Nr)   rC   rD   s    r   get_last_modified&MySQLBrowserResource.get_last_modified   s    ~~j))r   c           
         / nU R                   R                  5       n U R                   R                  U R                  5      u  p4Ucu  U R                   R	                  U5      nU HS  nUR                  [        U R                   [        R                  " U R                  U5      SU R                  5      5        MU     OUc  U R                   R                  X#5      nUbu  U R                   R                  X#U5      nU HS  nUR                  [        U R                   [        R                  " U R                  U5      SU R                  5      5        MU     UR                  S[        U R                   [        R                  " U R                  S5      SU R                  5      5        UR                  5         U$ ! UR                  5         f = f)ziReturn list of (direct) collection member names (UTF-8 byte strings).

See DAVResource.get_member_list()
TFr   r!   )r   _init_connectionr-   r   _list_tablesappendr   r   join_urir   _find_primary_key_list_fieldsinsertclose)r   membersconnr7   r8   retlistr/   pri_keys           r   get_member_list$MySQLBrowserResource.get_member_list   sh   
 }}--/$	!%!:!:499!EI --44T:#DNN, MM MM$))T:  LL	 $ --99$J&"mm88'RG '0 $ $dii > % $	 !( (dii1CD	 JJL JJLs   FF6 6Gc                    [        5       nU R                  R                  U R                  5      u  p#UGbB  U R                  R	                  5       nU R                  R                  XB5      n[        R                  " XSS9n0 nU H  nXU'   M	     UR                  U5        US:X  a  UR                  [        R                  R                  5      n	U	R                  SU R                  R                  -   S-   U-   5        U	R                  5       n
U
 H  nUR                  U5        M     U	R!                  5         O0U R                  R#                  XBU5      nUb  UR                  U5        UR!                  5         UR%                  S5        U$ )zEOpen content as a stream for reading.

See DAVResource.get_content()
ignore)extrasactionr!   zSELECT * from .r   )r   r   r-   r   rZ   _get_field_listcsv
DictWriterwriterowcursorMySQLdbcursors
DictCursorexecute_dbfetchallra   _get_record_by_primary_keyseek)r   
filestreamr7   r8   rc   
listFields	csvwriter
dictFields
field_namerp   
result_setrows               r   get_content MySQLBrowserResource.get_content   sB   
 Z
!]]66tyyA	==113D66tGJzHUIJ(
)3:& )z*,,W__%?%?@/$--2C2CCcIIUV#__.
%C&&s+ &mm>>tPWX?&&s+JJL
 	r   c                @  > [         TU ]  US9nU R                  R                  U R                  5      u  p4Ube  U R                  R                  5       nU R                  R                  XS5      nU H  nUR                  SU SU 35        M     UR                  5         U$ )zReturn list of supported property names in Clark Notation.

Return supported live and dead properties. (See also DAVProvider.get_property_names().)

In addition, all table field names are returned as properties.
)
is_allprop{z:})	r   get_property_namesr   r-   r   rZ   rl   r\   ra   )	r   r   	propNamesr7   r8   rc   	fieldlist	fieldnamer   s	           r   r   'MySQLBrowserResource.get_property_names   s     G.*.E	!]]66tyyA	==113D55dFI&	  2i[I;!?@ 'JJLr   c                   > U R                   R                  U R                  5      u  p#Ub  [        R                  " U5      u  pEXBS-   :X  ax  U R                   R                  5       nU R                   R                  Xb5      nXW;   a.  U R                   R                  XbX55      nUR                  5         U$ UR                  5         [        T	U ])  U5      $ )a  Return the value of a property.

The base implementation handles:

- ``{DAV:}lockdiscovery`` and ``{DAV:}supportedlock`` using the
  associated lock manager.
- All other *live* properties (i.e. name starts with ``{DAV:}``) are
  delegated to self.getLivePropertyValue()
- Finally, other properties are considered *dead*, and are handled  using
  the associated property manager, if one is present.
:)r   r-   r   r   split_namespacerZ   rl   _get_field_by_primary_keyra   r   get_property_value)
r   r/   r7   r8   ns	localNamerc   r   valr   s
            r   r   'MySQLBrowserResource.get_property_value	  s     "]]66tyyA	 006MB#o&}}557 MM99$J	)--AAC JJLJ

w)$//r   c                 &    [        [        [        S9e)zDSet or remove property value.

See DAVResource.set_property_value()
)err_condition)r   r   r   )r   r/   valuedry_runs       r   set_property_value'MySQLBrowserResource.set_property_value&  s    
 *M
 	
r   )r   )F)__name__
__module____qualname____firstlineno____doc__r   r;   r@   rE   rH   rK   rN   rQ   rT   rW   rf   r   r   r   r   __static_attributes____classcell__r   s   @r   r   r   O   s\    
.Q`%0-).&*,\"H&0:
 
r   r   c                   |   ^  \ rS rSrU 4S jrS rS rS rS rS r	S r
S	 rS
 rS rS rS rS rS rS rSrU =r$ )MySQLBrowserProvideri5  c                 `   > [         TU ]  5         Xl        X l        X0l        X@l        SU l        g )Nr   )r   r   _host_user_passwdru   r6   )r   hostuserpasswddbr   s        r   r   MySQLBrowserProvider.__init__6  s*    

%&"r   c                     U R                   R                   SU R                   SU R                   SU R                   S3$ )Nz	 for db 'z' on 'z
' (user: 'z')')r   r   ru   r   r   rD   s    r   __repr__MySQLBrowserProvider.__repr__>  s=    ..))*)DHH:VDJJ<zZ^ZdZdYeehiir   c                     UR                  5       S;   a  g[        R                  " UR                  S5      SS5      u  p#X#4$ )z8Return (tableName, primaryKey) tuple for a request path.)Nr   /)NNr   r   )stripr   
save_split)r   r   r7   r8   s       r   r-    MySQLBrowserProvider._split_pathA  s9    ::<?*!__TZZ_c1E	##r   c                     U =R                   S-  sl         [        R                  " U R                  U R                  U R
                  U R                  S9$ )Nr   )r   r   r   r   )r6   rq   connectr   r   r   ru   rD   s    r   rZ   %MySQLBrowserProvider._init_connectionI  s=    ""a'"$**T\\dhh
 	
r   c                     / nUR                  [        R                  R                  5      nUR	                  SU-   5        UR                  5       nU H  nUR                  US   5        M     UR                  5         U$ )N	DESCRIBE Field)rp   rq   rr   rs   rt   rv   r\   ra   )r   rc   
table_namerd   rp   r~   r   s          r   rl   $MySQLBrowserProvider._get_field_listO  sd    W__778{Z/0__&
CNN3w<( r   c                 v    Uc  g/ SQnUR                  5       nU H  nUR                  U5      (       d  M    g   g)NF)BIGINTINTT	MEDIUMINTSMALLINTTINYINTBITDECDECIMALDOUBLEFLOATREALzDOUBLE PRECISIONINTEGERNUMERICT)upper
startswith)r   datatypenumerictypesnumtypes       r   _is_data_type_numeric*MySQLBrowserProvider._is_data_type_numericY  sC    
  >>##G""7++ $ r   c                    S nS nUR                  [        R                  R                  5      nUR	                  SU-   5        UR                  5       nU H  nUS   S:X  d  M  Uc  US   nUS   nM    g   UR                  5         U R                  U5      n	UR                  [        R                  R                  5      nU	(       a7  UR	                  SU-   S-   U R                  -   S	-   U-   S
-   U-   S-   U-   5        O9UR	                  SU-   S-   U R                  -   S	-   U-   S
-   U-   S-   U-   S-   5        UR                  5       nUc  UR                  5         gUR                  5         g)Nr   KeyPRIr   TypeFSELECT  FROM rk    WHERE  =  = ''T)
rp   rq   rr   rs   rt   rv   ra   r   ru   fetchone)
r   rc   r   pri_key_valuere   pri_field_typerp   r~   r   	isNumTypes
             r   _exists_record_by_primary_key2MySQLBrowserProvider._exists_record_by_primary_keys  s   W__778{Z/0__&
C5zU"?!'lG%([N   	..~>	W__778NN (( 	
      	  NN (( 	
      	  
 oo;LLNr   c                    S nS nUR                  [        R                  R                  5      nUR	                  SU-   5        UR                  5       nU H  n	U	S   S:X  d  M  Uc  U	S   nU	S   nM    g    UR                  5         U R                  U5      n
UR                  [        R                  R                  5      nU
(       a7  UR	                  SU-   S-   U R                  -   S-   U-   S	-   U-   S
-   U-   5        O9UR	                  SU-   S-   U R                  -   S-   U-   S	-   U-   S-   U-   S-   5        UR                  5       n	U	c  UR                  5         g [        R                  " X   5      nUR                  5         U$ )Nr   r   r   r   r   r   r   rk   r   r   r   r   )rp   rq   rr   rs   rt   rv   ra   r   ru   r   r   to_str)r   rc   r   r   r}   re   r   rp   r~   r   r   r   s               r   r   .MySQLBrowserProvider._get_field_by_primary_key  s   W__778{Z/0__&
C5zU"?!'lG%([N  	..~>	W__778NN (( 	
      	  NN (( 	
      	  
 oo;LLNkk#/*
r   c                 &   0 nS nS nUR                  [        R                  R                  5      nUR	                  SU-   5        UR                  5       nU H  n	U	S   S:X  d  M  Uc  U	S   nU	S   nM    g    UR                  5         U R                  U5      n
UR                  [        R                  R                  5      nU
(       a1  UR	                  SU R                  -   S-   U-   S-   U-   S	-   U-   5        O3UR	                  SU R                  -   S-   U-   S-   U-   S
-   U-   S-   5        UR                  5       n	U	c  UR                  5         g U	R                  5        H  n[        R                  " X   5      XK'   M     UR                  5         U$ )Nr   r   r   r   r   zSELECT * FROM rk   r   r   r   r   )rp   rq   rr   rs   rt   rv   ra   r   ru   r   keysr   r   )r   rc   r   r   dictRetre   r   rp   r~   r   r   fnames               r   rw   /MySQLBrowserProvider._get_record_by_primary_key  s   W__778{Z/0__&
C5zU"?!'lG%([N  	..~>	W__778NN ((  	
     	 NN ((  	
      
 oo;LLNXXZE![[4GN  r   c                    S nUR                  [        R                  R                  5      nUR	                  SU-   5        UR                  5       nU H  nUS   nUS   nUS:X  d  M  Uc  UnM    g    UR                  5         U$ )Nr   r   r   r   )rp   rq   rr   rs   rt   rv   ra   )	r   rc   r   re   rp   r~   r   r   keyvalues	            r   r^   &MySQLBrowserProvider._find_primary_key  s}    W__778{Z/0__&
CGI5zH5 ?'G  	r   c                 P   / nUR                  [        R                  R                  5      nUR	                  SU-   S-   U R
                  -   S-   U-   5        UR                  5       nU H*  nUR                  [        R                  " Xs   5      5        M,     UR                  5         U$ )Nr   r   rk   )rp   rq   rr   rs   rt   ru   rv   r\   r   r   ra   )r   rc   r   r}   rd   rp   r~   r   s           r   r_   !MySQLBrowserProvider._list_fields  s    W__778y:-8488CcIJVW__&
CNN4;;s78 r   c                     / nUR                  5       nUR                  S5        UR                  5       nU H  nUR                  SUS   -  5        M     UR	                  5         U$ )NzSHOW TABLESz%sr   )rp   rt   rv   r\   ra   )r   rc   rd   rp   r~   r   s         r   r[   !MySQLBrowserProvider._list_tables)  sV    }%__&
CNN43q6?+ r   c                     U =R                   S-  sl         U R                  X5      (       d  gU R                  U5      u  p4USL n[        XXR5      $ )z:Return info dictionary for path.

See get_resource_inst()
r   N)_count_get_resource_instexistsr-   r   )r   r   r   
_tableNamer8   r   s         r   get_resource_inst&MySQLBrowserProvider.get_resource_inst3  sP     	%%*%{{4))"..t4
4#DGGr   c                    U R                  U5      u  p4Uc  g S nU R                  5       nU R                  U5      nX6;  a   U(       a  UR                  5         ggU(       a0  US:w  a*  U R	                  XSU5      U(       a  UR                  5         $ $  U(       a  UR                  5         gg! W(       a  UR                  5         f f = f)NTFr!   )r-   rZ   r[   ra   r   )r   r   r   r7   r8   rc   tbllists          r   r   MySQLBrowserProvider.existsB  s    !--d3		D((*D''-G' 

 	 7&8899$7S 

  

 t

 s   (B, B, ,Cc                 `    U R                  U5      u  p4U R                  X5      =(       a    US L $ r   )r-   r   )r   r   r   r   r8   s        r   r   "MySQLBrowserProvider.is_collectionV  s-    "..t4
{{4)=go=r   )r6   ru   r   r   r   )r   r   r   r   r   r   r-   rZ   rl   r   r   r   rw   r^   r_   r[   r   r   r   r   r   r   s   @r   r   r   5  sX    'j$
42h3j1f H(> >r   r   )r   rm   r0   r.   ior   rq   wsgidavr   wsgidav.dav_errorr   r   r   wsgidav.dav_providerr   r	   __docformat__get_module_loggerr   r4   r   r    r   r   <module>r     s`   6n       
 ;"

 
 
*^
< ^
Lc>; c>r   