
    >                     x   d Z ddlmZ ddlmZ ddlmZ ddlZddlmZmZm	Z	 ddl
mZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dej8                  j:                  fdZ ej>                         j@                  jB                  jD                  Z" ej>                         j@                  jB                  jF                  Z# ej>                         jH                  jJ                  jL                  Z' ej>                         jH                  jJ                  jP                  Z( ej>                         jH                  jR                  jT                  Z* ej>                         jV                  jX                  jZ                  Z. ej>                         jV                  j^                  j`                  Z0 ej>                         jV                  j^                  jb                  Z1 ej>                         jd                  jf                  jD                  Z4 ej>                         jd                  jf                  jF                  Z5dejH                  de	e6ejn                  f   fdZ8d Z9de6de	e6e6f   fdZ:dejV                  de	e6ejn                  f   fdZ;dejH                  jJ                  de6de6deejx                     dejH                  f
dZ=	 d4de6de>deejx                     de>dejV                  f
d Z?de>de6dee	e6e6f      dejn                  fd!Z@d"eejn                     deejn                     fd#ZAd$ejn                  dejn                  fd%ZBd"eejn                     deejn                     fd&ZCd$ejn                  dejn                  fd'ZDde6deejn                     fd(ZEde6d)e6deejn                     fd*ZFde6d+eejn                     ddfd,ZGde6d)e6d+eejn                     de>ddf
d-ZHde6d.ee6   ddfd/ZIde6d)e6d.ee6   ddfd0ZJde6d1ej                  ddfd2ZLde6d)e6d1ej                  de>ddf
d3ZMy)5z8Utilities for Cloud Datastore index management commands.    )absolute_import)division)unicode_literalsN)SequenceSetTuple)util)	api_utils)indexes)datastore_index)
exceptions)progress_tracker)datastore_v1_client)datastore_v1_messages)firestore_v1_messagesreturnc                  >    t        j                         j                  S )zReturns the service for interacting with the Datastore Admin Service.

  This is used to manage the datastore indexes (create/delete).
  )r	   	GetClientprojects_indexes     1lib/googlecloudsdk/api_lib/datastore/index_api.pyGetIndexesServicer   #   s     
		*	**r   protoc                    g }| j                   D ]^  }t        j                  t        |j                              }|j
                  t        k(  rd|_        nd|_        |j                  |       ` t        j                  t        | j                        |      }| j                  t        urd|_
        | j                  |fS )zHConverts a GoogleDatastoreAdminV1Index to an index definition structure.namedescasckind
propertiesT)r"   r   Propertystrr   	direction
DESCENDINGappendIndexr!   ancestorNO_ANCESTORindexId)r   r"   
prop_protoprop_definitionindexs        r   ApiMessageToIndexDefinitionr/   V   s     *$$j%..C
4HIOz)"(o"'oo& % 

S_
L%
^^;&EN		r   c                 >    t        j                  d| z   dz   |d      S )z"Emulate python-3.4 re.fullmatch().z(?:z)\Zr   )flags)rematchregexstrings     r   
_Fullmatchr7   h   s    	%%-&(&	::r   resource_pathc                     d}t        ||       }|st        dj                  |             |j                  d      |j                  d      fS )a  Extracts collectionId and indexId from a collectionGroup resource path.

  Args:
    resource_path: A str to represent firestore resource path contains
      collection group. ex: projects/p/databases/d/collectionGroups/c/indexes/i.

  Returns:
    collection_id: A str to represent the collection id in the resource path.
    index_id: A str to represent the index id in the resource path.

  Raises:
    ValueError: If the resource path is invalid.
  zM^projects/([^/]*)/databases/([^/]*)/collectionGroups/([^/]*)/indexes/([^/]*)$r4   zInvalid resource path: {}      )r7   
ValueErrorformatgroup)r8   index_name_patternr3   s      r   &CollectionIdAndIndexIdFromResourcePathr@   m   sM      g
-m
D%	
077F
GG	QQ	''r   c                    g }| j                   D ]  }t        j                  t        |j                              }|j
                  Ct        j                  |j
                  j                  t        j                               |_        n"|j                  t        k(  rd|_        nd|_        |j                  |        t        | j                        \  }}t        j                  t        |      |      }| j                   t"        k7  r$t%        dj'                  | j                               | j(                  t*        k(  rd|_        ||fS | j(                  t.        k(  rd|_        ||fS t%        d	j'                  | j(                              )
a  Converts a GoogleFirestoreAdminV1Index to an index definition structure.

  Args:
    proto: GoogleFirestoreAdminV1Index

  Returns:
    index_id: A str to represent the index id in the resource path.
    index: A datastore_index.Index that contains index definition.

  Raises:
    ValueError: If GoogleFirestoreAdminV1Index cannot be converted to index
    definition structure.
  r   )	dimensionflatr   r   r    zInvalid api scope: {}TFzInvalid query scope: {})fieldsr   r#   r$   	fieldPathvectorConfigVectorConfigrB   VectorFlatIndexorderFIRESTORE_DESCENDINGr%   r'   r@   r   r(   apiScopeDATASTORE_API_SCOPEr<   r=   
queryScopeCOLLECTION_RECURSIVEr)   COLLECTION_GROUP)r   r"   field_protor-   collection_idindex_idr.   s          r   $FirestoreApiMessageToIndexDefinitionrS      sU     *\\k%..C8M8M4NOO+%4%A%A,,66..0&o" 
		2	2"(o"'oo& " C5::N-


S%7J
O%
^^**
,33ENNC
DD
--EN 
5 ++EN 
5 .55e6F6FG
HHr   r)   r!   
project_idr"   c                    t        j                         }|j                         }||_        ||_        | |_        t        |_        g }|D ]q  }|j                         }|j                  |_	        |j                  t        d      |j                  dk(  rt        |_        nt        |_        |j                  |       s ||_        |S )z1Builds and returns a GoogleDatastoreAdminV1Index.z<Vector Indexes cannot be created via the Datastore Admin APIr   )r	   GetMessagesGoogleDatastoreAdminV1Index	projectIdr!   r)   CREATINGstate%GoogleDatastoreAdminV1IndexedPropertyr   rF   r<   r%   	ASCENDINGr&   r'   r"   )	r)   r!   rT   r"   messagesr   propspropr,   s	            r   BuildIndexProtor`      s     (

.
.
0%%/%*%.%+
%d??AJiiJO$
H  ~~&j'j	LL  %	,r   r   is_ancestorenable_vectorc                 d   t        j                         }|j                         }| |_        |rt        nt
        |_        t        |_        g }|D ]  }|j                         }|j                  |_
        |j                  r|st        j                  dd      |j                         |_        |j                  j                  |j                  _        |j!                         |j                  _        n&|j$                  dk(  rt&        |_        nt*        |_        |j-                  |        ||_        |S )z1Builds and returns a GoogleFirestoreAdminV1Index.z
index.yamlz>Vector Indexes are currently only supported in the Alpha Trackr   )firestore_utilsrV   GoogleFirestoreAdminV1Indexr   rN   rO   rM   rL   rK    GoogleFirestoreAdminV1IndexFieldrE   rF   r   InvalidArgumentException"GoogleFirestoreAdminV1VectorConfigrB   GoogleFirestoreAdminV1FlatIndexrC   r%   FIRESTORE_ASCENDINGrI   rJ   r'   rD   )	r   ra   r"   rb   r]   r   rD   r_   rP   s	            r   BuildIndexFirestoreProtork      s    ((*(

.
.
0%%*-8)>N%&%.&d;;=K IIK$11L
 	
 "*!L!L!Nk+/+<+<+F+Fk(&.&N&N&Pk#	5	 -k.k
MM+! " %,	,r   c                     t        j                  t        |      |D cg c](  }t        j                  t        |d         |d         * c}      }| |_        |S c c}w )z;Builds and returns a datastore_index.Index YAML rep object.r      )r   r%   r    )r   r(   r$   r#   r)   )ra   r!   r"   r_   r.   s        r   
BuildIndexrn      sd     

t9 ! d 
"
"DGQ
H % %.	,s   -A
r   c                 P    | xs g } | xs g D ]  }t        |        t        |       S )HRemoves the last index property if it is __key__:asc which is redundant.)NormalizeIndexForDatastoreApisetr   r.   s     r   NormalizeIndexesForDatastoreApirt     /     Mr'}"}e!%( 	Wr   r.   c                     | j                   rQ| j                   d   j                  dv r6| j                   d   j                  dk(  r| j                   j                          | S )rp   __key____name__r   r"   r   r%   pop)r.   s    r   rq   rq     sY    
  

2

#
#'>
>


2

(
(E
1		,r   c                 P    | xs g } | xs g D ]  }t        |        t        |       S )IRemoves the last index property if it is __name__:asc which is redundant.)NormalizeIndexForFirestoreApirr   rs   s     r   NormalizeIndexesForFirestoreApir     ru   r   c                    | j                   D ]  }|j                  dk(  sd|_         | j                   rQ| j                   d   j                  dv r6| j                   d   j                  dk(  r| j                   j                          | S )r~   ry   rz   rw   rx   r   r{   )r.   r_   s     r   r   r   '  s~     dyyIdi   

2

#
#'>
>


2

(
(E
1		,r   c                     t               j                  t        j                         j	                  |             }|j
                  D ch c]  }t        |       c}S c c}w )zFLists all datastore indexes under a database with Datastore Admin API.)rX   )r   Listr	   rV   #DatastoreProjectsIndexesListRequestr   r/   )rT   responser.   s      r   ListIndexesr   >  s]     %%
<< = (
 ;C:J:J	K:J
%e
,:J	KK	Ks   
Adatabase_idc                     t        j                  | |      }|j                  D ch c]   }|j                  t        k(  rt        |      " c}S c c}w )a  Lists all datastore indexes under a database with Firestore Admin API.

  Args:
    project_id: A str to represent the project id.
    database_id: A str to represent the database id.

  Returns:
    List[index]: A list of datastore_index.Index that contains index definition.
  )firestore_indexesr   r   rK   rL   rS   )rT   r   r   r.   s       r   #ListDatastoreIndexesViaFirestoreApir   H  sU     **:{C( ##
#%	.	. +51#
  
s   %Aindexes_to_createc           
         d}dt        j                  ddfd      5 }|D ]  }t               j                  t	        |j
                  rt        nt        |j                  | |j                               |dz   }d	j                  |t        |      z        |j                           	 ddd       y# 1 sw Y   yxY w)
z>Sends the index creation requests via the Datastore Admin API.r   N.Fc                       S Nr   detail_messages   r   <lambda>z.CreateIndexesViaDatastoreApi.<locals>.<lambda>e      >r   autotickdetail_message_callback)r!   rT   r"   rm   {0:.0%})r   ProgressTrackerr   Creater`   r)   ALL_ANCESTORSr*   r!   r"   r=   lenTick)rT   r   cntptr.   r   s        @r   CreateIndexesViaDatastoreApir   ]  s    
 	
#.''	E3I	"  
$~~m;::#))	 !Gc ''c2C.D(DEnggi #  s   B
B55B>c                 r   dt        j                  ddfd      5 }t        |      D ]u  \  }}t        j                  | ||j
                  t        d|j                  |j                  |             dj                  |t        |      z        |j                          w 	 ddd       y# 1 sw Y   yxY w)z>Sends the index creation requests via the Firestore Admin API.Nr   Fc                       S r   r   r   s   r   r   z.CreateIndexesViaFirestoreApi.<locals>.<lambda>~  r   r   r   )r   ra   r"   rb   r   )r   r   	enumerater   CreateIndexr!   rk   r)   r"   r=   r   r   )rT   r   r   rb   r   ir.   r   s          @r   CreateIndexesViaFirestoreApir   u  s     .''	E3I	/05##


**
"..)))		
 !''C0A,B(BCnggi 1  s   BB--B6indexes_to_delete_idsc                 Z   d}dt        j                  ddfd      5 }|D ]p  }t               j                  t	        j
                         j                  | |             |dz   }d	j                  |t        |      z        |j                          r 	 ddd       y# 1 sw Y   yxY w)
z>Sends the index deletion requests via the Datastore Admin API.r   Nr   Fc                       S r   r   r   s   r   r   zDeleteIndexes.<locals>.<lambda>      nr   r   )rX   r+   rm   r   )
r   r   r   Deleter	   rV   %DatastoreProjectsIndexesDeleteRequestr=   r   r   )rT   r   r   r   rR   r   s        @r   DeleteIndexesr     s    
 	
#.''	4 
)  




B
B"H C 
 !Gc ''c2G.H(HInggi *  s   A6B!!B*c                    d}dt        |      }t        j                  ddfd      5 }|D ]B  }t        j                  | ||       |dz   }dj                  ||z        |j                          D 	 ddd       y# 1 sw Y   yxY w)	z>Sends the index deletion requests via the Firestore Admin API.r   Nr   Fc                       S r   r   r   s   r   r   z.DeleteIndexesViaFirestoreApi.<locals>.<lambda>  r   r   r   rm   r   )r   r   r   r   DeleteIndexr=   r   )rT   r   r   r   
delete_cntr   rR   r   s          @r   DeleteIndexesViaFirestoreApir     s     	
#.()*''	4 
)##JXF!Gc ''j(89nggi	 *  s   AA>>Bindex_definitionsc                     t        |       }t        |j                        }||D ch c]  \  }}|	 c}}z
  }t        | |       yc c}}w )z>Creates the indexes if the index configuration is not present.N)r   rt   r   r   )rT   r   r   normalized_indexes_r.   new_indexess          r   #CreateMissingIndexesViaDatastoreApir     sQ    
 
#'6 #G%DG5eG%DD+z;7 &Es   Ac                     t        | |      }t        |D cg c]  \  }}|	 c}}      }t        |j                        }||z
  }	t        | ||	|       yc c}}w )zPCreates the indexes via Firestore API if the index configuration is not present.)rT   r   r   rb   N)r   r   r   r   )
rT   r   r   rb   existing_indexesr   r.   existing_indexes_normalizedr   r   s
             r   #CreateMissingIndexesViaFirestoreApir     sv     9+
 !@-.-Eu-.! 7 #%@@+#!	 /s   A
)T)N__doc__
__future__r   r   r   r2   typingr   r   r    googlecloudsdk.api_lib.datastorer	    googlecloudsdk.api_lib.firestorer
   rd   r   r   "googlecloudsdk.appengine.datastorer   googlecloudsdk.callioper   googlecloudsdk.core.consoler   2googlecloudsdk.generated_clients.apis.datastore.v1r   r   2googlecloudsdk.generated_clients.apis.firestore.v1r   DatastoreV1ProjectsIndexesServicer   rV   r[   DirectionValueValuesEnumr\   r&   rW   AncestorValueValuesEnumNONEr*   r   StateValueValuesEnumrY   re   ApiScopeValueValuesEnumDATASTORE_MODE_APIrL   QueryScopeValueValuesEnumrO   rN   rf   OrderValueValuesEnumrj   rJ   r$   r(   r/   r7   r@   rS   r#   r`   boolrk   rn   rt   rq   r   r   r   r   r   r   r   r   IndexDefinitionsr   r   r   r   r   <module>r      s   ? &  ' 	 ' ' 1 I I > . 8 R T T+##::+ D<<UU__ 

 D<<UU`` 
 D22JJOO 
 D22JJXX 
 D22GGPP 	
  O!==UUhh 
  O!==WWhh 
  O!==WWll 
  O!BBWWaa 
  O!BBWWbb 
 <<
3%%%&$;
((
38_(0* <<*
3%%%&*Z#??WW
  112	
 66D 	 
   112  	 
 66 F
 sCx) 	"o++,		  o++,		  .LC LH_-B-B$C L o##$* 5 56 
0   5 56 	
 
6#C= 
. $C= 
	*
8
8&77
8 

8 '77 	
 
r   