
    -iѪ                        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
mZ d dlmZmZmZmZ d dlmZmZmZmZ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Z! G d de"          Z# G d de#          Z$ G d de#          Z% G d de#          Z& G d de#          Z' G d de#          Z( G d de#          Z) G d de$          Z* G d d          Z+dS )     N)	getsourcegetfullargspec)	randrange)Storage
IU_Storage)IU_UniqueHashIndexIU_HashIndex	HashIndexUniqueHashIndex)ElemNotFoundDocIdNotFoundIndexExceptionIndexTryReindexExceptionReindexExceptionIndexNotFoundExceptionIndexConflict)Parser)NONE)cdb_environment)random_hex_4 c                 P    d| d|d|d|d|d}|                     d          S )Nz# z
# z

# inserted automatically
import os
import marshal

import struct
import shutil

from hashlib import md5

# custom db code start
# db_custom
z)

# custom index code start
# ind_custom
z;

# source of classes in index.classes_code
# classes_code
z

# index code start

utf8)encode)
index_nameindex_class	db_custom
ind_customclasses_codess         S/var/www/html/speakWrite/venv/lib/python3.11/site-packages/codernitydb3/database.pyheader_for_indexesr#   *   sA     > zz;;;			:::|||5	EA6 88F    c                       e Zd ZdS )DatabaseExceptionN__name__
__module____qualname__ r$   r"   r&   r&   M           Dr$   r&   c                       e Zd ZdS )PreconditionsExceptionNr'   r+   r$   r"   r.   r.   Q   r,   r$   r.   c                       e Zd ZdS )RecordDeletedNr'   r+   r$   r"   r0   r0   U   r,   r$   r0   c                       e Zd ZdS )RecordNotFoundNr'   r+   r$   r"   r2   r2   Y   r,   r$   r2   c                       e Zd ZdS )RevConflictNr'   r+   r$   r"   r4   r4   ]   r,   r$   r4   c                       e Zd ZdS )DatabaseConflictNr'   r+   r$   r"   r6   r6   a   r,   r$   r6   c                       e Zd ZdS )DatabasePathExceptionNr'   r+   r$   r"   r8   r8   e   r,   r$   r8   c                       e Zd ZdS )DatabaseIsNotOpenedNr'   r+   r$   r"   r:   r:   i   r,   r$   r:   c                      e Zd ZdZdZd Zd>dZd Zd>dZd Z	d>d	Z
d
 Zd?dZd@dZdAdZdAdZdBdZd ZdCdZd@dZd Zd Zd>dZd>dZ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(d, Z)d- Z*d. Z+dDd/Z,	 	 	 	 	 	 	 dEd1Z-	 	 	 	 dFd2Z.d3 Z/d4 Z0d5 Z1d6 Z2d7 Z3d8 Z4d9 Z5d: Z6d; Z7d< Z8d= Z9dS )GDatabasez2
    A default single thread database object.
    r   c                 Z    || _         d | _        g | _        d | _        i | _        d| _        d S )NF)pathstorageindexesid_indindexes_namesopenedselfr>   s     r"   __init__zDatabase.__init__t   s1    	r$   Nc                     |rP	 t          |dd         d          }n#  t                      xY w|dz  }|dk    rd}t          d          }d||fz  S t          d          }d	|z  S )
z
        Creates new revision number based on previous one.
        Increments it + random bytes. On overflow starts from 0 again.
        N         i  r   i   s   %04x%04xs   0001%04x)intr4   r   )rE   old_revrev_numrnds       r"   create_new_revzDatabase.create_new_rev|   s    
  
	0$gbqbk2..$!mm#qLGE""C'3//S  s    -c                 2    | j         st          d          d S )NzDatabase is not opened)rC   r:   rE   s    r"   __not_openedzDatabase.__not_opened   s(    { 	@%&>???	@ 	@r$   c                 J    |r|ng }|D ]}|                      |d           dS )z
        Set indexes using ``indexes`` param

        :param indexes: indexes to set in db
        :type indexes: iterable of :py:class:`codernitydb3.index.Index` objects.

        FcreateN)	add_index)rE   r@   inds      r"   set_indexeszDatabase.set_indexes   sD     %,''" 	. 	.CNN3uN----	. 	.r$   c                    t          |j                  }|                    d          st          j        |          }||_        t          |dg           }d}|D ]}|t          |          dz   z  }t          j        t          j
                            |d||j        fz  dz             d          5 }|                    t          |j        |j        j        t          | dd          t          |dd          |                     |                    |                    d	                     d
d
d
           n# 1 swxY w Y   dS )z
        Adds single index to a database.
        It will use :py:meth:`inspect.getsource` to get class source.
        Then it will build real index file, save it in ``_indexes`` directory.
        cr    r   z

%.2d%s.pywcustom_headerr   NT)r   	__class__
startswithtextwrapdedent_ordergetattrioFileIOosr>   joinnamewriter#   r(   r   )	rE   piindexcodecls_coder    currfs	            r"   _add_single_indexzDatabase._add_single_index   sy    ))s## 	)?4((D5."55 	5 	5DIdOOf44LLYrw||Ax1ej/'AE'IJJ  	) GG"5:u/G#*4"#E#E#*5/2#F#F#/1 12 2 2
 GGDKK''(((	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) ts   2A<D::D>D>c                 6   |r|ni }t          j        t          j                            ||          d          5 }|                                dd                                                             d          }|                                dd                                                             d          }|                                                    d          }ddd           n# 1 swxY w Y   	 t          |dt          j                            ||          z  d          }|t                      vrt          |t                                 n)t          |t                      t                                  t                      |         | j        |fi |}	t          |dd                   |	_        |	S #  t          j                            ||          }
t          j        |
|
dz              t!          j        d|
dz               xY w)	af  
        It will read single index from index file (ie. generated in :py:meth:`._add_single_index`).
        Then it will perform ``exec`` on that code

        If error will occur the index file will be saved with ``_broken`` suffix

        :param p: path
        :param ind: index name (will be joined with *p*)
        :returns: new index object
        r   Nr   z
<Index: %sexec_brokenzFatal error in index, saved as )re   rf   rg   r>   rh   readlinestripdecodereadcompileglobalsrv   localsrK   rc   renamewarningswarn)rE   rk   rW   
ind_kwargsrq   ri   _classrn   objind_objind_paths              r"   _read_index_singlezDatabase._read_index_single   s    $.5ZZ2
Yrw||As++S11 	+Q::<<#))++226::DZZ\\!""%++--44V<<F6688??6**D	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+	$rw||As/C/C CVLLCWYY&&S'))$$$$S'))VXX...'gii'	4FF:FFG RaR\\GN N	w||As++HIh*, , , MM#i//3 4 4 4s    B*C00C47C4<CG AHc                     t          j        t           j                            | j        d                    }t	          fd|D                       rt          d          d S )N_indexesc              3   n   K   | ]/}|d d         k    |dd          t                    k    +|V  0dS ru   N)str).0xri   nums     r"   	<genexpr>z3Database.__check_if_index_unique.<locals>.<genexpr>   sK      LLaa"goo!BQB%3s88:K:K:K:K:K:KLLr$   Already exists)rg   listdirr>   rh   anyr   )rE   ri   r   r@   s    `` r"   __check_if_index_uniquez Database.__check_if_index_unique   sf    *RW\\$)Z@@AALLLLL7LLLMM 	2 0111	2 	2r$   r   Fc                 :   |i }t           j                            | j        d          }t          |t                    r=|                    d          s't          |                                          dk     s|                                d         dk    rt                      }|	                    |          \  }}|                                }|d         dd          |d         dd          }	d	g}
|                                D ]}|

                    d
|z             |

                    d           t          |	|          }|d                    |dd                                        d          z  }|d                    |
                              d          z  }|}n6|                                d         dd                                          | j        v r|st          d          |r`t!          t#          fdt          j        |                              }|st'          d          t)          |d         d d                   }|dk    r|sdk    st'          d          d|fz  }|s|                     |           t           j                            ||dz             }t           j                            |          rt          j        ||dz              t1          j        |d          5 }t          |t                    r|                    d          }|                    |           d d d            n# 1 swxY w Y   |                     ||dz             }nt          |t                    rs|                    d          r^|dd          }|                    d          s|dz  }|                     |||          }|j        | j        v r|st          d          nt          |t<                    rm|t?          |j         j!                  j"        dd          }|D ]=}|dvr7tG          |tI                                }t          |tH                    s|||<   >|r`t!          t#          fdt          j        |                              }|st'          d          t)          |d         d d                   }j        | j        v r|st          d          |dk    r|sj        dk    st'          d          |s|                     j        |           | %                    ||           d|j        fz  }|                     ||dz   |          }|j        nt'          d          |fS )Nr   path:rH      z# inserted automaticallyr   ru   rJ   z

#SIMPLIFIED CODEz#%sz#SIMPLIFIED CODE END

)r   
r   r   c                 J    |                      d          o| dd         k    S Nr\   ru   r   endswith)r   ri   s    r"   <lambda>z(Database.__write_index.<locals>.<lambda>   s$    QZZ%6%6%J1QrT7d? r$   z+Can't edit index that's not yet in databaseidz Id index must be the first addedr[   r\   _lastr]      )argskwargsc                 T    |                      d          o| dd         j        k    S r   )r   ri   )r   rW   s    r"   r   z(Database.__write_index.<locals>.<lambda>,  s'    QZZ%6%6%N1QrT7ch;N r$   zPArgument must be Index instance, path to index_file or valid string index format)&rg   r>   rh   
isinstancer   r`   len
splitlinesr   parseappendr#   r   ry   rB   r   listfilterr   r.   rK    _Database__check_if_index_uniqueexistsr   re   rf   rj   r   r   ri   r   r   r_   rF   r   rd   r   rr   )rE   	new_indexnumbereditr   rk   parcustom_importsr!   rZ   comentedlines2previous_indexr   
ind_path_frq   r   r>   init_argumentsrp   vrW   ri   s                         @@r"   __write_indexzDatabase.__write_index   s9   JGLLJ//i%% [	i.B.B7.K.K [	9''))**Q..)2F2F 3 33.3/ 3/hh$'IIi$8$8!LLNNtABBxaDH23%0022 2 2DOOEDL1111 :;;;'aNKKKdii!""&&--f555dii))00888		 ++--a04zz||t)))$)#$4555 4!%JJJJ:a==* *"+ "+ & G0EG G G^A.rr233{{4{,68 8 864.0H ;,,T6:::aE)9::Jw~~j)) 0	*$w.0 0 0:s++ #qi-- 9 ) 0 0 8 8I	"""# # # # # # # # # # # # # # #
 --aE1ABBGG	3'' *	I,@,@,I,I *	QRR=D=='' --azBBG<Dt)))$)#$4555	5)) "	 C+#,. ..21227N& - -111T46622A%a.. -+,
4( 4!%NNNN:a==* *"+ "+ & G0EG G G^A.rr233x4---d-#$4555{{4{D0@0@,68 8 8 ?,,SXv>>>""1fc222638"44H--aE1A:NNG<DD(b   }s   A MM MTc                    |i }t           j                            | j        d          }t           j                            |          s|                                  t          t          d t          j        |                              }|r#t          |d         dd                   }|dz   }nd}| 	                    ||d	          \  }}	| j
                            |           || j        |	<   |r(|                                 r|                                 |	d
k    r(|                                  |                                  t!          |dd          D ]}
 |
| |           |	S )a  

        :param new_index: New index to add, can be Index object, index valid string or path to file with index code
        :type new_index: string
        :param create: Create the index after add or not
        :type create: bool

        :returns: new index name
        Nr   c                 ,    |                      d          S )Nr\   r   r   s    r"   r   z$Database.add_index.<locals>.<lambda>S  s    !**U*;*; r$   ru   rJ   r   Fr   r   patchersr+   )rg   r>   rh   r   
initializesortedr   r   rK   _Database__write_indexr@   r   rB   create_index_Database__set_main_storage_Database__compat_thingsrd   )rE   r   rU   r   rk   currentlast_nextr   ri   patchs              r"   rV   zDatabase.add_indexC  sr    JGLLJ//w~~a   	OO ; ;RZ]]KKLL 	wr{2A2''D1HEEE**9e%*HHG$$$#*4  	'{{}} '$$&&&4<<##%%%  """Wj! ! 	! 	!EE$    r$   c                 `   |i }|                      |dd          \  }t          fd| j        D                       }|                                 | j                            |          }|                                 || j        |<   || j        <   |r|                                S )z
        Allows to edit existing index.
        Previous working version will be saved with ``_last`` suffix (see :py:meth:`.revert_index`

        :param bool reindex: should be the index reindexed after change

        :returns: index name
        Nr   Tr   c              3   2   K   | ]}|j         k    |V  d S N)ri   )r   r   ri   s     r"   r   z&Database.edit_index.<locals>.<genexpr>t  s)      ==afnn1nnnn==r$   )r   nextr@   close_indexrm   
open_indexrB   reindex_index)rE   rm   reindexr   r   oldindex_of_indexri   s          @r"   
edit_indexzDatabase.edit_indexh  s     J**5"4*@@====dl=====++C00'.^$#*4  	%t$$$r$   c                 ~   t           j                            | j        d          }| j        v r| j                 }d|j        fz  }n/t          j        |          }t          fd|D                       }|st          dz            t           j                            ||dz             }t           j                            |          st          dz            |dd         }	t          j	        ||	           d	t           j        
                    |	          d
         z  }
|                     |
||          S )z
        Tries to revert index code from copy.
        It calls :py:meth:`.edit_index` with previous working.

        :param string index_name: index name to restore
        r   z	%.2d%s.pyc              3   8   K   | ]}|d d         k    |V  dS r   r+   )r   r   r   s     r"   r   z(Database.revert_index.<locals>.<genexpr>  s5      JJAAadGz4I4Ia4I4I4I4IJJr$   z%s index not foundr   zNo previous copy found for %sNzpath:%srJ   )rg   r>   rh   rB   rc   r   r   r&   r   r   splitr   )rE   r   r   r   r   rW   	full_namer@   	last_pathcorrect_last_pathrk   s    `         r"   revert_indexzDatabase.revert_index~  s:    7<<	:66+++$Z0C#sz:&>>IIj**GJJJJJJJKKI 	G#$8:$EFFFGLL9w+>??	w~~i(( 	0#$C$.%/ 0 0 0%crcN
	).///&788;;q':666r$   Allc                 T   || j         vr&|                                  t          d|z            | j         |         }d|j        |fz  }|dz  }t	          j        t          j                            | j        d|          d          5 }|	                                }|dk    r|cddd           S |dk    r	 |
                    d	          }||d         }|                                d
d         }t          d |          }	d                    |	          cddd           S # t          $ r Y ddd           dS w xY w|dk    rJ	 |
                    d	          }|d|         cddd           S # t          $ r |cY cddd           S w xY w	 ddd           n# 1 swxY w Y   dS )z
        It will return full index code from index file.

        :param index_name: the name of index to look for code
        Index `%s` doesn't existsr[   r\   r   rt   r   NSs   #SIMPLIFIED CODErJ   c                     | dd          S NrJ   r+   r   s    r"   r   z)Database.get_index_code.<locals>.<lambda>  s    qu r$      
r$   P)rB   _Database__not_openedr   rc   re   rf   rg   r>   rh   r{   rm   r   map
ValueError)
rE   r   code_switchrW   ri   rq   cor!   llls
             r"   get_index_codezDatabase.get_index_code  s    T///()D)3*4 5 5 5 ,3:z22Yrw||DIz4@@#FF 	$!Be##	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$
 c!!*((#677C 344Aqt,A__a00B ::b>>	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ "   	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ c!!$((#677C dsd8+	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$$ "   II'	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$$ "	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$. ssa   F0F7D$AF$
D=.F<D==	FE2	F2F>FFFF!$F!c                 |    	 | j         d         j        | _        | j         d         | _        dS # t          $ r Y dS w xY w)zD
        Sets database main storage (from the **id** index)
        r   N)rB   r?   rA   KeyErrorrQ   s    r"   __set_main_storagezDatabase.__set_main_storage  sP    	-d3;DL,T2DKKK 	 	 	 DD	s   )- 
;;c                 `   | j         du rt          d          |s| j        }n|| _        |r}| j        st          d          t          j                            | j        d          }t          j                            |          rt          d          t	          j        |           | j        S )a  
        Initialize new database

        :param path: Path to a database (allows delayed path configuration), if not provided self.path will be used
        :param makedir: Make the ``_indexes`` directory or not

        :returns: the database path
        TAlready openedNo path specifiedr   z$Cant't create because already exists)rC   r6   r>   r.   rg   rh   r   makedirs)rE   r>   makedirrk   s       r"   r   zDatabase.initialize  s     ;$"#3444 	9DDDI 	9 B,-@AAATY
33Aw~~a   O&'MNNNKNNNyr$   c                    |r|ni }| j         r>t          j                             | j                   s|                     | j                    d| j        vr8|r6d|vr
| j         |d<   d|d<   t          di |}|                     |d           | j        D ]<}	 |                                 # t          $ r t          d|j        z            w xY wdS )	zv
        Will open new database (works like create),
        if not self.path provided will call initialize()
        r   db_pathri   FrT   z%Already exists (detected on index=%s)Tr+   )r>   rg   r   r   rB   r   rV   r@   r   r   r6   ri   )rE   with_id_indexindex_kwargsrA   rm   s        r"   
__open_newzDatabase.__open_new  s   
 (4;||9 	+7>>$),, +	***t)))m),,*.)Y'#'L $44|44FNN6%N000\ 	J 	JEJ""$$$$! J J J&;ejHJ J JJ ts   B,,"Cc                     t           j                            | j        d          }t          j        |          D ]1}|                    d          r|                     d|z   d           2dS )z:
        Read all known indexes from ``_indexes``
        r   r\   r   FrT   N)rg   r>   rh   r   r   rV   )rE   rk   rW   s      r"   _read_indexeszDatabase._read_indexes  sk     GLLJ//:a== 	< 	<C||E"" <w}U;;;	< 	<r$   c                     | j         sdS | j         j        dd         dk    r"t          j        d           t          | _        dS dS )z+
        Things for compatibility.
        NrH      4szsYour database is using old rev mechanizm for ID index. You should update that index (codernitydb3.migrate.migrate).)rA   entry_line_formatr   r   r   rO   rQ   s    r"   __compat_thingszDatabase.__compat_things  s]    
 { 	F;(1-55M ! " " " #/D 65r$   c                    |r|                      |           | j        st          d          | j        du rt	          d           | j        di | |                                  |                                  d| _        | j        S )zz
        Create database

        :param path: path where to create the database

        :returns: database path
        r   Tr   r+   )r   r>   r.   rC   r6   _Database__open_newr   r   )rE   r>   r   s      r"   rU   zDatabase.create  s      	"OOD!!!y 	>()<===;$"#3444!!&!!!!!!yr$   c                     |s| j         }|sdS t          j                             |          r=t          j                             t          j                             |d                    S dS )zi
        Checks if database in given path exists

        :param path: path to look for database
        Fr   )r>   rg   r   rh   rD   s     r"   r   zDatabase.exists&  s`      	9D 	57>>$ 	B7>>"',,tZ"@"@AAAur$   c                 .   | j         du rt          d          |r|| _        | j        st          d          t          j                            | j                  st          d          g | _        d| _        i | _	        | 
                                 d| j	        vrt          d          | j        D ]}|                                 | j                            d 	           |                                  |                                  d| _         dS )
zf
        Will open already existing database

        :param path: path with database to open
        Tr   r   zCan't open databaseNr   zThere must be `id` index!c                     | j         S r   )rc   )rW   s    r"   r   zDatabase.open.<locals>.<lambda>M  s    #* r$   )key)rC   r6   r>   r.   rg   r   r8   r@   rA   rB   r   r   sortr   r   )rE   r>   rm   s      r"   openzDatabase.open4  s)    ;$"#3444  	DIy 	>()<===w~~di(( 	?'(=>>>t)))()DEEE\ 	 	E44555!!!tr$   c                     | j         st          d          d| _        i | _        d| _        | j        D ]}|                                 g | _        d| _         dS )z%
        Closes the database
        z
Not openedNFT)rC   r6   rA   rB   r?   r@   r   rE   rm   s     r"   closezDatabase.closeS  sk     { 	1"<000\ 	  	 Etr$   c                    |                                  st          d          t          | j        dd                   D ](}	 |                     |           # t
          $ r Y %w xY wt          | dd          | j                                         t          j
        | j        d          D ]t\  }}}|D ]4}t          j        t          j                            ||                     5|D ]4}t          j        t          j                            ||                     5ut          j        | j                   |                                  dS )zT
        Allows to destroy database.

        **not reversable** operation!
        zDoesn't exists'rJ   NrA   F)topdownT)r   r6   reversedr@   destroy_indexr   rd   rA   destroyrg   walkr>   removerh   rmdirr  )rE   rm   rootdirsfilesri   s         r"   r  zDatabase.destroyb  s[    {{}} 	6"#4555dl122.// 	 	E""5))))!   44((4K!!!!#E!B!B!B 	3 	3D$ 4 4	"',,tT223333 3 3dD1122223


ts   A
A&%A&c                    	 |                     |          }n?# t          $ r2}t          j        d|j        d|dt
                     d}Y d}~nd}~ww xY w|r|\  }}	 |                     |          }	n?# t          $ r2}t          j        d|j        d|dt
                     d}	Y d}~nd}~ww xY w|	r|	\  }
}|
|k    r/|                    ||           |                    ||
|           dS ||k    rN	 |                    ||
|           dS # t          t          f$ r  t          j        d|j        z             Y dS w xY wdS |                    ||           dS |                     |||           dS )z
        Performs update operation on single index

        :param index: the index to perform operation
        :param data: new data
        :param db_data: database data
        :param doc_id: the id of document
        zProblem during update for `	`, ex = `z`, uou should check index code.N`, you should check index code.z&Reindex might be required for index %s)make_key_value	Exceptionr   r   ri   RuntimeWarningdeleteinsert_with_storageupdate_with_storager   r   _single_insert_index)rE   rm   datadb_datadoc_idold_should_indexexold_key	old_valuenew_should_indexnew_key	new_values               r"   _single_update_indexzDatabase._single_update_index|  s-   	$$33G<< 	$ 	$ 	$MM#(:::rrr34BD D D  $		$
  	;!1GY(#(#7#7#=#=   ( ( (#(:::rrr34BD D D $(      	(
   .%5"g%%LL111--fgyIIIII)++(11&'9MMMMM(-8 ( ( ( !H!J'( ( ( ( ( (( ,+ VW-----%%eT6:::::s>    
A(AA A6 6
B2 (B--B28D -EEc                    | j                             |          \  }}|                     d|          }|d         |k    rt                      |                     |          }| j                             |||           |||fS )z1
        Performs update on **id** index
        r   _rev)rA   r  getr4   rO   r!  )rE   r/  r#  _idvaluer$  new_revs          r"   _update_id_indexzDatabase._update_id_index  s     [//55
U((4%%6?d""--%%d++ 	''We<<<GW$$r$   c                     |                      ||          \  }}}| j        dd         D ]}|                     ||||           ||fS )zC
        Performs update operation on all indexes in order
        rJ   N)r4  r@   r-  )rE   r/  r#  r1  r3  r$  rm   s          r"   _update_indexeszDatabase._update_indexes  sc     !% 5 5dD A AWg\!""% 	A 	AE%%eT7C@@@@G|r$   c                     	 |                     |          }n?# t          $ r2}t          j        d|j        d|dt
                     d}Y d}~nd}~ww xY w|r|\  }}|                    |||           dS dS )z
        Performs insert operation on single index

        :param index: index to perform operation
        :param data: new data
        :param doc_id: document id
        zProblem during insert for `r  r  N)r  r  r   r   ri   r  r   )rE   rm   r#  r%  should_indexr'  r  r2  s           r"   r"  zDatabase._single_insert_index  s    	  //55LL 	  	  	 MM#(:::rrr34BD D D  LLLLLL		 
  	:%JC%%fc599999	: 	:s    
A(AAc                 x    | j                             |          \  }}| j                             |||           |S )z2
        Performs insert on **id** index.
        )rA   r  r   )rE   r/  r#  r1  r2  s        r"   _insert_id_indexzDatabase._insert_id_index  s>     [//55
U 	''T5999
r$   c                     |                      ||          }| j        dd         D ]}|                     |||           dS )zC
        Performs insert operation on all indexes in order
        rJ   N)r:  r@   r"  )rE   r/  r#  r1  rm   s        r"   _insert_indexeszDatabase._insert_indexes  sX     ##D$//\!""% 	8 	8E%%eT37777	8 	8r$   c                     |                     |          }|sdS |\  }}	 |                    ||           dS # t          $ r Y dS w xY w)a\  
        Performs single delete operation on single index.
        It's very similar to update functions (that's why data is in arguments)

        :param index: index to perform operation
        :param data: not important (because of update operations)
        :param doc_id: document id
        :param old_data: current data in database
        N)r  r  r   )rE   rm   r#  r%  old_data
index_datar  r2  s           r"   _single_delete_indexzDatabase._single_delete_index  sn     ))(33
 	F
U	LL%%%%%" 	 	 	FF	s   8 
AAc                 n    | j                             |          }| j                             |           dS )z3
        Performs delete from **id** index
        N)rA   make_keyr  )rE   r1  r/  r#  r  s        r"   _delete_id_indexzDatabase._delete_id_index   s5     k""3''3r$   c                     |                      d|          }|d         |k    rt                      | j        dd         D ]}|                     ||||           |                     |||           dS )zC
        Performs delete operation on all indexes in order
        r   r/  rJ   N)r0  r4   r@   r@  rC  )rE   r1  r/  r#  r>  rm   s         r"   _delete_indexeszDatabase._delete_indexes	  s     88D#&&Ft##--\!""% 	B 	BE%%eT3AAAAc4.....r$   c                 H   t          |t                    r)|| j        vrt          d|z            | j        |         }n,|| j        vr#|                                  t          d          |j        dk    r#|                                  t          d          d|j        |j        fz  dz   }t          j	        
                    | j	        d|          }t          j        |           |                                 | j        |j        = | j                            |           dS )	z
        Destroys index

        :param index: the index to destroy
        :type index: :py:class:`codernitydb3.index.Index`` instance, or string
        No index named %s<Argument must be Index instance or valid string index formatr   zId index cannot be destroyedr[   r\   r   N)r   r   rB   r.   r@   r   ri   rc   rg   r>   rh   unlinkr  r  )rE   rm   	full_filerk   s       r"   r  zDatabase.destroy_index  s!    eS!! 	PD...,-@5-HIII&u-EE$,&&(NP P P:()GHHHej99EA	GLLJ	::
	!uz*E"""""r$   c                 d   t          |t                    r)|| j        vrt          d|z            | j        |         }n,|| j        vr#|                                  t          d          t          |dd          rt          d|j        z            d|_	        |
                                 |`	dS )a  
        Compacts index
        Used for better utilization of index metadata.
        The deleted documents will be not more in structure.

        :param index: the index to destroy
        :type index: :py:class:`codernitydb3.index.Index`` instance, or string
        rG  rH  
compactingFz The index=%s is still compactingTN)r   r   rB   r.   r@   r   rd   r   ri   rL  compactr  s     r"   compact_indexzDatabase.compact_index-  s     eS!! 	PD...,-@5-HIII&u-EE$,&&(NP P P5,.. 	/"#E#(:$. / / /r$   c                 D    | j         D ]}|                     |           dS )z-
        Runs compact on all indexes
        N)r@   rN  r  s     r"   _compact_indexeszDatabase._compact_indexesE  s6     \ 	& 	&Eu%%%%	& 	&r$   c                     | j                             |d                   \  }}}}}|t          j        t          j        fvr|                     |||           d S d S )Nr1  )rA   r0  r   STATUS_DSTATUS_Ur"  )rE   rm   r#  r%  revstartsizestatuss           r"   _single_reindex_indexzDatabase._single_reindex_indexL  sc    +/;??K, ,(UD&%.%.999%%eT6::::: :9r$   c                    t          |t                    r)|| j        vrt          d|z            | j        |         }n,|| j        vr#|                                  t          d          |j        dk    r#|                                  t          d          t          |dd          rt          d|j        z            | 	                    d          }d|_
        |                                 |                                 	 	 t          |          }|                     ||           n# t          $ r Y nw xY w8|`
d	S )
a  
        Performs reindex on index. Optimizes metadata and storage informations for given index.

        You can't reindex **id** index.

        :param index: the index to reindex
        :type index: :py:class:`codernitydb3.index.Index`` instance, or string
        rG  rH  r   zId index cannot be reindexed
reindexingFz The index=%s is still reindexingTN)r   r   rB   r.   r@   r   ri   rd   r   allrZ  r  r   r   rX  StopIteration)rE   rm   all_iterrp   s       r"   r   zDatabase.reindex_indexR  s}    eS!! 	PD...,-@5-HIII&u-EE$,&&(NP P P:()GHHH5,.. 	/"#E#(:$. / / / 88D>>	88H~~ **5$7777 !   	8 s   D- -
D:9D:c                 T    | j         dd          D ]}|                     |           d S r   )r@   r   r  s     r"   _reindex_indexeszDatabase._reindex_indexesx  s=    \!""% 	& 	&Eu%%%%	& 	&r$   c                    d|v r#|                                   t          d          |                                 }d|vrC	 | j                                        }n0#  |                                   t          d          xY w|d         }|J ||d<   ||d<   |                     ||           ||d}|                    |           |S )a  
        It's using **reference** on the given data dict object,
        to avoid it copy it before inserting!

        If data **will not** have ``_id`` field,
        it will be generated (random 32 chars string)

        :param data: data to insert
        r/  z&Can't add record with forbidden fieldsr1  zNo id?Nr1  r/  )r   r.   rO   rA   
create_keyr&   r<  update)rE   r#  r/  r1  rets        r"   insertzDatabase.insert|  s     T>>(8: : :""$$}}2k,,..2!!###'111u+CVUT4(((4((C
s   A %B c                 D   d|vsd|vr#|                                   t          d          |d         }	 t          |          }n(#  |                                   t          d          xY w|                     ||          \  }}||d}|                    |           |S )z
        It's using **reference** on the given data dict object,
        to avoid it copy it before updating!

        ``data`` **must** contain ``_id`` and ``_rev`` fields.

        :param data: data to update
        r/  r1  z Can't update without _rev or _idz!`_rev` must be valid bytes objectra  )r   r.   bytesr6  rc  )rE   r#  r/  r1  r3  rd  s         r"   rc  zDatabase.update  s     ~~Ud]]()KLLLF|	N;;DD	N()LMMM++D$77W7++C
s   A %A*c                 F   	 | j         |         }n4# t          $ r' |                                  t          d|z            w xY w	 |                    |          \  }}}}	}
n!# t
          $ r}t          |          d}~ww xY w|s|	st          d          |
t          j        k    rt          d          |r!|	r|j
        }|                    ||	|
          }ni }|r0|dk    r*|j
        }|                     d|d          }|r||d<   nd|i}||d<   |dk    r||d	<   n||d
<   |S )aP  
        Get single data from Database by ``key``.

        :param index_name: index to get data from
        :param key: key to get
        :param with_doc: if ``True`` data from **id** index will be included in output
        :param with_storage: if ``True`` data from index storage will be included, otherwise just metadata.
        r   Nz	Not foundDeletedr   Fdocr1  r/  r  )rB   r   r   r   r0  r   r2   r   rR  r0   r?   )rE   r   r  with_docwith_storagerW   l_key_unkrU  rV  rW  r'  r?   r#  rj  s                  r"   r0  zDatabase.get  s   	5$Z0CC 	5 	5 	5()D)3*4 5 5 5	5	%/2wws||,E4ff 	% 	% 	% $$$	% 	.T 	. ---U^##	*** 	D 	kG;;udF33DD D 	$
d**kG((4..C $!Us|UDLLDKs!    1AA! !
A?+A::A?r   c	              +   R  K   |dk    r#|                                   t          d          	 | j        |         }
n4# t          $ r' |                                   t	          d|z            w xY w|
j        }|||
                    |||          }n |
j        ||||fi |	}	 	 t          |          }|r|d         r |j	        |dd          }ni }|d         }|r#| 	                    d|d	          }|r||d
<   nd
|i}||d<   ||d         |d<   |V  n# t          $ r Y dS w xY w)a0  
        Allows to get **multiple** data for given ``key`` for *Hash based indexes*.
        Also allows get **range** queries for *Tree based indexes* with ``start`` and ``end`` arguments.

        :param index_name: Index to perform the operation
        :param key: key to look for (has to be ``None`` to use range queries)
        :param limit: defines limit for query
        :param offset: defines offset (how many records from start it will ignore)
        :param with_doc: if ``True`` data from **id** index will be included in output
        :param with_storage: if ``True`` data from index storage will be included, otherwise just metadata.
        :param start: ``start`` parameter for range queries
        :param end: ``end`` parameter for range queries

        :returns: iterator over records
        r   zCan't get many from `id`r   NTr   r   r   Frj  r1  rJ   r  )r   r.   rB   r   r   r?   get_manyget_betweenr   r0  r\  )rE   r   r  limitoffsetrk  rl  rU  endr   rW   r?   genind_datar#  r%  rj  s                    r"   rp  zDatabase.get_many  s     2 ()CDDD	5$Z0CC 	5 	5 	5()D)3*4 5 5 5	5 +=S[,,sE622CC!#/%eVFFvFFC	99   HRL &7;6DDD!! ,((477C ,&)U %s|$U;"*1+DK



# !   		s   ; 1A,%D 
D%$D%c              #     K   	 | j         |         }n4# t          $ r' |                                  t          d|z            w xY w|j        }|                    ||          }	 	 t          |          \  }	}
}}}|dk    r)|r|r|                    |||          }ni }|	|d<   |
|d<   nHi }|r|r|                    |||          |d<   |
|d<   |	|d<   |r|                     d|	d          }||d	<   |V  n# t          $ r Y d
S w xY w)a  
        Alows to get all records for given index

        :param index_name: Index to perform the operation
        :param limit: defines limit for query
        :param offset: defines offset (how many records from start it will ignore)
        :param with_doc: if ``True`` data from **id** index will be included in output
        :param with_storage: if ``True`` data from index storage will be included, otherwise just metadata
        r   Tr   r1  r/  r2  r  Frj  N)	rB   r   r   r   r?   r[  r   r0  r\  )rE   r   rr  rs  rk  rl  rW   r?   ru  r%  unkrU  rV  rW  r#  rj  s                   r"   r[  zDatabase.all  s     	5$Z0CC 	5 	5 	5()D)3*4 5 5 5	5 +ggeV$$	37990UD& %%# " "&{{5$??!"(DK#&DLLD# I I(/E4(H(HW"%DK"(DK *"hhtVU;;&)U



' !   	s    1A%C6 6
DDc                    	 | j         |         }n4# t          $ r' |                                  t          d|z            w xY w	 t	          |d|z             }n# t
          $ r t          d          w xY w || g|R i |S )a  
        Allows to execute given function on Database side
        (important for server mode)

        If ``target_funct==sum`` then given index must have ``run_sum`` method.

        :param index_name: index name to perform action.
        :param target_funct: target function name (without *run* prefix)
        :param *args: ``*args`` for function
        :param **kwargs: ``**kwargs`` for function

        r   run_zInvalid function to run)rB   r   r   r   rd   AttributeErrorr   )rE   r   target_functr   r   rW   functs          r"   runzDatabase.runL  s    	5$Z0CC 	5 	5 	5()D)3*4 5 5 5	5	<C,!677EE 	< 	< 	< !:;;;	<uT+D+++F+++s    1AA A3c                 ~    d|d<   d|d<    ||i |}d}	 	 t          |           |dz  }n# t          $ r Y nw xY w'|S )a:  
        Counter. Allows to execute for example

        .. code-block:: python

            db.count(db.all, 'id')

        And it will return then how much records are in your ``id`` index.

        .. warning::
            It sets ``kwargs['with_storage'] = False`` and ``kwargs['with_doc'] = False``


        Frl  rk  r   TrJ   )r   r\  )rE   r|  r   r   iter_rl   s         r"   countzDatabase.counte  s}     "'~"zd-f--	UQ    		 s   , 
99c                     d|vsd|vrt          d          |d         }|d         }	 t          |          }t          |          }n#  t          d          xY wd|d<   |                     |||           dS )z
        Delete data from database.

        ``data`` has to contain ``_id`` and ``_rev`` fields.

        :param data: data to delete
        r/  r1  z Can't delete without _rev or _idz+`_id` and `_rev` must be valid bytes objectT_deleted)r.   rg  rE  )rE   r#  r1  r/  s       r"   r  zDatabase.delete  s     ~~Ud]]()KLLL5kF|	?**C;;DD	?(=? ? ?ZS$---ts   A Ac                 V    |                                   |                                  dS )zP
        Compact all indexes. Runs :py:meth:`._compact_indexes` behind.
        N)r   rP  rQ   s    r"   rM  zDatabase.compact  .     	r$   c                 V    |                                   |                                  dS )zP
        Reindex all indexes. Runs :py:meth:`._reindex_indexes` behind.
        N)r   r_  rQ   s    r"   r   zDatabase.reindex  r  r$   c                 j    |                                   | j        D ]}|                                 dS )z%
        Flushes all indexes
        N)r   r@   flushr  s     r"   flush_indexeszDatabase.flush_indexes  s@     	\ 	 	EKKMMMM	 	r$   c                 *    |                                  S )zM
        Flushes all indexes. Runs :py:meth:`.flush_indexes` behind.
        )r  rQ   s    r"   r  zDatabase.flush  s     !!###r$   c                     |                                   | j        D ]*}|                                 |                                 +dS )zk
        It forces the kernel buffer to be written to disk. Use when you're sure that you need to.
        N)r   r@   r  fsyncr  s     r"   r  zDatabase.fsync  sM     	\ 	 	EKKMMMKKMMMM	 	r$   c                 t    | j         sdS t          d t          j        | j                   D                       S )z3
        :returns: total size of database.
        r   c              3      K   | ]J\  }}}|D ]A}t           j                            t           j                            ||                    V  BKd S r   )rg   r>   getsizerh   )r   dirpathdirnames	filenamesfilenames        r"   r   z&Database.__get_size.<locals>.<genexpr>  sq       ' ',9%' '  GOOBGLL(;;<<' ' ' ' ' ' 'r$   )r>   sumrg   r  rQ   s    r"   
__get_sizezDatabase.__get_size  sM     y 	1 ' '02	0B0B' ' ' ' ' 	'r$   c                    |                                   	 | j        |         }n1# t          $ r$ |                                   t          d          w xY wi }|j                                        D ]\  }}t          |          s|||<   |S )zP
        Will return index properties.

        :returns: index details
        zIndex doesn't exist)r   rB   r   r   __dict__itemscallable)rE   ri   db_indexpropsr  r2  s         r"   get_index_detailszDatabase.get_index_details  s     		@)$/HH 	@ 	@ 	@()>???	@ "+1133 	# 	#JCE?? #"c
s	   $ .Ac                     i }| j         |d<   |                                 |d<   | j                                        |d<   t          |d<   |S )zm
        Get's database details, size, indexes, environment etc.

        :returns: database details
        r>   rV  r@   r   )r>   _Database__get_sizerB   keysr   )rE   r  s     r"   get_db_detailszDatabase.get_db_details  sP     	f))f-2244i#2 r$   r   )r   FN)TN)FN)r   )NT)FT)Nr   r   FTNN)r   r   FT):r(   r)   r*   __doc__r^   rF   rO   r   rX   rr   r   r   r   rV   r   r   r   r   r   r  r   r   rU   r   r
  r  r  r-  r4  r6  r"  r:  r<  r@  rC  rE  r  rN  rP  rX  r   r_  re  rc  r0  rp  r[  r~  r  r  rM  r   r  r  r  r  r  r  r+   r$   r"   r<   r<   m   s         M  ! ! ! !(@ @ @
. 
. 
. 
.  0! ! ! !F2 2 2
a a a aF# # # #J   ,7 7 7 74$ $ $ $L
 
 
   2   0< < </ / /   (      >    4*; *; *;X% % %  : : :4	 	 	8 8 8  &     	/ 	/ 	/# # #2  0& & &; ; ;$ $ $L& & &  >  .+ + + +^ "< < < <@ - - - -^, , ,2  6  ,            $ $ $  	' 	' 	'  (    r$   r<   )r   r   r   ),rg   re   r   ra   inspectr   r   randomr   codernitydb3.storager   r   codernitydb3.hash_indexr   r	   r
   r   codernitydb3.indexr   r   r   r   r   r   r   r   codernitydb3.indexcreatorr   codernitydb3.miscr   codernitydb3.envr   r   r#   r  r&   r.   r0   r2   r4   r6   r8   r:   r<   r+   r$   r"   <module>r     s,  $ 
			 				   - - - - - - - -       5 4 4 4 4 4 4 4A A A A A A A A A A A AG G G G G G G G G G G G G G G G G G G G - , , , , , " " " " " " , , , , , , * * * * * *
 "$"$$&	       F	 	 	 	 		 	 	 		 	 	 	 	. 	 	 		 	 	 	 	% 	 	 		 	 	 	 	& 	 	 		 	 	 	 	# 	 	 		 	 	 	 	( 	 	 		 	 	 	 	- 	 	 		 	 	 	 	0 	 	 	x x x x x x x x x xr$   