Skip to content

Commit

Permalink
fixing dry run logic
Browse files Browse the repository at this point in the history
  • Loading branch information
radeusgd committed Nov 28, 2023
1 parent 8e58219 commit 89ff416
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 48 deletions.
20 changes: 16 additions & 4 deletions distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
16 changes: 7 additions & 9 deletions distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,43 +72,36 @@ public WriteHelper(ExcelFileFormat format) {
}

public <R> R writeWorkbook(File file, Function<Workbook, R> 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;
}
}
}
Expand Down

0 comments on commit 89ff416

Please sign in to comment.