From 5c8b3b31cb3caef73bc16f3fa61ddd183551e56b Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Mon, 22 May 2023 11:34:57 +0100 Subject: [PATCH 01/25] Restructure `Text.write` and reuse components to control `Table.write`. --- .../Base/0.0.0-dev/src/System/File.enso | 6 +++- .../System/File/Existing_File_Behavior.enso | 12 ++++++++ .../src/System/File/Write_Extensions.enso | 29 +++++-------------- .../Table/0.0.0-dev/src/Data/Table.enso | 11 +++++-- 4 files changed, 34 insertions(+), 24 deletions(-) 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 31372b8f74ba..8855ad50bc78 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 @@ -11,6 +11,7 @@ import project.Data.Text.Text import project.Data.Time.Time_Of_Day.Time_Of_Day import project.Data.Vector.Vector import project.Error.Error +import project.Errors.Common.Dry_Run_Operation import project.Errors.Common.Forbidden_Operation import project.Errors.Encoding_Error.Encoding_Error import project.Errors.File_Error.File_Error @@ -88,7 +89,10 @@ type File if self.exists && copy_original then Context.Output.with_enabled <| self.copy_to temp replace_existing=True - temp + + ## 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." + Warning.attach warning temp ## ALIAS Current Directory diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Existing_File_Behavior.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Existing_File_Behavior.enso index 5d9386786209..7331aa1b2c3c 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Existing_File_Behavior.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Existing_File_Behavior.enso @@ -4,6 +4,7 @@ import project.Errors.File_Error.File_Error import project.Nothing.Nothing import project.Panic.Panic import project.Panic.Caught_Panic +import project.Runtime.Context import project.System.File.File import project.System.File.File_Access.File_Access import project.System.File.Output_Stream @@ -33,6 +34,17 @@ type Existing_File_Behavior raised. Error + ## PRIVATE + Adjust the Existing_File_Behavior to take account of Context enablement. + get_effective_behavior : File -> Boolean -> Existing_File_Behavior ! File_Error + get_effective_behavior self file is_enabled=Context.Output.is_enabled = + if is_enabled then self else + case self of + Existing_File_Behavior.Backup -> Existing_File_Behavior.Overwrite + Existing_File_Behavior.Error -> + if file.exists then Error.throw (File_Error.Already_Exists file) else Existing_File_Behavior.Overwrite + _ -> self + ## PRIVATE Runs the `action` which is given a file output stream and should write the required contents to it. diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso index f44213fd67a1..919ce95f66ee 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso @@ -3,7 +3,6 @@ import project.Data.Text.Encoding.Encoding import project.Data.Text.Extensions import project.Data.Vector.Vector import project.Error.Error -import project.Errors.Common.Dry_Run_Operation import project.Errors.Common.Unsupported_Argument_Types import project.Errors.Encoding_Error.Encoding_Error import project.Errors.File_Error.File_Error @@ -53,27 +52,15 @@ polyglot java import org.enso.base.Array_Builder Text.write : (File|Text) -> Encoding -> Existing_File_Behavior -> Problem_Behavior -> File ! Encoding_Error | Illegal_Argument | File_Error Text.write self path encoding=Encoding.utf_8 on_existing_file=Existing_File_Behavior.Backup on_problems=Problem_Behavior.Report_Warning = bytes = self.bytes encoding on_problems - - actual = File.new path - - is_enabled = Context.Output.is_enabled - - effective_existing_behaviour = if is_enabled then on_existing_file else - case on_existing_file of - Existing_File_Behavior.Backup -> Existing_File_Behavior.Overwrite - Existing_File_Behavior.Error -> if actual.exists then Error.throw (File_Error.Already_Exists actual) else Existing_File_Behavior.Overwrite - _ -> on_existing_file - - file = if is_enabled then actual else actual.create_dry_run_file copy_original=on_existing_file==Existing_File_Behavior.Append - - Context.Output.with_enabled <| - r = effective_existing_behaviour.write file stream-> - bytes.if_not_error <| + bytes.if_not_error <| + actual = File.new path + effective_existing_behaviour = on_existing_file.get_effective_behavior actual + file = if Context.Output.is_enabled then actual else + actual.create_dry_run_file copy_original=on_existing_file==Existing_File_Behavior.Append + + Context.Output.with_enabled <| + effective_existing_behaviour.write file stream-> stream.write_bytes bytes - r.if_not_error <| - if is_enabled then file else - warning = Dry_Run_Operation.Warning "Only a dry run has occurred, with data written to a temporary file." - Warning.attach warning file ## Writes (or appends) the Vector of bytes into the specified file. The behavior specified in the `existing_file` parameter will be used if the file exists. 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 09fb7261f956..c5eb5c30ecf5 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 @@ -7,6 +7,7 @@ import Standard.Base.Errors.Common.Type_Error import Standard.Base.Errors.File_Error.File_Error import Standard.Base.Errors.Illegal_Argument.Illegal_Argument import Standard.Base.Errors.Unimplemented.Unimplemented +import Standard.Base.Runtime.Context from Standard.Base.Widget_Helpers import make_delimiter_selector @@ -1953,8 +1954,14 @@ type Table 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" then format.write_table file self on_existing_file match_columns on_problems else - Error.throw (File_Error.Unsupported_Output_Type format Table) + 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 + actual.create_dry_run_file copy_original=on_existing_file==Existing_File_Behavior.Append + + to_write = if Context.Output.is_enabled then self else self.take 1000 + Context.Output.with_enabled <| + format.write_table tgt_file to_write on_existing_file match_columns on_problems ## Creates a text representation of the table using the CSV format. to_csv : Text From f351e91b22405504189d157395513b6465fe7af7 Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Tue, 23 May 2023 17:08:15 +0100 Subject: [PATCH 02/25] Add dropdown for `aggregate`. Remove dead argument from `select_columns`, `remove_columns` and `reorder_columns`. Add ALIAS to `remove_columns`. --- .../Database/0.0.0-dev/src/Data/Table.enso | 12 +++++++----- .../Standard/Table/0.0.0-dev/src/Data/Table.enso | 16 +++++++++------- .../0.0.0-dev/src/Internal/Widget_Helpers.enso | 7 +++++++ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso index 0186a5199728..7ac012cdbd60 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso @@ -190,13 +190,14 @@ type Table table.select_columns [-1, 0, 1] reorder=True Icon: select_column - @columns (Widget_Helpers.make_column_name_vector_selector include_blanks=True) + @columns Widget_Helpers.make_column_name_vector_selector select_columns : Vector (Integer | Text | Column_Selector) | Text | Integer -> Boolean -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range select_columns self (columns = [self.columns.first.name]) (reorder = False) (error_on_missing_columns = True) (on_problems = Report_Warning) = new_columns = self.columns_helper.select_columns selectors=columns reorder=reorder error_on_missing_columns=error_on_missing_columns on_problems=on_problems self.updated_columns new_columns - ## Returns a new table with the chosen set of columns, as specified by the + ## ALIAS drop_columns + Returns a new table with the chosen set of columns, as specified by the `columns`, removed from the input table. Any unmatched input columns will be kept in the output. Columns are returned in the same order as in the input. @@ -243,7 +244,7 @@ type Table Remove the first two columns and the last column. table.remove_columns [-1, 0, 1] - @columns (Widget_Helpers.make_column_name_vector_selector include_blanks=True) + @columns Widget_Helpers.make_column_name_vector_selector remove_columns : Vector (Integer | Text | Column_Selector) | Text | Integer -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range remove_columns self (columns = [self.columns.first.name]) (error_on_missing_columns = False) (on_problems = Report_Warning) = new_columns = self.columns_helper.remove_columns selectors=columns error_on_missing_columns=error_on_missing_columns on_problems=on_problems @@ -299,7 +300,7 @@ type Table Move the first column to back. table.reorder_columns [0] position=Position.After_Other_Columns - @columns (Widget_Helpers.make_column_name_vector_selector include_blanks=True) + @columns Widget_Helpers.make_column_name_vector_selector reorder_columns : Vector (Integer | Text | Column_Selector) | Text | Integer -> Position -> Boolean -> Problem_Behavior -> Table ! Missing_Input_Columns | Column_Indexes_Out_Of_Range reorder_columns self (columns = [self.columns.first.name]) (position = Position.Before_Other_Columns) (error_on_missing_columns = False) (on_problems = Report_Warning) = new_columns = self.columns_helper.reorder_columns selectors=columns position=position error_on_missing_columns on_problems=on_problems @@ -809,7 +810,7 @@ type Table table.order_by [(Sort_Column.Select_By_Name "a.*" use_regex=True case_sensitivity=Case_Sensitivity.Insensitive)] @columns Widget_Helpers.make_order_by_selector - order_by : Vector (Text | Sort_Column) | Text | Sort_Column -> Text_Ordering -> Boolean -> Problem_Behavior -> Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns | Column_Indexes_Out_Of_Range + order_by : Vector (Text | Sort_Column) | Text -> Text_Ordering -> Boolean -> Problem_Behavior -> Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns | Column_Indexes_Out_Of_Range order_by self (columns = ([(Sort_Column.Name (self.columns.at 0 . name))])) text_ordering=Text_Ordering.Default error_on_missing_columns=True on_problems=Problem_Behavior.Report_Warning = Panic.handle_wrapped_dataflow_error <| problem_builder = Problem_Builder.new error_on_missing_columns=error_on_missing_columns types_to_always_throw=[No_Input_Columns_Selected] columns_for_ordering = Table_Helpers.prepare_order_by self.columns columns problem_builder @@ -1276,6 +1277,7 @@ type Table Group by the Key column, count the rows table.aggregate [Aggregate_Column.Group_By "Key", Aggregate_Column.Count] + @columns Widget_Helpers.make_aggregate_column_vector_selector aggregate : Vector Aggregate_Column -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Invalid_Aggregate_Column | Invalid_Output_Column_Names | Duplicate_Output_Column_Names | Floating_Point_Equality | Invalid_Aggregation | Unquoted_Delimiter | Additional_Warnings aggregate self columns (error_on_missing_columns=False) (on_problems=Report_Warning) = validated = Aggregate_Column_Helper.prepare_aggregate_columns columns self error_on_missing_columns=error_on_missing_columns 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 c5eb5c30ecf5..8990282808ef 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 @@ -313,13 +313,14 @@ type Table table.select_columns [-1, 0, 1] reorder=True Icon: select_column - @columns (Widget_Helpers.make_column_name_vector_selector include_blanks=True) + @columns Widget_Helpers.make_column_name_vector_selector select_columns : Vector (Integer | Text | Column_Selector) | Text | Integer -> Boolean -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range select_columns self columns=[self.columns.first.name] (reorder = False) (error_on_missing_columns = True) (on_problems = Report_Warning) = new_columns = self.columns_helper.select_columns selectors=columns reorder=reorder error_on_missing_columns=error_on_missing_columns on_problems=on_problems Table.new new_columns - ## Returns a new table with the chosen set of columns, as specified by thez + ## ALIAS drop_columns + Returns a new table with the chosen set of columns, as specified by thez `columns`, removed from the input table. Any unmatched input columns will be kept in the output. Columns are returned in the same order as in the input. @@ -366,7 +367,7 @@ type Table Remove the first two columns and the last column. table.remove_columns [-1, 0, 1] - @columns (Widget_Helpers.make_column_name_vector_selector include_blanks=True) + @columns Widget_Helpers.make_column_name_vector_selector remove_columns : Vector (Integer | Text | Column_Selector) | Text | Integer -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range remove_columns self (columns=[self.columns.first.name]) (error_on_missing_columns = False) (on_problems = Report_Warning) = new_columns = self.columns_helper.remove_columns selectors=columns error_on_missing_columns=error_on_missing_columns on_problems=on_problems @@ -422,7 +423,7 @@ type Table Move the first column to back. table.reorder_columns [0] position=Position.After_Other_Columns - @columns (Widget_Helpers.make_column_name_vector_selector include_blanks=True) + @columns Widget_Helpers.make_column_name_vector_selector reorder_columns : Vector (Integer | Text | Column_Selector) | Text | Integer -> Position -> Boolean -> Problem_Behavior -> Table ! Missing_Input_Columns | Column_Indexes_Out_Of_Range reorder_columns self (columns = [self.columns.first.name]) (position = Position.Before_Other_Columns) (error_on_missing_columns = False) (on_problems = Report_Warning) = new_columns = self.columns_helper.reorder_columns selectors=columns position=position error_on_missing_columns=error_on_missing_columns on_problems=on_problems @@ -602,6 +603,7 @@ type Table Group by the Key column, count the rows table.aggregate [Aggregate_Column.Group_By "Key", Aggregate_Column.Count] + @columns Widget_Helpers.make_aggregate_column_vector_selector aggregate : Vector Aggregate_Column -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Invalid_Aggregate_Column | Invalid_Output_Column_Names | Duplicate_Output_Column_Names | Floating_Point_Equality | Invalid_Aggregation | Unquoted_Delimiter | Additional_Warnings aggregate self columns (error_on_missing_columns=False) (on_problems=Report_Warning) = validated = Aggregate_Column_Helper.prepare_aggregate_columns columns self error_on_missing_columns=error_on_missing_columns @@ -686,7 +688,7 @@ type Table table.order_by [(Sort_Column.Select_By_Name "a.*" use_regex=True case_sensitivity=Case_Sensitivity.Insensitive)] @columns Widget_Helpers.make_order_by_selector - order_by : Vector (Text | Sort_Column) | Text | Sort_Column -> Text_Ordering -> Boolean -> Problem_Behavior -> Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns | Column_Indexes_Out_Of_Range + order_by : Vector (Text | Sort_Column) | Text -> Text_Ordering -> Boolean -> Problem_Behavior -> Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns | Column_Indexes_Out_Of_Range order_by self (columns = [self.columns.first.name]) text_ordering=Text_Ordering.Default error_on_missing_columns=True on_problems=Problem_Behavior.Report_Warning = problem_builder = Problem_Builder.new error_on_missing_columns=error_on_missing_columns types_to_always_throw=[No_Input_Columns_Selected] columns_for_ordering = Table_Helpers.prepare_order_by self.columns columns problem_builder @@ -1957,11 +1959,11 @@ type Table 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 - actual.create_dry_run_file copy_original=on_existing_file==Existing_File_Behavior.Append + file.create_dry_run_file copy_original=on_existing_file==Existing_File_Behavior.Append to_write = if Context.Output.is_enabled then self else self.take 1000 Context.Output.with_enabled <| - format.write_table tgt_file to_write on_existing_file match_columns on_problems + format.write_table tgt_file to_write effective_existing_behaviour 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/Internal/Widget_Helpers.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso index 108055366c12..13260a611b3e 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso @@ -50,6 +50,13 @@ make_aggregate_column_selector table display=Display.Always include_group_by=Tru Single_Choice display=display values=(group_by+[count, count_distinct, first, last, count_not_nothing, count_nothing, count_not_empty, count_empty, concatenate, shortest, longest, sum, average, median, percentile, mode, standard_deviation, maximum, minimum]) +## PRIVATE + Make an Aggregate_Column list editor +make_aggregate_column_vector_selector : Table -> Display -> Widget +make_aggregate_column_vector_selector table display=Display.Always = + item_editor = make_aggregate_column_selector table display=Display.Always + Vector_Editor item_editor=item_editor item_default=item_editor.values.first.value display=display + ## PRIVATE Make a column name selector. make_column_name_selector : Table -> Display -> Widget From 68e1584d37f3a2c6f50a9de61d6ac887eced84cb Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Wed, 24 May 2023 12:49:32 +0100 Subject: [PATCH 03/25] Add ALIAS for reading sheets and ranges. Add custom drop down for `keep_unmatched`. --- .../lib/Standard/Database/0.0.0-dev/src/Data/Table.enso | 2 ++ distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso | 2 ++ .../lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso index 7ac012cdbd60..700f51c5151c 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso @@ -8,6 +8,7 @@ import Standard.Base.Errors.Illegal_Argument.Illegal_Argument import Standard.Base.Errors.Illegal_State.Illegal_State import Standard.Base.Errors.Unimplemented.Unimplemented +from Standard.Base.Metadata import make_single_choice from Standard.Base.Widget_Helpers import make_delimiter_selector from Standard.Table import Aggregate_Column, Data_Formatter, Column_Selector, Sort_Column, Match_Columns, Position, Set_Mode, Auto, Value_Type @@ -1063,6 +1064,7 @@ type Table defined nor any ordering was specified explicitly by the user, the order of columns is undefined and the operation will fail, reporting a `Undefined_Column_Order` problem and returning an empty table. + @keep_unmatched (make_single_choice [["True", "True"], ["False", "False"], ["Report", "Report_Unmatched"]]) zip : Table -> Boolean | Report_Unmatched -> Text -> Problem_Behavior -> Table zip self right keep_unmatched=Report_Unmatched right_prefix="Right " on_problems=Report_Warning = _ = [right, keep_unmatched, right_prefix, on_problems] 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 8990282808ef..b522e46c863e 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 @@ -9,6 +9,7 @@ import Standard.Base.Errors.Illegal_Argument.Illegal_Argument import Standard.Base.Errors.Unimplemented.Unimplemented import Standard.Base.Runtime.Context +from Standard.Base.Metadata import make_single_choice from Standard.Base.Widget_Helpers import make_delimiter_selector import project.Data.Aggregate_Column.Aggregate_Column @@ -1530,6 +1531,7 @@ type Table defined nor any ordering was specified explicitly by the user, the order of columns is undefined and the operation will fail, reporting a `Undefined_Column_Order` problem and returning an empty table. + @keep_unmatched (make_single_choice [["True", "True"], ["False", "False"], ["Report", "Report_Unmatched"]]) zip : Table -> Boolean | Report_Unmatched -> Text -> Problem_Behavior -> Table zip self right keep_unmatched=Report_Unmatched right_prefix="Right " on_problems=Report_Warning = if check_table "right" right then diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso index ef67deb61682..ed9f5499958f 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso @@ -126,7 +126,8 @@ type Excel_Workbook _ = [alias] self.read query - ## Execute the query and load the results into memory as a Table. + ## ALIAS sheet, worksheet, range + Execute the query and load the results into memory as a Table. Arguments: - query: sheet name, range name or address to read from the workbook. From a34a8799a6f6f75c7818ee263ff7d93addae626c Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Wed, 24 May 2023 16:59:20 +0100 Subject: [PATCH 04/25] Fix issue where `tables` didn't allow a single value. --- .../Database/0.0.0-dev/src/Connection/Connection.enso | 7 +++++-- .../Table/0.0.0-dev/src/Excel/Excel_Workbook.enso | 9 +++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Connection.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Connection.enso index 7cac233bc99b..9b5ce9a7648a 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Connection.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Connection.enso @@ -120,9 +120,12 @@ type Connection - all_fields: Return all the fields in the metadata table. @types make_table_types_selector @schema make_schema_selector - tables : Text -> Text -> Text -> Vector -> Boolean -> Materialized_Table + tables : Text -> Text -> Text -> Vector Text | Text | Nothing -> Boolean -> Materialized_Table tables self name_like=Nothing database=self.database schema=Nothing types=self.dialect.default_table_types all_fields=False = - types_array = if types.is_nothing then Nothing else types.to_array + types_array = case types of + Nothing -> Nothing + _ : Vector -> types + _ -> [types] name_map = Map.from_vector [["TABLE_CAT", "Database"], ["TABLE_SCHEM", "Schema"], ["TABLE_NAME", "Name"], ["TABLE_TYPE", "Type"], ["REMARKS", "Description"], ["TYPE_CAT", "Type Database"], ["TYPE_SCHEM", "Type Schema"], ["TYPE_NAME", "Type Name"]] self.jdbc_connection.with_metadata metadata-> table = Managed_Resource.bracket (metadata.getTables database schema name_like types_array) .close result_set-> diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso index ed9f5499958f..e84078913a3a 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso @@ -103,10 +103,15 @@ type Excel_Workbook @types (self-> Single_Choice values=(self.table_types.map t-> Option t t.pretty)) tables : Text -> Text -> Text -> Vector -> Boolean -> Table tables self name_like=Nothing database=self.database schema=self.schema types=Nothing all_fields=False = + types_array = case types of + Nothing -> Nothing + _ : Vector -> types + _ -> [types] + _ = [all_fields] rows = if schema != Nothing then [] else - sheets = if types==Nothing || types.contains "Worksheet" then self.sheet_names.map s-> [s, 'Worksheet', database, Nothing] else [] - ranges = if types==Nothing || types.contains "Named Range" then self.named_ranges.map r-> [r, 'Named Range', database, Nothing] else [] + sheets = if types_array.is_nothing || types_array.contains "Worksheet" then self.sheet_names.map s-> [s, 'Worksheet', database, Nothing] else [] + ranges = if types_array.is_nothing || types_array.contains "Named Range" then self.named_ranges.map r-> [r, 'Named Range', database, Nothing] else [] sheets + ranges filtered = if name_like == Nothing then rows else From bc8d25a2aa4b68beb6db4c323fb64991bd38859b Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Wed, 24 May 2023 17:18:01 +0100 Subject: [PATCH 05/25] Fix not returning the File. --- .../Base/0.0.0-dev/src/System/File/Write_Extensions.enso | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso index 919ce95f66ee..3c04769ee1f7 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso @@ -61,6 +61,7 @@ Text.write self path encoding=Encoding.utf_8 on_existing_file=Existing_File_Beha Context.Output.with_enabled <| effective_existing_behaviour.write file stream-> stream.write_bytes bytes + file ## Writes (or appends) the Vector of bytes into the specified file. The behavior specified in the `existing_file` parameter will be used if the file exists. From 86d959b7c182a813c986d6553998d49b68463188 Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Wed, 24 May 2023 17:39:26 +0100 Subject: [PATCH 06/25] Fix not returning the File. --- .../0.0.0-dev/src/System/File/Existing_File_Behavior.enso | 2 +- .../Base/0.0.0-dev/src/System/File/Write_Extensions.enso | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Existing_File_Behavior.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Existing_File_Behavior.enso index 7331aa1b2c3c..0567934321ec 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Existing_File_Behavior.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Existing_File_Behavior.enso @@ -70,7 +70,7 @@ type Existing_File_Behavior handle_file_already_exists = catch_already_exists handle_existing_file handle_internal_dataflow = Panic.catch Internal_Write_Operation_Errored handler=handle_write_failure_dataflow ## We first attempt to write the file to the original - destination, but if that files due to the file already + destination, but if that fails due to the file already existing, we will run the alternative algorithm which uses a temporary file and creates a backup. handle_file_already_exists <| handle_internal_dataflow <| diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso index 3c04769ee1f7..a95d16fb08ef 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso @@ -59,9 +59,9 @@ Text.write self path encoding=Encoding.utf_8 on_existing_file=Existing_File_Beha actual.create_dry_run_file copy_original=on_existing_file==Existing_File_Behavior.Append Context.Output.with_enabled <| - effective_existing_behaviour.write file stream-> + r = effective_existing_behaviour.write file stream-> stream.write_bytes bytes - file + r.if_not_error file ## Writes (or appends) the Vector of bytes into the specified file. The behavior specified in the `existing_file` parameter will be used if the file exists. From 06eb7612ce9350cdd6f32c6f888ea4f7d238cb96 Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Thu, 25 May 2023 09:32:02 +0100 Subject: [PATCH 07/25] Simplify docs a bit. --- .../0.0.0-dev/src/Data/Join_Condition.enso | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Join_Condition.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Join_Condition.enso index b5741978cab2..c7855e4a30b9 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Join_Condition.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Join_Condition.enso @@ -1,44 +1,36 @@ from Standard.Base import all type Join_Condition - ## Specifies a join condition that correlates rows from the two tables if - the element from the `left` of the left table is equal to the element - from the `right` of the right table. + ## Correlates rows from the two tables if the `left` element is equal to the + `right` element. - Missing values are treated as equal to each other. + `Nothing` (or null in database) is considered equal to itself. Arguments: - left: A name or index of a column in the left table. - right: A name or index of a column in the right table. Equals (left : Text | Integer) (right : Text | Integer = left) - ## Specifies a join condition that correlates rows from the two tables if - the element from the `left` column of the left table is equal to the - element from the `right` column of the right table, ignoring case. + ## Correlates rows from the two tables if the `left` element is equal to the + `right` element, ignoring case. This is only supported for text columns. - Missing values are treated as equal to each other. + Case insensitive comparisons may mean a database has to perform a row + scan, which can cause a performance degradation. - This is only supported for text columns. - - Case insensitive comparisons may make it impossible for a database - operation to re-use an existing index, which can possibly lead to - performance degradation. + `Nothing` (or null in database) is considered equal to itself. Arguments: - left: A name or index of a column in the left table. - - right: A name or index of a column in the right table. Defaults to the - same column selector as provided for `left`. + - right: A name or index of a column in the right table. - locale: The locale to use for case insensitive comparisons. Equals_Ignore_Case (left : Text | Integer) (right : Text | Integer = left) (locale : Locale = Locale.default) - ## Specifies a join condition that correlates rows from the two tables if - the element from the `left` column of the left table fits between the - corresponding elements from `right_lower` and `right_upper` columns of - the right table. The comparison is inclusive. + ## Correlates rows from the two tables if the `left` element fits between + the `right_lower` and `right_upper` elements. The comparison is inclusive + for both lower and upper bounds. - Pairs of rows in which any of `left`, `right_lower`, or `right_upper` is - missing are ignored, as the comparison is assumed to be not well-defined - for missing values. + If any of the values on row are `Nothing` (or null in database) then the + rows won't be joined. Arguments: - left: A name or index of a column in the left table. From b0a60c562d355cb285c90c33141313feee0f8371 Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Tue, 30 May 2023 14:45:17 +0100 Subject: [PATCH 08/25] Fix for find_all. Add fetch to URI. Add some ALIASes (+, -, few methods). --- .../lib/Standard/Base/0.0.0-dev/src/Data.enso | 21 +++++++++++++--- .../Base/0.0.0-dev/src/Data/Array.enso | 3 ++- .../Base/0.0.0-dev/src/Data/Numbers.enso | 24 +++++++++---------- .../Base/0.0.0-dev/src/Data/Text.enso | 3 ++- .../src/Data/Text/Regex/Pattern.enso | 7 +++--- .../Base/0.0.0-dev/src/Data/Time/Date.enso | 8 +++---- .../0.0.0-dev/src/Data/Time/Date_Time.enso | 6 +++-- .../0.0.0-dev/src/Data/Time/Duration.enso | 6 +++-- .../Base/0.0.0-dev/src/Data/Time/Period.enso | 6 +++-- .../0.0.0-dev/src/Data/Time/Time_Of_Day.enso | 6 +++-- .../Base/0.0.0-dev/src/Data/Vector.enso | 3 ++- 11 files changed, 59 insertions(+), 34 deletions(-) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso index a4569f34a935..e8954e661939 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso @@ -140,11 +140,13 @@ list_directory : (File | Text) -> Text -> Boolean -> Vector File list_directory directory name_filter=Nothing recursive=False = File.new directory . list name_filter=name_filter recursive=recursive -## Fetches from the provided URL and returns the response body. - Will error if the status code does not represent a successful response. +## ALIAS Download, HTTP Get + Fetches from the provided URI and returns the response, parsing the body if + the content-type is recognised. Returns an error if the status code does not + represent a successful response. Arguments: - - url: The URL to fetch. + - uri: The URI to fetch. - method: The HTTP method to use. Defaults to `GET`. - headers: The headers to send with the request. Defaults to an empty vector. - parse: If successful should the body be parsed to an Enso native object. @@ -166,3 +168,16 @@ fetch uri method=HTTP_Method.Get headers=[] parse=True = format = Auto_Detect.get_web_parser content_type.value uri if format == Nothing then response else format.read_web response + +## ALIAS Download, HTTP Get + Fetches from the URI and returns the response, parsing the body if the + content-type is recognised. Returns an error if the status code does not + represent a successful response. + + Arguments: + - method: The HTTP method to use. Defaults to `GET`. + - headers: The headers to send with the request. Defaults to an empty vector. + - parse: If successful should the body be parsed to an Enso native object. +URI.fetch : HTTP_Method -> Vector (Header | Pair Text Text) -> Boolean -> Any +URI.fetch self method=HTTP_Method.Get headers=[] parse=True = + Data.fetch self method headers parse diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Array.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Array.enso index 726f68e4137d..7cb8176be8df 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Array.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Array.enso @@ -784,7 +784,8 @@ type Array each_with_index : (Integer -> Any -> Any) -> Nothing each_with_index self f = Vector.each_with_index self f - ## Concatenates two arrays, resulting in a new `Vector`, containing all the + ## ALIAS Concatenate + Concatenates two arrays, resulting in a new `Vector`, containing all the elements of `self`, followed by all the elements of `that`. Arguments: diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso index f9e60b11a194..8bb8f259e7f2 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso @@ -25,8 +25,7 @@ polyglot java import java.text.ParseException an Integer in its place. @Builtin_Type type Number - ## ALIAS Add - + ## ALIAS Add, Plus Adds two arbitrary numbers. Arguments: @@ -42,8 +41,7 @@ type Number + : Number -> Number + self that = @Builtin_Method "Integer.+" - ## ALIAS Subtract - + ## ALIAS Subtract, Minus Subtract an arbitrary number from this. Arguments: @@ -56,8 +54,7 @@ type Number - : Number -> Number - self that = @Builtin_Method "Integer.-" - ## ALIAS Multiply - + ## ALIAS Multiply, Times, Product Multiply two arbitrary numbers. Arguments: @@ -74,7 +71,6 @@ type Number * self that = @Builtin_Method "Integer.*" ## ALIAS Divide - Divides an this by an arbitrary number. Arguments: @@ -375,8 +371,8 @@ type Number floating point numbers. @Builtin_Type type Decimal - - ## Adds a deceimal and an arbitrary number. + ## ALIAS Add, Plus + Adds a decimal and an arbitrary number. Arguments: - that: The number to add to this. @@ -391,7 +387,8 @@ type Decimal + : Number -> Number + self that = @Builtin_Method "Decimal.+" - ## Subtract an arbitrary number from this. + ## ALIAS Subtract, Minus + Subtract an arbitrary number from this. Arguments: - that: The number to subtract from this. @@ -685,8 +682,8 @@ type Decimal degrade. @Builtin_Type type Integer - - ## Adds an integer and an arbitrary number. + ## ALIAS Add, Plus + Adds an integer and an arbitrary number. Arguments: - that: The number to add to this. @@ -701,7 +698,8 @@ type Integer + : Number -> Number + self that = @Builtin_Method "Integer.+" - ## Subtract an arbitrary number from this. + ## ALIAS Subtract, Minus + Subtract an arbitrary number from this. Arguments: - that: The number to subtract from this. diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text.enso index 1ef1c3f51af2..6f3cc9b32bc1 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text.enso @@ -20,7 +20,8 @@ polyglot java import org.enso.base.Text_Utils @Builtin_Type type Text - ## Concatenates the text that to the right side of this. + ## ALIAS Concatenate + Concatenates the text that to the right side of this. Arguments: - that: The text to concatenate to this. diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso index b4d95df7ea49..1b4b36004ced 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso @@ -4,6 +4,7 @@ import project.Data.Map.Map import project.Data.Numbers.Integer import project.Data.Range.Extensions import project.Data.Range.Range +import project.Data.Text.Extensions import project.Data.Text.Helpers import project.Data.Text.Span.Span import project.Data.Text.Span.Utf_16_Span @@ -97,7 +98,7 @@ type Pattern Arguments: - input: The text to match the pattern described by `self` against. - find_all : Text -> Vector Text | Type_Error + find_all : Text -> Vector Text ! Type_Error find_all self input = Helpers.expect_text input <| self.match_all input . map match_to_group_maybe @@ -352,8 +353,8 @@ type Match_Iterator Also returns the next iterator, if there was a match. next : Match_Iterator_Value next self = - regex_result = self.pattern.internal_regex_object.exec self.input self.cursor - case regex_result.isMatch of + regex_result = if self.cursor >= self.input.char_vector.length then Nothing else self.pattern.internal_regex_object.exec self.input self.cursor + case regex_result.is_nothing.not && regex_result.isMatch of False -> filler_range = Range.new self.cursor (Text_Utils.char_length self.input) filler_span = (Utf_16_Span.Value filler_range self.input) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Date.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Date.enso index 6fec6c39cbf4..033ef1acdb4a 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Date.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Date.enso @@ -425,7 +425,8 @@ type Date to_date_time : Time_Of_Day -> Time_Zone -> Date_Time to_date_time self (time_of_day=Time_Of_Day.new) (zone=Time_Zone.system) = self.to_time_builtin time_of_day zone - ## Add the specified amount of time to this instant to get another date. + ## ALIAS Add Period + Add the specified amount of time to this instant to get another date. Arguments: - amount: The time duration to add to this instant. @@ -447,7 +448,6 @@ type Date Error.throw (Illegal_Argument.Error "Illegal period argument") ## ALIAS Date Range - Creates an increasing range of dates from `self` to `end`. Arguments: @@ -472,7 +472,6 @@ type Date _ -> Error.throw (Type_Error.Error Date end "end") ## ALIAS Date Range - Creates a decreasing range of dates from `self` to `end`. Arguments: @@ -618,7 +617,8 @@ type Date if holidays.contains end_date || is_weekend end_date then @Tail_Call go (end_date - (Period.new days=1)) else end_date go end - ## Subtract the specified amount of time from this instant to get another + ## ALIAS Subtract Period + Subtract the specified amount of time from this instant to get another date. Arguments: diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Date_Time.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Date_Time.enso index 9cd24652241b..6a498cd65965 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Date_Time.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Date_Time.enso @@ -501,7 +501,8 @@ type Date_Time at_zone : Time_Zone -> Date_Time at_zone self zone = @Builtin_Method "Date_Time.at_zone" - ## Add the specified amount of time to this instant to produce a new instant. + ## ALIAS Add Period, Add Duration + Add the specified amount of time to this instant to produce a new instant. Arguments: - amount: The amount of time to add to this instant, either `Duration` for @@ -564,7 +565,8 @@ type Date_Time ensure_in_epoch self <| self.date.add_work_days days holidays . to_date_time self.time_of_day self.zone - ## Subtract the specified amount of time from this instant to get a new + ## ALIAS Subtract Duration, Subtract Period + Subtract the specified amount of time from this instant to get a new instant. Produces a warning if the resulting date time is before an Enso epoch. diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Duration.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Duration.enso index b71cf1d4bc68..062e81cc3842 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Duration.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Duration.enso @@ -128,7 +128,8 @@ type Duration duration = Duration.new nanoseconds=(end - start) Pair.new duration result - ## Add the specified amount of time to this duration. + ## ALIAS Add Duration + Add the specified amount of time to this duration. Arguments: - that: The duration to add to `self`. @@ -152,7 +153,8 @@ type Duration Panic.catch ArithmeticException (self.plus_builtin that) err-> Error.throw (Time_Error.Error err.payload.getMessage) - ## Subtract the specified amount of time from this duration. + ## ALIAS Subtract Duration + Subtract the specified amount of time from this duration. Arguments: - that: The duration to subtract from `self`. diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Period.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Period.enso index 6e2c81dc4f98..dc2fd41e2368 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Period.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Period.enso @@ -97,7 +97,8 @@ type Period days : Integer days self = self.internal_period.getDays - ## Add the specified amount of time to this period. + ## ALIAS Add Period + Add the specified amount of time to this period. Arguments: - other_period: The period to add to `self`. Note that this cannot be a @@ -115,7 +116,8 @@ type Period catch_java_exceptions "Period.+" <| Period.Value (self.internal_period.plus other_period.internal_period) - ## Subtract a specified amount of time from this period. + ## ALIAS Subtract Period + Subtract a specified amount of time from this period. Arguments: - other_period: Other Period to add to this Period. Note that this diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Time_Of_Day.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Time_Of_Day.enso index e6b8b0d035a6..662e2817071f 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Time_Of_Day.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Time_Of_Day.enso @@ -253,7 +253,8 @@ type Time_Of_Day to_date_time : Date -> Time_Zone -> Date_Time to_date_time self date (zone=Time_Zone.system) = self.to_date_time_builtin date zone - ## Add the specified amount of time to this instant to get a new instant. + ## ALIAS Add Duration + Add the specified amount of time to this instant to get a new instant. Arguments: - amount: The amount of time to add to this instant. Can be only @@ -270,7 +271,8 @@ type Time_Of_Day duration : Duration -> self.plus_builtin duration _ : Period -> Error.throw (Time_Error.Error "Time_Of_Day does not support date intervals (periods)") - ## Subtract the specified amount of time from this instant to get a new + ## ALIAS Subtract Duration + Subtract the specified amount of time from this instant to get a new instant. Arguments: diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Vector.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Vector.enso index 46f95679045e..84dbf1d5446e 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Vector.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Vector.enso @@ -651,7 +651,8 @@ type Vector a "and " + remaining_count.to_text + " more elements" prefix.map .to_text . join ", " "[" " "+remaining_text+"]" - ## Concatenates two vectors, resulting in a new `Vector`, containing all the + ## ALIAS Concatenate + Concatenates two vectors, resulting in a new `Vector`, containing all the elements of `self`, followed by all the elements of `that`. Arguments: From 2c49cb323abd40d2ef4abe131955effc47f97da0 Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Tue, 30 May 2023 14:46:21 +0100 Subject: [PATCH 09/25] Add some ALIASes (+, -, few methods). --- .../lib/Standard/Database/0.0.0-dev/src/Data/Column.enso | 6 ++---- .../lib/Standard/Database/0.0.0-dev/src/Data/Table.enso | 4 +--- .../lib/Standard/Table/0.0.0-dev/src/Data/Column.enso | 6 ++---- .../lib/Standard/Table/0.0.0-dev/src/Data/Table.enso | 4 +--- 4 files changed, 6 insertions(+), 14 deletions(-) diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso index 789fc8bb9576..0f151708ed77 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso @@ -348,8 +348,7 @@ type Column new_name = self.naming_helpers.to_expression_text self + " between " + self.naming_helpers.to_expression_text lower + " and " + self.naming_helpers.to_expression_text upper self.make_op "BETWEEN" [lower, upper] new_name - ## UNSTABLE - + ## ALIAS Add, Plus, Concatenate Element-wise addition. Arguments: @@ -365,8 +364,7 @@ type Column new_name = self.naming_helpers.binary_operation_name "+" self other self.make_binary_op op other new_name - ## UNSTABLE - + ## ALIAS Subtract, Minus Element-wise subtraction. Arguments: diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso index 700f51c5151c..177bbc643e4a 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso @@ -582,9 +582,7 @@ type Table new_ctx = self.context.set_limit max_rows self.updated_context new_ctx - ## UNSTABLE - ALIAS Add Column, Update Column - + ## ALIAS Add Column, Update Column, New Column Sets the column value at the given name. Arguments: diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso index a214e821e733..e35f381ad13e 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso @@ -355,8 +355,7 @@ type Column result = (self >= lower) && (self <= upper) result.rename new_name - ## ALIAS Add Columns - + ## ALIAS Add, Plus, Concatenate Element-wise addition. Arguments: @@ -385,8 +384,7 @@ type Column Value_Type_Helpers.resolve_addition_kind self other . if_not_error <| run_vectorized_binary_op self '+' fallback_fn=Nothing other - ## ALIAS Subtract Columns - + ## ALIAS Subtract, Minus Element-wise subtraction. Arguments: 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 b522e46c863e..953e75e819b3 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 @@ -1192,9 +1192,7 @@ type Table drop self range=(First 1) = Index_Sub_Range_Module.drop_helper self.row_count self.rows.at self.slice (slice_ranges self) range - ## UNSTABLE - ALIAS Add Column, Update Column - + ## ALIAS Add Column, Update Column, New Column Sets the column value at the given name. Arguments: From 73b6c865693ab6fae4e2c91334e567f4b5cf54ac Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Tue, 30 May 2023 15:00:29 +0100 Subject: [PATCH 10/25] ALIASes for `*` and `/`. --- .../Standard/Base/0.0.0-dev/src/Data/Numbers.enso | 13 ++++++++----- .../Base/0.0.0-dev/src/Data/Time/Period.enso | 3 ++- .../Database/0.0.0-dev/src/Data/Column.enso | 4 +--- .../Standard/Table/0.0.0-dev/src/Data/Column.enso | 4 +--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso index 8bb8f259e7f2..8f12778a42a9 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso @@ -85,7 +85,6 @@ type Number 10 / 4 / : Number -> Number / self that = @Builtin_Method "Integer./" - ## ALIAS Power Compute the result of raising this to the power that. @@ -400,7 +399,8 @@ type Decimal - : Number -> Number - self that = @Builtin_Method "Decimal.-" - ## Multiply a decimal by an arbitrary number. + ## ALIAS Multiply, Times, Product + Multiply a decimal by an arbitrary number. Arguments: - that: The number to multiply this by. @@ -415,7 +415,8 @@ type Decimal * : Number -> Number * self that = @Builtin_Method "Decimal.*" - ## Divides a decimal by an arbitrary number. + ## ALIAS Divide + Divides a decimal by an arbitrary number. Arguments: - that: The number to divide this by. @@ -711,7 +712,8 @@ type Integer - : Number -> Number - self that = @Builtin_Method "Integer.-" - ## Multiply an integer by an arbitrary number. + ## ALIAS Multiply, Times, Product + Multiply an integer by an arbitrary number. Arguments: - that: The number to multiply this by. @@ -726,7 +728,8 @@ type Integer * : Number -> Number * self that = @Builtin_Method "Integer.*" - ## Divides an integer by an arbitrary number. + ## ALIAS Divide + Divides an integer by an arbitrary number. Arguments: - that: The number to divide this by. diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Period.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Period.enso index dc2fd41e2368..2d4c3dd8fc27 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Period.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Time/Period.enso @@ -136,7 +136,8 @@ type Period catch_java_exceptions "Period.-" <| Period.Value (self.internal_period.minus other_period.internal_period) - ## Multiply the amount of time in this period by the specified scalar. + ## ALIAS Multiply, Times + Multiply the amount of time in this period by the specified scalar. Arguments: - factor: The scalar to multiply by. diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso index 0f151708ed77..2822ece6d87e 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso @@ -378,8 +378,7 @@ type Column Value_Type_Helpers.check_binary_numeric_op self other <| self.make_binary_op "-" other - ## UNSTABLE - + ## ALIAS Multiply, Times, Product Element-wise multiplication. Arguments: @@ -394,7 +393,6 @@ type Column self.make_binary_op "*" other ## ALIAS Divide Columns - Element-wise division. Arguments: diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso index e35f381ad13e..7171d666f7ab 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso @@ -413,8 +413,7 @@ type Column Value_Type_Helpers.check_binary_numeric_op self other <| run_vectorized_binary_op self '-' fallback_fn=Nothing other - ## ALIAS Multiply Columns - + ## ALIAS Multiply, Times, Product Element-wise multiplication. Arguments: @@ -444,7 +443,6 @@ type Column run_vectorized_binary_op self '*' fallback_fn=Nothing other ## ALIAS Divide Columns - Element-wise division. Arguments: From c45131025713ec5623161608d2abdade81cfc86c Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Tue, 30 May 2023 15:53:25 +0100 Subject: [PATCH 11/25] Add all the other ALIASes for operators. --- .../lib/Standard/Base/0.0.0-dev/src/Any.enso | 10 +---- .../Base/0.0.0-dev/src/Data/Boolean.enso | 6 ++- .../Base/0.0.0-dev/src/Data/Numbers.enso | 38 ++++++++++++------- .../Database/0.0.0-dev/src/Data/Column.enso | 30 +++++++-------- .../Table/0.0.0-dev/src/Data/Column.enso | 31 ++++++++------- 5 files changed, 62 insertions(+), 53 deletions(-) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso index 96d826ef9cf1..d3f91886b890 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso @@ -62,8 +62,7 @@ type Any to_display_text : Text to_display_text self = @Builtin_Method "Any.to_display_text" - ## ALIAS Equality - + ## ALIAS Equals Checks if `self` is equal to `that`. Arguments: @@ -110,8 +109,7 @@ type Any == : Any -> Boolean == self that = @Builtin_Method "Any.==" - ## ALIAS Inequality - + ## ALIAS Not Equals Checks if `self` is not equal to `that`. Arguments: @@ -134,7 +132,6 @@ type Any != self that = (self == that).not ## ALIAS Greater Than - Checks if `self` is greater than `that`. Arguments: @@ -162,7 +159,6 @@ type Any _ -> False ## ALIAS Greater Than or Equal - Checks if `self` is greater than or equal to `that`. Arguments: @@ -192,7 +188,6 @@ type Any _ -> False ## ALIAS Less Than - Checks if `self` is less than `that`. Arguments: @@ -220,7 +215,6 @@ type Any _ -> False ## ALIAS Less Than or Equal - Checks if `self` is less than or equal to `that`. Arguments: diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Boolean.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Boolean.enso index 512a0081bd20..b4105667ead8 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Boolean.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Boolean.enso @@ -15,7 +15,8 @@ type Boolean True False - ## Computes the logical and (conjunction) of two booleans. + ## ALIAS And + Computes the logical and (conjunction) of two booleans. Arguments: - that: The boolean to compute the conjunction of this with. @@ -31,7 +32,8 @@ type Boolean && : Boolean -> Boolean && self ~that = @Builtin_Method "Boolean.&&" - ## Computes the logical or (disjunction) of two booleans. + ## ALIAS Or + Computes the logical or (disjunction) of two booleans. Arguments: - that: The boolean to compute the disjunction of this with. diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso index 8f12778a42a9..0c8bdbf636b4 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso @@ -85,8 +85,8 @@ type Number 10 / 4 / : Number -> Number / self that = @Builtin_Method "Integer./" - ## ALIAS Power + ## ALIAS Power Compute the result of raising this to the power that. Arguments: @@ -431,7 +431,8 @@ type Decimal / : Number -> Number / self that = @Builtin_Method "Decimal./" - ## Computes the remainder when dividing this by that. + ## ALIAS Modulus + Computes the remainder when dividing this by that. Arguments: - that: The number to divide this by. @@ -451,7 +452,8 @@ type Decimal % : Number -> Number ! Arithmetic_Error % self that = @Builtin_Method "Decimal.%" - ## Compute the result of raising this to the power that. + ## ALIAS Power + Compute the result of raising this to the power that. Arguments: - that: The exponent. @@ -463,7 +465,8 @@ type Decimal ^ : Number -> Number ^ self that = @Builtin_Method "Decimal.^" - ## Checks if this is greater than that. + ## ALIAS Greater Than + Checks if this is greater than that. Arguments: - that: The number to compare this against. @@ -475,7 +478,8 @@ type Decimal > : Number -> Boolean > self that = @Builtin_Method "Decimal.>" - ## Checks if this is greater than or equal to thatthat. + ## ALIAS Greater Than or Equal + Checks if this is greater than or equal to that. Arguments: - that: The number to compare this against. @@ -487,7 +491,8 @@ type Decimal >= : Number -> Boolean >= self that = @Builtin_Method "Decimal.>=" - ## Checks if this is less than that. + ## ALIAS Less Than + Checks if this is less than that. Arguments: - that: The number to compare this against. @@ -499,7 +504,8 @@ type Decimal < : Number -> Boolean < self that = @Builtin_Method "Decimal.<" - ## Checks if this is less than or equal to thatthat. + ## ALIAS Less Than Or Equal + Checks if this is less than or equal to that. Arguments: - that: The number to compare this against. @@ -744,7 +750,8 @@ type Integer / : Number -> Number / self that = @Builtin_Method "Integer./" - ## Computes the remainder when dividing this by that. + ## ALIAS Modulus + Computes the remainder when dividing this by that. Arguments: - that: The number to divide this by. @@ -761,7 +768,8 @@ type Integer % : Number -> Number ! Arithmetic_Error % self that = @Builtin_Method "Integer.%" - ## Compute the result of raising this to the power that. + ## ALIAS Power + Compute the result of raising this to the power that. Arguments: - that: The exponent. @@ -773,7 +781,8 @@ type Integer ^ : Number -> Number ^ self that = @Builtin_Method "Integer.^" - ## Checks if this is greater than that. + ## ALIAS Greater Than + Checks if this is greater than that. Arguments: - that: The number to compare this against. @@ -785,7 +794,8 @@ type Integer > : Number -> Boolean > self that = @Builtin_Method "Integer.>" - ## Checks if this is greater than or equal to thatthat. + ## ALIAS Greater Than or Equal + Checks if this is greater than or equal to that. Arguments: - that: The number to compare this against. @@ -797,7 +807,8 @@ type Integer >= : Number -> Boolean >= self that = @Builtin_Method "Integer.>=" - ## Checks if this is less than that. + ## ALIAS Less Than + Checks if this is less than that. Arguments: - that: The number to compare this against. @@ -809,7 +820,8 @@ type Integer < : Number -> Boolean < self that = @Builtin_Method "Integer.<" - ## Checks if this is less than or equal to thatthat. + ## ALIAS Less Than Or Equal + Checks if this is less than or equal to that. Arguments: - that: The number to compare this against. diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso index 2822ece6d87e..2c839ba3eb56 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso @@ -190,7 +190,8 @@ type Column count self = self.to_table.filter 0 Filter_Condition.Not_Nothing . row_count - ## Element-wise equality comparison. + ## ALIAS Equals + Element-wise equality comparison. Arguments: - other: The value to compare `self` against. If `other` is a column, the @@ -240,7 +241,8 @@ type Column new_name = self.naming_helpers.function_name "equals_ignore_case" [self, other] self.make_binary_op "equals_ignore_case" other new_name - ## Element-wise non-equality comparison. + ## ALIAS Not Equals + Element-wise non-equality comparison. Arguments: - other: The value to compare `self` against. If `other` is a column, the @@ -273,8 +275,7 @@ type Column != self other = make_equality_check_with_floating_point_handling self other "!=" - ## UNSTABLE - + ## ALIAS Greater Than Or Equal Element-wise order comparison. Arguments: @@ -287,8 +288,7 @@ type Column >= self other = Value_Type.expect_comparable self other <| self.make_binary_op ">=" other - ## UNSTABLE - + ## ALIAS Less Than Or Equal Element-wise order comparison. Arguments: @@ -301,8 +301,7 @@ type Column <= self other = Value_Type.expect_comparable self other <| self.make_binary_op "<=" other - ## UNSTABLE - + ## ALIAS Greater Than Element-wise order comparison. Arguments: @@ -315,8 +314,7 @@ type Column > self other = Value_Type.expect_comparable self other <| self.make_binary_op ">" other - ## UNSTABLE - + ## ALIAS Less Than Element-wise order comparison. Arguments: @@ -392,7 +390,7 @@ type Column Value_Type_Helpers.check_binary_numeric_op self other <| self.make_binary_op "*" other - ## ALIAS Divide Columns + ## ALIAS Divide Element-wise division. Arguments: @@ -426,7 +424,8 @@ type Column Value_Type_Helpers.check_binary_numeric_op self other <| self.make_binary_op "/" other - ## Element-wise modulus. + ## ALIAS Modulus + Element-wise modulus. Arguments: - other: The value to modulo `self` against. If `other` is a column, the @@ -464,7 +463,6 @@ type Column self.make_binary_op op other new_name ## ALIAS Power - Element-wise raising to the power. Arguments: @@ -493,8 +491,7 @@ type Column Value_Type_Helpers.check_binary_numeric_op self other <| self.make_binary_op '^' other - ## UNSTABLE - + ## ALIAS And Element-wise boolean conjunction. Arguments: @@ -510,8 +507,7 @@ type Column new_name = self.naming_helpers.binary_operation_name "&&" self other self.make_binary_op "AND" other new_name - ## UNSTABLE - + ## ALIAS Or Element-wise boolean disjunction. Arguments: diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso index 7171d666f7ab..2494f9d6ad39 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso @@ -131,7 +131,8 @@ type Column IO.println (self.display show_rows format_terminal=True) IO.println '' - ## Element-wise equality comparison. + ## ALIAS Equals + Element-wise equality comparison. Arguments: - other: The value to compare `self` against. If `other` is a column, the @@ -193,7 +194,8 @@ type Column new_name = Naming_Helpers.function_name "equals_ignore_case" [self, other] run_vectorized_binary_op self "equals_ignore_case" fallback other expected_result_type=Value_Type.Boolean new_name - ## Element-wise non-equality comparison. + ## ALIAS Not Equals + Element-wise non-equality comparison. Arguments: - other: The value to compare `self` against. If `other` is a column, the @@ -227,7 +229,8 @@ type Column new_name = Naming_Helpers.binary_operation_name "!=" self other (self == other).not . rename new_name - ## Element-wise order comparison. + ## ALIAS Greater Than Or Equal + Element-wise order comparison. Arguments: - other: The value to compare `self` against. If `other` is a column, the @@ -254,7 +257,8 @@ type Column >= self other = Value_Type.expect_comparable self other <| run_vectorized_binary_op self ">=" (>=) other expected_result_type=Value_Type.Boolean - ## Element-wise order comparison. + ## ALIAS Less Than Or Equal + Element-wise order comparison. Arguments: - other: The value to compare `self` against. If `other` is a column, the @@ -281,7 +285,8 @@ type Column <= self other = Value_Type.expect_comparable self other <| run_vectorized_binary_op self "<=" (<=) other expected_result_type=Value_Type.Boolean - ## Element-wise order comparison. + ## ALIAS Greater Than + Element-wise order comparison. Arguments: - other: The value to compare `self` against. If `other` is a column, the @@ -308,7 +313,8 @@ type Column > self other = Value_Type.expect_comparable self other <| run_vectorized_binary_op self ">" (>) other expected_result_type=Value_Type.Boolean - ## Element-wise order comparison. + ## ALIAS Less Than + Element-wise order comparison. Arguments: - other: The value to compare `self` against. If `other` is a column, the @@ -442,7 +448,7 @@ type Column Value_Type_Helpers.check_binary_numeric_op self other <| run_vectorized_binary_op self '*' fallback_fn=Nothing other - ## ALIAS Divide Columns + ## ALIAS Divide Element-wise division. Arguments: @@ -477,7 +483,8 @@ type Column new_name = Naming_Helpers.binary_operation_name "/" self other run_vectorized_binary_op_with_problem_handling self "/" fallback_fn=Nothing other new_name - ## Element-wise modulus. + ## ALIAS Modulus + Element-wise modulus. Arguments: - other: The value to modulo `self` against. If `other` is a column, the @@ -511,8 +518,7 @@ type Column new_name = Naming_Helpers.binary_operation_name "%" self other run_vectorized_binary_op_with_problem_handling self "%" fallback_fn=Nothing other new_name - ## ALIAS Power Columns - + ## ALIAS Power Element-wise raising to the power. Arguments: @@ -541,8 +547,7 @@ type Column Value_Type_Helpers.check_binary_numeric_op self other <| run_vectorized_binary_op self '^' fallback_fn=Nothing other - ## ALIAS AND Columns - + ## ALIAS And Element-wise boolean conjunction. Arguments: @@ -572,7 +577,7 @@ type Column Value_Type_Helpers.check_binary_boolean_op self other <| run_vectorized_binary_op self "&&" fallback_fn=Nothing other - ## ALIAS OR Columns + ## ALIAS Or Element-wise boolean disjunction. From efd3d6ac3de03ea7fc8f1b4f7ba7d252e81992f3 Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Wed, 31 May 2023 14:11:20 +0100 Subject: [PATCH 12/25] Remove legacy default_widget for Filter_Condition. Use fully qualified name for Encoding. --- .../Base/0.0.0-dev/src/Data/Filter_Condition.enso | 9 --------- .../Standard/Base/0.0.0-dev/src/Data/Text/Encoding.enso | 4 +++- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Filter_Condition.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Filter_Condition.enso index 75a0b7d48ce7..f81ffa50b9af 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Filter_Condition.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Filter_Condition.enso @@ -231,15 +231,6 @@ type Filter_Condition Not_In values -> "is not in " + values.to_display_text "Filter Condition: " + condition - ## PRIVATE - Gets a widget set up for a Filter_Condition. - default_widget : Widget - default_widget = - names = ["Equal", "Not Equal", "Is In", "Not In", "Is True", "Is False", "Is Nothing", "Not Nothing", "Is Empty", "Not Empty", "Less", "Equal Or Less", "Greater", "Equal Or Greater", "Between", "Starts With", "Ends With", "Contains", "Not Contains", "Like", "Not Like"] - values = ["(Filter_Condition.Equal)", "(Filter_Condition.Not_Equal)", "(Filter_Condition.Is_In)", "(Filter_Condition.Not_In)", "Filter_Condition.Is_True", "Filter_Condition.Is_False", "Filter_Condition.Is_Nothing", "Filter_Condition.Not_Nothing", "Filter_Condition.Is_Empty", "Filter_Condition.Not_Empty", "(Filter_Condition.Less)", "(Filter_Condition.Equal_Or_Less)", "(Filter_Condition.Greater)", "(Filter_Condition.Equal_Or_Greater)", "(Filter_Condition.Between)", "(Filter_Condition.Starts_With)", "(Filter_Condition.Ends_With)", "(Filter_Condition.Contains)", "(Filter_Condition.Not_Contains)", "(Filter_Condition.Like)", "(Filter_Condition.Not_Like)"] - options = names.zip values . map p-> Option p.first p.second - Single_Choice values=options display=Display.Always - ## PRIVATE sql_like_to_regex sql_pattern = regex_pattern = Regex_Utils.sql_like_pattern_to_regex sql_pattern diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Encoding.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Encoding.enso index 17da232ec287..027d44acef90 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Encoding.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Encoding.enso @@ -1,6 +1,7 @@ import project.Data.Text.Text import project.Data.Vector.Vector import project.Error.Error +import project.Meta import project.Panic.Panic import project.Errors.Encoding_Error.Encoding_Error import project.Errors.Illegal_Argument.Illegal_Argument @@ -20,7 +21,8 @@ type Encoding Gets the default drop down option for this encoding. default_widget : Widget default_widget = - values = [Option "UTF-8" "Encoding.utf_8", Option "ASCII" "Encoding.ascii", Option "UTF-16LE" "Encoding.utf_16_le", Option "UTF-16BE" "Encoding.utf_16_be", Option "UTF-32LE" "Encoding.utf_32_le", Option "UTF-32BE" "Encoding.utf_32_be", Option "Windows-1250" "Encoding.windows_1250", Option "Windows-1251" "Encoding.windows_1251", Option "Windows-1252" "Encoding.windows_1252", Option "Windows-1253" "Encoding.windows_1253", Option "Windows-1254" "Encoding.windows_1254", Option "Windows-1255" "Encoding.windows_1255", Option "Windows-1256" "Encoding.windows_1256", Option "Windows-1257" "Encoding.windows_1257", Option "Windows-1258" "Encoding.windows_1258"] + fqn = Meta.get_qualified_type_name Encoding + values = [Option "UTF-8" fqn+".utf_8", Option "ASCII" fqn+".ascii", Option "UTF-16LE" fqn+".utf_16_le", Option "UTF-16BE" fqn+".utf_16_be", Option "UTF-32LE" fqn+".utf_32_le", Option "UTF-32BE" fqn+".utf_32_be", Option "Windows-1250" fqn+".windows_1250", Option "Windows-1251" fqn+".windows_1251", Option "Windows-1252" fqn+".windows_1252", Option "Windows-1253" fqn+".windows_1253", Option "Windows-1254" fqn+".windows_1254", Option "Windows-1255" fqn+".windows_1255", Option "Windows-1256" fqn+".windows_1256", Option "Windows-1257" fqn+".windows_1257", Option "Windows-1258" fqn+".windows_1258"] Single_Choice values=values display=Display.When_Modified ## PRIVATE From 8ecc91d9dafaa43b1ab501061febda1f3e44063a Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Wed, 31 May 2023 17:15:26 +0100 Subject: [PATCH 13/25] Use fully qualified name for Locale dropdowns. Use fully qualified names for File_Format dropdowns. Use fully qualified names for Report_Unmatched dropdowns. Use fully qualified names for aggregates and parse type dropdowns. --- .../Base/0.0.0-dev/src/Data/Locale.enso | 3 +- .../0.0.0-dev/src/System/File_Format.enso | 6 +-- .../Database/0.0.0-dev/src/Data/Table.enso | 2 +- .../Postgres/Postgres_Connection.enso | 2 +- .../Internal/SQLite/SQLite_Connection.enso | 2 +- .../Table/0.0.0-dev/src/Data/Table.enso | 2 +- .../src/Internal/Widget_Helpers.enso | 50 +++++++++++-------- 7 files changed, 37 insertions(+), 30 deletions(-) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Locale.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Locale.enso index be1d739a8726..a16b9317bb27 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Locale.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Locale.enso @@ -445,5 +445,6 @@ type Locale widget_options : Vector Option widget_options = Locale.predefined_locale_fields.map field_name-> display_string = field_name.replace '_' ' ' . to_case (if field_name.length == 2 then Case.Upper else Case.Title) - code_string = "Locale." + field_name + fqn = Meta.get_qualified_type_name Locale + code_string = fqn + "." + field_name Option display_string code_string diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File_Format.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File_Format.enso index 79f4f656eed0..4d81665fd0eb 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File_Format.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File_Format.enso @@ -90,11 +90,11 @@ type File_Format Create the constructor code for a File_Format type. constructor_code : Any -> Text constructor_code type_obj = - type_name = Meta.get_simple_type_name type_obj + type_name = Meta.get_qualified_type_name type_obj ctors = Meta.meta type_obj . constructors is_singleton_type = ctors.length == 0 if is_singleton_type then type_name else - "(" + type_name + "." + ctors.first.name + ")" + type_name + "." + ctors.first.name ## PRIVATE default_widget : Widget @@ -208,7 +208,7 @@ type JSON_Format Implements the `Data.parse` for this `File_Format` read_web : Response -> Any read_web self response = - response.body.parse_json + response.body.decode_as_json ## A setting to infer the default behaviour of some option. type Infer diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso index 177bbc643e4a..1cf1a55f969e 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso @@ -1062,7 +1062,7 @@ type Table defined nor any ordering was specified explicitly by the user, the order of columns is undefined and the operation will fail, reporting a `Undefined_Column_Order` problem and returning an empty table. - @keep_unmatched (make_single_choice [["True", "True"], ["False", "False"], ["Report", "Report_Unmatched"]]) + @keep_unmatched (make_single_choice [["True", "Boolean.True"], ["False", "Boolean.False"], ["Report", Meta.get_qualified_type_name Report_Unmatched]]) zip : Table -> Boolean | Report_Unmatched -> Text -> Problem_Behavior -> Table zip self right keep_unmatched=Report_Unmatched right_prefix="Right " on_problems=Report_Warning = _ = [right, keep_unmatched, right_prefix, on_problems] diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Connection.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Connection.enso index 3c21c341e277..a91855346232 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Connection.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Connection.enso @@ -72,7 +72,7 @@ type Postgres_Connection Arguments: - schema: The name of the schema to connect to. - @schema (self-> Single_Choice display=Display.Always values=(self.schemas . map s-> Option s s.pretty)) + @schema make_schema_selector set_schema : Text -> Connection ! SQL_Error set_schema self schema = if schema == self.schema then self else diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Connection.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Connection.enso index c10f17d79939..7f638d34c260 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Connection.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Connection.enso @@ -66,7 +66,7 @@ type SQLite_Connection Arguments: - schema: The name of the schema to connect to. - @schema (Single_Choice display=Display.Always values=[Option 'Nothing']) + @schema make_schema_selector set_schema : Text -> Connection ! SQL_Error set_schema self schema = if schema == self.schema then self else 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 953e75e819b3..a9685ccb48c8 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 @@ -1529,7 +1529,7 @@ type Table defined nor any ordering was specified explicitly by the user, the order of columns is undefined and the operation will fail, reporting a `Undefined_Column_Order` problem and returning an empty table. - @keep_unmatched (make_single_choice [["True", "True"], ["False", "False"], ["Report", "Report_Unmatched"]]) + @keep_unmatched (make_single_choice [["True", "Boolean.True"], ["False", "Boolean.False"], ["Report", Meta.get_qualified_type_name Report_Unmatched]]) zip : Table -> Boolean | Report_Unmatched -> Text -> Problem_Behavior -> Table zip self right keep_unmatched=Report_Unmatched right_prefix="Right " on_problems=Report_Warning = if check_table "right" right then diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso index 13260a611b3e..49edace495ac 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso @@ -7,6 +7,8 @@ from Standard.Base.Metadata.Choice import Option import Standard.Base.Metadata.Display import project.Data.Table.Table +import project.Data.Type.Value_Type.Auto +import project.Data.Type.Value_Type.Value_Type import project.Data.Aggregate_Column.Aggregate_Column import project.Internal.Parse_Values_Helper import project.Data.Table_Conversions @@ -16,37 +18,38 @@ import project.Data.Table_Conversions make_aggregate_column_selector : Table -> Display -> Boolean -> Widget make_aggregate_column_selector table display=Display.Always include_group_by=True = col_names_selector = make_column_name_selector table display=Display.Always - column_widget = Pair.new "column" col_names_selector + column_widget = ["column", col_names_selector] col_list_selector = make_column_name_vector_selector table display=Display.Always - group_by = if include_group_by then [Option "Group By" "(Aggregate_Column.Group_By)" [column_widget]] else [] - count = Option "Count" "Aggregate_Column.Count" - count_distinct = Option "Count Distinct" "(Aggregate_Column.Count_Distinct)" [Pair.new "columns" (col_list_selector)] - first = Option "First" "(Aggregate_Column.First)" [column_widget, Pair.new "order_by" (col_list_selector)] - last = Option "Last" "(Aggregate_Column.Last)" [column_widget, Pair.new "order_by" (col_list_selector)] + fqn = Meta.get_qualified_type_name Aggregate_Column + group_by = if include_group_by then [Option "Group By" fqn+".Group_By" [column_widget]] else [] + count = Option "Count" fqn+".Count" + count_distinct = Option "Count Distinct" fqn+".Count_Distinct" [["columns", col_list_selector]] + first = Option "First" fqn+".First" [column_widget, ["order_by" , col_list_selector]] + last = Option "Last" fqn+".Last" [column_widget, ["order_by" , col_list_selector]] - count_not_nothing = Option "Count Not Nothing" "(Aggregate_Column.Count_Not_Nothing)" [column_widget] - count_nothing = Option "Count Nothing" "(Aggregate_Column.Count_Nothing)" [column_widget] + count_not_nothing = Option "Count Not Nothing" fqn+".Count_Not_Nothing" [column_widget] + count_nothing = Option "Count Nothing" fqn+".Count_Nothing" [column_widget] ## Should be a list of Text columns only - count_not_empty = Option "Count Not Empty" "(Aggregate_Column.Count_Not_Empty)" [column_widget] - count_empty = Option "Count Empty" "(Aggregate_Column.Count_Empty)" [column_widget] - concatenate = Option "Concatenate" "(Aggregate_Column.Concatenate)" [column_widget] - shortest = Option "Shortest" "(Aggregate_Column.Shortest)" [column_widget] - longest = Option "Longest" "(Aggregate_Column.Longest)" [column_widget] + count_not_empty = Option "Count Not Empty" fqn+".Count_Not_Empty" [column_widget] + count_empty = Option "Count Empty" fqn+".Count_Empty" [column_widget] + concatenate = Option "Concatenate" fqn+".Concatenate" [column_widget] + shortest = Option "Shortest" fqn+".Shortest" [column_widget] + longest = Option "Longest" fqn+".Longest" [column_widget] ## Should be a list of Numeric columns only - sum = Option "Sum" "(Aggregate_Column.Sum)" [column_widget] - average = Option "Average" "(Aggregate_Column.Average)" [column_widget] - median = Option "Median" "(Aggregate_Column.Median)" [column_widget] - percentile = Option "Percentile" "(Aggregate_Column.Percentile)" [column_widget] - mode = Option "Mode" "(Aggregate_Column.Mode)" [column_widget] - standard_deviation = Option "Standard Deviation" "(Aggregate_Column.Standard_Deviation)" [column_widget] + sum = Option "Sum" fqn+".Sum" [column_widget] + average = Option "Average" fqn+".Average" [column_widget] + median = Option "Median" fqn+".Median" [column_widget] + percentile = Option "Percentile" fqn+".Percentile" [column_widget] + mode = Option "Mode" fqn+".Mode" [column_widget] + standard_deviation = Option "Standard Deviation" fqn+".Standard_Deviation" [column_widget] # Should be a list of comparable columns only - maximum = Option "Maximum" "(Aggregate_Column.Maximum)" [column_widget] - minimum = Option "Minimum" "(Aggregate_Column.Minimum)" [column_widget] + maximum = Option "Maximum" fqn+".Maximum" [column_widget] + minimum = Option "Minimum" fqn+".Minimum" [column_widget] Single_Choice display=display values=(group_by+[count, count_distinct, first, last, count_not_nothing, count_nothing, count_not_empty, count_empty, concatenate, shortest, longest, sum, average, median, percentile, mode, standard_deviation, maximum, minimum]) @@ -98,8 +101,11 @@ parse_type_selector include_auto=True = valid_parse_targets = Parse_Values_Helper.valid_parse_targets prefix = if include_auto then ['Auto'] else [] - choice = prefix + (valid_parse_targets.map t-> 'Value_Type.'+t) names = prefix + valid_parse_targets + + fqn = Meta.get_qualified_type_name Value_Type + choice = names.map n-> if n=='Auto' then (Meta.get_qualified_type_name Auto) else fqn+'.'+n + options = names.zip choice . map pair-> Option pair.first pair.second Single_Choice display=Display.Always values=options From eb4a6eac72564a3dc6c802853496c6fe48b5631b Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Wed, 31 May 2023 18:10:38 +0100 Subject: [PATCH 14/25] Adding decode to Response and Response_Body. --- .../lib/Standard/Base/0.0.0-dev/src/Data.enso | 7 +- .../0.0.0-dev/src/Network/HTTP/Response.enso | 68 +++++++++++++++++++ .../src/Network/HTTP/Response_Body.enso | 35 ++++++---- test/Tests/src/Network/Http_Spec.enso | 28 ++++---- 4 files changed, 106 insertions(+), 32 deletions(-) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso index e8954e661939..04be716d1003 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso @@ -162,12 +162,7 @@ fetch uri method=HTTP_Method.Get headers=[] parse=True = response = HTTP.new.request request if response.code.is_success.not then Error.throw (Request_Error.Error "Status Code" ("Request failed with status code: " + response.code.to_text + ". " + response.body.to_text)) else - response_headers = response.headers - content_type = response_headers.find if_missing=Nothing h-> "Content-Type".equals_ignore_case h.name - if (parse == False) || (content_type == Nothing) then response else - format = Auto_Detect.get_web_parser content_type.value uri - if format == Nothing then response else - format.read_web response + if parse then response.decode if_unsupported=response else response ## ALIAS Download, HTTP Get Fetches from the URI and returns the response, parsing the body if the diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso index 24865df1f9b6..be8d372bde1e 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso @@ -1,9 +1,19 @@ +import project.Any.Any +import project.Data.Boolean.Boolean import project.Data.Json.JS_Object +import project.Data.Numbers.Number +import project.Data.Text.Encoding.Encoding +import project.Data.Text.Extensions +import project.Data.Text.Text import project.Data.Vector.Vector +import project.Error.Error +import project.Nothing.Nothing import project.Network.HTTP.Header.Header import project.Network.HTTP.HTTP_Status_Code.HTTP_Status_Code import project.Network.HTTP.Response_Body.Response_Body +from project.System.File_Format import Auto_Detect, File_Format + polyglot java import org.enso.base.Http_Utils type Response @@ -30,6 +40,13 @@ type Response header_entries = Vector.from_polyglot_array (Http_Utils.get_headers self.internal_http_response.headers) header_entries.map e-> Header.new e.getKey e.getValue + ## Get the response content type. + content_type : Text | Nothing + content_type self = + response_headers = self.headers + content_type = response_headers.find if_missing=Nothing h-> "Content-Type".equals_ignore_case h.name + if content_type.is_nothing then Nothing else content_type.value + ## Get the response body. > Example @@ -54,6 +71,41 @@ type Response code : HTTP_Status_Code code self = HTTP_Status_Code.Value self.internal_http_response.statusCode + ## ALIAS Parse + Uses the format to decode the body. + If using `Auto_Detect`, the content-type will be used to determine the + format. + @format File_Format.default_widget + decode : File_Format -> Any -> Any + decode self format=Auto_Detect ~if_unsupported=(Error.throw (Unsupported_Content_Type.Value self.content_type)) = + if format != Auto_Detect then format.read_web self else + content_type = self.content_type + format = if content_type.is_nothing then Nothing else + Auto_Detect.get_web_parser content_type (self.internal_http_response.uri.toString) + if format.is_nothing then if_unsupported else + format.value.read_web self + + ## ALIAS Parse as Text + Decodes the body to a Text value. + @encoding Encoding.default_widget + decode_as_text : Encoding -> Text + decode_as_text self encoding=Encoding.utf_8 = + self.body.decode_as_text encoding + + ## ALIAS Parse as JSON, Parse JSON + Decodes the body as JSON. + + > Example + Convert a response from JSON. + + import Standard.Examples + + example_to_text = Examples.get_geo_data.decode_as_json + @encoding Encoding.default_widget + decode_as_json : Encoding -> JS_Object | Boolean | Number | Nothing | Text | Vector + decode_as_json self encoding=Encoding.utf_8 = + self.decode_as_text encoding . parse_json + ## PRIVATE Convert to a JavaScript Object representing this Response. @@ -69,3 +121,19 @@ type Response type_pair = ["type", "Response"] cons_pair = ["constructor", "Value"] JS_Object.from_pairs [type_pair, cons_pair, ["headers", self.headers], ["body", self.body], ["code", self.code]] + +## PRIVATE +type Unsupported_Content_Type + ## PRIVATE + A type representing an unsupported content type. + + Arguments: + - content_type: The content type that is unsupported. + Value content_type + + ## PRIVATE + Convert the error to a human readable string. + to_display_text : Text + to_display_text self = case self.content_type of + Nothing -> "The response did not contain a content type." + _ : Text -> "The content type '" + self.content_type +"' cannot be automatically decoded." diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response_Body.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response_Body.enso index fa0b9281f164..e37490625e07 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response_Body.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response_Body.enso @@ -2,6 +2,7 @@ import project.Data.Boolean.Boolean import project.Data.Json.Json import project.Data.Json.JS_Object import project.Data.Numbers.Number +import project.Data.Text.Encoding.Encoding import project.Data.Text.Extensions import project.Data.Text.Text import project.Data.Vector.Vector @@ -18,10 +19,31 @@ type Response_Body - bytes: The body of the response as binary data. Value bytes + ## ALIAS Parse as Text + Decodes the body to a Text value. + @encoding Encoding.default_widget + decode_as_text : Encoding -> Text + decode_as_text self encoding=Encoding.utf_8 = + Text.from_bytes self.bytes encoding + + ## ALIAS Parse as JSON, Parse JSON + Decodes the body as JSON. + + > Example + Convert a response from JSON. + + import Standard.Examples + + example_to_text = Examples.get_geo_data.decode_as_json + @encoding Encoding.default_widget + decode_as_json : Encoding -> JS_Object | Boolean | Number | Nothing | Text | Vector + decode_as_json self encoding=Encoding.utf_8 = + self.decode_as_text encoding . parse_json + ## PRIVATE Convert response body to Text. to_text : Text - to_text self = Text.from_utf_8 self.bytes + to_text self = self.decode_as_text Encoding.utf_8 ## Write response body to a File. @@ -41,14 +63,3 @@ type Response_Body to_file self file = self.bytes.write_bytes file file - - ## Convert response body from JSON to the Enso data types. - - > Example - Convert a response from JSON. NOTE: This example makes a network request. - - import Standard.Examples - - example_to_text = Examples.get_geo_data.parse_json - parse_json : JS_Object | Boolean | Number | Nothing | Text | Vector - parse_json self = Json.parse self.to_text diff --git a/test/Tests/src/Network/Http_Spec.enso b/test/Tests/src/Network/Http_Spec.enso index 9ecd745275a1..88dd6391e5ff 100644 --- a/test/Tests/src/Network/Http_Spec.enso +++ b/test/Tests/src/Network/Http_Spec.enso @@ -55,7 +55,7 @@ spec = } res = HTTP.new.get url_get res.code.should_equal HTTP_Status_Code.ok - res.body.parse_json.should_equal expected_response + res.body.decode_as_json.should_equal expected_response Test.specify "should send Get request using module method" <| expected_response = Json.parse <| ''' { @@ -69,7 +69,7 @@ spec = } res = HTTP.new.get url_get res.code.should_equal HTTP_Status_Code.ok - res.body.parse_json.should_equal expected_response + res.body.decode_as_json.should_equal expected_response Test.specify "should fetch the body of a Get request" <| expected_response = Json.parse <| ''' @@ -83,7 +83,7 @@ spec = "args": {} } res = HTTP.fetch url_get - res.parse_json.should_equal expected_response + res.decode_as_json.should_equal expected_response Test.specify "should return error if the fetch method fails" <| HTTP.fetch "http://undefined_host" . should_fail_with Request_Error @@ -110,7 +110,7 @@ spec = body_empty = Request_Body.Empty res = HTTP.new.post url_post body_empty res.code.should_equal HTTP_Status_Code.ok - res.body.parse_json.should_equal expected_response + res.body.decode_as_json.should_equal expected_response Test.specify "should Post empty body using module method" <| expected_response = Json.parse <| ''' { @@ -129,7 +129,7 @@ spec = body_empty = Request_Body.Empty res = HTTP.new.post url_post body_empty res.code.should_equal HTTP_Status_Code.ok - res.body.parse_json.should_equal expected_response + res.body.decode_as_json.should_equal expected_response Test.specify "should Post text body" <| expected_response = Json.parse <| ''' { @@ -149,7 +149,7 @@ spec = body_text = Request_Body.Text "Hello World!" res = HTTP.new.post url_post body_text res.code.should_equal HTTP_Status_Code.ok - res.body.parse_json.should_equal expected_response + res.body.decode_as_json.should_equal expected_response Test.specify "should Post form text" <| expected_response = Json.parse <| ''' { @@ -169,7 +169,7 @@ spec = form_parts = [Form.text_field "key" "val"] res = HTTP.new.post_form url_post form_parts res.code.should_equal HTTP_Status_Code.ok - res.body.parse_json.should_equal expected_response + res.body.decode_as_json.should_equal expected_response Test.specify "should Post form text using module method" <| expected_response = Json.parse <| ''' { @@ -189,7 +189,7 @@ spec = form_parts = [Form.text_field "key" "val"] res = HTTP.new.post_form url_post form_parts res.code.should_equal HTTP_Status_Code.ok - res.body.parse_json.should_equal expected_response + res.body.decode_as_json.should_equal expected_response Test.specify "should Post form file" <| test_file = enso_project.data / "sample.txt" form_parts = [Form.text_field "key" "val", Form.file_field "sample" test_file] @@ -221,7 +221,7 @@ spec = json = '{"key":"val"}' res = HTTP.new.post_json url_post json res.code.should_equal HTTP_Status_Code.ok - res.body.parse_json.should_equal expected_response + res.body.decode_as_json.should_equal expected_response Test.specify "should Post Json using module method" <| expected_response = Json.parse <| ''' { @@ -243,7 +243,7 @@ spec = json = '{"key":"val"}' res = HTTP.new.post_json url_post json res.code.should_equal HTTP_Status_Code.ok - res.body.parse_json.should_equal expected_response + res.body.decode_as_json.should_equal expected_response Test.specify "should Post binary" <| expected_response = Json.parse <| ''' { @@ -263,7 +263,7 @@ spec = body_bytes = Request_Body.Bytes "Hello World!".utf_8 res = HTTP.new.post url_post body_bytes res.code.should_equal HTTP_Status_Code.ok - res.body.parse_json.should_equal expected_response + res.body.decode_as_json.should_equal expected_response Test.specify "should create and send Get request" <| expected_response = Json.parse <| ''' @@ -279,7 +279,7 @@ spec = req = Request.new HTTP_Method.Get url_get res = HTTP.new.request req res.code.should_equal HTTP_Status_Code.ok - res.body.parse_json.should_equal expected_response + res.body.decode_as_json.should_equal expected_response Test.specify "should create and send Post request with json body" <| expected_response = Json.parse <| ''' { @@ -303,7 +303,7 @@ spec = req_with_body = req.with_json json_body res = HTTP.new.request req_with_body res.code.should_equal HTTP_Status_Code.ok - res.body.parse_json.should_equal expected_response + res.body.decode_as_json.should_equal expected_response Test.specify "should create and send Post request with json text" <| expected_response = Json.parse <| ''' { @@ -328,6 +328,6 @@ spec = req_with_body = req.with_json json_text res = HTTP.new.request req_with_body res.code.should_equal HTTP_Status_Code.ok - res.body.parse_json.should_equal expected_response + res.body.decode_as_json.should_equal expected_response main = Test_Suite.run_main spec From 8351227c852e43f048d0f6924caf864a0542e134 Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Thu, 1 Jun 2023 16:45:51 +0100 Subject: [PATCH 15/25] Align find_all with C#/python approach. --- .../Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso | 5 +++-- test/Tests/src/Data/Text/Regex_Spec.enso | 9 +++++++++ test/Tests/src/Data/Text_Spec.enso | 6 ++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso index 1b4b36004ced..23644aafe28f 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso @@ -353,7 +353,7 @@ type Match_Iterator Also returns the next iterator, if there was a match. next : Match_Iterator_Value next self = - regex_result = if self.cursor >= self.input.char_vector.length then Nothing else self.pattern.internal_regex_object.exec self.input self.cursor + regex_result = if self.cursor > self.input.char_vector.length then Nothing else self.pattern.internal_regex_object.exec self.input self.cursor case regex_result.is_nothing.not && regex_result.isMatch of False -> filler_range = Range.new self.cursor (Text_Utils.char_length self.input) @@ -364,7 +364,8 @@ type Match_Iterator filler_range = Range.new self.cursor match_start filler_span = (Utf_16_Span.Value filler_range self.input) match = Match.Value self.pattern regex_result self.input - next_cursor = match.utf_16_end 0 + ## Handle edge case where match is 0 length + next_cursor = (self.cursor + 1).max (match.utf_16_end 0) next_iterator = Match_Iterator.Value self.pattern self.input next_cursor Match_Iterator_Value.Next filler_span match next_iterator diff --git a/test/Tests/src/Data/Text/Regex_Spec.enso b/test/Tests/src/Data/Text/Regex_Spec.enso index 8cf282610e38..53f9af3e79d9 100644 --- a/test/Tests/src/Data/Text/Regex_Spec.enso +++ b/test/Tests/src/Data/Text/Regex_Spec.enso @@ -141,6 +141,15 @@ spec = match = pattern.find_all input match . should_equal [] + Test.specify "should handle matching empty matches" <| + pattern = Regex.compile ".*" + pattern.find_all "Hello World" . should_equal ["Hello World", ""] + pattern.find_all "" . should_equal [""] + + pattern_2 = Regex.compile ".*(?=.)" + pattern_2.find_all "Hello World" . should_equal ["Hello Worl", ""] + pattern_2.find_all "" . should_equal [] + Test.specify "should correctly handle edge cases where one-letter matches happen at the end of the word" <| Regex.compile "(a+|1+)" . find_all "a1a1" . should_equal ["a", "1", "a", "1"] Regex.compile "([a]+|[1]+)" . find_all "a1a1" . should_equal ["a", "1", "a", "1"] diff --git a/test/Tests/src/Data/Text_Spec.enso b/test/Tests/src/Data/Text_Spec.enso index f07b7c751c6b..caeb708eec36 100644 --- a/test/Tests/src/Data/Text_Spec.enso +++ b/test/Tests/src/Data/Text_Spec.enso @@ -1279,6 +1279,12 @@ spec = "Hello World!".find_all ".o" . map (match-> match.span 0) . should_equal [Span.Value (3.up_to 5) "Hello World!", Span.Value (6.up_to 8) "Hello World!"] "foobar".find "BAR" Case_Sensitivity.Insensitive . span 0 . should_equal (Span.Value (3.up_to 6) "foobar") + Test.specify "find_all should handle 0 length matches" <| + "Hello World".find_all ".*" . map (_.text) . should_equal ["Hello World", ""] + "".find_all ".*" . map (_.text) . should_equal [""] + "Hello World".find_all ".*(?=.)" . map (_.text) . should_equal ["Hello Worl", ""] + "".find_all ".*(?=.)" . map (_.text) . should_equal [] + Test.specify "should handle accents and other multi-point graphemes" <| accents = 'a\u{301}e\u{301}o\u{301}he\u{301}h' From c38e6b79dba8464e87c7e5ab728347ea2721e358 Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Thu, 1 Jun 2023 18:08:16 +0100 Subject: [PATCH 16/25] Remove context imports which aren't used. New test for disabled writing of tables. --- .../Table_Tests/src/Database/SQLite_Spec.enso | 1 - test/Table_Tests/src/IO/Csv_Spec.enso | 1 - .../src/IO/Delimited_Read_Spec.enso | 1 - .../src/IO/Delimited_Write_Spec.enso | 1 - test/Table_Tests/src/IO/Excel_Spec.enso | 1 - test/Table_Tests/src/IO/Formats_Spec.enso | 31 +++++++++++++++++++ .../System/Reporting_Stream_Decoder_Spec.enso | 1 - .../System/Reporting_Stream_Encoder_Spec.enso | 1 - test/Visualization_Tests/src/Table_Spec.enso | 1 - 9 files changed, 31 insertions(+), 8 deletions(-) diff --git a/test/Table_Tests/src/Database/SQLite_Spec.enso b/test/Table_Tests/src/Database/SQLite_Spec.enso index 615f9f4deac0..4621dcce289f 100644 --- a/test/Table_Tests/src/Database/SQLite_Spec.enso +++ b/test/Table_Tests/src/Database/SQLite_Spec.enso @@ -1,6 +1,5 @@ from Standard.Base import all import Standard.Base.Runtime.Ref.Ref -import Standard.Base.Runtime.Context import Standard.Base.Errors.File_Error.File_Error import Standard.Table.Data.Type.Value_Type.Bits diff --git a/test/Table_Tests/src/IO/Csv_Spec.enso b/test/Table_Tests/src/IO/Csv_Spec.enso index 56b8f0377d14..78bc0aab320f 100644 --- a/test/Table_Tests/src/IO/Csv_Spec.enso +++ b/test/Table_Tests/src/IO/Csv_Spec.enso @@ -1,5 +1,4 @@ from Standard.Base import all -import Standard.Base.Runtime.Context from Standard.Table import Table, Column, Delimited import Standard.Table.Main as Table_Module diff --git a/test/Table_Tests/src/IO/Delimited_Read_Spec.enso b/test/Table_Tests/src/IO/Delimited_Read_Spec.enso index 6237f164c444..a32002b94598 100644 --- a/test/Table_Tests/src/IO/Delimited_Read_Spec.enso +++ b/test/Table_Tests/src/IO/Delimited_Read_Spec.enso @@ -2,7 +2,6 @@ from Standard.Base import all import Standard.Base.Errors.Encoding_Error.Encoding_Error import Standard.Base.Errors.File_Error.File_Error import Standard.Base.Errors.Illegal_Argument.Illegal_Argument -import Standard.Base.Runtime.Context from Standard.Table import Table, Column, Data_Formatter, Quote_Style, Delimited import Standard.Table.Data.Table_Conversions diff --git a/test/Table_Tests/src/IO/Delimited_Write_Spec.enso b/test/Table_Tests/src/IO/Delimited_Write_Spec.enso index 3f57f964d4ba..a732b73da59e 100644 --- a/test/Table_Tests/src/IO/Delimited_Write_Spec.enso +++ b/test/Table_Tests/src/IO/Delimited_Write_Spec.enso @@ -2,7 +2,6 @@ from Standard.Base import all import Standard.Base.Errors.Encoding_Error.Encoding_Error import Standard.Base.Errors.File_Error.File_Error import Standard.Base.Errors.Illegal_Argument.Illegal_Argument -import Standard.Base.Runtime.Context from Standard.Table import Table, Column, Data_Formatter, Quote_Style, Match_Columns, Delimited from Standard.Table.Errors import all diff --git a/test/Table_Tests/src/IO/Excel_Spec.enso b/test/Table_Tests/src/IO/Excel_Spec.enso index 239b449363c6..5e209a763cf0 100644 --- a/test/Table_Tests/src/IO/Excel_Spec.enso +++ b/test/Table_Tests/src/IO/Excel_Spec.enso @@ -1,7 +1,6 @@ from Standard.Base import all import Standard.Base.Errors.File_Error.File_Error import Standard.Base.Errors.Illegal_Argument.Illegal_Argument -import Standard.Base.Runtime.Context from Standard.Table import Table, Match_Columns, Excel, Excel_Range, Data_Formatter, Sheet_Names, Range_Names, Worksheet, Cell_Range, Delimited, Excel_Workbook diff --git a/test/Table_Tests/src/IO/Formats_Spec.enso b/test/Table_Tests/src/IO/Formats_Spec.enso index 8164031e31de..f4479d654366 100644 --- a/test/Table_Tests/src/IO/Formats_Spec.enso +++ b/test/Table_Tests/src/IO/Formats_Spec.enso @@ -79,4 +79,35 @@ spec = Test.group 'Various File Format support on Table' <| r2.catch.should_be_a File_Error.Unsupported_Output_Type r2.catch.format . should_equal my_format + write_test extension = + f = transient / ("big." + extension) + f.delete_if_exists + f_bak = transient / ("big." + extension + ".bak") + f_bak.delete_if_exists + + big_table = Table.new [["a", 1.up_to 2000 . to_vector]] + big_table.write f + + new_table = Table.new [["a", 2000.up_to 4000 . to_vector]] + r = Context.Output.with_disabled <| + s = new_table.write f + s.exists.should_be_true + + r_data = s.read + r_data.row_count . should_equal 1000 + s + + f_bak.exists.should_be_false + f.read.row_count . should_equal 1999 + + f.delete_if_exists + f_bak.delete_if_exists + r.delete_if_exists + + Test.specify "should write to a temporary CSV file part of the data if context disabled" <| + write_test "csv" + + Test.specify "should write to a temporary JSON file part of the data if context disabled" <| + write_test "json" + main = Test_Suite.run_main spec diff --git a/test/Tests/src/System/Reporting_Stream_Decoder_Spec.enso b/test/Tests/src/System/Reporting_Stream_Decoder_Spec.enso index a9a0e832ff41..c5b45c8f8454 100644 --- a/test/Tests/src/System/Reporting_Stream_Decoder_Spec.enso +++ b/test/Tests/src/System/Reporting_Stream_Decoder_Spec.enso @@ -1,6 +1,5 @@ from Standard.Base import all import Standard.Base.Errors.Encoding_Error.Encoding_Error -import Standard.Base.Runtime.Context polyglot java import java.nio.CharBuffer diff --git a/test/Tests/src/System/Reporting_Stream_Encoder_Spec.enso b/test/Tests/src/System/Reporting_Stream_Encoder_Spec.enso index 948e4e6607d2..42cee53b6e34 100644 --- a/test/Tests/src/System/Reporting_Stream_Encoder_Spec.enso +++ b/test/Tests/src/System/Reporting_Stream_Encoder_Spec.enso @@ -1,7 +1,6 @@ from Standard.Base import all import Standard.Base.Errors.Encoding_Error.Encoding_Error import Standard.Base.Errors.Illegal_State.Illegal_State -import Standard.Base.Runtime.Context polyglot java import org.enso.base.Encoding_Utils polyglot java import java.nio.CharBuffer diff --git a/test/Visualization_Tests/src/Table_Spec.enso b/test/Visualization_Tests/src/Table_Spec.enso index eb74669c2a84..46960772b92c 100644 --- a/test/Visualization_Tests/src/Table_Spec.enso +++ b/test/Visualization_Tests/src/Table_Spec.enso @@ -1,5 +1,4 @@ from Standard.Base import all -import Standard.Base.Runtime.Context from Standard.Table import Table, Aggregate_Column, Value_Type From 5edd3b21842992719941e3998cdee94f5a625aad Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Thu, 1 Jun 2023 18:22:26 +0100 Subject: [PATCH 17/25] CHANGELOG. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 862d1a96c44a..9293ecfbf24d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -471,6 +471,7 @@ - [Implemented the `cast` operation for `Table` and `Column`.][6711] - [Added `.round` and `.int` to `Integer` and `Decimal`.][6743] - [Added `.round`, `.truncate`, `.ceil`, and `.floor` to `Column`.][6817] +- [Added execution control to `Table.write` and various bug fixes.][6835] [debug-shortcuts]: https://github.com/enso-org/enso/blob/develop/app/gui/docs/product/shortcuts.md#debug @@ -684,6 +685,7 @@ [6711]: https://github.com/enso-org/enso/pull/6711 [6743]: https://github.com/enso-org/enso/pull/6743 [6817]: https://github.com/enso-org/enso/pull/6817 +[6835]: https://github.com/enso-org/enso/pull/6835 #### Enso Compiler From f4496da161e63aef0602a8bc86f7642f8c3c8e9f Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Thu, 1 Jun 2023 18:26:39 +0100 Subject: [PATCH 18/25] Fix Formats test. --- test/Table_Tests/src/IO/Formats_Spec.enso | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/Table_Tests/src/IO/Formats_Spec.enso b/test/Table_Tests/src/IO/Formats_Spec.enso index f4479d654366..d539d3590ddb 100644 --- a/test/Table_Tests/src/IO/Formats_Spec.enso +++ b/test/Table_Tests/src/IO/Formats_Spec.enso @@ -94,11 +94,16 @@ spec = Test.group 'Various File Format support on Table' <| s.exists.should_be_true r_data = s.read - r_data.row_count . should_equal 1000 + row_count = if r_data . is_a Table then r_data.row_count else r_data.length + row_count . should_equal 1000 s f_bak.exists.should_be_false - f.read.row_count . should_equal 1999 + + f.exists.should_be_true + f_data = f.read + f_row_count = if f_data . is_a Table then f_data.row_count else f_data.length + f_row_count . should_equal 1999 f.delete_if_exists f_bak.delete_if_exists From fc87eeb68d065803aa215036591ced5d16e6d1df Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Thu, 1 Jun 2023 18:42:17 +0100 Subject: [PATCH 19/25] Add Modulo alias. Use `Math.max`. --- .../lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso | 4 ++-- .../Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso | 3 ++- .../lib/Standard/Database/0.0.0-dev/src/Data/Column.enso | 2 +- .../lib/Standard/Table/0.0.0-dev/src/Data/Column.enso | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso index 0c8bdbf636b4..b7b824c3280e 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso @@ -431,7 +431,7 @@ type Decimal / : Number -> Number / self that = @Builtin_Method "Decimal./" - ## ALIAS Modulus + ## ALIAS Modulus, Modulo Computes the remainder when dividing this by that. Arguments: @@ -750,7 +750,7 @@ type Integer / : Number -> Number / self that = @Builtin_Method "Integer./" - ## ALIAS Modulus + ## ALIAS Modulus, Modulo Computes the remainder when dividing this by that. Arguments: diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso index 23644aafe28f..cb688590a7f3 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Text/Regex/Pattern.enso @@ -16,6 +16,7 @@ import project.Data.Vector.Vector import project.Errors.Common.Type_Error import project.Error.Error import project.Errors.Illegal_Argument.Illegal_Argument +import project.Math import project.Meta import project.Nothing.Nothing import project.Polyglot.Polyglot @@ -365,7 +366,7 @@ type Match_Iterator filler_span = (Utf_16_Span.Value filler_range self.input) match = Match.Value self.pattern regex_result self.input ## Handle edge case where match is 0 length - next_cursor = (self.cursor + 1).max (match.utf_16_end 0) + next_cursor = Math.max (self.cursor + 1) (match.utf_16_end 0) next_iterator = Match_Iterator.Value self.pattern self.input next_cursor Match_Iterator_Value.Next filler_span match next_iterator diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso index 2c839ba3eb56..2e72f3bd95b7 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Column.enso @@ -424,7 +424,7 @@ type Column Value_Type_Helpers.check_binary_numeric_op self other <| self.make_binary_op "/" other - ## ALIAS Modulus + ## ALIAS Modulus, Modulo Element-wise modulus. Arguments: diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso index 2494f9d6ad39..d6e14a8adf3d 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso @@ -483,7 +483,7 @@ type Column new_name = Naming_Helpers.binary_operation_name "/" self other run_vectorized_binary_op_with_problem_handling self "/" fallback_fn=Nothing other new_name - ## ALIAS Modulus + ## ALIAS Modulus, Modulo Element-wise modulus. Arguments: From 7b377dc0d2c25cc4abcca7aea29477bd58bcf640 Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Thu, 1 Jun 2023 18:52:00 +0100 Subject: [PATCH 20/25] Use Java Optional for Content-Type. Make Response_Body to_text more stable. Add local variable for copying to temp file. --- .../Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso | 7 +++---- .../Base/0.0.0-dev/src/Network/HTTP/Response_Body.enso | 2 +- .../Base/0.0.0-dev/src/System/File/Write_Extensions.enso | 3 ++- .../lib/Standard/Table/0.0.0-dev/src/Data/Table.enso | 3 ++- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso index be8d372bde1e..c86b1fb7847e 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso @@ -43,9 +43,8 @@ type Response ## Get the response content type. content_type : Text | Nothing content_type self = - response_headers = self.headers - content_type = response_headers.find if_missing=Nothing h-> "Content-Type".equals_ignore_case h.name - if content_type.is_nothing then Nothing else content_type.value + content_type_optional = self.internal_http_response.headers.firstValue "Content-Type" + if content_type_optional.isPresent then content_type_optional.get else Nothing ## Get the response body. @@ -129,7 +128,7 @@ type Unsupported_Content_Type Arguments: - content_type: The content type that is unsupported. - Value content_type + Value (content_type : Text | Nothing) ## PRIVATE Convert the error to a human readable string. diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response_Body.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response_Body.enso index e37490625e07..4fef76ce4882 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response_Body.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response_Body.enso @@ -43,7 +43,7 @@ type Response_Body ## PRIVATE Convert response body to Text. to_text : Text - to_text self = self.decode_as_text Encoding.utf_8 + to_text self = "Response_Body [" ++ self.bytes.length.to_text ++ " bytes]" ## Write response body to a File. diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso index a95d16fb08ef..14b09fbcd359 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File/Write_Extensions.enso @@ -56,7 +56,8 @@ Text.write self path encoding=Encoding.utf_8 on_existing_file=Existing_File_Beha actual = File.new path effective_existing_behaviour = on_existing_file.get_effective_behavior actual file = if Context.Output.is_enabled then actual else - actual.create_dry_run_file copy_original=on_existing_file==Existing_File_Behavior.Append + should_copy_file = on_existing_file==Existing_File_Behavior.Append + actual.create_dry_run_file copy_original=should_copy_file Context.Output.with_enabled <| r = effective_existing_behaviour.write file stream-> 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 a9685ccb48c8..ad224d106d9a 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 @@ -1959,7 +1959,8 @@ type Table 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 - file.create_dry_run_file copy_original=on_existing_file==Existing_File_Behavior.Append + should_copy_file = on_existing_file==Existing_File_Behavior.Append + file.create_dry_run_file copy_original=should_copy_file to_write = if Context.Output.is_enabled then self else self.take 1000 Context.Output.with_enabled <| From 9c9b51bec8bd9633f89c2cece89f052bdcec1f80 Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Thu, 1 Jun 2023 19:07:12 +0100 Subject: [PATCH 21/25] Rename to types_vector. --- .../Database/0.0.0-dev/src/Connection/Connection.enso | 4 ++-- .../Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Connection.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Connection.enso index 9b5ce9a7648a..371acdce05bf 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Connection.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Connection.enso @@ -122,13 +122,13 @@ type Connection @schema make_schema_selector tables : Text -> Text -> Text -> Vector Text | Text | Nothing -> Boolean -> Materialized_Table tables self name_like=Nothing database=self.database schema=Nothing types=self.dialect.default_table_types all_fields=False = - types_array = case types of + types_vector = case types of Nothing -> Nothing _ : Vector -> types _ -> [types] name_map = Map.from_vector [["TABLE_CAT", "Database"], ["TABLE_SCHEM", "Schema"], ["TABLE_NAME", "Name"], ["TABLE_TYPE", "Type"], ["REMARKS", "Description"], ["TYPE_CAT", "Type Database"], ["TYPE_SCHEM", "Type Schema"], ["TYPE_NAME", "Type Name"]] self.jdbc_connection.with_metadata metadata-> - table = Managed_Resource.bracket (metadata.getTables database schema name_like types_array) .close result_set-> + table = Managed_Resource.bracket (metadata.getTables database schema name_like types_vector) .close result_set-> result_set_to_table result_set self.dialect.make_column_fetcher_for_type renamed = table.rename_columns name_map if all_fields then renamed else diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso index e84078913a3a..38fc2eeba590 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Excel/Excel_Workbook.enso @@ -103,15 +103,15 @@ type Excel_Workbook @types (self-> Single_Choice values=(self.table_types.map t-> Option t t.pretty)) tables : Text -> Text -> Text -> Vector -> Boolean -> Table tables self name_like=Nothing database=self.database schema=self.schema types=Nothing all_fields=False = - types_array = case types of + types_vector = case types of Nothing -> Nothing _ : Vector -> types _ -> [types] _ = [all_fields] rows = if schema != Nothing then [] else - sheets = if types_array.is_nothing || types_array.contains "Worksheet" then self.sheet_names.map s-> [s, 'Worksheet', database, Nothing] else [] - ranges = if types_array.is_nothing || types_array.contains "Named Range" then self.named_ranges.map r-> [r, 'Named Range', database, Nothing] else [] + sheets = if types_vector.is_nothing || types_vector.contains "Worksheet" then self.sheet_names.map s-> [s, 'Worksheet', database, Nothing] else [] + ranges = if types_vector.is_nothing || types_vector.contains "Named Range" then self.named_ranges.map r-> [r, 'Named Range', database, Nothing] else [] sheets + ranges filtered = if name_like == Nothing then rows else From 5aa8a8c3025c877ba954d9c2a62e08e653818509 Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Thu, 1 Jun 2023 20:38:25 +0100 Subject: [PATCH 22/25] Fix issues with decode. --- .../0.0.0-dev/src/Network/HTTP/Response.enso | 44 ++++++++++++++----- .../src/Network/HTTP/Response_Body.enso | 2 +- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso index c86b1fb7847e..c719860f8068 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso @@ -7,12 +7,19 @@ import project.Data.Text.Extensions import project.Data.Text.Text import project.Data.Vector.Vector import project.Error.Error +import project.Errors.Illegal_Argument.Illegal_Argument +import project.Meta import project.Nothing.Nothing import project.Network.HTTP.Header.Header import project.Network.HTTP.HTTP_Status_Code.HTTP_Status_Code import project.Network.HTTP.Response_Body.Response_Body -from project.System.File_Format import Auto_Detect, File_Format +from project.System.File_Format import Auto_Detect, File_Format, format_types + +import project.Metadata.Widget +from project.Metadata.Widget import Single_Choice +from project.Metadata.Choice import Option +import project.Metadata.Display polyglot java import org.enso.base.Http_Utils @@ -74,15 +81,20 @@ type Response Uses the format to decode the body. If using `Auto_Detect`, the content-type will be used to determine the format. - @format File_Format.default_widget + @format decode_format_selector decode : File_Format -> Any -> Any - decode self format=Auto_Detect ~if_unsupported=(Error.throw (Unsupported_Content_Type.Value self.content_type)) = - if format != Auto_Detect then format.read_web self else - content_type = self.content_type - format = if content_type.is_nothing then Nothing else - Auto_Detect.get_web_parser content_type (self.internal_http_response.uri.toString) - if format.is_nothing then if_unsupported else - format.value.read_web self + decode self format=Auto_Detect ~if_unsupported=(Error.throw (Unsupported_Content_Type.Error self.content_type)) = + case format of + Auto_Detect -> + content_type = self.content_type + format = if content_type.is_nothing then Nothing else + Auto_Detect.get_web_parser content_type (self.internal_http_response.uri.toString) + if format.is_nothing then if_unsupported else + format.value.read_web self + _ -> + type_obj = Meta.type_of format + if can_decode type_obj then format.read_web self else + Error.throw (Illegal_Argument.Error type_obj.to_text+" cannot be used to decode from the web.") ## ALIAS Parse as Text Decodes the body to a Text value. @@ -128,7 +140,7 @@ type Unsupported_Content_Type Arguments: - content_type: The content type that is unsupported. - Value (content_type : Text | Nothing) + Error (content_type : Text | Nothing) ## PRIVATE Convert the error to a human readable string. @@ -136,3 +148,15 @@ type Unsupported_Content_Type to_display_text self = case self.content_type of Nothing -> "The response did not contain a content type." _ : Text -> "The content type '" + self.content_type +"' cannot be automatically decoded." + +## PRIVATE +can_decode : File_Format -> Boolean +can_decode type = Meta.meta type . methods . contains "read_web" + +## PRIVATE + Selector for decoding from the web. +decode_format_selector : Widget +decode_format_selector = + all_types = [Auto_Detect] + (format_types.filter can_decode) + make_name type_obj = type_obj.to_text.replace "_Format" "" . replace "_" " " + Single_Choice display=Display.Always values=(all_types.map n->(Option (make_name n) (File_Format.constructor_code n))) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response_Body.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response_Body.enso index 4fef76ce4882..2059040fbc87 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response_Body.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response_Body.enso @@ -43,7 +43,7 @@ type Response_Body ## PRIVATE Convert response body to Text. to_text : Text - to_text self = "Response_Body [" ++ self.bytes.length.to_text ++ " bytes]" + to_text self = "Response_Body [" + self.bytes.length.to_text + " bytes]" ## Write response body to a File. From 7a9947cdc59a33dbb4df69810b685ff0701abab7 Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Thu, 1 Jun 2023 21:09:46 +0100 Subject: [PATCH 23/25] Fix issues with format types and fetch methods. --- .../0.0.0-dev/src/Network/HTTP/Response.enso | 2 +- .../0.0.0-dev/src/System/File_Format.enso | 15 +++++++++----- .../Database/0.0.0-dev/src/Data/Table.enso | 4 ++-- .../Table/0.0.0-dev/src/Data/Table.enso | 4 ++-- .../src/Internal/Widget_Helpers.enso | 20 +++++++++++++++++-- 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso index c719860f8068..f33dbdbfb700 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Network/HTTP/Response.enso @@ -90,7 +90,7 @@ type Response format = if content_type.is_nothing then Nothing else Auto_Detect.get_web_parser content_type (self.internal_http_response.uri.toString) if format.is_nothing then if_unsupported else - format.value.read_web self + format.read_web self _ -> type_obj = Meta.type_of format if can_decode type_obj then format.read_web self else diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File_Format.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File_Format.enso index 4d81665fd0eb..5cccfab7acb2 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/System/File_Format.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/System/File_Format.enso @@ -90,11 +90,16 @@ type File_Format Create the constructor code for a File_Format type. constructor_code : Any -> Text constructor_code type_obj = - type_name = Meta.get_qualified_type_name type_obj - ctors = Meta.meta type_obj . constructors - is_singleton_type = ctors.length == 0 - if is_singleton_type then type_name else - type_name + "." + ctors.first.name + ## Workaround for JSON and Auto_Detect + case type_obj of + JSON_Format -> "JSON_Format" + Auto_Detect -> "Auto_Detect" + _ -> + type_name = Meta.get_qualified_type_name type_obj + ctors = Meta.meta type_obj . constructors + is_singleton_type = ctors.length == 0 + if is_singleton_type then type_name else + type_name + "." + ctors.first.name ## PRIVATE default_widget : Widget diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso index 1cf1a55f969e..bae38f880388 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Data/Table.enso @@ -927,8 +927,8 @@ type Table allows to join the two tables on equality of corresponding columns with the same name. So `table.join other on=["A", "B"]` is a shorthand for: table.join other on=[Join_Condition.Equals "A" "A", Join_Condition.Equals "B" "B"] - @on Widget_Helpers.make_column_name_selector - join : Table -> Join_Kind -> Join_Condition | Text | Vector (Join_Condition | Text) -> Text -> Problem_Behavior -> Table + @on Widget_Helpers.make_join_condition_selector + join : Table -> Join_Kind -> Vector (Join_Condition | Text) | Text -> Text -> Problem_Behavior -> Table join self right join_kind=Join_Kind.Left_Outer on=[Join_Condition.Equals self.column_names.first] right_prefix="Right " on_problems=Report_Warning = can_proceed = if Table_Helpers.is_table right . not then Error.throw (Type_Error.Error Table right "right") else same_backend = case right of 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 ad224d106d9a..b2f11bdf8e56 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 @@ -1411,8 +1411,8 @@ type Table allows to join the two tables on equality of corresponding columns with the same name. So `table.join other on=["A", "B"]` is a shorthand for: table.join other on=[Join_Condition.Equals "A" "A", Join_Condition.Equals "B" "B"] - @on Widget_Helpers.make_column_name_selector - join : Table -> Join_Kind -> Join_Condition | Text | Vector (Join_Condition | Text) -> Text -> Problem_Behavior -> Table + @on Widget_Helpers.make_join_condition_selector + join : Table -> Join_Kind -> Vector (Join_Condition | Text) | Text -> Text -> Problem_Behavior -> Table join self right join_kind=Join_Kind.Left_Outer on=[Join_Condition.Equals self.column_names.first] right_prefix="Right " on_problems=Report_Warning = if check_table "right" right then # [left_unmatched, matched, right_unmatched] diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso index 49edace495ac..f733c22b6828 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso @@ -6,12 +6,13 @@ from Standard.Base.Metadata.Widget import Single_Choice, Vector_Editor from Standard.Base.Metadata.Choice import Option import Standard.Base.Metadata.Display +import project.Data.Aggregate_Column.Aggregate_Column +import project.Data.Join_Condition.Join_Condition import project.Data.Table.Table import project.Data.Type.Value_Type.Auto import project.Data.Type.Value_Type.Value_Type -import project.Data.Aggregate_Column.Aggregate_Column -import project.Internal.Parse_Values_Helper import project.Data.Table_Conversions +import project.Internal.Parse_Values_Helper ## PRIVATE Make an aggregate column selector. @@ -75,6 +76,21 @@ make_column_name_vector_selector table display=Display.Always = item_editor = make_column_name_selector table display=Display.Always Vector_Editor item_editor=item_editor item_default=item_editor.values.first.value display=display +## PRIVATE + Make a join condition selector. +make_join_condition_selector : Table -> Display -> Widget +make_join_condition_selector table display=Display.Always = + col_names_selector = make_column_name_selector table display=Display.Always + + fqn = Meta.get_qualified_type_name Join_Condition + equals = Option "Equals" fqn+".Equals" [["left", col_names_selector]] + equals_ci = Option "Equals (Ignore Case)" fqn+".Equals_Ignore_Case" [["left", col_names_selector]] + between = Option "Between" fqn+".Between" [["left", col_names_selector]] + names=[equals, equals_ci, between] + + item_editor = Single_Choice display=display values=names + Vector_Editor item_editor=item_editor item_default="Join_Condition.Equals" display=display + ## PRIVATE Make a column name selector. make_order_by_selector : Table -> Display -> Widget From ad897c88465875c4022cee921cf3891774841ba4 Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Thu, 1 Jun 2023 21:26:39 +0100 Subject: [PATCH 24/25] Better `on` for `join`. --- .../Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso index f733c22b6828..8d08f566a48e 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Widget_Helpers.enso @@ -82,14 +82,14 @@ make_join_condition_selector : Table -> Display -> Widget make_join_condition_selector table display=Display.Always = col_names_selector = make_column_name_selector table display=Display.Always - fqn = Meta.get_qualified_type_name Join_Condition + fqn = "Join_Condition" equals = Option "Equals" fqn+".Equals" [["left", col_names_selector]] equals_ci = Option "Equals (Ignore Case)" fqn+".Equals_Ignore_Case" [["left", col_names_selector]] between = Option "Between" fqn+".Between" [["left", col_names_selector]] names=[equals, equals_ci, between] item_editor = Single_Choice display=display values=names - Vector_Editor item_editor=item_editor item_default="Join_Condition.Equals" display=display + Vector_Editor item_editor=item_editor item_default="("+item_editor.values.first.value+")" display=display ## PRIVATE Make a column name selector. From 85ac034a2fb006b5c8f9ae0942ba3ce92bf4337f Mon Sep 17 00:00:00 2001 From: James Dunkerley Date: Thu, 1 Jun 2023 22:18:38 +0100 Subject: [PATCH 25/25] Fix failed test. --- distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso | 2 +- test/Tests/src/Network/Http_Spec.enso | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso index 04be716d1003..37dcf1a32e24 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data.enso @@ -161,7 +161,7 @@ fetch uri method=HTTP_Method.Get headers=[] parse=True = request = Request.new method uri parsed_headers response = HTTP.new.request request - if response.code.is_success.not then Error.throw (Request_Error.Error "Status Code" ("Request failed with status code: " + response.code.to_text + ". " + response.body.to_text)) else + if response.code.is_success.not then Error.throw (Request_Error.Error "Status Code" ("Request failed with status code: " + response.code.to_text + ". " + response.body.decode_as_text)) else if parse then response.decode if_unsupported=response else response ## ALIAS Download, HTTP Get diff --git a/test/Tests/src/Network/Http_Spec.enso b/test/Tests/src/Network/Http_Spec.enso index 88dd6391e5ff..fd9d30300a42 100644 --- a/test/Tests/src/Network/Http_Spec.enso +++ b/test/Tests/src/Network/Http_Spec.enso @@ -90,7 +90,7 @@ spec = Test.specify "should send Head request" <| res = HTTP.new.head url_get res.code.should_equal HTTP_Status_Code.ok - res.body.to_text.should_equal '' + res.body.decode_as_text.should_equal '' Test.specify "should Post empty body" <| expected_response = Json.parse <| '''