| 1070 | } |
| 1071 | |
| 1072 | Status Init(const bool truncate, |
| 1073 | std::function<Status()> ensure_not_flat_namespace_directory) { |
| 1074 | if (truncate) { |
| 1075 | content_length_ = 0; |
| 1076 | pos_ = 0; |
| 1077 | // We need to create an empty file overwriting any existing file, but |
| 1078 | // fail if there is an existing directory. |
| 1079 | RETURN_NOT_OK(ensure_not_flat_namespace_directory()); |
| 1080 | // On hierarchical namespace CreateEmptyBlockBlob will fail if there is an existing |
| 1081 | // directory so we don't need to check like we do on flat namespace. |
| 1082 | RETURN_NOT_OK(CreateEmptyBlockBlob(*block_blob_client_)); |
| 1083 | } else { |
| 1084 | try { |
| 1085 | auto properties = block_blob_client_->GetProperties(); |
| 1086 | if (MetadataIndicatesIsDirectory(properties.Value.Metadata)) { |
| 1087 | return NotAFile(location_); |
| 1088 | } |
| 1089 | content_length_ = properties.Value.BlobSize; |
| 1090 | pos_ = content_length_; |
| 1091 | } catch (const Core::RequestFailedException& exception) { |
| 1092 | if (exception.StatusCode == Http::HttpStatusCode::NotFound) { |
| 1093 | // No file exists but on flat namespace its possible there is a directory |
| 1094 | // marker or an implied directory. Ensure there is no directory before starting |
| 1095 | // a new empty file. |
| 1096 | RETURN_NOT_OK(ensure_not_flat_namespace_directory()); |
| 1097 | RETURN_NOT_OK(CreateEmptyBlockBlob(*block_blob_client_)); |
| 1098 | } else { |
| 1099 | return ExceptionToStatus( |
| 1100 | exception, "GetProperties failed for '", block_blob_client_->GetUrl(), |
| 1101 | "'. Cannot initialise an ObjectAppendStream without knowing whether a " |
| 1102 | "file already exists at this path, and if it exists, its size."); |
| 1103 | } |
| 1104 | content_length_ = 0; |
| 1105 | } |
| 1106 | } |
| 1107 | |
| 1108 | upload_state_ = std::make_shared<UploadState>(); |
| 1109 | |
| 1110 | if (content_length_ > 0) { |
| 1111 | ARROW_ASSIGN_OR_RAISE(auto block_list, GetBlockList(block_blob_client_)); |
| 1112 | for (auto block : block_list.CommittedBlocks) { |
| 1113 | upload_state_->block_ids.push_back(block.Name); |
| 1114 | } |
| 1115 | } |
| 1116 | initialised_ = true; |
| 1117 | return Status::OK(); |
| 1118 | } |
| 1119 | |
| 1120 | Status Abort() override { |
| 1121 | if (closed_) { |
nothing calls this directly
no test coverage detected