
                              S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSSKJ	r	  SSK
Jr  SSKJr  SS	KJr   " S
 S5      rS rg)zBProvides split file preprocessing for adding splits to a database.    )absolute_import)division)unicode_literalsN)extra_types)apis)
exceptions)filesc                   6    \ rS rSrSrS rS rS rS rS r	Sr
g	)
SplitFileParser   a+  Parses a split file into a list of split points.

The split file is expected to be in the format of:
<ObjectType>[space]<ObjectName>[space](<Split Value>)
<ObjectType>[space]<ObjectName>[space](<Split Value>)
...
where ObjectType can be TABLE or INDEX.
Each split point must be in a new line.
Split value is expected to be a comma separated list of key parts.
  Split values should be surrounded by parenthesis like ()
  String values should be supplied in single quotes:'splitKeyPart'
  Boolean values should be one of: true/false
  INT64 and NUMERIC spanner datatype values should be supplied within
  single quotes values like string format: '123',
  '999999999999999999999999999.99'
  Other number values should be supplied without quotes: 1.287
  Timestamp values should be provided in the following format in single quote
  values: '2020-06-18T17:24:53Z'
  If the split value needs to have a comma, then that should be escaped by
  backslash.

  Examples:
  TABLE Singers ('c32ca57a-786c-2268-09d4-95182a9930be')
  INDEX Order (4.2)
  TABLE TableD  (0,'7ef9db22-d0e5-6041-8937-4bc6a7ef9db2')
  INDEX IndexXYZ ('8762203435012030000',NULL,NULL)
  INDEX IndexABC  (0, '2020-06-18T17:24:53Z') TableKey (123,'ab\,c')
  -- note that the above split value has a delimieter (comma) in it,
      hence escaped by a backslash.
c                 *   Xl         X l        [        R                  " S5      U l        [        R                  " S5      U l        [        R                  " S5      U l        [        R                  " S5      U l        [        R                  " S5      U l        g )Nz(\S+)\s+(\S+)\s+(.+)z"\((.*?)\) TABLE (\S+)\s+\((.*?)\)$z"\((.*?)\) INDEX (\S+)\s+\((.*?)\)$z\((.*?)\) TableKey \((.*?)\)$z
\((.*?)\)$)	splits_filesplit_expiration_daterecompilesplit_line_pattern&incorrect_split_with_table_key_pattern&incorrect_split_with_index_key_patternindex_full_key_patternsingle_key_pattern)selfr   r   s      ;lib/googlecloudsdk/command_lib/spanner/split_file_parser.py__init__SplitFileParser.__init__?   so    "!6 jj)@AD24**-3D/ 35**-3D/ #%**-M"ND jj7D    c                 4   [         R                  " SS5      n/ n[        R                  " U R                  5       nUR                  5       R                  5        GH   nU R                  U5      nU(       a5  US   (       a+  US   (       a!  US   (       a  US   R                  5       S;  a&  [        R                  " SSR                  U5      5      eUR                  5       nUS   R                  5       S	:X  a  US   Ul        O!US   R                  5       S
:X  a
  US   Ul        US   (       a  U R                  US   5      Ul        U R"                  (       a  U R"                  Ul        UR'                  U5        GM#     SSS5        U$ ! , (       d  f       U$ = f)*Gets the split points from the input file.spannerv1
SplitValue
ObjectName
ObjectType)TABLEINDEX--splits-fileInvalid split point string: {}. Each split point must be in the format of <ObjectType> <ObjectName> (<Split Value>) where ObjectType can be TABLE or INDEXr#   r$   N)r   GetMessagesModuler	   
FileReaderr   read
splitlinesParseSplitPointStringupperc_exceptionsInvalidArgumentExceptionformatSplitPointstableindexParseSplitValuekeysr   
expireTimeappend)r   msgssplit_points_listfilesingle_split_stringsingle_splitsplits          r   ProcessSplitFileParser.ProcessL   si   !!)T2D			$**	+t!%!7!7!9
112EF---L)//19KK55228&9L2M	    "%++-8$\2%+,'--/7:$\2%+%++L,FG%*%%!77%
  '5 ": 
,8 9 
,	+8 s   EF
Fc                     U R                   R                  U5      nU(       a3  UR                  S5      UR                  S5      UR                  S5      S.$ [        R                  " SSR                  U5      5      e)a?  Parses a string in the format "<ObjectType> <ObjectName> (<Split Value>)".

and returns a dictionary with the extracted information.

Args:
  input_string: The string to parse.

Returns:
  A dictionary with keys "ObjectType", "ObjectName", and "SplitValue",
  or None if the input string is not in the expected format.
         )r"   r!   r    r%   r&   )r   matchgroupr-   r.   r/   )r   input_stringrC   s      r   r+   %SplitFileParser.ParseSplitPointStringn   so     ##)),7EAAA  11
..4f\.B	 r   c                    [         R                  " SS5      n/ nUR                  5       nU R                  R	                  U5      (       d   U R
                  R	                  U5      (       a&  [        R                  " SSR                  U5      5      e/ nU R                  R	                  U5      nU(       aA  UR                  UR                  S5      5        UR                  UR                  S5      5        OZU R                  R	                  U5      nU(       a!  UR                  UR                  S5      5        O[        R                  " SS5      eU GH  nUR                  5       nUR                  S5      nUR                  5       nU R                  U5       H  n[        R                   " 5       n	US	:X  a  S
U	l        OsUS:X  d  US:X  d  US:X  d  US:X  a  [%        UR'                  5       5      U	l        O<UR+                  S5      S:X  a  [-        U5      U	l        OUR                  S5      U	l        UR2                  R                  U	5        M     UR                  U5        GM     U$ )zParses a string in the format "(CommaSeparatedKeyParts) TableKey (CommaSeparatedKeyParts)".

and returns a dictionary with the extracted information.

Args:
  input_string: The string to parse.

Returns:
  A split point key.
r   r   r%   zaInvalid split point string: {}. Each line must contain a single split point for a table or index.r@   rA   z2The split value must be surrounded by parenthesis.z()NULLTtruefalseTRUEFALSE')r   r'   stripr   rC   r   r-   r.   r/   r   r6   rD   r   KeyTokenizeWithCsvr   	JsonValueis_nullboollowerboolean_valuefindfloatdouble_valuestring_valuekeyParts)
r   rE   r7   keys_allall_keys_stringsrC   input_string_per_key
single_keysplit_token	key_partss
             r   r3   SplitFileParser.ParseSplitValue   s    !!)T2DH%%'L2288 		4	4	:	:<	H	H11
//5vl/C  ''--l;Eekk!n-ekk!n-%%++L9e	A/33@
 	
 !11779177=88:j--.BC+))+	& ")
 V#'&'&*;+<+<+>&?I#%+',['9i$'2'8'8'>i$""9-# D$ ooj!- !1. Or   c                     [         R                  " [        R                  " U5      SS[         R                  SS9n[        U5      $ )zTokenizes text using commas as delimiters, ignoring commas within single quotes.

Args:
  text: The text to tokenize.

Returns:
  A list of tokens.
rM   T\)	quotecharskipinitialspacequoting
escapechar)csvreaderioStringIO
QUOTE_NONEnext)r   textrj   s      r   rQ   SplitFileParser.TokenizeWithCsv   s9     ZZ
Ds~~	F <r   )r   r   r   r   r   r   r   N)__name__
__module____qualname____firstlineno____doc__r   r=   r+   r3   rQ   __static_attributes__ r   r   r   r      s"    >8 D8>@r   r   c                 ^    [        U R                  U R                  5      R                  5       $ )r   )r   r   r   r=   )argss    r   ParseSplitPointsrz      s$    	))4+E+E	F	N	N	PPr   )ru   
__future__r   r   r   ri   rk   r   apitools.base.pyr   googlecloudsdk.api_lib.utilr   googlecloudsdk.callioper   r-   googlecloudsdk.core.utilr	   r   rz   rw   r   r   <module>r      s<    I &  ' 
 	 	 ( , > *z zzQr   