diff --git a/Snowflake.Data.Tests/IntegrationTests/SFPutGetTest.cs b/Snowflake.Data.Tests/IntegrationTests/SFPutGetTest.cs index 6178f16b8..536195fd9 100644 --- a/Snowflake.Data.Tests/IntegrationTests/SFPutGetTest.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFPutGetTest.cs @@ -208,7 +208,49 @@ public void TestPutFileRelativePathWithoutDirectory() VerifyFilesAreUploaded(conn, new List { t_inputFilePath }, t_internalStagePath); } } + + [Test] + public void TestPutFileProvidesQueryIdOnFailure() + { + // Arrange + // Set the PUT query variables but do not create a file + t_inputFilePath = "unexisting_file.csv"; + t_internalStagePath = $"@{t_schemaName}.{t_stageName}"; + + // Act + using (var conn = new SnowflakeDbConnection(ConnectionString)) + { + conn.Open(); + var queryId = PutFile(conn); + + // Assert + Assert.IsNotNull(queryId); + Assert.DoesNotThrow(()=>Guid.Parse(queryId)); + } + } + [Test] + public void TestPutFileProvidesQueryIdOnSuccess() + { + // Arrange + // Set the PUT query variables + t_inputFilePath = $"{Guid.NewGuid()}_1.csv"; + t_internalStagePath = $"@{t_schemaName}.{t_stageName}"; + PrepareFileData(t_inputFilePath); + + // Act + using (var conn = new SnowflakeDbConnection(ConnectionString)) + { + conn.Open(); + var queryId = PutFile(conn); + + // Assert + Assert.IsNotNull(queryId); + Assert.DoesNotThrow(()=>Guid.Parse(queryId)); + VerifyFilesAreUploaded(conn, new List { t_inputFilePath }, t_internalStagePath); + } + } + [Test] public void TestPutFileRelativePathWithDirectory() { @@ -459,11 +501,12 @@ private static bool IsCompressedByTheDriver() } // PUT - upload file from local directory to the stage - void PutFile( + string PutFile( SnowflakeDbConnection conn, String additionalAttribute = "", ResultStatus expectedStatus = ResultStatus.UPLOADED) { + String queryId; using (var command = conn.CreateCommand()) { // Prepare PUT query @@ -474,9 +517,21 @@ void PutFile( // Upload file command.CommandText = putQuery; - var reader = command.ExecuteReader(); + DbDataReader reader; + try + { + reader = command.ExecuteReader(); + } + catch (Exception) + { + queryId = ((SnowflakeDbCommand)command).GetQueryId(); + return queryId; + } + // Checking query id when reader succeeded Assert.IsTrue(reader.Read()); - + queryId = ((SnowflakeDbDataReader)reader).GetQueryId(); + // Checking if query Id is provided on the command level as well + Assert.AreEqual(queryId, ((SnowflakeDbCommand)command).GetQueryId()); // Check file status Assert.AreEqual(expectedStatus.ToString(), reader.GetString((int)SFResultSet.PutGetResponseRowTypeInfo.ResultStatus)); @@ -497,6 +552,7 @@ void PutFile( } Assert.IsNull(reader.GetString((int)SFResultSet.PutGetResponseRowTypeInfo.ErrorDetails)); } + return queryId; } // COPY INTO - Copy data from the stage into temp table diff --git a/Snowflake.Data/Client/SnowflakeDbException.cs b/Snowflake.Data/Client/SnowflakeDbException.cs index 014ad62e1..47ab44138 100755 --- a/Snowflake.Data/Client/SnowflakeDbException.cs +++ b/Snowflake.Data/Client/SnowflakeDbException.cs @@ -40,55 +40,55 @@ public override int ErrorCode public SnowflakeDbException(string sqlState, int vendorCode, string errorMessage, string queryId) : base(FormatExceptionMessage(errorMessage, vendorCode, sqlState, queryId)) { - this.SqlState = sqlState; - this.VendorCode = vendorCode; - this.QueryId = queryId; + SqlState = sqlState; + VendorCode = vendorCode; + QueryId = queryId; } public SnowflakeDbException(SFError error, params object[] args) : base(FormatExceptionMessage(error, args, string.Empty, string.Empty)) { - this.VendorCode = error.GetAttribute().errorCode; + VendorCode = error.GetAttribute().errorCode; } public SnowflakeDbException(string sqlState, SFError error, params object[] args) : base(FormatExceptionMessage(error, args, sqlState, string.Empty)) { - this.VendorCode = error.GetAttribute().errorCode; - this.SqlState = sqlState; + VendorCode = error.GetAttribute().errorCode; + SqlState = sqlState; } public SnowflakeDbException(Exception innerException, SFError error, params object[] args) : base(FormatExceptionMessage(error, args, string.Empty, string.Empty), innerException) { - this.VendorCode = error.GetAttribute().errorCode; + VendorCode = error.GetAttribute().errorCode; } public SnowflakeDbException(Exception innerException, string sqlState, SFError error, params object[] args) : base(FormatExceptionMessage(error, args, sqlState, string.Empty), innerException) { - this.VendorCode = error.GetAttribute().errorCode; - this.SqlState = sqlState; + VendorCode = error.GetAttribute().errorCode; + SqlState = sqlState; } static string FormatExceptionMessage(SFError error, object[] args, string sqlState, - string queryId) - { - return FormatExceptionMessage(string.Format(rm.GetString(error.ToString()), args) - , error.GetAttribute().errorCode - , sqlState - , queryId); - } - - static string FormatExceptionMessage(string errorMessage, - int vendorCode, - string sqlState, string queryId) - { - return string.Format("Error: {0} SqlState: {1}, VendorCode: {2}, QueryId: {3}", - errorMessage, sqlState, vendorCode, queryId); + { + return FormatExceptionMessage(string.Format(rm.GetString(error.ToString()), args) + , error.GetAttribute().errorCode + , sqlState + , queryId); + } + + static string FormatExceptionMessage(string errorMessage, + int vendorCode, + string sqlState, + string queryId) + { + return string.Format("Error: {0} SqlState: {1}, VendorCode: {2}, QueryId: {3}", + errorMessage, sqlState, vendorCode, queryId); } } } diff --git a/Snowflake.Data/Core/ErrorMessages.resx b/Snowflake.Data/Core/ErrorMessages.resx index 7159b86a0..83235cf27 100755 --- a/Snowflake.Data/Core/ErrorMessages.resx +++ b/Snowflake.Data/Core/ErrorMessages.resx @@ -183,4 +183,4 @@ Browser response timed out after {0} seconds. - \ No newline at end of file + diff --git a/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs b/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs index e5badcf19..b0cbf1e65 100644 --- a/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs +++ b/Snowflake.Data/Core/FileTransfer/SFFileTransferAgent.cs @@ -185,46 +185,55 @@ public SFFileTransferAgent( /// public void execute() { - // Initialize the encryption metadata - initEncryptionMaterial(); - - if (CommandTypes.UPLOAD == CommandType) - { - initFileMetadataForUpload(); - } - else if (CommandTypes.DOWNLOAD == CommandType) + try { - initFileMetadata(TransferMetadata.src_locations); + // Initialize the encryption metadata + initEncryptionMaterial(); - Directory.CreateDirectory(TransferMetadata.localLocation); - } + if (CommandTypes.UPLOAD == CommandType) + { + initFileMetadataForUpload(); + } + else if (CommandTypes.DOWNLOAD == CommandType) + { + initFileMetadata(TransferMetadata.src_locations); - // Update the file metadata with GCS presigned URL - updatePresignedUrl(); + Directory.CreateDirectory(TransferMetadata.localLocation); + } - foreach (SFFileMetadata fileMetadata in FilesMetas) - { - // If the file is larger than the threshold, add it to the large files list - // Otherwise add it to the small files list - if (fileMetadata.srcFileSize > TransferMetadata.threshold) + // Update the file metadata with GCS presigned URL + updatePresignedUrl(); + + foreach (SFFileMetadata fileMetadata in FilesMetas) { - LargeFilesMetas.Add(fileMetadata); + // If the file is larger than the threshold, add it to the large files list + // Otherwise add it to the small files list + if (fileMetadata.srcFileSize > TransferMetadata.threshold) + { + LargeFilesMetas.Add(fileMetadata); + } + else + { + SmallFilesMetas.Add(fileMetadata); + } } - else + + // Check command type + if (CommandTypes.UPLOAD == CommandType) { - SmallFilesMetas.Add(fileMetadata); + upload(); + } + else if (CommandTypes.DOWNLOAD == CommandType) + { + download(); } } - - // Check command type - if (CommandTypes.UPLOAD == CommandType) - { - upload(); - } - else if (CommandTypes.DOWNLOAD == CommandType) + catch (Exception e) { - download(); + Logger.Error("Error while transferring file(s): " + e.Message); + throw; } + } public async Task executeAsync(CancellationToken cancellationToken) diff --git a/Snowflake.Data/Core/SFStatement.cs b/Snowflake.Data/Core/SFStatement.cs index 3c48688ee..9f85fc5cd 100644 --- a/Snowflake.Data/Core/SFStatement.cs +++ b/Snowflake.Data/Core/SFStatement.cs @@ -356,6 +356,11 @@ internal SFBaseResultSet Execute(int timeout, string sql, Dictionary