
    s2                     |   d Z ddlmZ ddlmZ ddlmZ ddlZddlZddl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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 Z"d Z#d Z$d Z%d Z&d Z'ejP                   G d dejR                               Z*y)z!Command for spanner samples init.    )absolute_import)division)unicode_literalsN)
exceptions)database_operations)database_sessions)	databases)	instances)storage_api)storage_util)base)
ddl_parser)samples)log)
properties)	resources)progress_tracker)files)retryc                     	 t        j                  |        y# t        j                  $ r/ t	        t        j                  dj                  |                   w xY w)z*Raise if the given instance doesn't exist.z        Instance '{instance_id}' does not exist. Create it with:

        $ gcloud spanner instances create {instance_id}
        instance_idN)r
   Getapitools_exceptionsHttpNotFoundError
ValueErrortextwrapdedentformatr   s    #lib/surface/spanner/samples/init.pycheck_instancer!   ,   sT    .MM+		.	. .
  F{F+		-. ..s
    AAc                 B   t        j                         }t        j                  j	                  t
        j                        }t        j                  j                  |t        j                  |             t        j                  |       fg}|j                  |t        j                  |             }t        j                  |       }|D ]  }|j                  j                  d      d   s"t        j                  j!                  |      }t"        j$                  j'                  ||j                  j                  d      d         }|j)                  ||f        t        j*                  |       rt        j,                  |       }|j                  ||      }	|	D ]  }
t        j                  j!                  |
      }|j                  j/                  d      r>t        j0                  |       }t"        j$                  j'                  ||j                  j                  d      d         }|j)                  ||f        t3        d |D              rt4        j6                  j9                  dj;                  |              |D ]  \  }}t4        j6                  j9                  dj;                  |             t"        j$                  j                  |      d   }t"        j$                  j=                  |      st?        j@                  |       |jC                  ||d	        y
y
)zDownload schema and binaries for the given sample app.

  If the schema and all binaries exist already, skip download. If any file
  doesn't exist, download them all.

  Args:
    appname: The name of the sample app, should exist in samples.APP_NAMES
  )prefix/c              3   b   K   | ]'  \  }}t         j                  j                  |        ) y w)N)ospathexists).0_	file_paths      r    	<genexpr>z(download_sample_files.<locals>.<genexpr>d   s%     H<<1iRWW^^I&	&<s   -/z'Downloading files for the {} sample appzDownloading {}r   T)	overwriteN)"r   StorageClientr   BucketReferenceFromUrlr   
GCS_BUCKETObjectReferenceFromBucketRefget_gcs_schema_nameget_local_schema_path
ListBucketget_gcs_bin_prefixget_local_bin_pathnamesplitFromMessager'   r(   joinappendhas_sample_data_statements%get_gcs_data_insert_statements_prefixendswith%get_local_data_insert_statements_pathanyr   statusPrintr   r)   r   MakeDirCopyFileFromGCS)appnamestorage_client
bucket_refgcs_to_localgcs_bin_msgsbin_pathgcs_ref
local_pathinsert_pathgcs_insert_filesinsert_fileinsert_file_refdata_local_path	local_dirs                 r    download_sample_filesrV   9   s    ,,..++33G4F4FG*  //=='--g68009; <,  **33G< + >,''0(g<<c"2&**66w?Gh(:(:3(?(CDJ*-.  ''0??HK%00K0P'$44@@Mo 
			&	&s	+EEgNo77<<
?//55c:2>j ?J78 ( 	H<HHJJ>EEgNO+	jj'..z:;''--
+A.iWW^^I&i $$WjD$I  , I    c           	         	 t        j                  | |||      S # t        j                  $ r: t	        t        j                  dj                  || j                                    t        j                  $ r3}t	        t        j                  |j                        d   d         d}~wt        $ r t	        dj                  |            w xY w)z2Wrapper over databases.Create with error handling.)database_dialectz        Database '{database_id}' exists already. Delete it with:

        $ gcloud spanner databases delete {database_id} --instance={instance_id}
        )database_idr   errormessageNzFailed to create database '{}'.)r	   Creater   HttpConflictErrorr   r   r   r   instancesId	HttpErrorjsonloadscontent	Exception)instance_refrZ   
statementsrY   exs        r    _create_db_oprh   n   s    L)	+ +
 
	.	. M
  F#1I1I  K		LM M 
	&	& A
TZZ

+G4Y?
@@	 L
6==kJ
KKLs    AC9.B'''Cc                 X   t        j                  |       st        dj                  |             t	        j
                  |      }|j                  d      D ]R  }|s|j                  d      st        j                  d      j                  t        j                  |d|gd d	       T y
)z3Read and execute all insert statements in one file.{} cannot pre-populate data.
INSERT   )max_retrialsNORMALc                      y)NT )exc_typeargss     r    <lambda>z0insert_sample_data_in_one_file.<locals>.<lambda>   s    rW   i  )rs   should_retry_ifsleep_msN)r   r?   r   r   r   ReadFileContentsr;   
startswithr   RetryerRetryOnExceptionr   
ExecuteSql)rH   	file_namesession_refinsert_statementsinsert_statements        r    insert_sample_data_in_one_filer      s    		+	+G	4
3::7C
DD,,Y7+11$7&&x0 
MMq!22$$+64	 3  8rW   c                 R   t        j                  |       st        dj                  |             t	        j
                  dj                  |      d      5  t        j                  t        j                  |             }|D ]  }t        | ||        	 ddd       y# 1 sw Y   yxY w)zInsert sample data.rj   zPopulating data into `{}`z#Aborting wait for data population.
)aborted_messageN)
r   r?   r   r   r   ProgressTrackerr   GetDirectoryTreeListingrB   r   )rH   rZ   r}   
data_files	data_files        r    insert_sample_datar      s    		+	+G	4
3::7C
DD''!((5< ..55g>J  	$


    s   =BB&c                    t        j                  |       }t        j                  |       }t        j                  |      }|t
        j                  k(  rdg }dj                  |j                  d      D cg c]  }|j                  d      r| c}      }|j                  d      D cg c]  }|s|	 }	}nt        j                  |      }g }	t        ||||      }
t        j                  |
dj                  |             |	rut         j"                  j%                  ||j&                  |j(                  dd      }t        j*                  ||	      }t        j                  |dj                  |             y	y	c c}w c c}w )
z;Create the DB if it doesn't exist already, raise otherwise.rk   z--;zCreating database '{}'r_   
projectsId$spanner.projects.instances.databasesparams
collectionzUpdating database '{}'N)r   r6   get_database_dialectr   rw   r	   DATABASE_DIALECT_POSTGRESQLr=   r;   rx   r   PreprocessDDLWithParserrh   r   Awaitr   r   REGISTRYParser_   r   	UpdateDdl)rH   re   rZ   schema_filerY   schema
create_ddllinestmt
update_ddl	create_opdatabase_ref	update_ops                r    check_create_dbr      si   --g6+11':!!+.& >>>JYY ,,t,J,$DOOD4I,JLF $*<<#4=#44$#4J=33F;JJL+z,.)I4;;KHJ%%++'33&11
 : , ;L ##L*=Ii6==kJL  	K >s   3E9
E9(E>0E>c                   N    e Zd ZdZd ej
                  d      iZed        Zd Z	y)InitzInitialize a Cloud Spanner sample app.

  This command creates a Cloud Spanner database in the given instance for the
  sample app and loads any initial data required by the application.
  EXAMPLESaC            To initialize the 'finance' sample app using instance
          'my-instance', run:

          $ {command} finance --instance-id=my-instance

          To initialize the 'finance-graph' sample app using instance
          'my-instance', run:

          $ {command} finance-graph --instance-id=my-instance
        c                     | j                  dd       | j                  ddt        d       | j                  dt        d	
       y)zArgs is called by calliope to gather arguments for this command.

    Args:
      parser: An argparse parser that you can use to add arguments that go on
        the command line after this command. Positional arguments are allowed.
    rH   z5The sample app name, e.g. "finance", "finance-graph".)help--instance-idTz1The Cloud Spanner instance ID for the sample app.)requiredtyper   --database-idzBID of the new Cloud Spanner database to create for the sample app.)r   r   N)add_argumentstr)parsers    r    Argsz	Init.Args   s_     O   @	  B
   rW   c                    |j                   }	 t        j                  |       |j                  }t        j                  j                  |dt        j                  j                  j                  j                  id      }|j                  |j                  }nt        j                   |      }t"        j$                  j'                  dj)                  |             	 t+        |       t-        |       t"        j$                  j'                  dj)                  ||	             	 t/        |||       t        j0                  |      rt        j                  j                  ||j2                  |j4                  dd      }t7        j8                  |      }t        j                  j;                  |j<                  d      }		 t?        |||	       tA        jB                  d      t7        jD                  |	       S dj)                  ||      }
|j                  |
dj)                  |      z  }
tA        jB                  dj)                  |
            S # t        $ r}t	        j
                  d|      d}~ww xY w# t        $ r}t	        j
                  d|      d}~ww xY w# t        $ r}t	        j
                  d
|      d}~ww xY w# tF        $ r tI        d      w xY w# t7        jD                  |	       w xY w)zThis is what gets called when the user runs this command.

    Args:
      args: an argparse namespace. All the arguments that were provided to this
        command invocation.

    Returns:
      Some value that we want to have printed later.
    APPNAMENr   zspanner.projects.instancesr   zChecking instance '{}'r   z@Initializing database '{database_id}' for sample app '{appname}')rZ   rH   r   r   r   z-spanner.projects.instances.databases.sessions)relative_namer   zG            Initialization done for your Spanner database.
            zKFailed to insert data for the database. Please fallback to manually insert.z%{appname} --instance-id={instance_id})rH   r   z --database-id {}z          Initialization done. Next, start the backend gRPC service with:

          $ gcloud spanner samples backend {}
          )%rH   r   check_appnamer   calliope_exceptionsBadArgumentExceptionr   r   r   r   r   VALUEScoreproject	GetOrFailrZ   get_db_id_for_appr   rD   rE   r   r!   rV   r   r?   r_   r   r   r]   ParseRelativeNamer:   r   r   r   Deleterd   SystemError)selfrs   rH   rg   r   re   rZ   r   sessionr}   backend_argss              r    RunzInit.Run  s    llGDG$ ""K%%++*++0088BB
 0 , 1L #$$k--g6k JJ-44[ABJ[! '" JJJ	K	9;Jg|[9 ))'2''--
)55(33 < . l "((6g&&88D 9 k.7K=     	  -<CC{ D l 
			%+22;??__  f\"	$ $K  D44YCCD(  J44_bIIJ  J44_bIIJ&  

 	

 	  -se   I I4 #J ?K K 	I1I,,I14	J=JJ	J?$J::J?KK K1N)
__name__
__module____qualname____doc__r   r   detailed_helpstaticmethodr   r   rq   rW   r    r   r      s?     /(// 
# 
-  *V$rW   r   )+r   
__future__r   r   r   ra   r'   r   apitools.base.pyr   r   googlecloudsdk.api_lib.spannerr   r   r	   r
   googlecloudsdk.api_lib.storager   r   googlecloudsdk.callioper   r   "googlecloudsdk.command_lib.spannerr   r   googlecloudsdk.corer   r   r   googlecloudsdk.core.consoler   googlecloudsdk.core.utilr   r   r!   rV   rh   r   r   r   DefaultUniverseOnlyCommandr   rq   rW   r    <module>r      s    ( &  '  	  > > < 4 4 6 7 ( E 9 6 # * ) 8 * *
.2JjL,,(%LP A$4<< A$ A$rW   