diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso index 4e979155a1650..355b5b6b1bb72 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso @@ -90,17 +90,29 @@ type File ## PRIVATE Create a dry run temporary file which will be deleted when Enso exits. - For an absolute path the same temporary file is returned. + The same temporary file is returned for paths that point to the same + location (not accounting for symlinks). + If this file is a temporary file that was generated by `create_dry_run_file` on another file, it is returned as-is. + + Arguments: + - copy_original: If `True`, the created dry run file is 'synchronized' + with the original file - the file is copied to the temporary file, or + if the original file does not exit - it is ensured tha the temporary + file also does not exist. If `False`, no actions are taken. create_dry_run_file : Boolean -> File ! File_Error create_dry_run_file self copy_original=False = + # TODO add normalize here too! temp_path = DryRunFileManager.getTemporaryFile self.absolute.path if temp_path.is_nothing then Error.throw (File_Error.IO_Error "Unable to create a temporary file.") else temp = File.new temp_path - if self.exists && copy_original then - Context.Output.with_enabled <| - self.copy_to temp replace_existing=True + if copy_original then Context.Output.with_enabled <| Panic.rethrow <| + case self.exists of + True -> + self.copy_to temp replace_existing=True + False -> + temp.delete_if_exists ## Attach a warning to the file that it is a dry run warning = Dry_Run_Operation.Warning "Only a dry run has occurred, with data written to a temporary file." diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso index 5afaaa0588c13..fb51bab926d27 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso @@ -5,6 +5,7 @@ import Standard.Base.Data.Index_Sub_Range as Index_Sub_Range_Module import Standard.Base.Data.Time.Errors.Date_Time_Format_Parse_Error import Standard.Base.Errors.Common.Incomparable_Values import Standard.Base.Errors.Common.Index_Out_Of_Bounds +import Standard.Base.Errors.Common.No_Such_Method import Standard.Base.Errors.Common.Out_Of_Memory import Standard.Base.Errors.Common.Type_Error import Standard.Base.Errors.File_Error.File_Error @@ -2488,16 +2489,13 @@ type Table if base_format == Nothing then Error.throw (File_Error.Unsupported_Output_Type file Table) else self.write file format=base_format on_existing_file match_columns on_problems _ -> - methods = if format == JSON_Format then ["write_table"] else Meta.meta (Meta.type_of format) . methods - if methods.contains "write_table" . not then Error.throw (File_Error.Unsupported_Output_Type format Table) else - effective_existing_behaviour = on_existing_file.get_effective_behavior file - tgt_file = if Context.Output.is_enabled then file else - should_copy_file = on_existing_file==Existing_File_Behavior.Append - file.create_dry_run_file copy_original=should_copy_file - + handle_no_write_method caught_panic = + is_write = caught_panic.payload.method_name == "write_table" + if is_write.not then Panic.throw caught_panic else + Error.throw (File_Error.Unsupported_Output_Type format Table) + Panic.catch No_Such_Method handler=handle_no_write_method <| to_write = if Context.Output.is_enabled then self else self.take 1000 - Context.Output.with_enabled <| - format.write_table tgt_file to_write effective_existing_behaviour match_columns on_problems + format.write_table file to_write on_existing_file match_columns on_problems ## Creates a text representation of the table using the CSV format. to_csv : Text diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Format.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Format.enso index 69967c5219448..2fe8886af04cb 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Format.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Format.enso @@ -124,10 +124,9 @@ type Excel_Format write_table self file table on_existing_file match_columns on_problems = format = should_treat_as_xls_format self.xls_format file - r = case self.section of + case self.section of Excel_Section.Sheet_Names -> Error.throw (Illegal_Argument.Error "Sheet_Names cannot be used for `write`.") Excel_Section.Range_Names -> Error.throw (Illegal_Argument.Error "Range_Names cannot be used for `write`.") Excel_Section.Workbook -> Excel_Writer.write_file file table on_existing_file (Excel_Section.Worksheet self.default_sheet) True match_columns on_problems format _ -> Excel_Writer.write_file file table on_existing_file self.section self.headers match_columns on_problems format - r.if_not_error file diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Excel_Writer.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Excel_Writer.enso index e3df92ddd5d52..6d002f96b0d5b 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Excel_Writer.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Excel_Writer.enso @@ -67,16 +67,17 @@ write_file (file : File) (table : Table) (on_existing_file : Existing_File_Behav preexisting_dry_run_file = DryRunFileManager.preExistingTemporaryFile file.absolute.normalize.path preexisting_dry_run_file.if_not_nothing <| Java_File.new preexisting_dry_run_file - accompanying_files = [possible_backup_file, possible_dry_run_file].filter (!= Nothing) + accompanying_files = [possible_backup_file, possible_dry_run_file].filter (!= Nothing) . filter (!= java_file) ExcelConnectionPool.INSTANCE.lockForWriting java_file file_format accompanying_files write_helper-> Context.Output.with_enabled <| + # TODO this should work with False, why? temp_file = if is_dry_run then file.create_dry_run_file copy_original=False else find_temp_file file ## We 'sync' the temp_file to reflect the original target file - if it exists we copy the contents, if the source doesn't exist we also ensure that the temp file is not polluted with data from previous (dry-run) writes. Panic.rethrow <| - if file.exists then (file.copy_to temp_file) else (temp_file.delete_if_exists) + if file.exists then (file.copy_to temp_file replace_existing=True) else (temp_file.delete_if_exists) write_helper.writeWorkbook (file_as_java temp_file) modification_strategy result_file = if is_dry_run then temp_file else needs_backup = on_existing_file == Existing_File_Behavior.Backup @@ -88,7 +89,6 @@ write_file (file : File) (table : Table) (on_existing_file : Existing_File_Behav Panic.rethrow <| temp_file.move_to file replace_existing=True file - result_file ## PRIVATE diff --git a/std-bits/table/src/main/java/org/enso/table/excel/ExcelConnectionPool.java b/std-bits/table/src/main/java/org/enso/table/excel/ExcelConnectionPool.java index 2b4d66434b51a..41b32c2da2a59 100644 --- a/std-bits/table/src/main/java/org/enso/table/excel/ExcelConnectionPool.java +++ b/std-bits/table/src/main/java/org/enso/table/excel/ExcelConnectionPool.java @@ -72,43 +72,36 @@ public WriteHelper(ExcelFileFormat format) { } public R writeWorkbook(File file, Function writeAction) throws IOException { -// File tempFile = File.createTempFile("enso-tmp-workbook-", ".tmp"); boolean preExistingFile = file.exists() && Files.size(file.toPath()) > 0; -// if (appendingToExisting) { -// Files.copy(file.toPath(), tempFile.toPath()); -// } - try { - try (Workbook tempWorkbook = preExistingFile ? ExcelConnectionPool.openWorkbook(file, format, true) : - createEmptyWorkbook(format)) { - R result = writeAction.apply(tempWorkbook); - if (preExistingFile) { - // Save the file in place. - switch (tempWorkbook) { - case HSSFWorkbook wb -> { - wb.write(); - } - case XSSFWorkbook wb -> { - try { - wb.write(null); - } catch (OpenXML4JRuntimeException e) { - // Ignore: Workaround for bug https://bz.apache.org/bugzilla/show_bug.cgi?id=59252 - } - } - default -> throw new IllegalStateException("Unknown workbook type: " + tempWorkbook.getClass()); + try (Workbook workbook = preExistingFile ? ExcelConnectionPool.openWorkbook(file, format, true) : + createEmptyWorkbook(format)) { + R result = writeAction.apply(workbook); + + if (preExistingFile) { + // Save the file in place. + switch (workbook) { + case HSSFWorkbook wb -> { + wb.write(); } - } else { - try (OutputStream fileOut = Files.newOutputStream(file.toPath())) { - try (BufferedOutputStream workbookOut = new BufferedOutputStream(fileOut)) { - tempWorkbook.write(workbookOut); + case XSSFWorkbook wb -> { + try { + wb.write(null); + } catch (OpenXML4JRuntimeException e) { + // Ignore: Workaround for bug https://bz.apache.org/bugzilla/show_bug.cgi?id=59252 } } + default -> throw new IllegalStateException("Unknown workbook type: " + workbook.getClass()); + } + } else { + try (OutputStream fileOut = Files.newOutputStream(file.toPath())) { + try (BufferedOutputStream workbookOut = new BufferedOutputStream(fileOut)) { + workbook.write(workbookOut); + } } - - return result; } - } finally { -// tempFile.delete(); + + return result; } } }