1- /*
1+ /*
22 * Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved.
33 */
44
@@ -560,16 +560,36 @@ public void TestPutGetGcsDownscopedCredential(
560560 }
561561 }
562562
563+ [ Test ]
564+ public void TestPutGetFileWithSpaceAndSingleQuote (
565+ [ Values ] StageType stageType ,
566+ [ Values ( "/STAGE PATH WITH SPACE" ) ] string stagePath )
567+ {
568+ PrepareTest ( null , stageType , stagePath , false , true , true ) ;
569+ using ( var conn = new SnowflakeDbConnection ( ConnectionString ) )
570+ {
571+ conn . Open ( ) ;
572+ PutFile ( conn , "" , ResultStatus . UPLOADED , true ) ;
573+ CopyIntoTable ( conn , true ) ;
574+ GetFile ( conn , true ) ;
575+ }
576+ }
577+
563578 private void PrepareTest ( string sourceFileCompressionType , StageType stageType , string stagePath ,
564- bool autoCompress , bool clientEncryption = true )
579+ bool autoCompress , bool clientEncryption = true , bool makeFilePathWithSpace = false )
565580 {
566581 t_stageType = stageType ;
567582 t_sourceCompressionType = sourceFileCompressionType ;
568583 t_autoCompress = autoCompress ;
569584 // Prepare temp file name with specified file extension
570585 t_fileName = Guid . NewGuid ( ) + ".csv" +
571- ( t_autoCompress ? SFFileCompressionTypes . LookUpByName ( t_sourceCompressionType ) . FileExtension : "" ) ;
572- t_inputFilePath = Path . GetTempPath ( ) + t_fileName ;
586+ ( t_autoCompress ? SFFileCompressionTypes . LookUpByName ( t_sourceCompressionType ) . FileExtension : "" ) ;
587+ var sourceFolderWithSpace = $ "{ Guid . NewGuid ( ) } source file path with space";
588+ var inputPathBase = makeFilePathWithSpace ?
589+ Path . Combine ( s_outputDirectory , sourceFolderWithSpace ) :
590+ Path . GetTempPath ( ) ;
591+ t_inputFilePath = Path . Combine ( inputPathBase , t_fileName ) ;
592+
573593 if ( IsCompressedByTheDriver ( ) )
574594 {
575595 t_destCompressionType = "gzip" ;
@@ -580,7 +600,16 @@ private void PrepareTest(string sourceFileCompressionType, StageType stageType,
580600 t_destCompressionType = t_sourceCompressionType ;
581601 t_outputFileName = t_fileName ;
582602 }
583- t_outputFilePath = $@ "{ s_outputDirectory } /{ t_outputFileName } ";
603+ var destinationFolderWithSpace = $ "{ Guid . NewGuid ( ) } destination file path with space";
604+ var outputPathBase = makeFilePathWithSpace ?
605+ Path . Combine ( s_outputDirectory , destinationFolderWithSpace ) :
606+ s_outputDirectory ;
607+ t_outputFilePath = Path . Combine ( outputPathBase , t_outputFileName ) ;
608+ if ( makeFilePathWithSpace )
609+ {
610+ Directory . CreateDirectory ( inputPathBase ) ;
611+ Directory . CreateDirectory ( outputPathBase ) ;
612+ }
584613 t_filesToDelete . Add ( t_outputFilePath ) ;
585614 PrepareFileData ( t_inputFilePath ) ;
586615
@@ -610,16 +639,17 @@ private static bool IsCompressedByTheDriver()
610639 string PutFile (
611640 SnowflakeDbConnection conn ,
612641 String additionalAttribute = "" ,
613- ResultStatus expectedStatus = ResultStatus . UPLOADED )
642+ ResultStatus expectedStatus = ResultStatus . UPLOADED ,
643+ bool encloseInSingleQuotes = false )
614644 {
615645 string queryId ;
616646 using ( var command = conn . CreateCommand ( ) )
617647 {
618648 // Prepare PUT query
619- string putQuery =
620- $ "PUT file://{ t_inputFilePath } { t_internalStagePath } " +
621- $ " AUTO_COMPRESS= { ( t_autoCompress ? "TRUE" : "FALSE" ) } " +
622- $ " { additionalAttribute } ";
649+ var putQuery = encloseInSingleQuotes ?
650+ $ "PUT ' file://{ t_inputFilePath . Replace ( " \\ " , "/" ) } ' ' { t_internalStagePath } '" :
651+ $ "PUT file:// { t_inputFilePath } { t_internalStagePath } " ;
652+ putQuery += $ " AUTO_COMPRESS= { ( t_autoCompress ? "TRUE" : "FALSE" ) } " + $ " { additionalAttribute } ";
623653 // Upload file
624654 command . CommandText = putQuery ;
625655 var reader = command . ExecuteReader ( ) ;
@@ -661,7 +691,7 @@ string PutFile(
661691 }
662692
663693 // COPY INTO - Copy data from the stage into temp table
664- private void CopyIntoTable ( SnowflakeDbConnection conn )
694+ private void CopyIntoTable ( SnowflakeDbConnection conn , bool encloseInSingleQuotes = false )
665695 {
666696 using ( var command = conn . CreateCommand ( ) )
667697 {
@@ -671,7 +701,8 @@ private void CopyIntoTable(SnowflakeDbConnection conn)
671701 command . CommandText = $ "COPY INTO { t_schemaName } .{ t_tableName } ";
672702 break ;
673703 default :
674- command . CommandText =
704+ command . CommandText = encloseInSingleQuotes ?
705+ $ "COPY INTO { t_schemaName } .{ t_tableName } FROM '{ t_internalStagePath } /{ t_fileName } '" :
675706 $ "COPY INTO { t_schemaName } .{ t_tableName } FROM { t_internalStagePath } /{ t_fileName } ";
676707 break ;
677708 }
@@ -696,12 +727,14 @@ private void CopyIntoTable(SnowflakeDbConnection conn)
696727 }
697728
698729 // GET - Download from the stage into local directory
699- private void GetFile ( DbConnection conn )
730+ private void GetFile ( DbConnection conn , bool encloseInSingleQuotes = false )
700731 {
701732 using ( var command = conn . CreateCommand ( ) )
702733 {
703734 // Prepare GET query
704- var getQuery = $ "GET { t_internalStagePath } /{ t_fileName } file://{ s_outputDirectory } ";
735+ var getQuery = encloseInSingleQuotes ?
736+ $ "GET '{ t_internalStagePath } /{ t_fileName } ' 'file://{ Path . GetDirectoryName ( t_outputFilePath ) . Replace ( "\\ " , "/" ) } '" :
737+ $ "GET { t_internalStagePath } /{ t_fileName } file://{ s_outputDirectory } ";
705738
706739 // Download file
707740 command . CommandText = getQuery ;
0 commit comments