Moving library statics to type for Table. (#3760)

- Generally export types not modules from the `Standard.Table` import.
- Moved `new`, `from_rows` the `Standard.Table` library into the `Table` type.
- Renames `Standard.Table.Data.Storage.Type` to `Standard.Table.Data.Storage.Storage`
- Removed the internal `from_columns` method.
- Removed `join` and `concat` and merged into instance methods.
- Removed `Table` and `Column` from the `Standard.Database` exports.
- Removed `Standard.Table.Data.Column.Aggregate_Column` as not used any more.
This commit is contained in:
James Dunkerley 2022-10-06 18:01:18 +01:00 committed by GitHub
parent 486874216b
commit 185378f07c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
89 changed files with 698 additions and 1063 deletions

View File

@ -1,7 +1,6 @@
from Standard.Base import all from Standard.Base import all
import Standard.Base.Data.Index_Sub_Range import Standard.Base.Data.Index_Sub_Range
import Standard.Base.Random import Standard.Base.Random
import Standard.Base.Runtime.Unsafe
polyglot java import java.lang.IndexOutOfBoundsException polyglot java import java.lang.IndexOutOfBoundsException
polyglot java import org.enso.base.Array_Builder polyglot java import org.enso.base.Array_Builder

View File

@ -40,7 +40,7 @@ type Connection
## Returns the list of databases (or catalogs) for the connection. ## Returns the list of databases (or catalogs) for the connection.
databases : [Text] databases : Vector Text
databases self = databases self =
self.jdbc_connection.with_metadata metadata-> self.jdbc_connection.with_metadata metadata->
read_column metadata.getCatalogs "TABLE_CAT" read_column metadata.getCatalogs "TABLE_CAT"
@ -60,7 +60,7 @@ type Connection
SQL_Error.throw_sql_error "Changing database is not supported." SQL_Error.throw_sql_error "Changing database is not supported."
## Returns the list of schemas for the connection within the current database (or catalog). ## Returns the list of schemas for the connection within the current database (or catalog).
schemas : [Text] schemas : Vector Text
schemas self = schemas self =
self.jdbc_connection.with_metadata metadata-> self.jdbc_connection.with_metadata metadata->
read_column metadata.getSchemas "TABLE_SCHEM" read_column metadata.getSchemas "TABLE_SCHEM"
@ -94,7 +94,7 @@ type Connection
- schema: The schema name to search in (defaults to current schema). - schema: The schema name to search in (defaults to current schema).
- types: The table types to search for. The list of possible values can be obtained using the `table_types` method. - types: The table types to search for. The list of possible values can be obtained using the `table_types` method.
- all_fields: Return all the fields in the metadata table. - all_fields: Return all the fields in the metadata table.
tables : Text -> Text -> Text -> Vector -> Boolean -> Materialized_Table tables : Text -> Text -> Text -> Vector -> Boolean -> Materialized_Table.Table
tables self name_like=Nothing database=self.database schema=self.schema types=Nothing all_fields=False = tables self name_like=Nothing database=self.database schema=self.schema types=Nothing all_fields=False =
types_array = if types.is_nothing then Nothing else types.to_array types_array = if types.is_nothing then Nothing else types.to_array
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"]] 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"]]
@ -112,7 +112,7 @@ type Connection
- query: name of the table or sql statement to query. - query: name of the table or sql statement to query.
If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query. If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query.
- alias: optionally specify a friendly alias for the query. - alias: optionally specify a friendly alias for the query.
query : Text | SQL_Query -> Text -> Database_Table query : Text | SQL_Query -> Text -> Database_Table.Table
query self query alias="" = handle_sql_errors <| case query of query self query alias="" = handle_sql_errors <| case query of
_ : Text -> _ : Text ->
self.query alias=alias <| self.query alias=alias <|
@ -134,13 +134,13 @@ type Connection
- query: name of the table or sql statement to query. - query: name of the table or sql statement to query.
If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query. If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query.
- limit: the maximum number of rows to return. - limit: the maximum number of rows to return.
read : Text | SQL_Query -> Text -> Integer | Nothing -> Table read : Text | SQL_Query -> Text -> Integer | Nothing -> Materialized_Table.Table
read self query limit=Nothing = read self query limit=Nothing =
self.query query . read max_rows=limit self.query query . read max_rows=limit
## PRIVATE ## PRIVATE
Internal read function for a statement with optional types. Internal read function for a statement with optional types.
read_statement : Statement -> (Nothing | Vector SQL_Type) -> Table read_statement : Statement -> (Nothing | Vector SQL_Type) -> Materialized_Table.Table
read_statement self statement expected_types=Nothing = read_statement self statement expected_types=Nothing =
self.jdbc_connection.with_prepared_statement statement stmt-> self.jdbc_connection.with_prepared_statement statement stmt->
result_set_to_table stmt.executeQuery expected_types result_set_to_table stmt.executeQuery expected_types
@ -177,7 +177,7 @@ type Connection
usually not be visible to other connections. usually not be visible to other connections.
- batch_size: Specifies how many rows should be uploaded in a single - batch_size: Specifies how many rows should be uploaded in a single
batch. batch.
upload_table : Text -> Materialized_Table -> Boolean -> Integer -> Database_Table upload_table : Text -> Materialized_Table.Table -> Boolean -> Integer -> Database_Table.Table
upload_table self name table temporary=True batch_size=1000 = Panic.recover Illegal_State_Error_Data <| upload_table self name table temporary=True batch_size=1000 = Panic.recover Illegal_State_Error_Data <|
create_sql = create_table_statement name table temporary create_sql = create_table_statement name table temporary
create_table = self.execute_update create_sql create_table = self.execute_update create_sql

View File

@ -2,12 +2,13 @@ from Standard.Base import all
import Standard.Database.Internal.Helpers import Standard.Database.Internal.Helpers
import Standard.Database.Internal.IR import Standard.Database.Internal.IR
import Standard.Database.Data.Table from Standard.Database.Data.Table import Table, freshen_columns
from Standard.Table import Filter_Condition from Standard.Table import Filter_Condition
import Standard.Table.Data.Column as Materialized_Column
import Standard.Table.Data.Sort_Column_Selector import Standard.Table.Data.Column.Column as Materialized_Column
import Standard.Table.Data.Sort_Column import Standard.Table.Data.Sort_Column_Selector.Sort_Column_Selector
from Standard.Table.Data.Value_Type import Value_Type import Standard.Table.Data.Sort_Column.Sort_Column
import Standard.Table.Data.Value_Type.Value_Type
from Standard.Database.Data.SQL import SQL_Type, Statement from Standard.Database.Data.SQL import SQL_Type, Statement
from Standard.Database.Data.Table import Integrity_Error from Standard.Database.Data.Table import Integrity_Error
@ -69,7 +70,7 @@ type Column
## UNSTABLE ## UNSTABLE
Converts this column into a single-column table. Converts this column into a single-column table.
to_table : Table.Table to_table : Table
to_table self = to_table self =
Table.Table_Data self.name self.connection [self.as_internal] self.context Table.Table_Data self.name self.connection [self.as_internal] self.context
@ -558,7 +559,7 @@ lift_aggregate new_name connection expected_type expr context =
# TODO [RW] This is a simple workaround for #1643 - we always wrap the # TODO [RW] This is a simple workaround for #1643 - we always wrap the
# aggregate into a subquery, thus making it safe to use it everywhere. A # aggregate into a subquery, thus making it safe to use it everywhere. A
# more complex solution may be adopted at some point. # more complex solution may be adopted at some point.
ixes = Table.freshen_columns [new_name] context.meta_index ixes = freshen_columns [new_name] context.meta_index
col = IR.Internal_Column_Data new_name expected_type expr col = IR.Internal_Column_Data new_name expected_type expr
setup = context.as_subquery new_name+"_sub" [[col], ixes] setup = context.as_subquery new_name+"_sub" [[col], ixes]
subquery = setup.first subquery = setup.first

View File

@ -1,6 +1,6 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table.Internal.Vector_Builder import Standard.Table.Internal.Vector_Builder.Vector_Builder
polyglot java import java.sql.Types polyglot java import java.sql.Types
@ -285,7 +285,7 @@ type Builder
It can be used to concatenate parts of SQL code in O(1) time and at the It can be used to concatenate parts of SQL code in O(1) time and at the
end build the actual query in linear time. end build the actual query in linear time.
Builder_Data (fragments:(Vector_Builder.Vector_Builder SQL_Fragment)) Builder_Data (fragments:(Vector_Builder SQL_Fragment))
## UNSTABLE ## UNSTABLE

View File

@ -7,31 +7,26 @@ import Standard.Database.Internal.IR
from Standard.Database.Data.SQL_Query import Raw_SQL from Standard.Database.Data.SQL_Query import Raw_SQL
from Standard.Database.Data.SQL import Statement, SQL_Type from Standard.Database.Data.SQL import Statement, SQL_Type
from Standard.Table import Auto_Detect, Aggregate_Column, Data_Formatter, Column_Name_Mapping, Sort_Column_Selector, Sort_Column, Match_Columns, Position
from Standard.Table.Data.Column import get_item_string
import Standard.Table.Data.Table.Table as Materialized_Table
from Standard.Table.Data.Table import print_table
from Standard.Table.Data.Filter_Condition import make_filter_column, Filter_Condition from Standard.Table.Data.Filter_Condition import make_filter_column, Filter_Condition
import Standard.Table.Data.Column as Materialized_Column
import Standard.Table.Data.Table as Materialized_Table
from Standard.Table import Auto_Detect, Aggregate_Column, Data_Formatter, Column_Name_Mapping, Sort_Column_Selector, Sort_Column, Match_Columns
from Standard.Table.Errors import No_Such_Column_Error, No_Such_Column_Error_Data from Standard.Table.Errors import No_Index_Set_Error, No_Such_Column_Error, No_Such_Column_Error_Data
from Standard.Table.Data.Column_Selector import Column_Selector, By_Index, By_Name from Standard.Table.Data.Column_Selector import Column_Selector
import Standard.Table.Internal.Java_Exports import Standard.Table.Internal.Java_Exports
import Standard.Table.Internal.Table_Helpers import Standard.Table.Internal.Table_Helpers
import Standard.Table.Internal.Problem_Builder import Standard.Table.Internal.Problem_Builder.Problem_Builder
import Standard.Table.Internal.Aggregate_Column_Helper import Standard.Table.Internal.Aggregate_Column_Helper
from Standard.Database.Data.Column import Column, Column_Data from Standard.Database.Data.Column import Column, Column_Data
from Standard.Database.Internal.IR import Internal_Column, Internal_Column_Data from Standard.Database.Internal.IR import Internal_Column, Internal_Column_Data
from Standard.Database.Errors import Unsupported_Database_Operation_Error_Data from Standard.Database.Errors import Unsupported_Database_Operation_Error_Data
import Standard.Table.Data.Position
polyglot java import java.sql.JDBCType polyglot java import java.sql.JDBCType
# TODO Dubious constructor export
from project.Data.Table.Table import all
from project.Data.Table.Table export all
## Represents a column-oriented table data structure backed by a database. ## Represents a column-oriented table data structure backed by a database.
type Table type Table
@ -124,7 +119,7 @@ type Table
> Example > Example
Select columns by name. Select columns by name.
table.select_columns (By_Name ["bar", "foo"]) table.select_columns (Column_Selector.By_Name ["bar", "foo"])
> Example > Example
Select columns using names passed as a Vector. Select columns using names passed as a Vector.
@ -134,21 +129,21 @@ type Table
> Example > Example
Select columns matching a regular expression. Select columns matching a regular expression.
table.select_columns (By_Name ["foo.+", "b.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Insensitive)) table.select_columns (Column_Selector.By_Name ["foo.+", "b.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Insensitive))
> Example > Example
Select the first two columns and the last column, moving the last one to front. Select the first two columns and the last column, moving the last one to front.
table.select_columns (By_Index [-1, 0, 1]) reorder=True table.select_columns (Column_Selector.By_Index [-1, 0, 1]) reorder=True
> Example > Example
Select columns with the same names as the ones provided. Select columns with the same names as the ones provided.
table.select_columns (By_Column [column1, column2]) table.select_columns (Column_Selector.By_Column [column1, column2])
Icon: select_column Icon: select_column
select_columns : Vector Text | Column_Selector -> Boolean -> Problem_Behavior -> Table select_columns : Vector Text | Column_Selector -> Boolean -> Problem_Behavior -> Table
select_columns self (columns = By_Index [0]) (reorder = False) (on_problems = Report_Warning) = select_columns self (columns = Column_Selector.By_Index [0]) (reorder = False) (on_problems = Report_Warning) =
new_columns = Table_Helpers.select_columns internal_columns=self.internal_columns selector=columns reorder=reorder on_problems=on_problems new_columns = Table_Helpers.select_columns internal_columns=self.internal_columns selector=columns reorder=reorder on_problems=on_problems
self.updated_columns new_columns self.updated_columns new_columns
@ -176,7 +171,7 @@ type Table
> Example > Example
Remove columns with given names. Remove columns with given names.
table.remove_columns (By_Name ["bar", "foo"]) table.remove_columns (Column_Selector.By_Name ["bar", "foo"])
> Example > Example
Remove columns using names passed as a Vector. Remove columns using names passed as a Vector.
@ -186,19 +181,19 @@ type Table
> Example > Example
Remove columns matching a regular expression. Remove columns matching a regular expression.
table.remove_columns (By_Name ["foo.+", "b.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Insensitive)) table.remove_columns (Column_Selector.By_Name ["foo.+", "b.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Insensitive))
> Example > Example
Remove the first two columns and the last column. Remove the first two columns and the last column.
table.remove_columns (By_Index [-1, 0, 1]) table.remove_columns (Column_Selector.By_Index [-1, 0, 1])
> Example > Example
Remove columns with the same names as the ones provided. Remove columns with the same names as the ones provided.
table.remove_columns (By_Column [column1, column2]) table.remove_columns (Column_Selector.By_Column [column1, column2])
remove_columns : Vector Text | Column_Selector -> Problem_Behavior -> Table remove_columns : Vector Text | Column_Selector -> Problem_Behavior -> Table
remove_columns self (columns = By_Index [0]) (on_problems = Report_Warning) = remove_columns self (columns = Column_Selector.By_Index [0]) (on_problems = Report_Warning) =
new_columns = Table_Helpers.remove_columns internal_columns=self.internal_columns selector=columns on_problems=on_problems new_columns = Table_Helpers.remove_columns internal_columns=self.internal_columns selector=columns on_problems=on_problems
self.updated_columns new_columns self.updated_columns new_columns
@ -241,19 +236,19 @@ type Table
> Example > Example
Swap the first two columns. Swap the first two columns.
table.reorder_columns (By_Index [1, 0]) position=Before_Other_Columns table.reorder_columns (Column_Selector.By_Index [1, 0]) position=Before_Other_Columns
> Example > Example
Move the first column to back. Move the first column to back.
table.reorder_columns (By_Index [0]) position=After_Other_Columns table.reorder_columns (Column_Selector.By_Index [0]) position=After_Other_Columns
> Example > Example
Move the columns with names matching the provided columns to the front. Move the columns with names matching the provided columns to the front.
table.reorder_columns (By_Column [column1, column2]) table.reorder_columns (Column_Selector.By_Column [column1, column2])
reorder_columns : Vector Text | Column_Selector -> Position.Position -> Problem_Behavior -> Table reorder_columns : Vector Text | Column_Selector -> Position.Position -> Problem_Behavior -> Table
reorder_columns self (columns = By_Index [0]) (position = Position.Before_Other_Columns) (on_problems = Report_Warning) = reorder_columns self (columns = Column_Selector.By_Index [0]) (position = Position.Before_Other_Columns) (on_problems = Report_Warning) =
new_columns = Table_Helpers.reorder_columns internal_columns=self.internal_columns selector=columns position=position on_problems=on_problems new_columns = Table_Helpers.reorder_columns internal_columns=self.internal_columns selector=columns position=position on_problems=on_problems
self.updated_columns new_columns self.updated_columns new_columns
@ -531,11 +526,11 @@ type Table
itself). itself).
Throws `No_Index_Set_Error` if there is no index set. Throws `No_Index_Set_Error` if there is no index set.
index : Column | Vector Column ! Materialized_Table.No_Index_Set_Error index : Column | Vector Column ! No_Index_Set_Error
index self = index self =
ixes = self.indices ixes = self.indices
len = ixes.length len = ixes.length
if len == 0 then Error.throw Materialized_Table.No_Index_Set_Error else if len == 0 then Error.throw No_Index_Set_Error else
if len == 1 then ixes.at 0 else ixes if len == 1 then ixes.at 0 else ixes
## Sorts the rows of the table according to the specified columns and order. ## Sorts the rows of the table according to the specified columns and order.
@ -632,7 +627,7 @@ type Table
- If floating points values are present in the distinct columns, a - If floating points values are present in the distinct columns, a
`Floating_Point_Grouping` warning. `Floating_Point_Grouping` warning.
distinct : Vector Text | Column_Selector -> Case_Sensitivity -> Problem_Behavior -> Table distinct : Vector Text | Column_Selector -> Case_Sensitivity -> Problem_Behavior -> Table
distinct self (columns = By_Name (self.columns.map .name)) case_sensitivity=Case_Sensitivity.Sensitive on_problems=Report_Warning = distinct self (columns = Column_Selector.By_Name (self.columns.map .name)) case_sensitivity=Case_Sensitivity.Sensitive on_problems=Report_Warning =
_ = [columns, case_sensitivity, on_problems] _ = [columns, case_sensitivity, on_problems]
Error.throw (Unsupported_Database_Operation_Error_Data "`Table.distinct` is not yet implemented for the database backend.") Error.throw (Unsupported_Database_Operation_Error_Data "`Table.distinct` is not yet implemented for the database backend.")
@ -659,8 +654,8 @@ type Table
Icon: join Icon: join
join : Table | Column -> Nothing | Text | Column | Vector (Text | Column) -> Boolean -> Text -> Text -> Table join : Table | Column -> Nothing | Text | Column | Vector (Text | Column) -> Boolean -> Text -> Text -> Table
join self other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' = case other of join self other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' = case other of
Column_Data _ _ _ _ _ -> self.join other.to_table on drop_unmatched left_suffix right_suffix _ : Column -> self.join other.to_table on drop_unmatched left_suffix right_suffix
Table_Data _ _ _ _ -> Panic.recover Any <| _ : Table -> Panic.recover Any <|
Panic.rethrow (Helpers.ensure_name_is_sane left_suffix && Helpers.ensure_name_is_sane right_suffix) Panic.rethrow (Helpers.ensure_name_is_sane left_suffix && Helpers.ensure_name_is_sane right_suffix)
if left_suffix == right_suffix then if left_suffix == right_suffix then
Panic.throw <| Illegal_State_Error_Data "left_suffix must be different from right_suffix" Panic.throw <| Illegal_State_Error_Data "left_suffix must be different from right_suffix"
@ -729,7 +724,7 @@ type Table
new_limit = Nothing new_limit = Nothing
new_ctx = IR.Context_Data new_from [] [] [] new_index new_limit new_ctx = IR.Context_Data new_from [] [] [] new_index new_limit
Table_Data new_table_name self.connection new_columns new_ctx Table.Table_Data new_table_name self.connection new_columns new_ctx
## ALIAS group, summarize ## ALIAS group, summarize
@ -833,7 +828,7 @@ type Table
Arguments: Arguments:
- max_rows: specifies a maximum amount of rows to fetch; if not set, all - max_rows: specifies a maximum amount of rows to fetch; if not set, all
available rows are fetched. available rows are fetched.
read : (Integer | Nothing) -> Materialized_Table.Table read : (Integer | Nothing) -> Materialized_Table
read self max_rows=Nothing = read self max_rows=Nothing =
case self.context.meta_index.length > 1 of case self.context.meta_index.length > 1 of
True -> Error.throw <| Illegal_State_Error_Data "Multi-indexes are not implemented in the dataframes, if you want to materialize such a Table, remove the index first using `set_index`." True -> Error.throw <| Illegal_State_Error_Data "Multi-indexes are not implemented in the dataframes, if you want to materialize such a Table, remove the index first using `set_index`."
@ -841,8 +836,7 @@ type Table
preprocessed = self.reset_index.limit max_rows preprocessed = self.reset_index.limit max_rows
case preprocessed.internal_columns.is_empty of case preprocessed.internal_columns.is_empty of
True -> True ->
internal_table = Java_Exports.make_table_without_columns self.row_count Java_Exports.make_table_without_columns self.row_count
Materialized_Table.Table_Data internal_table
False -> False ->
sql = preprocessed.to_sql sql = preprocessed.to_sql
expected_types = preprocessed.internal_columns.map .sql_type expected_types = preprocessed.internal_columns.map .sql_type
@ -919,7 +913,7 @@ type Table
Arguments: Arguments:
- columns: The columns with which to update this table. - columns: The columns with which to update this table.
updated_columns : Vector Internal_Column -> Table updated_columns : Vector Internal_Column -> Table
updated_columns self internal_columns = Table_Data self.name self.connection internal_columns self.context updated_columns self internal_columns = Table.Table_Data self.name self.connection internal_columns self.context
## PRIVATE ## PRIVATE
@ -928,7 +922,7 @@ type Table
Arguments: Arguments:
- ctx: The new context for this table. - ctx: The new context for this table.
updated_context : Context -> Table updated_context : Context -> Table
updated_context self ctx = Table_Data self.name self.connection self.internal_columns ctx updated_context self ctx = Table.Table_Data self.name self.connection self.internal_columns ctx
## PRIVATE ## PRIVATE
@ -938,7 +932,7 @@ type Table
- ctx: The new context for this table. - ctx: The new context for this table.
- internal_columns: The new columns to include in the table. - internal_columns: The new columns to include in the table.
updated_context_and_columns : Context -> Vector Internal_Column -> Table updated_context_and_columns : Context -> Vector Internal_Column -> Table
updated_context_and_columns self ctx internal_columns = Table_Data self.name self.connection internal_columns ctx updated_context_and_columns self ctx internal_columns = Table.Table_Data self.name self.connection internal_columns ctx
## PRIVATE ## PRIVATE
@ -1067,7 +1061,7 @@ type Integrity_Error
make_table : Connection -> Text -> Vector -> IR.Context -> Table make_table : Connection -> Text -> Vector -> IR.Context -> Table
make_table connection table_name columns ctx = make_table connection table_name columns ctx =
cols = columns.map (p -> Internal_Column_Data p.first p.second (IR.Column table_name p.first)) cols = columns.map (p -> Internal_Column_Data p.first p.second (IR.Column table_name p.first))
Table_Data table_name connection cols ctx Table.Table_Data table_name connection cols ctx
## PRIVATE ## PRIVATE
@ -1085,7 +1079,7 @@ make_table connection table_name columns ctx =
line will be included that will say how many hidden rows there are. line will be included that will say how many hidden rows there are.
- format_term: A boolean flag, specifying whether to use ANSI escape codes - format_term: A boolean flag, specifying whether to use ANSI escape codes
for rich formatting in the terminal. for rich formatting in the terminal.
display_dataframe : Materialized_Table.Table -> Integer -> Integer -> Boolean -> Text display_dataframe : Materialized_Table -> Integer -> Integer -> Boolean -> Text
display_dataframe df indices_count all_rows_count format_terminal = display_dataframe df indices_count all_rows_count format_terminal =
cols = Vector.from_polyglot_array df.java_table.getColumns cols = Vector.from_polyglot_array df.java_table.getColumns
col_names = cols.map .getName col_names = cols.map .getName
@ -1093,8 +1087,8 @@ display_dataframe df indices_count all_rows_count format_terminal =
display_rows = df.row_count display_rows = df.row_count
rows = Vector.new display_rows row_num-> rows = Vector.new display_rows row_num->
col_vals.map col-> col_vals.map col->
if col.isNa row_num then "Nothing" else Materialized_Column.get_item_string col row_num if col.isNa row_num then "Nothing" else get_item_string col row_num
table = Materialized_Table.print_table col_names rows indices_count format_terminal table = print_table col_names rows indices_count format_terminal
if display_rows == all_rows_count then table else if display_rows == all_rows_count then table else
missing_rows_count = all_rows_count - display_rows missing_rows_count = all_rows_count - display_rows
missing = '\n\u2026 and ' + missing_rows_count.to_text + ' hidden rows.' missing = '\n\u2026 and ' + missing_rows_count.to_text + ' hidden rows.'

View File

@ -1,6 +1,6 @@
from Standard.Base import all hiding First, Last from Standard.Base import all hiding First, Last
from Standard.Table.Data.Aggregate_Column import all from Standard.Table.Data.Aggregate_Column.Aggregate_Column import all
import Standard.Database.Internal.IR import Standard.Database.Internal.IR
from Standard.Database.Data.SQL import SQL_Type from Standard.Database.Data.SQL import SQL_Type
from Standard.Database.Errors import Unsupported_Database_Operation_Error_Data from Standard.Database.Errors import Unsupported_Database_Operation_Error_Data

View File

@ -7,7 +7,7 @@ import Standard.Database.Data.SQL
from Standard.Database.Data.SQL import SQL_Type, SQL_Type_Data, Statement, Statement_Data from Standard.Database.Data.SQL import SQL_Type, SQL_Type_Data, Statement, Statement_Data
from Standard.Database.Errors import SQL_Error, SQL_Error_Data, SQL_Timeout_Error, SQL_Timeout_Error_Data from Standard.Database.Errors import SQL_Error, SQL_Error_Data, SQL_Timeout_Error, SQL_Timeout_Error_Data
import Standard.Database.Internal.Base_Generator import Standard.Database.Internal.Base_Generator
import Standard.Table.Data.Storage import Standard.Table.Data.Storage.Storage
import Standard.Database.Data.Table as Database_Table import Standard.Database.Data.Table as Database_Table
import Standard.Table.Data.Table as Materialized_Table import Standard.Table.Data.Table as Materialized_Table
@ -101,7 +101,7 @@ type JDBC_Connection
Given an insert query template and the associated Database_Table, and a Given an insert query template and the associated Database_Table, and a
Materialized_Table of data, load to the database. Materialized_Table of data, load to the database.
load_table : Text -> Database_Table -> Materialized_Table -> Integer -> Nothing load_table : Text -> Database_Table.Table -> Materialized_Table.Table -> Integer -> Nothing
load_table self insert_template db_table table batch_size = load_table self insert_template db_table table batch_size =
db_types = db_table.internal_columns.map .sql_type db_types = db_table.internal_columns.map .sql_type
self.with_connection java_connection-> self.with_connection java_connection->
@ -182,7 +182,7 @@ set_statement_values stmt holes =
## PRIVATE ## PRIVATE
Given a Materialized_Table, create a SQL statement to build the table. Given a Materialized_Table, create a SQL statement to build the table.
create_table_statement : Text -> Materialized_Table -> Boolean -> Statement create_table_statement : Text -> Materialized_Table.Table -> Boolean -> Statement
create_table_statement name table temporary = create_table_statement name table temporary =
column_types = table.columns.map col-> default_storage_type col.storage_type column_types = table.columns.map col-> default_storage_type col.storage_type
column_names = table.columns.map .name column_names = table.columns.map .name

View File

@ -57,7 +57,7 @@ type Postgres_Connection
self.make_new database Nothing self.make_new database Nothing
## Returns the list of schemas for the connection within the current database (or catalog). ## Returns the list of schemas for the connection within the current database (or catalog).
schemas : [Text] schemas : Vector Text
schemas self = self.connection.schemas schemas self = self.connection.schemas
## Returns the name of the current schema. ## Returns the name of the current schema.
@ -74,7 +74,7 @@ type Postgres_Connection
self.make_new Nothing schema self.make_new Nothing schema
## Gets a list of the table types. ## Gets a list of the table types.
table_types : [Text] table_types : Vector Text
table_types self = self.connection.table_types table_types self = self.connection.table_types
## Returns a materialised Table of all the matching views and tables. ## Returns a materialised Table of all the matching views and tables.
@ -85,7 +85,7 @@ type Postgres_Connection
- schema: The schema name to search in (defaults to current schema). - schema: The schema name to search in (defaults to current schema).
- types: The table types to search for. The list of values can be obtained using the `table_types` method. - types: The table types to search for. The list of values can be obtained using the `table_types` method.
- all_fields: Return all the fields in the metadata table. - all_fields: Return all the fields in the metadata table.
tables : Text -> Text -> Text -> Vector -> Boolean -> Materialized_Table tables : Text -> Text -> Text -> Vector -> Boolean -> Materialized_Table.Table
tables self name_like=Nothing database=self.database schema=self.schema types=Nothing all_fields=False = tables self name_like=Nothing database=self.database schema=self.schema types=Nothing all_fields=False =
self.connection.tables name_like database schema types all_fields self.connection.tables name_like database schema types all_fields
@ -95,7 +95,7 @@ type Postgres_Connection
- query: name of the table or sql statement to query. - query: name of the table or sql statement to query.
If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query. If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query.
- alias: optionally specify a friendly alias for the query. - alias: optionally specify a friendly alias for the query.
query : Text | SQL_Query -> Text -> Database_Table query : Text | SQL_Query -> Text -> Database_Table.Table
query self query alias="" = self.connection.query query alias query self query alias="" = self.connection.query query alias
## Execute the query and load the results into memory as a Table. ## Execute the query and load the results into memory as a Table.
@ -104,12 +104,12 @@ type Postgres_Connection
- query: name of the table or sql statement to query. - query: name of the table or sql statement to query.
If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query. If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query.
- limit: the maximum number of rows to return. - limit: the maximum number of rows to return.
read : Text | SQL_Query -> Integer | Nothing -> Table read : Text | SQL_Query -> Integer | Nothing -> Materialized_Table.Table
read self query limit=Nothing = self.connection.read query limit read self query limit=Nothing = self.connection.read query limit
## PRIVATE ## PRIVATE
Internal read function for a statement with optional types. Internal read function for a statement with optional types.
read_statement : Statement -> (Nothing | Vector SQL_Type) -> Table read_statement : Statement -> (Nothing | Vector SQL_Type) -> Materialized_Table.Table
read_statement self statement expected_types=Nothing = read_statement self statement expected_types=Nothing =
self.connection.read_statement statement expected_types self.connection.read_statement statement expected_types
@ -143,7 +143,7 @@ type Postgres_Connection
usually not be visible to other connections. usually not be visible to other connections.
- batch_size: Specifies how many rows should be uploaded in a single - batch_size: Specifies how many rows should be uploaded in a single
batch. batch.
upload_table : Text -> Materialized_Table -> Boolean -> Integer -> Database_Table upload_table : Text -> Materialized_Table.Table -> Boolean -> Integer -> Database_Table.Table
upload_table self name table temporary=True batch_size=1000 = Panic.recover Illegal_State_Error <| upload_table self name table temporary=True batch_size=1000 = Panic.recover Illegal_State_Error <|
self.connection.upload_table name table temporary batch_size self.connection.upload_table name table temporary batch_size

View File

@ -1,7 +1,7 @@
from Standard.Base import all hiding First, Last from Standard.Base import all hiding First, Last
import Standard.Base.Error.Common as Errors import Standard.Base.Error.Common as Errors
from Standard.Table.Data.Aggregate_Column import all from Standard.Table.Data.Aggregate_Column.Aggregate_Column import all
from Standard.Database.Data.SQL import SQL_Type, Statement, code from Standard.Database.Data.SQL import SQL_Type, Statement, code
import Standard.Database.Data.SQL import Standard.Database.Data.SQL
import Standard.Database.Data.Dialect import Standard.Database.Data.Dialect

View File

@ -1,6 +1,7 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table.Data.Table as Materialized_Table import Standard.Table.Data.Table as Materialized_Table
import Standard.Table.Data.Column as Materialized_Column
import Standard.Table.Internal.Java_Exports import Standard.Table.Internal.Java_Exports
from Standard.Database.Data.SQL import SQL_Type, SQL_Type_Data from Standard.Database.Data.SQL import SQL_Type, SQL_Type_Data
@ -23,7 +24,7 @@ read_column result_set column_name =
## PRIVATE ## PRIVATE
Converts a ResultSet into a Materialized_Table. Converts a ResultSet into a Materialized_Table.
result_set_to_table : ResultSet -> (Vector | Nothing) -> Materialized_Table result_set_to_table : ResultSet -> (Vector | Nothing) -> Materialized_Table.Table
result_set_to_table result_set expected_types=Nothing = result_set_to_table result_set expected_types=Nothing =
metadata = result_set.getMetaData metadata = result_set.getMetaData
ncols = metadata.getColumnCount ncols = metadata.getColumnCount
@ -42,7 +43,7 @@ result_set_to_table result_set expected_types=Nothing =
go result_set.next go result_set.next
columns = column_builders.zip column_names builder-> name-> columns = column_builders.zip column_names builder-> name->
builder.make_column name builder.make_column name
Materialized_Table.from_columns columns Materialized_Table.Table.new columns
## PRIVATE ## PRIVATE
@ -54,14 +55,10 @@ result_set_to_table result_set expected_types=Nothing =
create_builder : SQL_Type -> Builder create_builder : SQL_Type -> Builder
create_builder sql_type = create_builder sql_type =
initial_size = 10 initial_size = 10
if sql_type.is_definitely_boolean then Builder_Boolean (Java_Exports.make_bool_builder) else if sql_type.is_definitely_boolean then Builder.Builder_Boolean (Java_Exports.make_bool_builder) else
if sql_type.is_definitely_integer then Builder_Long (Java_Exports.make_long_builder initial_size) else if sql_type.is_definitely_integer then Builder.Builder_Long (Java_Exports.make_long_builder initial_size) else
if sql_type.is_definitely_double then Builder_Double (Java_Exports.make_double_builder initial_size) else if sql_type.is_definitely_double then Builder.Builder_Double (Java_Exports.make_double_builder initial_size) else
Builder_Inferred (Java_Exports.make_inferred_builder initial_size) Builder.Builder_Inferred (Java_Exports.make_inferred_builder initial_size)
# TODO Dubious constructor export
from project.Internal.Result_Set.Builder import all
from project.Internal.Result_Set.Builder export all
type Builder type Builder
@ -108,20 +105,20 @@ type Builder
ResultSet convention). ResultSet convention).
fetch_and_append : ResultSet -> Integer -> Nothing fetch_and_append : ResultSet -> Integer -> Nothing
fetch_and_append self rs i = case self of fetch_and_append self rs i = case self of
Builder_Inferred _ -> Builder.Builder_Inferred _ ->
obj = rs.getObject i obj = rs.getObject i
self.java_builder.append obj self.java_builder.append obj
Builder_Boolean _ -> Builder.Builder_Boolean _ ->
bool = rs.getBoolean i bool = rs.getBoolean i
case rs.wasNull of case rs.wasNull of
True -> self.java_builder.appendNulls 1 True -> self.java_builder.appendNulls 1
False -> self.java_builder.appendBoolean bool False -> self.java_builder.appendBoolean bool
Builder_Long _ -> Builder.Builder_Long _ ->
long = rs.getLong i long = rs.getLong i
case rs.wasNull of case rs.wasNull of
True -> self.java_builder.appendNulls 1 True -> self.java_builder.appendNulls 1
False -> self.java_builder.appendLong long False -> self.java_builder.appendLong long
Builder_Double _ -> Builder.Builder_Double _ ->
double = rs.getDouble i double = rs.getDouble i
case rs.wasNull of case rs.wasNull of
True -> self.java_builder.appendNulls 1 True -> self.java_builder.appendNulls 1
@ -133,7 +130,7 @@ type Builder
Argument: Argument:
- name: The name of the column. - name: The name of the column.
make_column : Text -> Java_Exports.Column make_column : Text -> Materialized_Column.Column
make_column self name = make_column self name =
storage = self.java_builder.seal storage = self.java_builder.seal
Java_Exports.make_column name storage Java_Exports.make_column name storage

View File

@ -33,7 +33,7 @@ type SQLite_Connection
close self = self.connection.close close self = self.connection.close
## Returns the list of databases (or catalogs) for the connection. ## Returns the list of databases (or catalogs) for the connection.
databases : [Text] databases : Vector Text
databases self = [Nothing] databases self = [Nothing]
## Returns the name of the current database (or catalog). ## Returns the name of the current database (or catalog).
@ -50,7 +50,7 @@ type SQLite_Connection
SQL_Error.throw_sql_error "Changing database is not supported." SQL_Error.throw_sql_error "Changing database is not supported."
## Returns the list of schemas for the connection within the current database (or catalog). ## Returns the list of schemas for the connection within the current database (or catalog).
schemas : [Text] schemas : Vector Text
schemas self = [Nothing] schemas self = [Nothing]
## Returns the name of the current schema. ## Returns the name of the current schema.
@ -67,7 +67,7 @@ type SQLite_Connection
SQL_Error.throw_sql_error "Changing schema is not supported." SQL_Error.throw_sql_error "Changing schema is not supported."
## Gets a list of the table types ## Gets a list of the table types
table_types : [Text] table_types : Vector Text
table_types self = self.connection.table_types table_types self = self.connection.table_types
## Returns a materialised Table of all the matching views and tables. ## Returns a materialised Table of all the matching views and tables.
@ -78,7 +78,7 @@ type SQLite_Connection
- schema: The schema name to search in (defaults to current schema). - schema: The schema name to search in (defaults to current schema).
- types: The table types to search for. The list of values can be obtained using the `table_types` method. - types: The table types to search for. The list of values can be obtained using the `table_types` method.
- all_fields: Return all the fields in the metadata table. - all_fields: Return all the fields in the metadata table.
tables : Text -> Text -> Text -> Vector -> Boolean -> Materialized_Table tables : Text -> Text -> Text -> Vector -> Boolean -> Materialized_Table.Table
tables self name_like=Nothing database=self.database schema=self.schema types=Nothing all_fields=False = tables self name_like=Nothing database=self.database schema=self.schema types=Nothing all_fields=False =
self.connection.tables name_like database schema types all_fields self.connection.tables name_like database schema types all_fields
@ -88,7 +88,7 @@ type SQLite_Connection
- query: name of the table or sql statement to query. - query: name of the table or sql statement to query.
If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query. If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query.
- alias: optionally specify a friendly alias for the query. - alias: optionally specify a friendly alias for the query.
query : Text | SQL_Query -> Text -> Database_Table query : Text | SQL_Query -> Text -> Database_Table.Table
query self query alias="" = self.connection.query query alias query self query alias="" = self.connection.query query alias
## Execute the query and load the results into memory as a Table. ## Execute the query and load the results into memory as a Table.
@ -97,12 +97,12 @@ type SQLite_Connection
- query: name of the table or sql statement to query. - query: name of the table or sql statement to query.
If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query. If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query.
- limit: the maximum number of rows to return. - limit: the maximum number of rows to return.
read : Text | SQL_Query -> Integer | Nothing -> Table read : Text | SQL_Query -> Integer | Nothing -> Materialized_Table.Table
read self query limit=Nothing = self.connection.read query limit read self query limit=Nothing = self.connection.read query limit
## PRIVATE ## PRIVATE
Internal read function for a statement with optional types. Internal read function for a statement with optional types.
read_statement : Statement -> (Nothing | Vector SQL_Type) -> Table read_statement : Statement -> (Nothing | Vector SQL_Type) -> Materialized_Table.Table
read_statement self statement expected_types=Nothing = read_statement self statement expected_types=Nothing =
self.connection.read_statement statement expected_types self.connection.read_statement statement expected_types
@ -136,7 +136,7 @@ type SQLite_Connection
usually not be visible to other connections. usually not be visible to other connections.
- batch_size: Specifies how many rows should be uploaded in a single - batch_size: Specifies how many rows should be uploaded in a single
batch. batch.
upload_table : Text -> Materialized_Table -> Boolean -> Integer -> Database_Table upload_table : Text -> Materialized_Table.Table -> Boolean -> Integer -> Database_Table.Table
upload_table self name table temporary=True batch_size=1000 = Panic.recover Illegal_State_Error <| upload_table self name table temporary=True batch_size=1000 = Panic.recover Illegal_State_Error <|
self.connection.upload_table name table temporary batch_size self.connection.upload_table name table temporary batch_size

View File

@ -1,6 +1,6 @@
from Standard.Base import all hiding First, Last from Standard.Base import all hiding First, Last
from Standard.Table.Data.Aggregate_Column import all from Standard.Table.Data.Aggregate_Column.Aggregate_Column import all
import Standard.Database.Data.SQL import Standard.Database.Data.SQL
from Standard.Database.Data.SQL import SQL_Type, Statement, code from Standard.Database.Data.SQL import SQL_Type, Statement, code
import Standard.Database.Data.Dialect import Standard.Database.Data.Dialect

View File

@ -1,5 +1,3 @@
import Standard.Database.Data.Table
import Standard.Database.Data.Column
import Standard.Database.Data.SQL_Query import Standard.Database.Data.SQL_Query
import Standard.Database.Connection.Database import Standard.Database.Connection.Database
@ -12,9 +10,6 @@ import Standard.Database.Connection.Postgres_Options
import Standard.Database.Connection.SQLite_Options import Standard.Database.Connection.SQLite_Options
import Standard.Database.Connection.Redshift_Options import Standard.Database.Connection.Redshift_Options
export Standard.Database.Data.Table
export Standard.Database.Data.Column
export Standard.Database.Connection.SSL_Mode export Standard.Database.Connection.SSL_Mode
from Standard.Database.Connection.Credentials export Credentials, Username_And_Password from Standard.Database.Connection.Credentials export Credentials, Username_And_Password

View File

@ -6,7 +6,7 @@ import Standard.Base.System.Platform
import Standard.Base.Network.URI import Standard.Base.Network.URI
import Standard.Base.Data.Text.Regex.Engine.Default as Default_Engine import Standard.Base.Data.Text.Regex.Engine.Default as Default_Engine
import Standard.Table from Standard.Table import Table, Column
import Standard.Image import Standard.Image
import Standard.Image.Codecs import Standard.Image.Codecs
@ -240,41 +240,41 @@ geo_json = Json.parse <| '''
} }
## A small table column containing integers. ## A small table column containing integers.
integer_column : Table.Column.Column integer_column : Column.Column
integer_column = Table.Column.from_vector "Integer" [1, 4, 8, 2, 5] integer_column = Column.from_vector "Integer" [1, 4, 8, 2, 5]
## A small table column containing decimal numbers. ## A small table column containing decimal numbers.
decimal_column : Table.Column.Column decimal_column : Column.Column
decimal_column = Table.Column.from_vector "Decimal" [2.30, -2.1, Nothing, -10.1, 1.0] decimal_column = Column.from_vector "Decimal" [2.30, -2.1, Nothing, -10.1, 1.0]
## A small table column containing booleans. ## A small table column containing booleans.
bool_column_1 : Table.Column.Column bool_column_1 : Column.Column
bool_column_1 = Table.Column.from_vector "Bools" [True, True, False, True, False] bool_column_1 = Column.from_vector "Bools" [True, True, False, True, False]
## A small table column containing booleans. ## A small table column containing booleans.
bool_column_2 : Table.Column.Column bool_column_2 : Column.Column
bool_column_2 = Table.Column.from_vector "Bools" [False, True, Nothing, True, True] bool_column_2 = Column.from_vector "Bools" [False, True, Nothing, True, True]
## A small table column containing text. ## A small table column containing text.
text_column_1 : Table.Column.Column text_column_1 : Column.Column
text_column_1 = Table.Column.from_vector "Text" ["Hello,", "my", "name", "is", "Enso"] text_column_1 = Column.from_vector "Text" ["Hello,", "my", "name", "is", "Enso"]
## A small table column containing text. ## A small table column containing text.
text_column_2 : Table.Column.Column text_column_2 : Column.Column
text_column_2 = Table.Column.from_vector "Text" ["He,", "he", "he", "i", "so"] text_column_2 = Column.from_vector "Text" ["He,", "he", "he", "i", "so"]
## A simple table that contains basic shop inventory data for the food shop. ## A simple table that contains basic shop inventory data for the food shop.
inventory_table : Table.Table inventory_table : Table
inventory_table = csv.read . set_index "item_id" inventory_table = csv.read . set_index "item_id"
## A simple table that contains basic item popularity data for the food shop. ## A simple table that contains basic item popularity data for the food shop.
popularity_table : Table.Table popularity_table : Table
popularity_table = popularity_table =
table = (enso_project.data / "food_shop_popularity.csv") . read table = (enso_project.data / "food_shop_popularity.csv") . read
table.set_index "item_id" table.set_index "item_id"
## A simple tablethat contains basic transaction data for the food shop. ## A simple tablethat contains basic transaction data for the food shop.
transactions_table : Table.Table transactions_table : Table
transactions_table = transactions_table =
(enso_project.data / "food_shop_transactions.csv") . read (enso_project.data / "food_shop_transactions.csv") . read

View File

@ -1,5 +1,5 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table
## UNSTABLE ## UNSTABLE
@ -21,6 +21,6 @@ import Standard.Table
import Standard.Geo import Standard.Geo
example_point = Geo.point 51.509865 -0.118092 example_point = Geo.point 51.509865 -0.118092
point : Decimal -> Decimal -> Decimal -> Table.Table point : Decimal -> Decimal -> Decimal -> Table
point latitude longitude elevation=0 = point latitude longitude elevation=0 =
Table.new [["latitude", [latitude]], ["longitude", [longitude]], ["elevation", [elevation]]] Table.new [["latitude", [latitude]], ["longitude", [longitude]], ["elevation", [elevation]]]

View File

@ -1,5 +1,5 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table
polyglot java import com.google.api.client.googleapis.auth.oauth2.GoogleCredential polyglot java import com.google.api.client.googleapis.auth.oauth2.GoogleCredential
polyglot java import com.google.api.services.sheets.v4.SheetsScopes polyglot java import com.google.api.services.sheets.v4.SheetsScopes

View File

@ -8,7 +8,7 @@
> Example > Example
Read the active sheet of an XLSX from disk and convert it into a table. Read the active sheet of an XLSX from disk and convert it into a table.
import Standard.Table from Standard.Table import all
import Standard.Examples import Standard.Examples
example_xlsx_to_table = Examples.xlsx.read example_xlsx_to_table = Examples.xlsx.read
@ -27,12 +27,11 @@
to make sure the indices are correct. to make sure the indices are correct.
import Standard.Examples import Standard.Examples
import Standard.Table
example_join = example_join =
table_1 = Examples.inventory_table table_1 = Examples.inventory_table
table_2 = Examples.popularity_table table_2 = Examples.popularity_table
Table.join [table_1, table_2] table_1.join table_2
> Example > Example
Select only the items where more than half the stock has been sold. Select only the items where more than half the stock has been sold.
@ -60,7 +59,6 @@
well as the number of each item sold across those transactions. well as the number of each item sold across those transactions.
import Standard.Examples import Standard.Examples
import Standard.Table
example_group = example_group =
transactions = Examples.transactions_table transactions = Examples.transactions_table
@ -68,5 +66,5 @@
aggregated = transactions.group by="item_id" aggregated = transactions.group by="item_id"
num_transactions = aggregated.at "transaction_id" . reduce .length . rename "transaction_count" num_transactions = aggregated.at "transaction_id" . reduce .length . rename "transaction_count"
num_sold = aggregated.at "quantity" . reduce .sum . rename "num_sold" num_sold = aggregated.at "quantity" . reduce .sum . rename "num_sold"
Table.join [item_names, num_transactions, num_sold] item_names.join [num_transactions, num_sold]

View File

@ -10,7 +10,6 @@
well as the number of each item sold across those transactions. well as the number of each item sold across those transactions.
import Standard.Examples import Standard.Examples
import Standard.Table
example_group = example_group =
transactions = Examples.transactions_table transactions = Examples.transactions_table
@ -18,7 +17,7 @@
aggregated = transactions.group by="item_id" aggregated = transactions.group by="item_id"
num_transactions = aggregated.at "transaction_id" . reduce .length . rename "transaction_count" num_transactions = aggregated.at "transaction_id" . reduce .length . rename "transaction_count"
num_sold = aggregated.at "quantity" . reduce .sum . rename "num_sold" num_sold = aggregated.at "quantity" . reduce .sum . rename "num_sold"
Table.join [item_names, num_transactions, num_sold] item_names.join [num_transactions, num_sold]
> Example > Example
Compute the maximum value of a column, the minimum value, the sum of its Compute the maximum value of a column, the minimum value, the sum of its

View File

@ -9,7 +9,7 @@
> Example > Example
Read the active sheet of an XLSX from disk and convert it into a table. Read the active sheet of an XLSX from disk and convert it into a table.
import Standard.Table from Standard.Table import Table
import Standard.Examples import Standard.Examples
example_xlsx_to_table = Examples.xlsx.read example_xlsx_to_table = Examples.xlsx.read
@ -17,7 +17,7 @@
> Example > Example
Read a CSV from disk and convert it into a table. Read a CSV from disk and convert it into a table.
import Standard.Table from Standard.Table import Table
import Standard.Examples import Standard.Examples
example_csv_to_table = Examples.csv.read example_csv_to_table = Examples.csv.read
@ -25,6 +25,7 @@
> Example > Example
Write a table to an XLSX file. Write a table to an XLSX file.
from Standard.Table import Table
import Standard.Examples import Standard.Examples
example_to_xlsx = example_to_xlsx =
@ -34,6 +35,7 @@
> Example > Example
Write a table to a CSV file. Write a table to a CSV file.
from Standard.Table import Table
import Standard.Examples import Standard.Examples
example_to_csv = example_to_csv =

View File

@ -9,16 +9,15 @@
to make sure the indices are correct. to make sure the indices are correct.
import Standard.Examples import Standard.Examples
import Standard.Table
example_join = example_join =
table_1 = Examples.inventory_table table_1 = Examples.inventory_table
table_2 = Examples.popularity_table table_2 = Examples.popularity_table
Table.join [table_1, table_2] table_1.join table_2
> Example > Example
Join the popularity table and the inventory table to see the relative Join the popularity table and the inventory table to see the relative
popularities of the items in the shop inventory. popularity of the items in the shop inventory.
import Standard.Examples import Standard.Examples

View File

@ -46,7 +46,7 @@ number_input = Error.unimplemented "This function should not be called."
Creating a node containing a table with two columns, one titled "name", and Creating a node containing a table with two columns, one titled "name", and
the other titled "stars". the other titled "stars".
import Standard.Table from Standard.Table import Table
example_table_input = example_table_input =
column_1 = ["name", "Enso"] column_1 = ["name", "Enso"]

View File

@ -12,9 +12,9 @@ component-groups:
extends: extends:
- Standard.Base.Input: - Standard.Base.Input:
exports: exports:
- Standard.Table.Data.Table.new - Standard.Table.Data.Table.Table.new
- Standard.Table.Data.Table.from_rows - Standard.Table.Data.Table.Table.from_rows
- Standard.Table.Data.Column.from_vector - Standard.Table.Data.Column.Column.from_vector
- Standard.Base.System.File.read - Standard.Base.System.File.read
- Standard.Base.Select: - Standard.Base.Select:
exports: exports:

View File

@ -1,12 +1,8 @@
from Standard.Base import all from Standard.Base import all
from Standard.Table.Data.Column import Column import Standard.Table.Data.Column.Column
from Standard.Table.Data.Column_Selector import Column_Selector import Standard.Table.Data.Column_Selector.Column_Selector
from Standard.Table.Data.Sort_Column_Selector import Sort_Column_Selector import Standard.Table.Data.Sort_Column_Selector.Sort_Column_Selector
# TODO Dubious constructor export
from project.Data.Aggregate_Column.Aggregate_Column import all
from project.Data.Aggregate_Column.Aggregate_Column export all
## Defines an Aggregate Column ## Defines an Aggregate Column
type Aggregate_Column type Aggregate_Column

View File

@ -2,34 +2,34 @@ from Standard.Base import all
import Standard.Base.Data.Ordering.Comparator import Standard.Base.Data.Ordering.Comparator
import Standard.Base.Data.Index_Sub_Range import Standard.Base.Data.Index_Sub_Range
import Standard.Table.Data.Table import Standard.Table.Data.Table.Table
import Standard.Table.Data.Storage from Standard.Table.Data.Table import print_table
from Standard.Table.Data.Value_Type import Value_Type import Standard.Table.Data.Storage.Storage
import Standard.Table.Data.Value_Type.Value_Type
# TODO Dubious constructor export from project.Errors import No_Index_Set_Error
from Standard.Table.Data.Column.Column import all
from Standard.Table.Data.Column.Column export all
polyglot java import org.enso.table.data.table.Column as Java_Column polyglot java import org.enso.table.data.table.Column as Java_Column
polyglot java import org.enso.table.operations.OrderBuilder polyglot java import org.enso.table.operations.OrderBuilder
## Creates a new column given a name and a vector of elements. from project.Data.Column.Column import Column_Data
Arguments:
- name: The name of the column to create.
- items: The elements to contain in the column.
> Example
Create a new column called "My Column" from a vector of numbers.
import Standard.Table
example_from_vector =
Table.Column.from_vector "My Column" [1, 2, 3, 4, 5]
from_vector : Text -> Vector -> Column
from_vector name items = Column_Data (Java_Column.fromItems name items.to_array)
type Column type Column
## Creates a new column given a name and a vector of elements.
Arguments:
- name: The name of the column to create.
- items: The elements to contain in the column.
> Example
Create a new column called "My Column" from a vector of numbers.
from Standard.Table import Column
example_from_vector =
Column.from_vector "My Column" [1, 2, 3, 4, 5]
from_vector : Text -> Vector -> Column
from_vector name items = Column_Data (Java_Column.fromItems name items.to_array)
## PRIVATE ## PRIVATE
@ -63,7 +63,7 @@ type Column
row = if storage.isNa num then "Nothing" else row = if storage.isNa num then "Nothing" else
get_item_string storage num get_item_string storage num
[index.ilocString num, row] [index.ilocString num, row]
table = Table.print_table [index.getName, col_name] items 1 format_terminal table = print_table [index.getName, col_name] items 1 format_terminal
if num_rows - display_rows <= 0 then table else if num_rows - display_rows <= 0 then table else
missing = '\n\u2026 and ' + (num_rows - display_rows).to_text + ' hidden rows.' missing = '\n\u2026 and ' + (num_rows - display_rows).to_text + ' hidden rows.'
table + missing table + missing
@ -687,9 +687,9 @@ type Column
import Standard.Examples import Standard.Examples
example_index = Examples.decimal_column.index example_index = Examples.decimal_column.index
index : Column ! Table.No_Index_Set_Error index : Column ! No_Index_Set_Error
index self = case self.java_column.getIndex.toColumn of index self = case self.java_column.getIndex.toColumn of
Nothing -> Error.throw Table.No_Index_Set_Error Nothing -> Error.throw No_Index_Set_Error
i -> Column_Data i i -> Column_Data i
## Sets the index of this column, using the provided column. ## Sets the index of this column, using the provided column.
@ -748,7 +748,7 @@ type Column
import Standard.Examples import Standard.Examples
example_storage_type = Examples.integer_column.storage_type example_storage_type = Examples.integer_column.storage_type
storage_type : Storage.Type storage_type : Storage
storage_type self = storage_type self =
tp = self.java_column.getStorage.getType tp = self.java_column.getStorage.getType
storage_types.at tp . catch Index_Out_Of_Bounds_Error _-> storage_types.at tp . catch Index_Out_Of_Bounds_Error _->
@ -816,7 +816,7 @@ type Column
import Standard.Examples import Standard.Examples
example_join = Examples.integer_column.join Examples.bool_column_1 example_join = Examples.integer_column.join Examples.bool_column_1
join : Table.Table | Column -> Text | Nothing -> Boolean -> Text -> Text -> Table join : Table | Column -> Text | Nothing -> Boolean -> Text -> Text -> Table
join self other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' = join self other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' =
self.to_table.join other on drop_unmatched left_suffix right_suffix self.to_table.join other on drop_unmatched left_suffix right_suffix
@ -828,7 +828,7 @@ type Column
import Standard.Examples import Standard.Examples
example_to_table = Examples.integer_column.to_table example_to_table = Examples.integer_column.to_table
to_table : Table.Table to_table : Table
to_table self = Table.Table_Data self.java_column.toTable to_table self = Table.Table_Data self.java_column.toTable
## UNSTABLE ## UNSTABLE
@ -1091,168 +1091,6 @@ type Column
duplicate_count : Column duplicate_count : Column
duplicate_count self = Column_Data self.java_column.duplicateCount duplicate_count self = Column_Data self.java_column.duplicateCount
# TODO Dubious constructor export
from project.Data.Column.Aggregate_Column import all
from project.Data.Column.Aggregate_Column export all
## Wraps a column grouped by its index. Allows performing aggregation operations
on the contained values.
type Aggregate_Column
## PRIVATE
Aggregate_Column_Data java_column
## Converts this aggregate column into a column, aggregating groups
with the provided `function`.
Arguments:
- function: the function used for value aggregation. Values belonging to
each group are passed to this function in a vector.
- skip_missing: controls whether missing values should be included in
groups.
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
> Example
Convert an aggregate column of transaction ids into a column by
counting the number of transactions. per item.
import Standard.Examples
example_reduce =
Examples.aggregate_column.reduce .length . rename "transaction_count"
reduce : (Vector.Vector -> Any) -> Boolean -> Text -> Column
reduce self function skip_missing=True name_suffix="_result" =
f arr = function (Vector.from_polyglot_array arr)
r = self.java_column.aggregate Nothing name_suffix f skip_missing
Column_Data r
## Sums the values in each group.
Arguments:
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
> Example
Convert an aggregate column of transaction ids into a column by summing
the transaction IDs together.
import Standard.Examples
example_sum = Examples.aggregate_column.sum . rename "id_sum"
sum : Text -> Column
sum self name_suffix='_sum' =
r = self.java_column.aggregate 'sum' name_suffix (x-> Vector.from_polyglot_array x . reduce (+)) True
Column r
## Computes the maximum element of each group.
Arguments:
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
> Example
Get the latest (maximum ID) transaction id for each item.
import Standard.Examples
example_max = Examples.aggregate_column.max . rename "latest_transaction"
max : Text -> Column
max self name_suffix='_max' =
r = self.java_column.aggregate 'max' name_suffix (x-> Vector.from_polyglot_array x . reduce Math.max) True
Column_Data r
## Computes the minimum element of each group.
Arguments:
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
> Example
Get the earliest (mimumum ID) transaction id for each item.
import Standard.Examples
example_min = Examples.aggregate_column.min . rename "first_transaction"
min : Text -> Column
min self name_suffix='_min' =
r = self.java_column.aggregate 'min' name_suffix (x-> Vector.from_polyglot_array x . reduce Math.min) True
Column_Data r
## Computes the number of non-missing elements in each group.
Arguments:
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
> Example
Count the number of non-missing elements in each group in the column,
which gives the number of transactions in which a given item was sold.
import Standard.Examples
example_count = Examples.aggregate_column.count . rename "transaction_count"
count : Text -> Column
count self name_suffix='_count' =
r = self.java_column.aggregate 'count' name_suffix (x-> x.length) True
Column_Data r
## Computes the mean of non-missing elements in each group.
Arguments:
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
> Example
Get the mean transaction id for each item.
import Standard.Examples
example_mean = Examples.aggregate_column.mean
mean : Text -> Column
mean self name_suffix='_mean' =
vec_mean v = if v.length == 0 then Nothing else
(Vector.from_polyglot_array v).reduce (+) / v.length
r = self.java_column.aggregate 'mean' name_suffix vec_mean True
Column_Data r
## Gathers all elements in a group into a vector and returns a column of
such vectors.
Arguments:
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
> Example
Gather the values of the aggregate column together.
import Standard.Examples
example_values = Examples.aggregate_column.values
values : Text -> Column
values self name_suffix='_values' =
r = self.java_column.aggregate Nothing name_suffix Vector.from_polyglot_array False
Column_Data r
## Prints an ASCII-art column with this data to the standard output.
Arguments:
- show_rows: the number of initial rows that should be displayed.
> Example
Pretty-print an aggregate column and display it using the standard
output.
import Standard.Examples
example_print = Examples.aggregate_column.print
print : Nothing
print self = self.values.print
# TODO Dubious constructor export
from project.Data.Column.Empty_Error import all
from project.Data.Column.Empty_Error export all
## UNSTABLE ## UNSTABLE
An error for when the column contains no elements. An error for when the column contains no elements.
@ -1274,17 +1112,17 @@ type Empty_Error
- operand: The operand to apply to the function after `column`. - operand: The operand to apply to the function after `column`.
run_vectorized_binary_op : Column -> Text -> (Any -> Any) -> Any -> Column run_vectorized_binary_op : Column -> Text -> (Any -> Any) -> Any -> Column
run_vectorized_binary_op column name fallback_fn operand = case operand of run_vectorized_binary_op column name fallback_fn operand = case operand of
Column_Data col2 -> Column.Column_Data col2 ->
s1 = column.java_column.getStorage s1 = column.java_column.getStorage
ix = column.java_column.getIndex ix = column.java_column.getIndex
s2 = col2.getStorage s2 = col2.getStorage
rs = s1.zip name fallback_fn s2 True rs = s1.zip name fallback_fn s2 True
Column_Data (Java_Column.new "Result" ix rs) Column.Column_Data (Java_Column.new "Result" ix rs)
_ -> _ ->
s1 = column.java_column.getStorage s1 = column.java_column.getStorage
ix = column.java_column.getIndex ix = column.java_column.getIndex
rs = s1.bimap name fallback_fn operand rs = s1.bimap name fallback_fn operand
Column_Data (Java_Column.new "Result" ix rs) Column.Column_Data (Java_Column.new "Result" ix rs)
## PRIVATE ## PRIVATE
@ -1299,19 +1137,19 @@ run_vectorized_unary_op column name fallback_fn =
s = column.java_column.getStorage s = column.java_column.getStorage
ix = column.java_column.getIndex ix = column.java_column.getIndex
rs = s.map name fallback_fn rs = s.map name fallback_fn
Column_Data (Java_Column.new "Result" ix rs) Column.Column_Data (Java_Column.new "Result" ix rs)
## PRIVATE ## PRIVATE
Enumerates storage types in a way that is consistent with Enumerates storage types in a way that is consistent with
`org.enso.table.data.Storage.Type`, i.e. `org.enso.table.data.Storage.Storage`, i.e.
`storage_type.at org.enso.table.data.Storage.Type.LONG` will yield the `storage_type.at org.enso.table.data.Storage.Storage.LONG` will yield the
corresponding `Storage.Integer`. corresponding `Storage.Integer`.
storage_types : Vector Storage.Type storage_types : Vector Storage
storage_types = [Storage.Any, Storage.Integer, Storage.Decimal, Storage.Text, Storage.Boolean, Storage.Date, Storage.Time_Of_Day, Storage.Date_Time] storage_types = [Storage.Any, Storage.Integer, Storage.Decimal, Storage.Text, Storage.Boolean, Storage.Date, Storage.Time_Of_Day, Storage.Date_Time]
## PRIVATE ## PRIVATE
Keep this in sync with `org.enso.table.data.Storage.Type.STRING` Keep this in sync with `org.enso.table.data.Storage.Storage.STRING`
storage_type_string : Integer storage_type_string : Integer
storage_type_string = 3 storage_type_string = 3

View File

@ -1,9 +1,5 @@
from Standard.Base import all from Standard.Base import all
# TODO Dubious constructor export
from project.Data.Column_Name_Mapping.Column_Name_Mapping import all
from project.Data.Column_Name_Mapping.Column_Name_Mapping export all
## Specifies a selection of columns from the table and the new name for them to ## Specifies a selection of columns from the table and the new name for them to
become. become.
type Column_Name_Mapping type Column_Name_Mapping

View File

@ -1,9 +1,5 @@
from Standard.Base import all from Standard.Base import all
# TODO Dubious constructor export
from project.Data.Column_Selector.Column_Selector import all
from project.Data.Column_Selector.Column_Selector export all
## Specifies a selection of columns from the table on which an operation is ## Specifies a selection of columns from the table on which an operation is
going to be performed. going to be performed.
type Column_Selector type Column_Selector

View File

@ -1,8 +1,9 @@
from Standard.Base import all from Standard.Base import all
import Standard.Base.Error.Common as Errors import Standard.Base.Error.Common as Errors
from Standard.Table.Data.Column_Type_Selection import Auto import Standard.Table.Data.Column_Type_Selection.Auto
import Standard.Table.Data.Storage import Standard.Table.Data.Storage.Storage
import Standard.Table.Internal.Parse_Values_Helper import Standard.Table.Internal.Parse_Values_Helper
polyglot java import org.enso.table.parsing.IntegerParser polyglot java import org.enso.table.parsing.IntegerParser
@ -24,10 +25,6 @@ polyglot java import org.enso.table.formatting.DateTimeFormatter
polyglot java import org.enso.table.formatting.TimeFormatter polyglot java import org.enso.table.formatting.TimeFormatter
polyglot java import org.enso.table.formatting.TextFormatter polyglot java import org.enso.table.formatting.TextFormatter
# TODO Dubious constructor export
from project.Data.Data_Formatter.Data_Formatter import all
from project.Data.Data_Formatter.Data_Formatter export all
type Data_Formatter type Data_Formatter
## Specifies options for reading text data in a table to more specific types and ## Specifies options for reading text data in a table to more specific types and
serializing them back. serializing them back.
@ -57,7 +54,7 @@ type Data_Formatter
- datetime_locale: The locale to use when parsing dates and times. - datetime_locale: The locale to use when parsing dates and times.
- true_values: Values representing True. - true_values: Values representing True.
- false_values: Values representing False. - false_values: Values representing False.
Data_Formatter_Data trim_values:Boolean=True allow_leading_zeros:Boolean=False decimal_point:Text='.' thousand_separator:Text='' allow_exponential_notation:Boolean=False datetime_formats:[Text]=["yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm"] date_formats:[Text]=["yyyy-MM-dd"] time_formats:[Text]=["HH:mm:ss", "HH:mm"] datetime_locale:Locale=Locale.default true_values:[Text]=["True","true","TRUE"] false_values:[Text]=["False","false","FALSE"] Value trim_values:Boolean=True allow_leading_zeros:Boolean=False decimal_point:Text='.' thousand_separator:Text='' allow_exponential_notation:Boolean=False datetime_formats:[Text]=["yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm"] date_formats:[Text]=["yyyy-MM-dd"] time_formats:[Text]=["HH:mm:ss", "HH:mm"] datetime_locale:Locale=Locale.default true_values:[Text]=["True","true","TRUE"] false_values:[Text]=["False","false","FALSE"]
## Parse a Text into a value. ## Parse a Text into a value.
@ -125,14 +122,14 @@ type Data_Formatter
Arguments: Arguments:
- locale: The locale to use when parsing dates and times. - locale: The locale to use when parsing dates and times.
with_locale : Locale -> Data_Formatter_Data with_locale : Locale -> Data_Formatter
with_locale self datetime_locale = self.clone datetime_locale=datetime_locale with_locale self datetime_locale = self.clone datetime_locale=datetime_locale
## PRIVATE ## PRIVATE
Clone the instance with some properties overridden. Clone the instance with some properties overridden.
clone : Boolean -> Boolean -> Text -> Text -> Boolean -> [Text] -> [Text] -> [Text] -> Locale -> [Text] -> [Text] -> Data_Formatter clone : Boolean -> Boolean -> Text -> Text -> Boolean -> [Text] -> [Text] -> [Text] -> Locale -> [Text] -> [Text] -> Data_Formatter
clone self (trim_values=self.trim_values) (allow_leading_zeros=self.allow_leading_zeros) (decimal_point=self.decimal_point) (thousand_separator=self.thousand_separator) (allow_exponential_notation=self.allow_exponential_notation) (datetime_formats=self.datetime_formats) (date_formats=self.date_formats) (time_formats=self.time_formats) (datetime_locale=self.datetime_locale) (true_values=self.true_values) (false_values=self.false_values) = clone self (trim_values=self.trim_values) (allow_leading_zeros=self.allow_leading_zeros) (decimal_point=self.decimal_point) (thousand_separator=self.thousand_separator) (allow_exponential_notation=self.allow_exponential_notation) (datetime_formats=self.datetime_formats) (date_formats=self.date_formats) (time_formats=self.time_formats) (datetime_locale=self.datetime_locale) (true_values=self.true_values) (false_values=self.false_values) =
Data_Formatter_Data trim_values=trim_values allow_leading_zeros=allow_leading_zeros decimal_point=decimal_point thousand_separator=thousand_separator allow_exponential_notation=allow_exponential_notation datetime_formats=datetime_formats date_formats=date_formats time_formats=time_formats datetime_locale=datetime_locale true_values=true_values false_values=false_values Data_Formatter.Value trim_values=trim_values allow_leading_zeros=allow_leading_zeros decimal_point=decimal_point thousand_separator=thousand_separator allow_exponential_notation=allow_exponential_notation datetime_formats=datetime_formats date_formats=date_formats time_formats=time_formats datetime_locale=datetime_locale true_values=true_values false_values=false_values
## PRIVATE ## PRIVATE
get_thousand_separator self = get_thousand_separator self =

View File

@ -1,9 +1,5 @@
from Standard.Base import all from Standard.Base import all
# TODO Dubious constructor export
from project.Data.Match_Columns.Match_Columns import all
from project.Data.Match_Columns.Match_Columns export all
## Specifies how to join columns in the table to existing data. ## Specifies how to join columns in the table to existing data.
type Match_Columns type Match_Columns
## Columns are matched by Name against an existing file. ## Columns are matched by Name against an existing file.

View File

@ -1,9 +1,5 @@
from Standard.Base import all from Standard.Base import all
# TODO Dubious constructor export
from project.Data.Position.Position import all
from project.Data.Position.Position export all
type Position type Position
## UNSTABLE ## UNSTABLE
Selected columns will be moved to the front of the output table. Selected columns will be moved to the front of the output table.

View File

@ -1,9 +1,5 @@
from Standard.Base import all from Standard.Base import all
# TODO Dubious constructor export
from project.Data.Sort_Column.Sort_Column import all
from project.Data.Sort_Column.Sort_Column export all
type Sort_Column type Sort_Column
Name name:Text direction:Sort_Direction=Sort_Direction.Ascending Name name:Text direction:Sort_Direction=Sort_Direction.Ascending
Index index:Integer direction:Sort_Direction=Sort_Direction.Ascending Index index:Integer direction:Sort_Direction=Sort_Direction.Ascending

View File

@ -1,10 +1,7 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table.Data.Sort_Column import Standard.Table.Data.Column.Column
import Standard.Table.Data.Sort_Column.Sort_Column
# TODO Dubious constructor export
from project.Data.Sort_Column_Selector.Sort_Column_Selector import all
from project.Data.Sort_Column_Selector.Sort_Column_Selector export all
type Sort_Column_Selector type Sort_Column_Selector
By_Name (columns : Vector (Sort_Column.Name | Text)) (matcher:Matcher=Text_Matcher.Case_Sensitive) By_Name (columns : Vector (Sort_Column.Name | Text)) (matcher:Matcher=Text_Matcher.Case_Sensitive)

View File

@ -1,9 +1,5 @@
# TODO Dubious constructor export
from project.Data.Storage.Type import all
from project.Data.Storage.Type export all
## Represents different types of underlying storage for Columns. ## Represents different types of underlying storage for Columns.
type Type type Storage
## A column storing text data. ## A column storing text data.
Text Text

View File

@ -6,35 +6,30 @@ import Standard.Base.Data.Ordering.Comparator
import Standard.Base.Data.Text.Case import Standard.Base.Data.Text.Case
import Standard.Base.System.Platform import Standard.Base.System.Platform
import Standard.Table.Data.Column import Standard.Table.Data.Column.Column
from Standard.Table.Data.Filter_Condition import make_filter_column, Filter_Condition from Standard.Table.Data.Filter_Condition import make_filter_column, Filter_Condition
import Standard.Table.Internal.Table_Helpers import Standard.Table.Internal.Table_Helpers
import Standard.Table.Internal.Aggregate_Column_Helper import Standard.Table.Internal.Aggregate_Column_Helper
import Standard.Table.Internal.Parse_Values_Helper import Standard.Table.Internal.Parse_Values_Helper
import Standard.Table.Internal.Problem_Builder import Standard.Table.Internal.Problem_Builder.Problem_Builder
from Standard.Table.IO.Auto_Detect import Auto_Detect import Standard.Table.IO.Auto_Detect.Auto_Detect
from Standard.Table.Delimited.Delimited_Format import Delimited_Format, Delimited from Standard.Table.Delimited.Delimited_Format import Delimited_Format, Delimited
import Standard.Table.Delimited.Delimited_Reader
import Standard.Table.Delimited.Delimited_Writer
from Standard.Table.Data.Column_Selector import Column_Selector, By_Index, By_Name import Standard.Table.Data.Column_Selector.Column_Selector
from Standard.Table.Data.Column_Type_Selection import Column_Type_Selection, Auto from Standard.Table.Data.Column_Type_Selection import Column_Type_Selection, Auto
from Standard.Table.Data.Data_Formatter import Data_Formatter, Data_Formatter_Data import Standard.Table.Data.Data_Formatter.Data_Formatter
from Standard.Table.Errors import Missing_Input_Columns, Column_Indexes_Out_Of_Range, Duplicate_Type_Selector, No_Index_Set_Error, No_Such_Column_Error, No_Such_Column_Error_Data, No_Input_Columns_Selected, No_Output_Columns from Standard.Table.Errors import Missing_Input_Columns, Column_Indexes_Out_Of_Range, Duplicate_Type_Selector, No_Index_Set_Error, No_Such_Column_Error, No_Such_Column_Error_Data, No_Input_Columns_Selected, No_Output_Columns
import Standard.Table.Data.Match_Columns import Standard.Table.Data.Match_Columns.Match_Columns
import Standard.Table.Data.Column_Name_Mapping from Standard.Table.Data.Column_Name_Mapping import Column_Name_Mapping
import Standard.Table.Data.Position import Standard.Table.Data.Position.Position
import Standard.Table.Data.Sort_Column_Selector import Standard.Table.Data.Sort_Column_Selector.Sort_Column_Selector
import Standard.Table.Data.Sort_Column import Standard.Table.Data.Sort_Column.Sort_Column
# TODO Dubious constructor export import Standard.Table.Data.Aggregate_Column.Aggregate_Column
from Standard.Table.Data.Table.Table import all
from Standard.Table.Data.Table.Table export all
import Standard.Table.Data.Aggregate_Column
import Standard.Visualization import Standard.Visualization
polyglot java import org.enso.table.data.table.Table as Java_Table polyglot java import org.enso.table.data.table.Table as Java_Table
@ -42,105 +37,54 @@ polyglot java import org.enso.table.data.table.Column as Java_Column
polyglot java import org.enso.table.operations.OrderBuilder polyglot java import org.enso.table.operations.OrderBuilder
polyglot java import org.enso.table.data.mask.OrderMask polyglot java import org.enso.table.data.mask.OrderMask
## Creates a new table from a vector of `[name, items]` pairs.
Arguments:
- columns: The `[name, items]` pairs to construct a new table from.
> Example
Create a new table with the given columns.
import Standard.Table
example_new =
first_column = ["count", [1, 2, 3]]
second_column = ["is_valid", [True, False, True]]
Table.new [first_column, second_column]
new : Vector (Vector | Column) -> Table
new columns =
cols = columns.map c->
case c of
_ : Vector.Vector -> Column.from_vector (c.at 0) (c.at 1) . java_column
Column.Column_Data java_col -> java_col
from_columns cols
## Creates a new table from a vector of column names and a vector of vectors
specifying row contents.
Arguments:
- header: A list of texts specifying the column names
- rows: A vector of vectors, specifying the contents of each table row. The
length of each element of `rows` must be equal in length to `header`.
> Example
Create a table with 3 columns, named `foo`, `bar`, and `baz`, containing
`[1, 2, 3]`, `[True, False, True]`, and `['a', 'b', 'c']`, respectively.
import Standard.Table
example_from_rows =
header = [ 'foo' , 'bar' , 'baz' ]
row_1 = [ 1 , True , 'a' ]
row_2 = [ 2 , False , 'b' ]
row_3 = [ 3 , True , 'c' ]
Table.from_rows header [row_1, row_2, row_3]
from_rows : Vector.Vector -> Vector.Vector -> Table
from_rows header rows =
columns = header.map_with_index i-> name-> [name, rows.map (_.at i)]
new columns
## ALIAS Join Tables
Joins a vector of tables (or columns) into a single table, using each table's
index as the join key.
Arguments:
- tables: A vector of tables to join into a single table.
Particularly useful for joining multiple columns derived from one original
table into a new table.
> Example
Join multiple tables together. It joins tables on their indices, so we need
to make sure the indices are correct.
import Standard.Examples
import Standard.Table
example_join =
table_1 = Examples.inventory_table
table_2 = Examples.popularity_table
Table.join [table_1, table_2]
join : Vector -> Table
join tables =
tables.reduce .join
## UNSTABLE
Concatenates multiple tables, resulting in a table with the number of rows
being the sum of numbers of rows of `tables`. Any column that is present in
some tables, but missing in others, will be `Nothing`-padded in the positions
corresponding to the missing values.
Arguments:
- tables: the tables to concatenate.
> Example
Concatenate multiple tables together.
import Standard.Examples
import Standard.Table
example_concat =
table_1 = Examples.inventory_table
table_2 = Examples.popularity_table
Table.concat [table_1, table_2]
concat : Vector -> Table
concat tables =
Table_Data (Java_Table.concat (tables.map .java_table).to_array)
## Represents a column-oriented table data structure. ## Represents a column-oriented table data structure.
type Table type Table
## Creates a new table from a vector of `[name, items]` pairs.
Arguments:
- columns: The `[name, items]` pairs to construct a new table from.
> Example
Create a new table with the given columns.
from Standard.Table import Table
example_new =
first_column = ["count", [1, 2, 3]]
second_column = ["is_valid", [True, False, True]]
Table.new [first_column, second_column]
new : Vector (Vector | Column) -> Table
new columns =
cols = columns.map c->
case c of
_ : Vector.Vector -> Column.from_vector (c.at 0) (c.at 1) . java_column
Column.Column_Data java_col -> java_col
Table.Table_Data (Java_Table.new cols.to_array)
## Creates a new table from a vector of column names and a vector of vectors
specifying row contents.
Arguments:
- header: A list of texts specifying the column names
- rows: A vector of vectors, specifying the contents of each table row. The
length of each element of `rows` must be equal in length to `header`.
> Example
Create a table with 3 columns, named `foo`, `bar`, and `baz`, containing
`[1, 2, 3]`, `[True, False, True]`, and `['a', 'b', 'c']`, respectively.
from Standard.Table import Table
example_from_rows =
header = [ 'foo' , 'bar' , 'baz' ]
row_1 = [ 1 , True , 'a' ]
row_2 = [ 2 , False , 'b' ]
row_3 = [ 3 , True , 'c' ]
Table.from_rows header [row_1, row_2, row_3]
from_rows : Vector.Vector -> Vector.Vector -> Table
from_rows header rows =
columns = header.map_with_index i-> name-> [name, rows.map (_.at i)]
Table.new columns
## PRIVATE ## PRIVATE
@ -301,7 +245,7 @@ type Table
> Example > Example
Select columns by name. Select columns by name.
table.select_columns (By_Name ["bar", "foo"]) table.select_columns (Column_Selector.By_Name ["bar", "foo"])
> Example > Example
Select columns using names passed as a Vector. Select columns using names passed as a Vector.
@ -311,23 +255,23 @@ type Table
> Example > Example
Select columns matching a regular expression. Select columns matching a regular expression.
table.select_columns (By_Name ["foo.+", "b.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Insensitive)) table.select_columns (Column_Selector.By_Name ["foo.+", "b.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Insensitive))
> Example > Example
Select the first two columns and the last column, moving the last one to front. Select the first two columns and the last column, moving the last one to front.
table.select_columns (By_Index [-1, 0, 1]) reorder=True table.select_columns (Column_Selector.By_Index [-1, 0, 1]) reorder=True
> Example > Example
Select columns with the same names as the ones provided. Select columns with the same names as the ones provided.
table.select_columns (By_Column [column1, column2]) table.select_columns (Column_Selector.By_Column [column1, column2])
Icon: select_column Icon: select_column
select_columns : Vector Text | Column_Selector -> Boolean -> Problem_Behavior -> Table select_columns : Vector Text | Column_Selector -> Boolean -> Problem_Behavior -> Table
select_columns self (columns = By_Index [0]) (reorder = False) (on_problems = Report_Warning) = select_columns self (columns = Column_Selector.By_Index [0]) (reorder = False) (on_problems = Report_Warning) =
new_columns = Table_Helpers.select_columns internal_columns=self.columns selector=columns reorder=reorder on_problems=on_problems new_columns = Table_Helpers.select_columns internal_columns=self.columns selector=columns reorder=reorder on_problems=on_problems
new new_columns Table.new new_columns
## Returns a new table with the chosen set of columns, as specified by the ## 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 `columns`, removed from the input table. Any unmatched input columns will
@ -353,7 +297,7 @@ type Table
> Example > Example
Remove columns with given names. Remove columns with given names.
table.remove_columns (By_Name ["bar", "foo"]) table.remove_columns (Column_Selector.By_Name ["bar", "foo"])
> Example > Example
Remove columns using names passed as a Vector. Remove columns using names passed as a Vector.
@ -363,21 +307,21 @@ type Table
> Example > Example
Remove columns matching a regular expression. Remove columns matching a regular expression.
table.remove_columns (By_Name ["foo.+", "b.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Insensitive)) table.remove_columns (Column_Selector.By_Name ["foo.+", "b.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Insensitive))
> Example > Example
Remove the first two columns and the last column. Remove the first two columns and the last column.
table.remove_columns (By_Index [-1, 0, 1]) table.remove_columns (Column_Selector.By_Index [-1, 0, 1])
> Example > Example
Remove columns with the same names as the ones provided. Remove columns with the same names as the ones provided.
table.remove_columns (By_Column [column1, column2]) table.remove_columns (Column_Selector.By_Column [column1, column2])
remove_columns : Vector Text | Column_Selector -> Problem_Behavior -> Table remove_columns : Vector Text | Column_Selector -> Problem_Behavior -> Table
remove_columns self (columns = By_Index [0]) (on_problems = Report_Warning) = remove_columns self (columns = Column_Selector.By_Index [0]) (on_problems = Report_Warning) =
new_columns = Table_Helpers.remove_columns internal_columns=self.columns selector=columns on_problems=on_problems new_columns = Table_Helpers.remove_columns internal_columns=self.columns selector=columns on_problems=on_problems
new new_columns Table.new new_columns
## Returns a new table with the specified selection of columns moved to ## Returns a new table with the specified selection of columns moved to
either the start or the end in the specified order. either the start or the end in the specified order.
@ -403,7 +347,7 @@ type Table
> Example > Example
Move a column with a specified name to back. Move a column with a specified name to back.
table.reorder_columns (By_Name ["foo"]) position=After_Other_Columns table.reorder_columns (Column_Selector.By_Name ["foo"]) position=After_Other_Columns
> Example > Example
Move columns using names passed as a Vector. Move columns using names passed as a Vector.
@ -413,26 +357,26 @@ type Table
> Example > Example
Move columns matching a regular expression to front, keeping columns matching "foo.+" before columns matching "b.*". Move columns matching a regular expression to front, keeping columns matching "foo.+" before columns matching "b.*".
table.reorder_columns (By_Name ["foo.+", "b.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Insensitive)) table.reorder_columns (Column_Selector.By_Name ["foo.+", "b.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Insensitive))
> Example > Example
Swap the first two columns. Swap the first two columns.
table.reorder_columns (By_Index [1, 0]) position=Before_Other_Columns table.reorder_columns (Column_Selector.By_Index [1, 0]) position=Before_Other_Columns
> Example > Example
Move the first column to back. Move the first column to back.
table.reorder_columns (By_Index [0]) position=After_Other_Columns table.reorder_columns (Column_Selector.By_Index [0]) position=After_Other_Columns
> Example > Example
Move the columns with names matching the provided columns to the front. Move the columns with names matching the provided columns to the front.
table.reorder_columns (By_Column [column1, column2]) table.reorder_columns (Column_Selector.By_Column [column1, column2])
reorder_columns : Vector Text | Column_Selector -> Position.Position -> Problem_Behavior -> Table reorder_columns : Vector Text | Column_Selector -> Position.Position -> Problem_Behavior -> Table
reorder_columns self (columns = By_Index [0]) (position = Position.Before_Other_Columns) (on_problems = Report_Warning) = reorder_columns self (columns = Column_Selector.By_Index [0]) (position = Position.Before_Other_Columns) (on_problems = Report_Warning) =
new_columns = Table_Helpers.reorder_columns internal_columns=self.columns selector=columns position=position on_problems=on_problems new_columns = Table_Helpers.reorder_columns internal_columns=self.columns selector=columns position=position on_problems=on_problems
new new_columns Table.new new_columns
## Returns a new table with the columns sorted by name according to the ## Returns a new table with the columns sorted by name according to the
specified sort method. By default, sorting will be according to specified sort method. By default, sorting will be according to
@ -460,7 +404,7 @@ type Table
sort_columns : Sort_Direction -> Text_Ordering -> Table sort_columns : Sort_Direction -> Text_Ordering -> Table
sort_columns self direction=Sort_Direction.Ascending text_ordering=Text_Ordering.Default = sort_columns self direction=Sort_Direction.Ascending text_ordering=Text_Ordering.Default =
new_columns = Table_Helpers.sort_columns internal_columns=self.columns direction text_ordering new_columns = Table_Helpers.sort_columns internal_columns=self.columns direction text_ordering
new new_columns Table.new new_columns
## Returns a new table with the columns renamed based on either a mapping ## Returns a new table with the columns renamed based on either a mapping
from the old name to the new or a positional list of new names. from the old name to the new or a positional list of new names.
@ -503,7 +447,7 @@ type Table
new_names = Table_Helpers.rename_columns internal_columns=self.columns mapping=column_map on_problems=on_problems new_names = Table_Helpers.rename_columns internal_columns=self.columns mapping=column_map on_problems=on_problems
if new_names.is_error then new_names else if new_names.is_error then new_names else
new_columns = self.columns.map_with_index i->c->(c.rename (new_names.at i)) new_columns = self.columns.map_with_index i->c->(c.rename (new_names.at i))
new new_columns Table.new new_columns
## Returns a new table with the columns renamed based on entries in the ## Returns a new table with the columns renamed based on entries in the
first row. first row.
@ -569,7 +513,7 @@ type Table
new_columns = validated.valid_columns.map c->(Aggregate_Column_Helper.java_aggregator c.first c.second) new_columns = validated.valid_columns.map c->(Aggregate_Column_Helper.java_aggregator c.first c.second)
java_table = index.makeTable new_columns.to_array java_table = index.makeTable new_columns.to_array
new_table = Table_Data java_table new_table = Table.Table_Data java_table
on_problems.attach_problems_after new_table <| on_problems.attach_problems_after new_table <|
problems = java_table.getProblems problems = java_table.getProblems
@ -657,7 +601,7 @@ type Table
the number of items sold in descending order to break ties. the number of items sold in descending order to break ties.
import Standard.Examples import Standard.Examples
import Standard.Table from Standard.Table import Table
example_sort = example_sort =
table = Examples.inventory_table table = Examples.inventory_table
@ -673,7 +617,7 @@ type Table
comparator = Comparator.for_text_ordering text_ordering comparator = Comparator.for_text_ordering text_ordering
java_table = Illegal_Argument_Error.handle_java_exception <| Vector.handle_incomparable_value <| java_table = Illegal_Argument_Error.handle_java_exception <| Vector.handle_incomparable_value <|
self.java_table.orderBy selected_columns.to_array ordering.to_array comparator self.java_table.orderBy selected_columns.to_array ordering.to_array comparator
Table_Data java_table Table.Table_Data java_table
## Returns the distinct set of rows within the specified columns from the ## Returns the distinct set of rows within the specified columns from the
input table. input table.
@ -703,7 +647,7 @@ type Table
- If floating points values are present in the distinct columns, a - If floating points values are present in the distinct columns, a
`Floating_Point_Grouping` warning. `Floating_Point_Grouping` warning.
distinct : Vector Text | Column_Selector -> Case_Sensitivity -> Problem_Behavior -> Table distinct : Vector Text | Column_Selector -> Case_Sensitivity -> Problem_Behavior -> Table
distinct self (columns = By_Name (self.columns.map .name)) case_sensitivity=Case_Sensitivity.Sensitive on_problems=Report_Warning = distinct self (columns = Column_Selector.By_Name (self.columns.map .name)) case_sensitivity=Case_Sensitivity.Sensitive on_problems=Report_Warning =
warning_mapper error = case error of warning_mapper error = case error of
No_Output_Columns -> Maybe.Some No_Input_Columns_Selected No_Output_Columns -> Maybe.Some No_Input_Columns_Selected
_ -> Nothing _ -> Nothing
@ -713,7 +657,7 @@ type Table
text_folding_strategy = Case.folding_strategy case_sensitivity text_folding_strategy = Case.folding_strategy case_sensitivity
java_table = Illegal_Argument_Error.handle_java_exception <| java_table = Illegal_Argument_Error.handle_java_exception <|
self.java_table.distinct java_columns.to_array text_folding_strategy self.java_table.distinct java_columns.to_array text_folding_strategy
on_problems.attach_problems_after (Table_Data java_table) <| on_problems.attach_problems_after (Table.Table_Data java_table) <|
problems = java_table.getProblems problems = java_table.getProblems
Aggregate_Column_Helper.parse_aggregated_problems problems Aggregate_Column_Helper.parse_aggregated_problems problems
@ -729,7 +673,7 @@ type Table
a leading 0). However, settings in the `Data_Formatter` can a leading 0). However, settings in the `Data_Formatter` can
control this. control this.
parse_values : Data_Formatter -> (Nothing | [Column_Type_Selection]) -> Problem_Behavior -> Table parse_values : Data_Formatter -> (Nothing | [Column_Type_Selection]) -> Problem_Behavior -> Table
parse_values self value_formatter=Data_Formatter_Data column_types=Nothing on_problems=Report_Warning = parse_values self value_formatter=Data_Formatter.Value column_types=Nothing on_problems=Report_Warning =
columns = self.columns columns = self.columns
problem_builder = Vector.new_builder problem_builder = Vector.new_builder
@ -783,7 +727,7 @@ type Table
## TODO [RW] this case of is a workaround for wrong dataflow handling on arrays, it can be removed once the PR fixing it is merged, the relevant PR is: ## TODO [RW] this case of is a workaround for wrong dataflow handling on arrays, it can be removed once the PR fixing it is merged, the relevant PR is:
https://github.com/enso-org/enso/pull/3400 https://github.com/enso-org/enso/pull/3400
result = new new_columns result = Table.new new_columns
on_problems.attach_problems_after result problem_builder.to_vector on_problems.attach_problems_after result problem_builder.to_vector
## ALIAS Filter Rows ## ALIAS Filter Rows
@ -831,8 +775,8 @@ type Table
people.filter "age" (age -> (age%10 == 0)) people.filter "age" (age -> (age%10 == 0))
filter : (Column | Text | Integer) -> (Filter_Condition|(Any->Boolean)) -> Problem_Behavior -> Table filter : (Column | Text | Integer) -> (Filter_Condition|(Any->Boolean)) -> Problem_Behavior -> Table
filter self column filter=(Filter_Condition.Is_True) on_problems=Report_Warning = case column of filter self column filter=(Filter_Condition.Is_True) on_problems=Report_Warning = case column of
_ : Column.Column -> _ : Column ->
mask filter_column = Table_Data (self.java_table.mask filter_column.java_column) mask filter_column = Table.Table_Data (self.java_table.mask filter_column.java_column)
case Meta.type_of filter of case Meta.type_of filter of
Filter_Condition -> Filter_Condition ->
on_problems.handle_errors fallback=self.with_no_rows <| on_problems.handle_errors fallback=self.with_no_rows <|
@ -891,7 +835,7 @@ type Table
_ : Vector.Vector -> _ : Vector.Vector ->
self.set name (Column.from_vector name column) self.set name (Column.from_vector name column)
Column.Column_Data _ -> Column.Column_Data _ ->
Table_Data (self.java_table.addOrReplaceColumn (column.rename name . java_column)) Table.Table_Data (self.java_table.addOrReplaceColumn (column.rename name . java_column))
## Returns the vector of columns contained in this table. ## Returns the vector of columns contained in this table.
@ -918,8 +862,8 @@ type Table
example_set_index = Examples.inventory_table.set_index "item_name" example_set_index = Examples.inventory_table.set_index "item_name"
set_index : Text | Column -> Table set_index : Text | Column -> Table
set_index self index = case index of set_index self index = case index of
_ : Text -> Table_Data (self.java_table.indexFromColumn index) _ : Text -> Table.Table_Data (self.java_table.indexFromColumn index)
Column.Column_Data c -> Table_Data (self.java_table.indexFromColumn c) Column.Column_Data c -> Table.Table_Data (self.java_table.indexFromColumn c)
## Returns the index of this table, as a column that is indexed by itself. ## Returns the index of this table, as a column that is indexed by itself.
@ -939,11 +883,12 @@ type Table
## ALIAS Join Table ## ALIAS Join Table
Efficiently joins two tables based on either the index or the specified Efficiently joins two or more tables based on either the index or the
key column. specified key column.
Arguments: Arguments:
- other: The table being the right operand of this join operation. - other: The table (or vector of tables) being the right operand of this
join operation.
- on: The column of `self` that should be used as the join key. If this - on: The column of `self` that should be used as the join key. If this
argument is not provided, the index of `self` will be used. argument is not provided, the index of `self` will be used.
- drop_unmatched: Whether the rows of `self` without corresponding - drop_unmatched: Whether the rows of `self` without corresponding
@ -960,7 +905,7 @@ type Table
> Example > Example
Join the popularity table and the inventory table to see the relative Join the popularity table and the inventory table to see the relative
popularities of the items in the shop inventory. popularity of the items in the shop inventory.
import Standard.Examples import Standard.Examples
@ -968,12 +913,13 @@ type Table
Examples.inventory_table.join Examples.popularity_table Examples.inventory_table.join Examples.popularity_table
Icon: join Icon: join
join : Table | Column -> Text | Nothing -> Boolean -> Text -> Text -> Table join : Vector Table | Table | Column.Column -> Text | Nothing -> Boolean -> Text -> Text -> Table
join self other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' = join self other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' =
case other of case other of
_ : Vector.Vector -> other.fold self current->item->(current.join item on drop_unmatched left_suffix right_suffix)
Column.Column_Data _ -> self.join other.to_table on drop_unmatched left_suffix right_suffix Column.Column_Data _ -> self.join other.to_table on drop_unmatched left_suffix right_suffix
Table_Data t -> Table.Table_Data t ->
Table_Data (self.java_table.join t drop_unmatched on left_suffix right_suffix) Table.Table_Data (self.java_table.join t drop_unmatched on left_suffix right_suffix)
## DEPRECATED Will be replaced with `filter_incomplete_rows`. ## DEPRECATED Will be replaced with `filter_incomplete_rows`.
drop_missing_rows : Table drop_missing_rows : Table
@ -991,7 +937,7 @@ type Table
drop_missing_columns self = drop_missing_columns self =
non_missing = self.columns . filter (col -> col.count_missing == 0) non_missing = self.columns . filter (col -> col.count_missing == 0)
index = self.java_table.getIndex index = self.java_table.getIndex
Table_Data (Java_Table.new (non_missing.map .java_column . to_array) index) Table.Table_Data (Java_Table.new (non_missing.map .java_column . to_array) index)
## Returns the number of rows in this table. ## Returns the number of rows in this table.
@ -1018,14 +964,17 @@ type Table
info : Table info : Table
info self = info self =
cols = self.columns cols = self.columns
new [["Column", cols.map .name], ["Items Count", cols.map .count], ["Storage Type", cols.map .storage_type]] . set_index "Column" Table.new [["Column", cols.map .name], ["Items Count", cols.map .count], ["Storage Type", cols.map .storage_type]] . set_index "Column"
## UNSTABLE ## UNSTABLE
Concatenates `other` to `self`. Concatenates `other` to `self`, resulting in a table with the number of rows
being the sum of numbers of rows of `tables`. Any column that is present in
some tables, but missing in others, will be `Nothing`-padded in the positions
corresponding to the missing values.
Arguments: Arguments:
- other: The table to concatenate to `self`. - other: The table or vector of tables to concatenate to `self`.
Any column that is present in one table, but missing in another, will be Any column that is present in one table, but missing in another, will be
`Nothing`-padded in the positions corresponding to the missing column. `Nothing`-padded in the positions corresponding to the missing column.
@ -1037,8 +986,12 @@ type Table
example_concat = example_concat =
Examples.inventory_table.concat Examples.popularity_table Examples.inventory_table.concat Examples.popularity_table
concat : Table -> Table concat : Table | Vector Table -> Table
concat self other = Table_Data (Java_Table.concat [self.java_table, other.java_table].to_array) concat self other = case other of
_ : Vector.Vector ->
java_tables = Vector.new (other.length + 1) i->(if i==0 then self else other.at i).java_table
Table.Table_Data (Java_Table.concat java_tables.to_array)
Table.Table_Data other_java_table -> Table.Table_Data (Java_Table.concat [self.java_table, other_java_table].to_array)
## PRIVATE ## PRIVATE
Returns a table with a continuous sub-range of rows taken. Returns a table with a continuous sub-range of rows taken.
@ -1047,7 +1000,7 @@ type Table
length = self.row_count length = self.row_count
offset = Math.max (Math.min start length) 0 offset = Math.max (Math.min start length) 0
limit = Math.max (Math.min (end - offset) (length - offset)) 0 limit = Math.max (Math.min (end - offset) (length - offset)) 0
Table_Data (self.java_table.slice offset limit) Table.Table_Data (self.java_table.slice offset limit)
## UNSTABLE ## UNSTABLE
@ -1063,7 +1016,7 @@ type Table
reverse : Table reverse : Table
reverse self = reverse self =
mask = OrderBuilder.buildReversedMask self.row_count mask = OrderBuilder.buildReversedMask self.row_count
Table_Data <| self.java_table.applyMask mask Table.Table_Data <| self.java_table.applyMask mask
## ALIAS Write JSON ## ALIAS Write JSON
UNSTABLE UNSTABLE
@ -1134,7 +1087,6 @@ type Table
Write a table to a CSV file, without writing the header. Write a table to a CSV file, without writing the header.
import Standard.Examples import Standard.Examples
import Standard.Table
from Standard.Table import Delimited from Standard.Table import Delimited
example_to_csv = Examples.inventory_table.write (Enso_Project.data / "example_csv_output.csv") (Delimited delimiter="," headers=False) example_to_csv = Examples.inventory_table.write (Enso_Project.data / "example_csv_output.csv") (Delimited delimiter="," headers=False)
@ -1143,7 +1095,6 @@ type Table
Write a table to an XLSX file. Write a table to an XLSX file.
import Standard.Examples import Standard.Examples
import Standard.Table
from Standard.Table import Excel from Standard.Table import Excel
example_to_xlsx = Examples.inventory_table.write (enso_project.data / "example_xlsx_output.xlsx") Excel example_to_xlsx = Examples.inventory_table.write (enso_project.data / "example_xlsx_output.xlsx") Excel
@ -1165,9 +1116,6 @@ type Empty_Error
to_display_text : Text to_display_text : Text
to_display_text self = "The table is empty." to_display_text self = "The table is empty."
## PRIVATE
from_columns cols = Table_Data (Java_Table.new cols.to_array)
## PRIVATE ## PRIVATE
Ensures that the `txt` has at least `len` characters by appending spaces at Ensures that the `txt` has at least `len` characters by appending spaces at
@ -1222,16 +1170,8 @@ print_table header rows indices_count format_term =
" " + y " " + y
([" " + header_line, divider] + row_lines).join '\n' ([" " + header_line, divider] + row_lines).join '\n'
Table.from (that : Text) (format:Delimited_Format = Delimited '\t') (on_problems:Problem_Behavior=Report_Warning) =
if format.is_a Delimited then Delimited_Reader.read_text that format on_problems else
Errors.unimplemented "Table.from for fixed-width files is not yet implemented."
Text.from (that : Table) (format:Delimited_Format = Delimited '\t') =
if format.is_a Delimited then Delimited_Writer.write_text that format else
Errors.unimplemented "Text.from for fixed-width files is not yet implemented."
## PRIVATE ## PRIVATE
A helper to create a new table consisting of slices of the original table. A helper to create a new table consisting of slices of the original table.
slice_ranges table ranges = slice_ranges table ranges =
normalized = Index_Sub_Range.normalize_ranges ranges normalized = Index_Sub_Range.normalize_ranges ranges
Table_Data (table.java_table.slice normalized.to_array) Table.Table_Data (table.java_table.slice normalized.to_array)

View File

@ -0,0 +1,17 @@
from Standard.Base import all
from Standard.Base.Error.Problem_Behavior import Report_Warning
import project.Data.Table.Table
import project.Errors
from project.Delimited.Delimited_Format import Delimited_Format, Delimited
import project.Delimited.Delimited_Reader
import project.Delimited.Delimited_Writer
Table.from (that : Text) (format:Delimited_Format = Delimited '\t') (on_problems:Problem_Behavior=Report_Warning) =
if format.is_a Delimited then Delimited_Reader.read_text that format on_problems else
Errors.unimplemented "Table.from for fixed-width files is not yet implemented."
Text.from (that : Table) (format:Delimited_Format = Delimited '\t') =
if format.is_a Delimited then Delimited_Writer.write_text that format else
Errors.unimplemented "Text.from for fixed-width files is not yet implemented."

View File

@ -1,17 +1,14 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table.Data.Table from Standard.Table.Data.Table import Table
import Standard.Table.Data.Match_Columns from Standard.Table.Data.Data_Formatter import Data_Formatter
from Standard.Table.Data.Match_Columns import Match_Columns
import Standard.Table.Delimited.Delimited_Reader import Standard.Table.Delimited.Delimited_Reader
import Standard.Table.Delimited.Delimited_Writer import Standard.Table.Delimited.Delimited_Writer
import Standard.Table.Delimited.Quote_Style.Quote_Style
from Standard.Table.Data.Data_Formatter import Data_Formatter, Data_Formatter_Data from project.Delimited.Delimited_Format.Delimited_Format import Delimited
from project.Delimited.Delimited_Format.Delimited_Format export Delimited
import Standard.Table.Delimited.Quote_Style
# TODO Dubious constructor export
from project.Delimited.Delimited_Format.Delimited_Format import all
from project.Delimited.Delimited_Format.Delimited_Format export all
## Read delimited files such as CSVs into a Table. ## Read delimited files such as CSVs into a Table.
type Delimited_Format type Delimited_Format
@ -51,7 +48,7 @@ type Delimited_Format
character if it anywhere else than at the beginning of the line. This character if it anywhere else than at the beginning of the line. This
option is only applicable for read mode and does not affect writing. It option is only applicable for read mode and does not affect writing. It
defaults to `Nothing` which means that comments are disabled. defaults to `Nothing` which means that comments are disabled.
Delimited (delimiter:Text) (encoding:Encoding=Encoding.utf_8) (skip_rows:Integer=0) (row_limit:Integer|Nothing=Nothing) (quote_style:Quote_Style=Quote_Style.With_Quotes) (headers:Boolean|Infer=Infer) (value_formatter:Data_Formatter|Nothing=Data_Formatter_Data) (keep_invalid_rows:Boolean=True) (line_endings:Line_Ending_Style=Infer) (comment_character:Text|Nothing=Nothing) Delimited (delimiter:Text) (encoding:Encoding=Encoding.utf_8) (skip_rows:Integer=0) (row_limit:Integer|Nothing=Nothing) (quote_style:Quote_Style=Quote_Style.With_Quotes) (headers:Boolean|Infer=Infer) (value_formatter:Data_Formatter|Nothing=Data_Formatter.Value) (keep_invalid_rows:Boolean=True) (line_endings:Line_Ending_Style=Infer) (comment_character:Text|Nothing=Nothing)
## If the File_Format supports reading from the file, return a configured instance. ## If the File_Format supports reading from the file, return a configured instance.
for_file : File -> Delimited_Format | Nothing for_file : File -> Delimited_Format | Nothing
@ -101,7 +98,7 @@ type Delimited_Format
A custom `Data_Formatter` can be provided to customize parser options. A custom `Data_Formatter` can be provided to customize parser options.
with_parsing : Data_Formatter -> Delimited_Format with_parsing : Data_Formatter -> Delimited_Format
with_parsing self (value_formatter=Data_Formatter_Data) = with_parsing self (value_formatter=Data_Formatter.Value) =
self.clone value_formatter=value_formatter self.clone value_formatter=value_formatter
## Create a clone of this without value parsing. ## Create a clone of this without value parsing.

View File

@ -2,11 +2,12 @@ from Standard.Base import all
import Standard.Base.Error.Common as Errors import Standard.Base.Error.Common as Errors
from Standard.Base.Error.Problem_Behavior import Ignore, Report_Error from Standard.Base.Error.Problem_Behavior import Ignore, Report_Error
import Standard.Table.Data.Table import Standard.Table.Data.Table.Table
import Standard.Table.Data.Data_Formatter.Data_Formatter
import Standard.Table.Delimited.Delimited_Format.Delimited_Format
import Standard.Table.Delimited.Quote_Style.Quote_Style
from Standard.Table.Errors import Duplicate_Output_Column_Names_Data, Invalid_Output_Column_Names_Data, Invalid_Row_Data, Mismatched_Quote, Parser_Error, Additional_Invalid_Rows_Data from Standard.Table.Errors import Duplicate_Output_Column_Names_Data, Invalid_Output_Column_Names_Data, Invalid_Row_Data, Mismatched_Quote, Parser_Error, Additional_Invalid_Rows_Data
from Standard.Table.Data.Data_Formatter import Data_Formatter_Data
from Standard.Table.Delimited.Delimited_Format import Delimited_Format
import Standard.Table.Delimited.Quote_Style
polyglot java import org.enso.base.encoding.NewlineDetector polyglot java import org.enso.base.encoding.NewlineDetector
polyglot java import org.enso.table.read.DelimitedReader polyglot java import org.enso.table.read.DelimitedReader
@ -117,7 +118,7 @@ prepare_reader java_reader format max_columns on_problems newline_override=Nothi
wrapped = format.value_formatter.wrap_base_parser base_parser wrapped = format.value_formatter.wrap_base_parser base_parser
TypeInferringParser.new format.value_formatter.get_specific_type_parsers.to_array wrapped TypeInferringParser.new format.value_formatter.get_specific_type_parsers.to_array wrapped
cell_type_guesser = if format.headers != Infer then Nothing else cell_type_guesser = if format.headers != Infer then Nothing else
formatter = format.value_formatter.if_nothing Data_Formatter_Data formatter = format.value_formatter.if_nothing Data_Formatter.Value
TypeInferringParser.new formatter.get_specific_type_parsers.to_array IdentityParser.new TypeInferringParser.new formatter.get_specific_type_parsers.to_array IdentityParser.new
newline = newline_override.if_nothing <| case format.line_endings of newline = newline_override.if_nothing <| case format.line_endings of
Infer -> Nothing Infer -> Nothing
@ -136,22 +137,14 @@ translate_reader_problem problem =
if found.is_error then problem else if found.is_error then problem else
found.second problem found.second problem
# TODO Dubious constructor export
from project.Delimited.Delimited_Reader.Detected_Headers import all
from project.Delimited.Delimited_Reader.Detected_Headers export all
## PRIVATE ## PRIVATE
An internal type representing columns deduced from an existing file. An internal type representing columns deduced from an existing file.
type Detected_Headers type Detected_Headers
## Represents the headers found in the file. ## Represents the headers found in the file.
Existing_Headers (column_names : Vector Text) Existing (column_names : Vector Text)
## Indicates that the file exists but no headers have been found, so only positional column matching is possible. ## Indicates that the file exists but no headers have been found, so only positional column matching is possible.
No_Headers (column_count : Integer) None (column_count : Integer)
# TODO Dubious constructor export
from project.Delimited.Delimited_Reader.Detected_File_Metadata import all
from project.Delimited.Delimited_Reader.Detected_File_Metadata export all
type Detected_File_Metadata type Detected_File_Metadata
## PRIVATE ## PRIVATE
@ -164,12 +157,12 @@ type Detected_File_Metadata
- ends_with_newline: specifies if the last line ends with a line - ends_with_newline: specifies if the last line ends with a line
separator that is consistent with the detected one. separator that is consistent with the detected one.
- has_any_content: specifies if the file contains any content. - has_any_content: specifies if the file contains any content.
Detected_File_Metadata_Data (headers : Detected_Headers) (line_separator : Text|Nothing) (ends_with_newline : Boolean) (has_any_content : Boolean) Value (headers : Detected_Headers) (line_separator : Text|Nothing) (ends_with_newline : Boolean) (has_any_content : Boolean)
## PRIVATE ## PRIVATE
Reads the beginning of the file to detect the existing headers and column Reads the beginning of the file to detect the existing headers and column
count. count.
detect_metadata : File -> Delimited_Format -> Detected_Headers detect_metadata : File -> Delimited_Format -> Detected_File_Metadata
detect_metadata file format = detect_metadata file format =
on_problems = Ignore on_problems = Ignore
result = handle_io_exception file <| Illegal_Argument_Error.handle_java_exception <| handle_parsing_failure <| handle_parsing_exception <| result = handle_io_exception file <| Illegal_Argument_Error.handle_java_exception <| handle_parsing_failure <| handle_parsing_exception <|
@ -190,8 +183,8 @@ detect_metadata file format =
Nothing -> Nothing ->
column_count = reader.getColumnCount column_count = reader.getColumnCount
if column_count == 0 then Nothing else if column_count == 0 then Nothing else
No_Headers column_count Detected_Headers.None column_count
_ -> Existing_Headers (Vector.from_polyglot_array defined_columns) _ -> Detected_Headers.Existing (Vector.from_polyglot_array defined_columns)
line_separator_from_parser = reader.getEffectiveLineSeparator line_separator_from_parser = reader.getEffectiveLineSeparator
has_seen_newline = newline_detecting_reader.newlineEncountered has_seen_newline = newline_detecting_reader.newlineEncountered
## If the parser has seen a newline, we can trust that it ## If the parser has seen a newline, we can trust that it
@ -203,8 +196,8 @@ detect_metadata file format =
True -> line_separator_from_parser True -> line_separator_from_parser
False -> trailing_line_separator False -> trailing_line_separator
has_any_content = reader.getVisitedCharactersCount > 0 has_any_content = reader.getVisitedCharactersCount > 0
Detected_File_Metadata_Data headers effective_line_separator has_trailing_line_separator has_any_content Detected_File_Metadata.Value headers effective_line_separator has_trailing_line_separator has_any_content
result.catch File.File_Not_Found (_->(Detected_File_Metadata_Data Nothing Nothing False False)) result.catch File.File_Not_Found (_->(Detected_File_Metadata.Value Nothing Nothing False False))
## PRIVATE ## PRIVATE
Checks if the file has a newline at the end. Checks if the file has a newline at the end.

View File

@ -2,14 +2,14 @@ from Standard.Base import all
import Standard.Base.System import Standard.Base.System
import Standard.Base.Error.Common as Errors import Standard.Base.Error.Common as Errors
import Standard.Table.Data.Table from Standard.Table.Data.Table import Table
from Standard.Table.Errors import Duplicate_Output_Column_Names, Invalid_Output_Column_Names, Invalid_Row, Mismatched_Quote, Parser_Error, Additional_Invalid_Rows, Column_Count_Mismatch, Column_Name_Mismatch from Standard.Table.Errors import Duplicate_Output_Column_Names, Invalid_Output_Column_Names, Invalid_Row, Mismatched_Quote, Parser_Error, Additional_Invalid_Rows, Column_Count_Mismatch, Column_Name_Mismatch
from Standard.Table.Data.Data_Formatter import Data_Formatter from Standard.Table.Data.Data_Formatter import Data_Formatter
import Standard.Table.Data.Storage from Standard.Table.Data.Storage import Storage
from Standard.Table.Delimited.Delimited_Format import Delimited_Format from Standard.Table.Delimited.Delimited_Format import Delimited_Format
import Standard.Table.Delimited.Quote_Style from Standard.Table.Delimited.Quote_Style import Quote_Style
from Standard.Table.Delimited.Delimited_Reader import Existing_Headers, No_Headers, detect_metadata from Standard.Table.Delimited.Delimited_Reader import Detected_Headers, detect_metadata
import Standard.Table.Data.Match_Columns from Standard.Table.Data.Match_Columns import Match_Columns
polyglot java import org.enso.table.write.DelimitedWriter polyglot java import org.enso.table.write.DelimitedWriter
polyglot java import org.enso.table.write.WriteQuoteBehavior polyglot java import org.enso.table.write.WriteQuoteBehavior
@ -63,13 +63,13 @@ append_to_file table format file match_columns on_problems =
reordered_java_table = case preexisting_headers of reordered_java_table = case preexisting_headers of
Nothing -> table.java_table Nothing -> table.java_table
Existing_Headers column_names -> case match_columns of Detected_Headers.Existing column_names -> case match_columns of
Match_Columns.By_Name -> Match_Columns.By_Name ->
ColumnMapper.mapColumnsByName table.java_table column_names.to_array ColumnMapper.mapColumnsByName table.java_table column_names.to_array
Match_Columns.By_Position -> Match_Columns.By_Position ->
column_count = column_names.length column_count = column_names.length
ColumnMapper.mapColumnsByPosition table.java_table column_count ColumnMapper.mapColumnsByPosition table.java_table column_count
No_Headers column_count -> case match_columns of Detected_Headers.None column_count -> case match_columns of
Match_Columns.By_Name -> Match_Columns.By_Name ->
Error.throw (Illegal_Argument_Error_Data "Cannot append by name when headers are not present in the existing data.") Error.throw (Illegal_Argument_Error_Data "Cannot append by name when headers are not present in the existing data.")
Match_Columns.By_Position -> Match_Columns.By_Position ->

View File

@ -1,9 +1,5 @@
from Standard.Base import all from Standard.Base import all
# TODO Dubious constructor export
from project.Delimited.Quote_Style.Quote_Style import all
from project.Delimited.Quote_Style.Quote_Style export all
type Quote_Style type Quote_Style
## Does not handle quotes at all. ## Does not handle quotes at all.

View File

@ -1,11 +1,14 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table.Data.Table import Standard.Table.Data.Table.Table
from Standard.Table.Excel.Section import Excel_Section, Worksheet, Sheet_Names, Range_Names from Standard.Table.Excel.Section import Excel_Section, Worksheet, Sheet_Names, Range_Names
import Standard.Table.Excel.Excel_Reader import Standard.Table.Excel.Excel_Reader
import Standard.Table.Excel.Excel_Writer import Standard.Table.Excel.Excel_Writer
from project.Excel.Excel_Format.Excel_Format import Excel
from project.Excel.Excel_Format.Excel_Format export Excel
## PRIVATE ## PRIVATE
Resolve the xls_format setting to a boolean. Resolve the xls_format setting to a boolean.
should_treat_as_xls_format : (Boolean|Infer) -> File -> Boolean | Illegal_Argument should_treat_as_xls_format : (Boolean|Infer) -> File -> Boolean | Illegal_Argument
@ -18,9 +21,6 @@ should_treat_as_xls_format xls_format file =
".xlt" -> True ".xlt" -> True
_ -> Error.throw (Illegal_Argument_Error_Data ("Unknown file extension for Excel file (" + file.extension + ")")) _ -> Error.throw (Illegal_Argument_Error_Data ("Unknown file extension for Excel file (" + file.extension + ")"))
# TODO Dubious constructor export
from project.Excel.Excel_Format.Excel_Format import all
from project.Excel.Excel_Format.Excel_Format export all
## Read the file to a `Table` from an Excel file ## Read the file to a `Table` from an Excel file
type Excel_Format type Excel_Format

View File

@ -1,9 +1,9 @@
from Standard.Base import all from Standard.Base import all
import Standard.Base.System.File.Option import Standard.Base.System.File.Option
import Standard.Table.Data.Table import Standard.Table.Data.Table.Table
import Standard.Table.Excel.Range.Excel_Range
from Standard.Table.Excel.Range import Excel_Range_Data
from Standard.Table.Excel.Section import Excel_Section, Sheet_Names, Range_Names, Worksheet, Cell_Range from Standard.Table.Excel.Section import Excel_Section, Sheet_Names, Range_Names, Worksheet, Cell_Range
from Standard.Table.Errors import Invalid_Location_Data, Duplicate_Output_Column_Names_Data, Invalid_Output_Column_Names_Data from Standard.Table.Errors import Invalid_Location_Data, Duplicate_Output_Column_Names_Data, Invalid_Output_Column_Names_Data
@ -71,7 +71,7 @@ read_file file section headers on_problems xls_format=False =
_ : Text -> ExcelReader.readSheetByName stream sheet (make_java_headers headers) skip_rows row_limit xls_format _ : Text -> ExcelReader.readSheetByName stream sheet (make_java_headers headers) skip_rows row_limit xls_format
Cell_Range address skip_rows row_limit -> Cell_Range address skip_rows row_limit ->
prepare_reader_table on_problems <| case address of prepare_reader_table on_problems <| case address of
Excel_Range_Data _ -> ExcelReader.readRange stream address.java_range (make_java_headers headers) skip_rows row_limit xls_format _ : Excel_Range -> ExcelReader.readRange stream address.java_range (make_java_headers headers) skip_rows row_limit xls_format
_ : Text -> ExcelReader.readRangeByName stream address (make_java_headers headers) skip_rows row_limit xls_format _ : Text -> ExcelReader.readRangeByName stream address (make_java_headers headers) skip_rows row_limit xls_format
handle_reader file reader handle_reader file reader

View File

@ -4,10 +4,10 @@ import Standard.Table.Data.Table
from Standard.Table.Excel.Excel_Reader import handle_reader, make_java_headers from Standard.Table.Excel.Excel_Reader import handle_reader, make_java_headers
from Standard.Table.Excel.Section import Worksheet, Cell_Range from Standard.Table.Excel.Section import Worksheet, Cell_Range
from Standard.Table.Excel.Range import Excel_Range_Data import Standard.Table.Excel.Range.Excel_Range
from Standard.Table.Errors import Invalid_Location_Data, Range_Exceeded_Data, Existing_Data_Data, Column_Count_Mismatch, Column_Name_Mismatch from Standard.Table.Errors import Invalid_Location_Data, Range_Exceeded_Data, Existing_Data_Data, Column_Count_Mismatch, Column_Name_Mismatch
import Standard.Table.Data.Match_Columns import Standard.Table.Data.Match_Columns.Match_Columns
polyglot java import org.enso.table.read.ExcelReader polyglot java import org.enso.table.read.ExcelReader
polyglot java import org.enso.table.write.ExcelWriter polyglot java import org.enso.table.write.ExcelWriter
@ -44,7 +44,7 @@ write_file file table on_existing_file section headers match_columns _ xls_forma
Worksheet sheet skip_rows row_limit -> Worksheet sheet skip_rows row_limit ->
ExcelWriter.writeTableToSheet workbook sheet existing_data_mode skip_rows table.java_table row_limit java_headers ExcelWriter.writeTableToSheet workbook sheet existing_data_mode skip_rows table.java_table row_limit java_headers
Cell_Range address skip_rows row_limit -> case address of Cell_Range address skip_rows row_limit -> case address of
Excel_Range_Data java_range -> ExcelWriter.writeTableToRange workbook java_range existing_data_mode skip_rows table.java_table row_limit java_headers Excel_Range.Value java_range -> ExcelWriter.writeTableToRange workbook java_range existing_data_mode skip_rows table.java_table row_limit java_headers
_ : Text -> ExcelWriter.writeTableToRange workbook address existing_data_mode skip_rows table.java_table row_limit java_headers _ : Text -> ExcelWriter.writeTableToRange workbook address existing_data_mode skip_rows table.java_table row_limit java_headers
if result.is_error then result else if result.is_error then result else

View File

@ -14,13 +14,9 @@ excel_2007_column_limit = 16384
## PRIVATE ## PRIVATE
excel_2007_row_limit = 1048576 excel_2007_row_limit = 1048576
# TODO Dubious constructor export
from project.Excel.Range.Excel_Range import all
from project.Excel.Range.Excel_Range export all
type Excel_Range type Excel_Range
## Specifies a range within an Excel Workbook. ## Specifies a range within an Excel Workbook.
Excel_Range_Data java_range:Java_Range Value java_range:Java_Range
## Gets the name of the sheet. ## Gets the name of the sheet.
sheet_name : Text sheet_name : Text
@ -89,7 +85,7 @@ type Excel_Range
from_address : Text -> Excel_Range from_address : Text -> Excel_Range
from_address address = from_address address =
Illegal_Argument_Error.handle_java_exception <| Illegal_Argument_Error.handle_java_exception <|
Excel_Range_Data (Java_Range.new address) Excel_Range.Value (Java_Range.new address)
## Create a Range for a single cell. ## Create a Range for a single cell.
for_cell : Text -> (Text|Integer) -> Integer -> Excel_Range for_cell : Text -> (Text|Integer) -> Integer -> Excel_Range
@ -100,7 +96,7 @@ type Excel_Range
row_valid = validate (Excel_Range.is_valid_row row) ("Invalid row for Excel: " + row.to_text + ".") row_valid = validate (Excel_Range.is_valid_row row) ("Invalid row for Excel: " + row.to_text + ".")
col_valid <| row_valid <| col_valid <| row_valid <|
Excel_Range_Data (Java_Range.new sheet col_index row) Excel_Range.Value (Java_Range.new sheet col_index row)
## Create an Excel_Range for a range of cells. ## Create an Excel_Range for a range of cells.
for_range : Text -> (Text|Integer) -> Integer -> (Text|Integer) -> Integer -> Excel_Range for_range : Text -> (Text|Integer) -> Integer -> (Text|Integer) -> Integer -> Excel_Range
@ -114,7 +110,7 @@ type Excel_Range
bottom_valid = validate (Excel_Range.is_valid_row bottom) ("Invalid bottom row for Excel: " + bottom.to_text + ".") bottom_valid = validate (Excel_Range.is_valid_row bottom) ("Invalid bottom row for Excel: " + bottom.to_text + ".")
left_valid <| right_valid <| top_valid <| bottom_valid <| left_valid <| right_valid <| top_valid <| bottom_valid <|
Excel_Range_Data (Java_Range.new sheet left_index top right_index bottom) Excel_Range.Value (Java_Range.new sheet left_index top right_index bottom)
## Create an Excel_Range for a set of columns. ## Create an Excel_Range for a set of columns.
for_columns : Text -> (Text|Integer) -> (Text|Integer) -> Excel_Range for_columns : Text -> (Text|Integer) -> (Text|Integer) -> Excel_Range
@ -126,7 +122,7 @@ type Excel_Range
right_valid = validate (Excel_Range.is_valid_column right_index) ("Invalid right column for Excel: " + right.to_text + ".") right_valid = validate (Excel_Range.is_valid_column right_index) ("Invalid right column for Excel: " + right.to_text + ".")
left_valid <| right_valid <| left_valid <| right_valid <|
Excel_Range_Data (Java_Range.forColumns sheet left_index right_index) Excel_Range.Value (Java_Range.forColumns sheet left_index right_index)
## Create an Excel_Range for a set of rows. ## Create an Excel_Range for a set of rows.
for_rows : Text -> Integer -> Integer -> Excel_Range for_rows : Text -> Integer -> Integer -> Excel_Range
@ -135,4 +131,4 @@ type Excel_Range
bottom_valid = validate (Excel_Range.is_valid_row bottom) ("Invalid bottom row for Excel: " + bottom.to_text + ".") bottom_valid = validate (Excel_Range.is_valid_row bottom) ("Invalid bottom row for Excel: " + bottom.to_text + ".")
top_valid <| bottom_valid <| top_valid <| bottom_valid <|
Excel_Range_Data (Java_Range.forRows sheet top bottom) Excel_Range.Value (Java_Range.forRows sheet top bottom)

View File

@ -1,8 +1,7 @@
from Standard.Base import all from Standard.Base import all
from Standard.Table.Excel.Range import Excel_Range import Standard.Table.Excel.Range.Excel_Range
# TODO Dubious constructor export
from project.Excel.Section.Excel_Section import all from project.Excel.Section.Excel_Section import all
from project.Excel.Section.Excel_Section export all from project.Excel.Section.Excel_Section export all

View File

@ -1,8 +1,8 @@
from Standard.Base import Any, Problem_Behavior, Nothing, Error, Panic, Meta, File, File_Format, Plain_Text_Format, Bytes from Standard.Base import Any, Problem_Behavior, Nothing, Error, Panic, Meta, File, File_Format, Plain_Text_Format, Bytes
from Standard.Base.Error.Common import Unsupported_File_Type, Unsupported_File_Type_Data, No_Such_Method_Error_Data, Illegal_Argument_Error_Data from Standard.Base.Error.Common import Unsupported_File_Type, Unsupported_File_Type_Data, No_Such_Method_Error_Data, Illegal_Argument_Error_Data
from Standard.Table.Delimited.Delimited_Format import Delimited_Format import Standard.Table.Delimited.Delimited_Format.Delimited_Format
from Standard.Table.Excel.Excel_Format import Excel_Format import Standard.Table.Excel.Excel_Format.Excel_Format
## PRIVATE ## PRIVATE
Set of File_Format types for read files. Set of File_Format types for read files.
@ -19,7 +19,6 @@ get_format file =
reader 0 reader 0
type Auto_Detect type Auto_Detect
## PRIVATE ## PRIVATE
Implements the `File.read` for this `File_Format` Implements the `File.read` for this `File_Format`
read : File -> Problem_Behavior -> Any ! Unsupported_File_Type read : File -> Problem_Behavior -> Any ! Unsupported_File_Type

View File

@ -2,7 +2,7 @@ from Standard.Base import Any, Text, Problem_Behavior, Nothing, Error, Panic, Me
from Standard.Base.Error.Problem_Behavior import Report_Warning from Standard.Base.Error.Problem_Behavior import Report_Warning
from Standard.Base.Error.Common import Unsupported_File_Type_Data, No_Such_Method_Error_Data, Illegal_Argument_Error_Data from Standard.Base.Error.Common import Unsupported_File_Type_Data, No_Such_Method_Error_Data, Illegal_Argument_Error_Data
from Standard.Table.IO.Auto_Detect import Auto_Detect import Standard.Table.IO.Auto_Detect.Auto_Detect
## ALIAS Read Text File, Read File ## ALIAS Read Text File, Read File
@ -46,7 +46,7 @@ File.read path (format=Auto_Detect) (on_problems=Report_Warning) =
> Example > Example
Read the first sheet of an XLSX from disk and convert it into a table. Read the first sheet of an XLSX from disk and convert it into a table.
import Standard.Table from Standard.Table import all
import Standard.Examples import Standard.Examples
example_xlsx_to_table = Examples.xlsx.read example_xlsx_to_table = Examples.xlsx.read
@ -54,7 +54,7 @@ File.read path (format=Auto_Detect) (on_problems=Report_Warning) =
> Example > Example
Read the sheet named `Dates` from an XLS and convert it to a table. Read the sheet named `Dates` from an XLS and convert it to a table.
import Standard.Table from Standard.Table import all
from Standard.Table import Excel, Worksheet from Standard.Table import Excel, Worksheet
import Standard.Examples import Standard.Examples

View File

@ -1,14 +1,16 @@
from Standard.Base import all hiding First, Last from Standard.Base import all hiding First, Last
from Standard.Table.Data.Column import Column import Standard.Table.Data.Column.Column
from Standard.Table.Data.Aggregate_Column import all
from Standard.Table.Data.Column_Selector import Column_Selector, By_Name, By_Index, By_Column from Standard.Table.Data.Aggregate_Column.Aggregate_Column import all
import Standard.Table.Internal.Problem_Builder import Standard.Table.Data.Column_Selector.Column_Selector
import Standard.Table.Internal.Unique_Name_Strategy
import Standard.Table.Internal.Problem_Builder.Problem_Builder
import Standard.Table.Internal.Unique_Name_Strategy.Unique_Name_Strategy
import Standard.Table.Internal.Table_Helpers import Standard.Table.Internal.Table_Helpers
import Standard.Table.Data.Sort_Column_Selector import Standard.Table.Data.Sort_Column_Selector.Sort_Column_Selector
import Standard.Table.Data.Sort_Column import Standard.Table.Data.Sort_Column.Sort_Column
import Standard.Base.Data.Ordering.Comparator import Standard.Base.Data.Ordering.Comparator
@ -35,16 +37,12 @@ polyglot java import org.enso.table.data.table.problems.InvalidAggregation
polyglot java import org.enso.table.data.table.problems.FloatingPointGrouping polyglot java import org.enso.table.data.table.problems.FloatingPointGrouping
polyglot java import org.enso.table.data.table.problems.UnquotedDelimiter polyglot java import org.enso.table.data.table.problems.UnquotedDelimiter
# TODO Dubious constructor export
from project.Internal.Aggregate_Column_Helper.Validated_Aggregate_Columns import all
from project.Internal.Aggregate_Column_Helper.Validated_Aggregate_Columns export all
## Result type for aggregate_columns validation ## Result type for aggregate_columns validation
- key_columns: Vector of Columns from the table to group by - key_columns: Vector of Columns from the table to group by
- valid_columns: Table structure to build as pairs of unique column name and Aggregate_Column - valid_columns: Table structure to build as pairs of unique column name and Aggregate_Column
- problems: Set of any problems when validating the input - problems: Set of any problems when validating the input
type Validated_Aggregate_Columns type Validated_Aggregate_Columns
Validated_Aggregate_Columns_Data (key_columns:[Column]) (valid_columns:[Pair Text Aggregate_Column]) (problems:[Any]) Value (key_columns:[Column]) (valid_columns:[Pair Text Aggregate_Column]) (problems:[Any])
## PRIVATE ## PRIVATE
Prepares an aggregation input for further processing: Prepares an aggregation input for further processing:
@ -85,7 +83,7 @@ prepare_aggregate_columns aggregates table =
if unique.renames.not_empty then if unique.renames.not_empty then
problem_builder.report_other_warning (Duplicate_Output_Column_Names_Data unique.renames) problem_builder.report_other_warning (Duplicate_Output_Column_Names_Data unique.renames)
Validated_Aggregate_Columns_Data unique_key_columns renamed_columns problem_builder.build_problemset Validated_Aggregate_Columns.Value unique_key_columns renamed_columns problem_builder.build_problemset
## PRIVATE ## PRIVATE
Defines the default name of an `Aggregate_Column`. Defines the default name of an `Aggregate_Column`.
@ -147,9 +145,9 @@ resolve_aggregate table problem_builder aggregate_column =
Count_Distinct c new_name ignore_nothing -> Count_Distinct c new_name ignore_nothing ->
new_c = case c of new_c = case c of
## TODO once we have sum type pattern matching this could be replaced with a single branch ## TODO once we have sum type pattern matching this could be replaced with a single branch
By_Name _ _ -> resolve_selector_to_vector c Column_Selector.By_Name _ _ -> resolve_selector_to_vector c
By_Index _ -> resolve_selector_to_vector c Column_Selector.By_Index _ -> resolve_selector_to_vector c
By_Column _ -> resolve_selector_to_vector c Column_Selector.By_Column _ -> resolve_selector_to_vector c
_ -> [resolve c] _ -> [resolve c]
Count_Distinct new_c new_name ignore_nothing Count_Distinct new_c new_name ignore_nothing
Count_Not_Nothing c new_name -> Count_Not_Nothing (resolve c) new_name Count_Not_Nothing c new_name -> Count_Not_Nothing (resolve c) new_name

View File

@ -1,7 +1,11 @@
from Standard.Base import all from Standard.Base import all
polyglot java import org.enso.table.data.table.Column import Standard.Table.Data.Column.Column
polyglot java import org.enso.table.data.table.Table polyglot java import org.enso.table.data.table.Column as Java_Column
import Standard.Table.Data.Table.Table
polyglot java import org.enso.table.data.table.Table as Java_Table
polyglot java import org.enso.table.data.index.DefaultIndex polyglot java import org.enso.table.data.index.DefaultIndex
polyglot java import org.enso.table.data.column.builder.object.InferredBuilder polyglot java import org.enso.table.data.column.builder.object.InferredBuilder
polyglot java import org.enso.table.data.column.builder.object.NumericBuilder polyglot java import org.enso.table.data.column.builder.object.NumericBuilder
@ -25,10 +29,10 @@ make_inferred_builder initial_size = InferredBuilder.new initial_size
## PRIVATE ## PRIVATE
make_column : Text -> Storage -> Column make_column : Text -> Storage -> Column
make_column name storage = Column.new name storage make_column name storage = Column.Column_Data (Java_Column.new name storage)
## PRIVATE ## PRIVATE
make_table_without_columns : Integer -> Table make_table_without_columns : Integer -> Table
make_table_without_columns row_count = make_table_without_columns row_count =
index = DefaultIndex.new row_count index = DefaultIndex.new row_count
Table.new [].to_array index Table.Table_Data (Java_Table.new [].to_array index)

View File

@ -2,16 +2,12 @@ from Standard.Base import all
from Standard.Base.Error.Problem_Behavior import Report_Warning from Standard.Base.Error.Problem_Behavior import Report_Warning
import Standard.Base.Runtime.Ref import Standard.Base.Runtime.Ref
import Standard.Table.Internal.Vector_Builder import Standard.Table.Internal.Vector_Builder.Vector_Builder
from Standard.Table.Errors import Missing_Input_Columns_Data, Column_Indexes_Out_Of_Range_Data, No_Output_Columns, Duplicate_Column_Selectors_Data, Input_Indices_Already_Matched_Data, Too_Many_Column_Names_Provided, Duplicate_Output_Column_Names, Invalid_Output_Column_Names, Column_Matched_By_Multiple_Selectors_Data from Standard.Table.Errors import Missing_Input_Columns_Data, Column_Indexes_Out_Of_Range_Data, No_Output_Columns, Duplicate_Column_Selectors_Data, Input_Indices_Already_Matched_Data, Too_Many_Column_Names_Provided, Duplicate_Output_Column_Names, Invalid_Output_Column_Names, Column_Matched_By_Multiple_Selectors_Data
# TODO Dubious constructor export
from project.Internal.Problem_Builder.Problem_Builder import all
from project.Internal.Problem_Builder.Problem_Builder export all
type Problem_Builder type Problem_Builder
Problem_Builder_Data oob_indices duplicate_column_selectors input_indices_already_matched missing_input_columns other Value oob_indices duplicate_column_selectors input_indices_already_matched missing_input_columns other
report_oob_indices self indices = report_oob_indices self indices =
append_to_ref self.oob_indices indices append_to_ref self.oob_indices indices
@ -62,11 +58,11 @@ type Problem_Builder
attach_problems_before self problem_behavior ~computation = attach_problems_before self problem_behavior ~computation =
problem_behavior.attach_problems_before self.build_problemset computation problem_behavior.attach_problems_before self.build_problemset computation
## PRIVATE ## PRIVATE
Creates a new helper object for aggregating problems to report. Creates a new helper object for aggregating problems to report.
new : Problem_Builder new : Problem_Builder
new = new =
Problem_Builder_Data (Ref.new Vector_Builder.empty) (Ref.new Vector_Builder.empty) (Ref.new Vector_Builder.empty) (Ref.new Vector_Builder.empty) other=Vector.new_builder Problem_Builder.Value (Ref.new Vector_Builder.empty) (Ref.new Vector_Builder.empty) (Ref.new Vector_Builder.empty) (Ref.new Vector_Builder.empty) other=Vector.new_builder
## PRIVATE ## PRIVATE
Appends a `Vector` to a `Vector_Builder` stored in a `Ref`. Appends a `Vector` to a `Vector_Builder` stored in a `Ref`.

View File

@ -4,14 +4,14 @@ import Standard.Base.Data.Ordering.Vector_Lexicographic_Order
from Standard.Base.Data.Text.Text_Ordering import Text_Ordering from Standard.Base.Data.Text.Text_Ordering import Text_Ordering
from Standard.Base.Error.Problem_Behavior import Report_Warning from Standard.Base.Error.Problem_Behavior import Report_Warning
import Standard.Table.Data.Position import Standard.Table.Data.Position.Position
from Standard.Table.Errors import Missing_Input_Columns_Data, No_Output_Columns, Too_Many_Column_Names_Provided_Data, Duplicate_Output_Column_Names_Data, Invalid_Output_Column_Names_Data, No_Input_Columns_Selected from Standard.Table.Errors import Missing_Input_Columns_Data, No_Output_Columns, Too_Many_Column_Names_Provided_Data, Duplicate_Output_Column_Names_Data, Invalid_Output_Column_Names_Data, No_Input_Columns_Selected
from Standard.Table.Data.Column_Selector import Column_Selector, By_Name, By_Index, By_Column import Standard.Table.Data.Column_Selector.Column_Selector
import Standard.Table.Data.Column_Name_Mapping import Standard.Table.Data.Column_Name_Mapping.Column_Name_Mapping
import Standard.Table.Internal.Unique_Name_Strategy import Standard.Table.Internal.Unique_Name_Strategy.Unique_Name_Strategy
import Standard.Table.Internal.Problem_Builder import Standard.Table.Internal.Problem_Builder.Problem_Builder
import Standard.Table.Data.Sort_Column_Selector import Standard.Table.Data.Sort_Column_Selector.Sort_Column_Selector
import Standard.Table.Data.Sort_Column import Standard.Table.Data.Sort_Column.Sort_Column
polyglot java import java.util.HashSet polyglot java import java.util.HashSet
@ -234,20 +234,20 @@ sort_columns internal_columns direction text_ordering =
select_columns_helper : Vector -> Vector | Column_Selector -> Boolean -> Problem_Builder -> Vector select_columns_helper : Vector -> Vector | Column_Selector -> Boolean -> Problem_Builder -> Vector
select_columns_helper internal_columns selector reorder problem_builder = case selector of select_columns_helper internal_columns selector reorder problem_builder = case selector of
_ : Vector.Vector -> _ : Vector.Vector ->
select_columns_helper internal_columns (By_Name selector) reorder problem_builder select_columns_helper internal_columns (Column_Selector.By_Name selector) reorder problem_builder
By_Name names matcher -> Column_Selector.By_Name names matcher ->
valid_names = validate_unique names problem_builder.report_duplicate_column_selectors valid_names = validate_unique names problem_builder.report_duplicate_column_selectors
Matching.match_criteria_callback matcher internal_columns valid_names reorder=reorder name_mapper=(_.name) problem_callback=problem_builder.report_missing_input_columns Matching.match_criteria_callback matcher internal_columns valid_names reorder=reorder name_mapper=(_.name) problem_callback=problem_builder.report_missing_input_columns
By_Index indices -> Column_Selector.By_Index indices ->
good_indices = validate_indices internal_columns.length indices problem_builder . map .first good_indices = validate_indices internal_columns.length indices problem_builder . map .first
case reorder of case reorder of
True -> True ->
select_indices_reordering internal_columns good_indices select_indices_reordering internal_columns good_indices
False -> False ->
select_indices_preserving_order internal_columns good_indices select_indices_preserving_order internal_columns good_indices
By_Column columns -> Column_Selector.By_Column columns ->
column_names = columns.map .name column_names = columns.map .name
new_selector = By_Name column_names Text_Matcher.Case_Sensitive new_selector = Column_Selector.By_Name column_names Text_Matcher.Case_Sensitive
select_columns_helper internal_columns new_selector reorder=reorder problem_builder=problem_builder select_columns_helper internal_columns new_selector reorder=reorder problem_builder=problem_builder
## PRIVATE ## PRIVATE
@ -356,14 +356,10 @@ validate_unique vector problem_callback on=(x->x) =
acc.at 1 . to_vector acc.at 1 . to_vector
# TODO Dubious constructor export
from project.Internal.Table_Helpers.Column_Transform_Element import all
from project.Internal.Table_Helpers.Column_Transform_Element export all
## PRIVATE ## PRIVATE
A helper type used by transform helpers. A helper type used by transform helpers.
type Column_Transform_Element type Column_Transform_Element
Column_Transform_Element_Data column associated_selector Value column associated_selector
## PRIVATE ## PRIVATE
prepare_order_by : Vector -> Problem_Builder -> Vector Column_Transform_Element prepare_order_by : Vector -> Problem_Builder -> Vector Column_Transform_Element
@ -422,7 +418,7 @@ transform_columns_by_name internal_columns name_selectors matcher problem_builde
if matching_selectors.length > 1 then if matching_selectors.length > 1 then
problem_builder.report_column_matched_by_multiple_selectors column.name matching_selectors problem_builder.report_column_matched_by_multiple_selectors column.name matching_selectors
matching_selectors.first matching_selectors.first
Column_Transform_Element column associated_selector Column_Transform_Element.Value column associated_selector
## PRIVATE ## PRIVATE
A helper function which can be used by methods that transform a subset of A helper function which can be used by methods that transform a subset of
@ -446,7 +442,7 @@ transform_columns_by_index internal_columns index_selectors problem_builder inde
selectors_map = Map.from_vector good_indices selectors_map = Map.from_vector good_indices
internal_columns.map_with_index i-> column-> internal_columns.map_with_index i-> column->
associated_selector = selectors_map.get_or_else i Nothing associated_selector = selectors_map.get_or_else i Nothing
Column_Transform_Element_Data column associated_selector Column_Transform_Element.Value column associated_selector
## PRIVATE ## PRIVATE
A helper function which can be used by methods that transform a subset of A helper function which can be used by methods that transform a subset of
@ -504,7 +500,7 @@ select_columns_by_name internal_columns name_selectors matcher problem_builder n
problem_builder.report_column_matched_by_multiple_selectors column.name matching_selectors problem_builder.report_column_matched_by_multiple_selectors column.name matching_selectors
associated_selector_index = matching_selector_indices.first associated_selector_index = matching_selector_indices.first
associated_selector = name_selectors.at associated_selector_index associated_selector = name_selectors.at associated_selector_index
element = Column_Transform_Element_Data column associated_selector element = Column_Transform_Element.Value column associated_selector
results.append (Pair_Data element [associated_selector_index, i]) results.append (Pair_Data element [associated_selector_index, i])
# We sort the results by the associated selector index, breaking ties by the column index. # We sort the results by the associated selector index, breaking ties by the column index.
sorted = results.to_vector.sort on=(_.second) by=Vector_Lexicographic_Order.compare sorted = results.to_vector.sort on=(_.second) by=Vector_Lexicographic_Order.compare
@ -531,7 +527,7 @@ select_columns_by_index : Vector -> Vector -> Problem_Builder -> (Any -> Integer
select_columns_by_index internal_columns index_selectors problem_builder index_extractor = select_columns_by_index internal_columns index_selectors problem_builder index_extractor =
good_selectors = validate_indices internal_columns.length index_selectors problem_builder index_extractor good_selectors = validate_indices internal_columns.length index_selectors problem_builder index_extractor
good_selectors.map pair-> good_selectors.map pair->
Column_Transform_Element_Data (internal_columns.at pair.first) pair.second Column_Transform_Element.Value (internal_columns.at pair.first) pair.second
## PRIVATE ## PRIVATE
A helper function which can be used by methods that select a subset of A helper function which can be used by methods that select a subset of

View File

@ -2,34 +2,29 @@ from Standard.Base import Any, Vector, Text, Nothing
polyglot java import org.enso.table.util.NameDeduplicator polyglot java import org.enso.table.util.NameDeduplicator
## Creates a new Unique_Name_Strategy instance.
This is a mutable data structure, that allows for creating a collection
of columns names and making them unique. It will track any duplicates or
invalid names thet are passed to it.
> Example
Construct a set of unique names from two duplicate lists
unique_name_strategy = Unique_Name_Strategy.new
unique_names = ["A","B","A",""] . map unique_name_strategy.make_unique
duplicates = unique_name_strategy.renames
invalid = unique_name_strategy.invalid_names
new : Unique_Name_Strategy
new = Unique_Name_Strategy_Data NameDeduplicator.new
# TODO Dubious constructor export
from project.Internal.Unique_Name_Strategy.Unique_Name_Strategy import all
from project.Internal.Unique_Name_Strategy.Unique_Name_Strategy export all
type Unique_Name_Strategy type Unique_Name_Strategy
## PRIVATE ## PRIVATE
Creates a Unique_Name_Strategy Creates a Unique_Name_Strategy
Arguments: Arguments:
- deduplicator: Name deduplicator - deduplicator: Name deduplicator
Unique_Name_Strategy_Data deduplicator Value deduplicator
## Creates a new Unique_Name_Strategy instance.
This is a mutable data structure, that allows for creating a collection
of columns names and making them unique. It will track any duplicates or
invalid names thet are passed to it.
> Example
Construct a set of unique names from two duplicate lists
unique_name_strategy = Unique_Name_Strategy.new
unique_names = ["A","B","A",""] . map unique_name_strategy.make_unique
duplicates = unique_name_strategy.renames
invalid = unique_name_strategy.invalid_names
new : Unique_Name_Strategy
new = Unique_Name_Strategy.Value NameDeduplicator.new
## Vector of any duplicates renamed ## Vector of any duplicates renamed
renames : Vector renames : Vector

View File

@ -1,8 +1,6 @@
from Standard.Base import all from Standard.Base import all
# TODO Dubious constructor export from project.Internal.Vector_Builder.Vector_Builder import Leaf, Append
from project.Internal.Vector_Builder.Vector_Builder import all
from project.Internal.Vector_Builder.Vector_Builder export all
## PRIVATE ## PRIVATE
@ -79,18 +77,18 @@ type Vector_Builder
Append _ _ _ -> Append self other len Append _ _ _ -> Append self other len
_ : Vector.Vector -> Append self (Leaf other) len _ : Vector.Vector -> Append self (Leaf other) len
## PRIVATE ## PRIVATE
Creates an empty vector builder. Creates an empty vector builder.
empty : Vector_Builder Any empty : Vector_Builder Any
empty = Leaf [] empty = Leaf []
## PRIVATE ## PRIVATE
Creates a vector builder from a vector. Creates a vector builder from a vector.
Arguments: Arguments:
- vec: The vector to create a vector builder from. - vec: The vector to create a vector builder from.
from_vector : Vector.Vector Any -> Vector_Builder Any from_vector : Vector.Vector Any -> Vector_Builder Any
from_vector vec = Leaf vec from_vector vec = Leaf vec

View File

@ -1,50 +1,53 @@
from Standard.Base import all from Standard.Base import all
from Standard.Base import all
import Standard.Base.System.File_Format import Standard.Base.System.File_Format
import project.Data.Table import project.Data.Table.Table
import project.Data.Column import project.Data.Column.Column
import project.Data.Column_Selector import project.Data.Column_Selector.Column_Selector
import project.Data.Sort_Column import project.Data.Sort_Column.Sort_Column
import project.Data.Sort_Column_Selector import project.Data.Sort_Column_Selector.Sort_Column_Selector
import project.Data.Column_Name_Mapping import project.Data.Column_Name_Mapping.Column_Name_Mapping
import project.Data.Data_Formatter import project.Data.Data_Formatter.Data_Formatter
import project.Data.Match_Columns import project.Data.Match_Columns.Match_Columns
import project.Data.Aggregate_Column import project.Data.Position.Position
import project.Data.Filter_Condition import project.Data.Aggregate_Column.Aggregate_Column
import project.Data.Filter_Condition.Filter_Condition
import project.IO.File_Read import project.IO.File_Read
import project.IO.Auto_Detect import project.IO.Auto_Detect.Auto_Detect
import project.Delimited.Quote_Style import project.Delimited.Quote_Style.Quote_Style
import project.Delimited.Delimited_Format import project.Delimited.Delimited_Format
import project.Data.Table_Conversions
import project.Excel.Section import project.Excel.Section
import project.Excel.Range import project.Excel.Range.Excel_Range
import project.Excel.Excel_Format import project.Excel.Excel_Format
import project.Errors export project.Data.Table.Table
export project.Data.Column.Column
from project.Data.Table export new, from_columns, from_rows, join, concat, Table, Table_Data export project.Data.Column_Selector.Column_Selector
export project.Data.Column export project.Data.Sort_Column.Sort_Column
export project.Data.Column_Selector export project.Data.Sort_Column_Selector.Sort_Column_Selector
export project.Data.Sort_Column export project.Data.Column_Name_Mapping.Column_Name_Mapping
export project.Data.Sort_Column_Selector export project.Data.Match_Columns.Match_Columns
export project.Data.Column_Name_Mapping export project.Data.Position.Position
export project.Data.Match_Columns export project.Data.Aggregate_Column.Aggregate_Column
export project.Data.Aggregate_Column export project.Data.Filter_Condition.Filter_Condition
from project.Data.Filter_Condition export Filter_Condition
export project.IO.File_Read export project.IO.File_Read
from project.IO.Auto_Detect export Auto_Detect export project.IO.Auto_Detect.Auto_Detect
export project.Delimited.Quote_Style export project.Delimited.Quote_Style.Quote_Style
from project.Delimited.Delimited_Format export Delimited_Format, Delimited from project.Delimited.Delimited_Format export Delimited_Format, Delimited
export project.Data.Table_Conversions
from project.Excel.Excel_Format export Excel_Format, Excel from project.Excel.Excel_Format export Excel_Format, Excel
from project.Excel.Section export Excel_Section, Sheet_Names, Range_Names, Worksheet, Cell_Range from project.Excel.Section export Excel_Section, Sheet_Names, Range_Names, Worksheet, Cell_Range
from project.Excel.Range export Excel_Range export project.Excel.Range.Excel_Range
from project.Data.Data_Formatter export Data_Formatter, Data_Formatter_Data export project.Data.Data_Formatter.Data_Formatter
import Standard.Geo.Geo_Json import Standard.Geo.Geo_Json
@ -74,8 +77,8 @@ import Standard.Geo.Geo_Json
> Example Converts a JSON array containing key-value pairs into a table for the > Example Converts a JSON array containing key-value pairs into a table for the
provided headers. provided headers.
from Standard.Table import Table
import Standard.Examples import Standard.Examples
import Standard.Table
example_to_table = example_to_table =
json = Examples.simple_table_json json = Examples.simple_table_json
@ -93,7 +96,7 @@ Json.Json.to_table self fields=Nothing = case self of
[n, rows.map (_.at i)] [n, rows.map (_.at i)]
Table.new cols Table.new cols
Json.Object _ -> Json.Object _ ->
if self.get_type != Geo_Json.Feature_Collection.to_text then Error.throw (Invalid_Format_Error_Data self "not being a feature collection") else if self.get_type != Geo_Json.Feature_Collection.to_text then Error.throw (Invalid_Format_Error.Invalid_Format_Error_Data self "not being a feature collection") else
case self.get "features" of case self.get "features" of
Json.Array items -> Json.Array items ->
feature_rows = items.map .get_feature_row feature_rows = items.map .get_feature_row
@ -110,12 +113,7 @@ Json.Json.to_table self fields=Nothing = case self of
[n, rows.map (_.at i)] [n, rows.map (_.at i)]
Table.new cols Table.new cols
_ -> Error.throw (Invalid_Format_Error_Data self "not having the 'features' key.") _ -> Error.throw (Invalid_Format_Error.Invalid_Format_Error_Data self "not having the 'features' key.")
# TODO Dubious constructor export
from project.Main.Invalid_Format_Error import all
from project.Main.Invalid_Format_Error export all
## UNSTABLE ## UNSTABLE

View File

@ -1,6 +1,6 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table
import Standard.Test import Standard.Test
import Standard.Visualization.Helpers import Standard.Visualization.Helpers
@ -10,7 +10,7 @@ import Standard.Visualization.Helpers
Arguments: Arguments:
- table: the Table to be visualized. - table: the Table to be visualized.
json_from_table : Table.Table -> Object json_from_table : Table -> Object
json_from_table table = json_from_table table =
names = ['label', 'latitude', 'longitude', 'radius', 'color'] names = ['label', 'latitude', 'longitude', 'radius', 'color']
pairs = names.map <| name-> pairs = names.map <| name->

View File

@ -1,7 +1,7 @@
from Standard.Base import all from Standard.Base import all
from Standard.Table import Table, Column from Standard.Table import Table, Column
import Standard.Table.Data.Storage import Standard.Table.Data.Storage.Storage
## PRIVATE ## PRIVATE
@ -111,6 +111,6 @@ Table.lookup_ignore_case self name =
## PRIVATE ## PRIVATE
Checks if the column stores numbers. Checks if the column stores numbers.
Column.Column.is_numeric : Boolean Column.is_numeric : Boolean
Column.Column.is_numeric self = Column.is_numeric self =
[Storage.Integer,Storage.Decimal].contains self.storage_type [Storage.Integer,Storage.Decimal].contains self.storage_type

View File

@ -1,27 +1,22 @@
from Standard.Base import all from Standard.Base import all
from Standard.Table import Table, Column from Standard.Table import Table, Column
import Standard.Table
import Standard.Visualization.Helpers import Standard.Visualization.Helpers
## PRIVATE ## PRIVATE
Get first numeric column of the table. Get first numeric column of the table.
Table.Table.first_numeric : Table -> Column ! Nothing Table.first_numeric : Table -> Column ! Nothing
Table.Table.first_numeric self = self.all_columns.find _.is_numeric Table.first_numeric self = self.all_columns.find _.is_numeric
## PRIVATE ## PRIVATE
Get the value column - the column that will be used to create histogram. Get the value column - the column that will be used to create histogram.
Table.Table.value_column : Table -> Column ! Nothing Table.value_column : Table -> Column ! Nothing
Table.Table.value_column self = Table.value_column self =
named_col = self.lookup_ignore_case 'value' named_col = self.lookup_ignore_case 'value'
named_col.catch_ self.first_numeric named_col.catch_ self.first_numeric
# TODO Dubious constructor export
from project.Histogram.Update import all
from project.Histogram.Update export all
## PRIVATE ## PRIVATE
Information that are placed in an update sent to a visualization. Information that are placed in an update sent to a visualization.
@ -48,21 +43,21 @@ from_table table =
col = table.value_column col = table.value_column
label = col.name.catch_ Nothing label = col.name.catch_ Nothing
values = col.to_vector.catch_ [] values = col.to_vector.catch_ []
Update_Data values label Update.Update_Data values label
## PRIVATE ## PRIVATE
from_vector : Vector -> Update from_vector : Vector -> Update
from_vector vector = from_vector vector =
Update_Data vector Nothing Update.Update_Data vector Nothing
## PRIVATE ## PRIVATE
from_value : Any -> Update from_value : Any -> Update
from_value value = from_value value =
case value of case value of
Table.Table_Data _ -> from_table value _ : Table -> from_table value
_ : Vector.Vector -> from_vector value _ : Vector.Vector -> from_vector value
Column.Column_Data _ -> from_table value.to_table _ : Column -> from_table value.to_table
_ -> from_vector value.to_vector _ -> from_vector value.to_vector
## PRIVATE ## PRIVATE

View File

@ -1,7 +1,6 @@
from Standard.Base import all from Standard.Base import all
from Standard.Table import Table, Column from Standard.Table import Table, Column
import Standard.Table
import Standard.Visualization.Helpers import Standard.Visualization.Helpers
from Standard.Base.Data.Index_Sub_Range import Sample from Standard.Base.Data.Index_Sub_Range import Sample
@ -106,8 +105,8 @@ type No_Fallback_Column
## PRIVATE ## PRIVATE
Generates JSON that describes points data. Generates JSON that describes points data.
Table.Table.point_data : Table -> Object Table.point_data : Table -> Object
Table.Table.point_data self = Table.point_data self =
get_point_data field = field.lookup_in self . rename field.name . catch Any (_->Nothing) get_point_data field = field.lookup_in self . rename field.name . catch Any (_->Nothing)
columns = Point_Data.all_fields.map get_point_data . filter (x -> x.is_nothing.not) columns = Point_Data.all_fields.map get_point_data . filter (x -> x.is_nothing.not)
(0.up_to self.row_count).to_vector.map <| row_n-> (0.up_to self.row_count).to_vector.map <| row_n->
@ -119,8 +118,8 @@ Table.Table.point_data self =
## PRIVATE ## PRIVATE
Generates JSON that describes plot axes. Generates JSON that describes plot axes.
Table.Table.axes : Table -> Object Table.axes : Table -> Object
Table.Table.axes self = Table.axes self =
describe_axis field = describe_axis field =
col_name = field.lookup_in self . name col_name = field.lookup_in self . name
label = Json.from_pairs [[label_field, col_name]] label = Json.from_pairs [[label_field, col_name]]
@ -209,10 +208,10 @@ json_from_vector vec bounds limit =
process_to_json_text : Any -> Integer | Nothing -> Integer | Nothing -> Text process_to_json_text : Any -> Integer | Nothing -> Integer | Nothing -> Text
process_to_json_text value bounds=Nothing limit=Nothing = process_to_json_text value bounds=Nothing limit=Nothing =
json = case value of json = case value of
Column.Column_Data _ -> json_from_table value.to_table bounds limit _ : Column -> json_from_table value.to_table bounds limit
Table.Table_Data _ -> json_from_table value bounds limit _ : Table -> json_from_table value bounds limit
_ : Vector.Vector -> json_from_vector value bounds limit _ : Vector.Vector -> json_from_vector value bounds limit
_ -> json_from_vector value.to_vector bounds limit _ -> json_from_vector value.to_vector bounds limit
json.to_text json.to_text

View File

@ -1,10 +1,12 @@
from Standard.Base import all from Standard.Base import all
from Standard.Table.Data.Column_Selector import By_Name
import Standard.Table.Data.Table as Dataframe_Table import Standard.Table.Data.Table.Table as Dataframe_Table
import Standard.Table.Data.Column as Dataframe_Column import Standard.Table.Data.Column.Column as Dataframe_Column
import Standard.Database.Data.Table as Database_Table import Standard.Database.Data.Table.Table as Database_Table
import Standard.Database.Data.Column as Database_Column import Standard.Database.Data.Column.Column as Database_Column
import Standard.Table.Data.Column_Selector.Column_Selector
import Standard.Visualization.Helpers import Standard.Visualization.Helpers
# TODO add an initial offset to fully support lazy visualizations # TODO add an initial offset to fully support lazy visualizations
@ -32,8 +34,8 @@ prepare_visualization x max_rows=1000 = Helpers.recover_errors <| case x of
# Materialize a table with indices as normal columns (because dataframe does not support multi-indexing). # Materialize a table with indices as normal columns (because dataframe does not support multi-indexing).
df = x.reset_index.read max_rows df = x.reset_index.read max_rows
# Then split into actual columns and indices. # Then split into actual columns and indices.
vis_df = df.select_columns (By_Name (x.columns.map .name)) vis_df = df.select_columns (Column_Selector.By_Name (x.columns.map .name))
indices = df.select_columns (By_Name (x.indices.map .name)) . columns indices = df.select_columns (Column_Selector.By_Name (x.indices.map .name)) . columns
all_rows_count = x.row_count all_rows_count = x.row_count
make_json vis_df indices all_rows_count make_json vis_df indices all_rows_count
@ -43,11 +45,6 @@ prepare_visualization x max_rows=1000 = Helpers.recover_errors <| case x of
Database_Column.Column_Data _ _ _ _ _ -> Database_Column.Column_Data _ _ _ _ _ ->
prepare_visualization x.to_table max_rows prepare_visualization x.to_table max_rows
# We display aggregates as their ungrouped counterparts.
Dataframe_Column.Aggregate_Column_Data _ ->
ungrouped = Dataframe_Column.Column_Data x.java_column.getColumn
prepare_visualization ungrouped.to_table max_rows
# TODO [RW] Should we truncate Vectors? # TODO [RW] Should we truncate Vectors?
# We also visualize Vectors and arrays # We also visualize Vectors and arrays
_ : Vector.Vector -> _ : Vector.Vector ->

View File

@ -1,7 +1,6 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table, Column_Selector
from Standard.Table import Column_Selector
from Standard.Table.Data.Aggregate_Column import all from Standard.Table.Data.Aggregate_Column import all
import Standard.Test.Bench import Standard.Test.Bench

View File

@ -2,8 +2,7 @@ from Standard.Base import all
from Standard.Base.Data.Index_Sub_Range import Sample from Standard.Base.Data.Index_Sub_Range import Sample
import Standard.Base.Data.Time.Duration import Standard.Base.Data.Time.Duration
import Standard.Table from Standard.Table import Table, Sort_Column_Selector
from Standard.Table import Sort_Column_Selector
from Standard.Table.Data.Aggregate_Column import all from Standard.Table.Data.Aggregate_Column import all
import Standard.Test.Bench import Standard.Test.Bench

View File

@ -1,5 +1,5 @@
from Standard.Base import all from Standard.Base import all
from Standard.Table.Data.Table import Table_Data from Standard.Table.Data.Table.Table import Table_Data
import Standard.Geo import Standard.Geo

View File

@ -1,11 +1,10 @@
from Standard.Base import all hiding First, Last from Standard.Base import all hiding First, Last
import Standard.Table from Standard.Table import Table, Column_Selector
from Standard.Table.Data.Aggregate_Column import all from Standard.Table.Data.Aggregate_Column.Aggregate_Column import all
from Standard.Table.Data.Column_Selector import By_Name, By_Index
import Standard.Table.Internal.Aggregate_Column_Helper import Standard.Table.Internal.Aggregate_Column_Helper
import Standard.Table.Internal.Problem_Builder import Standard.Table.Internal.Problem_Builder.Problem_Builder
import Standard.Test import Standard.Test
@ -150,9 +149,9 @@ spec = Test.group "Aggregate Columns" <|
test_aggregator simple_table (Count_Distinct float_col test_name ignore_nothing=True) test_name 4 test_aggregator simple_table (Count_Distinct float_col test_name ignore_nothing=True) test_name 4
Test.specify "should be able to count distinct items on a multiple sets of values" <| Test.specify "should be able to count distinct items on a multiple sets of values" <|
test_aggregator simple_table (Count_Distinct (By_Index [0, 1])) "Count Distinct count is_valid" 5 test_aggregator simple_table (Count_Distinct (Column_Selector.By_Index [0, 1])) "Count Distinct count is_valid" 5
test_aggregator simple_table (Count_Distinct (By_Name ["is_valid", "float"])) "Count Distinct is_valid float" 5 test_aggregator simple_table (Count_Distinct (Column_Selector.By_Name ["is_valid", "float"])) "Count Distinct is_valid float" 5
test_aggregator simple_table (Count_Distinct (By_Name ["is_valid", "float"]) ignore_nothing=True) "Count Distinct is_valid float" 4 test_aggregator simple_table (Count_Distinct (Column_Selector.By_Name ["is_valid", "float"]) ignore_nothing=True) "Count Distinct is_valid float" 4
Test.specify "should be able to get the minimum of a set of values" <| Test.specify "should be able to get the minimum of a set of values" <|
test_aggregator simple_table (Minimum -2) "Minimum float" 1 test_aggregator simple_table (Minimum -2) "Minimum float" 1

View File

@ -1,9 +1,8 @@
from Standard.Base import all hiding First, Last from Standard.Base import all hiding First, Last
import Standard.Table from Standard.Table import Table, Sort_Column, Sort_Column_Selector, Column_Selector
from Standard.Table import Sort_Column, Sort_Column_Selector from Standard.Table.Data.Column_Selector.Column_Selector import By_Name
from Standard.Table.Data.Column_Selector import By_Name, By_Index from Standard.Table.Data.Aggregate_Column.Aggregate_Column import all
from Standard.Table.Data.Aggregate_Column import all
from Standard.Table.Errors import Missing_Input_Columns_Data, Column_Indexes_Out_Of_Range_Data, No_Output_Columns, Duplicate_Output_Column_Names_Data, Invalid_Output_Column_Names_Data, Invalid_Aggregation_Data, Floating_Point_Grouping_Data, Unquoted_Delimiter_Data, Additional_Warnings_Data from Standard.Table.Errors import Missing_Input_Columns_Data, Column_Indexes_Out_Of_Range_Data, No_Output_Columns, Duplicate_Output_Column_Names_Data, Invalid_Output_Column_Names_Data, Invalid_Aggregation_Data, Floating_Point_Grouping_Data, Unquoted_Delimiter_Data, Additional_Warnings_Data
from Standard.Database.Errors import Unsupported_Database_Operation_Error_Data from Standard.Database.Errors import Unsupported_Database_Operation_Error_Data
@ -12,12 +11,8 @@ import Standard.Test.Problems
polyglot java import java.lang.Double polyglot java import java.lang.Double
# TODO Dubious constructor export
from project.Aggregate_Spec.Test_Selection import all
from project.Aggregate_Spec.Test_Selection export all
type Test_Selection type Test_Selection
Test_Selection_Data problem_handling=True advanced_stats=True text_concat=True text_shortest_longest=True first_last=True first_last_row_order=True std_dev=True multi_distinct=True aggregation_problems=True nan=True date_support=True Config problem_handling=True advanced_stats=True text_concat=True text_shortest_longest=True first_last=True first_last_row_order=True std_dev=True multi_distinct=True aggregation_problems=True nan=True date_support=True
spec = spec =
table = (enso_project.data / "data.csv") . read table = (enso_project.data / "data.csv") . read
@ -41,7 +36,7 @@ spec =
skip checks for backends which do not support particular features. skip checks for backends which do not support particular features.
- pending: An optional mark to disable all test groups. Can be used to - pending: An optional mark to disable all test groups. Can be used to
indicate that some tests are disabled due to missing test setup. indicate that some tests are disabled due to missing test setup.
aggregate_spec prefix table empty_table table_builder materialize is_database test_selection=Test_Selection_Data pending=Nothing = aggregate_spec prefix table empty_table table_builder materialize is_database test_selection=Test_Selection.Config pending=Nothing =
expect_column_names names table = expect_column_names names table =
table.columns . map .name . should_equal names frames_to_skip=2 table.columns . map .name . should_equal names frames_to_skip=2
@ -1244,7 +1239,7 @@ aggregate_spec prefix table empty_table table_builder materialize is_database te
Problems.test_problem_handling action problems tester Problems.test_problem_handling action problems tester
Test.specify "should ignore Count_Distinct if no columns matched" <| Test.specify "should ignore Count_Distinct if no columns matched" <|
action = table.aggregate [Count_Distinct (By_Index [-100])] on_problems=_ action = table.aggregate [Count_Distinct (Column_Selector.By_Index [-100])] on_problems=_
problems = [Column_Indexes_Out_Of_Range_Data [-100], No_Output_Columns] problems = [Column_Indexes_Out_Of_Range_Data [-100], No_Output_Columns]
tester = expect_column_names [] tester = expect_column_names []
Problems.test_problem_handling action problems tester Problems.test_problem_handling action problems tester

View File

@ -1,6 +1,7 @@
from Standard.Base import all from Standard.Base import all
from Standard.Table import Column from Standard.Table import Column
import Standard.Table.Data.Storage import Standard.Table.Data.Column as Column_Module
import Standard.Table.Data.Storage.Storage
import Standard.Examples import Standard.Examples
import Standard.Test import Standard.Test
@ -12,14 +13,14 @@ spec = Test.group "Columns" <|
empty_column = Column.from_vector "Test" [] empty_column = Column.from_vector "Test" []
Test.specify "should correctly map storage types" <| Test.specify "should correctly map storage types" <|
Column.storage_types.at Java_Storage.Type.LONG . should_equal Storage.Integer Column_Module.storage_types.at Java_Storage.Type.LONG . should_equal Storage.Integer
Column.storage_types.at Java_Storage.Type.DOUBLE . should_equal Storage.Decimal Column_Module.storage_types.at Java_Storage.Type.DOUBLE . should_equal Storage.Decimal
Column.storage_types.at Java_Storage.Type.STRING . should_equal Storage.Text Column_Module.storage_types.at Java_Storage.Type.STRING . should_equal Storage.Text
Column.storage_types.at Java_Storage.Type.BOOL . should_equal Storage.Boolean Column_Module.storage_types.at Java_Storage.Type.BOOL . should_equal Storage.Boolean
Column.storage_types.at Java_Storage.Type.OBJECT . should_equal Storage.Any Column_Module.storage_types.at Java_Storage.Type.OBJECT . should_equal Storage.Any
Column.storage_types.at Java_Storage.Type.DATE . should_equal Storage.Date Column_Module.storage_types.at Java_Storage.Type.DATE . should_equal Storage.Date
Column.storage_types.at Java_Storage.Type.TIME_OF_DAY . should_equal Storage.Time_Of_Day Column_Module.storage_types.at Java_Storage.Type.TIME_OF_DAY . should_equal Storage.Time_Of_Day
Column.storage_types.at Java_Storage.Type.DATE_TIME . should_equal Storage.Date_Time Column_Module.storage_types.at Java_Storage.Type.DATE_TIME . should_equal Storage.Date_Time
Test.specify "should allow getting specific elements" <| Test.specify "should allow getting specific elements" <|
test_column.at 0 . should_equal 1 test_column.at 0 . should_equal 1
@ -47,12 +48,12 @@ spec = Test.group "Columns" <|
Test.specify "should be able to get the first / head element" <| Test.specify "should be able to get the first / head element" <|
test_column.first . should_equal 1 test_column.first . should_equal 1
test_column.head . should_equal 1 test_column.head . should_equal 1
empty_column.first.should_fail_with Column.Empty_Error empty_column.first.should_fail_with Column_Module.Empty_Error
empty_column.head.should_fail_with Column.Empty_Error empty_column.head.should_fail_with Column_Module.Empty_Error
Test.specify "should be able to get the last element" <| Test.specify "should be able to get the last element" <|
test_column.last . should_equal 6 test_column.last . should_equal 6
empty_column.last.should_fail_with Column.Empty_Error empty_column.last.should_fail_with Column_Module.Empty_Error
Test.specify "should be able to be reversed" <| Test.specify "should be able to be reversed" <|
expected_1 = Column.from_vector "Test" [6, 4, 2, 5, 3, 1] expected_1 = Column.from_vector "Test" [6, 4, 2, 5, 3, 1]

View File

@ -3,11 +3,10 @@ from Standard.Base.Data.Index_Sub_Range import While, Sample, Every
import Standard.Base.Data.Index_Sub_Range import Standard.Base.Data.Index_Sub_Range
from Standard.Base.Error.Problem_Behavior import Report_Error from Standard.Base.Error.Problem_Behavior import Report_Error
from Standard.Table import Column_Name_Mapping, Sort_Column, Sort_Column_Selector from Standard.Table import Column_Name_Mapping, Sort_Column, Sort_Column_Selector, Position
from Standard.Table.Data.Value_Type import Value_Type import Standard.Table.Data.Value_Type.Value_Type
from Standard.Table.Data.Column_Selector.Column_Selector import By_Name, By_Index, By_Column
from Standard.Table.Errors import all from Standard.Table.Errors import all
from Standard.Table.Data.Column_Selector import all
from Standard.Table.Data.Position import all
from Standard.Table.Data.Filter_Condition import Filter_Condition from Standard.Table.Data.Filter_Condition import Filter_Condition
from Standard.Database.Errors import SQL_Error_Data from Standard.Database.Errors import SQL_Error_Data
@ -17,12 +16,8 @@ import Standard.Test.Problems
from project.Util import all from project.Util import all
# TODO Dubious constructor export
from project.Common_Table_Spec.Test_Selection import all
from project.Common_Table_Spec.Test_Selection export all
type Test_Selection type Test_Selection
Test_Selection_Data supports_case_sensitive_columns=True order_by=True natural_ordering=False case_insensitive_ordering=True order_by_unicode_normalization_by_default=False case_insensitive_ascii_only=False take_drop=True allows_mixed_type_comparisons=True Config supports_case_sensitive_columns=True order_by=True natural_ordering=False case_insensitive_ordering=True order_by_unicode_normalization_by_default=False case_insensitive_ascii_only=False take_drop=True allows_mixed_type_comparisons=True
## A common test suite for shared operations on the Table API. ## A common test suite for shared operations on the Table API.
@ -337,18 +332,18 @@ spec prefix table_builder test_selection pending=Nothing =
Test.group prefix+"Table.reorder_columns" pending=pending <| Test.group prefix+"Table.reorder_columns" pending=pending <|
Test.specify "should work as shown in the doc examples" <| Test.specify "should work as shown in the doc examples" <|
expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] <| table.reorder_columns (By_Name ["foo"]) position=After_Other_Columns expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] <| table.reorder_columns (By_Name ["foo"]) Position.After_Other_Columns
expect_column_names ["Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo", "bar"] <| table.reorder_columns ["foo", "bar"] position=After_Other_Columns expect_column_names ["Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo", "bar"] <| table.reorder_columns ["foo", "bar"] Position.After_Other_Columns
expect_column_names ["foo_1", "foo_2", "bar", "Baz", "foo", "ab.+123", "abcd123"] <| table.reorder_columns (By_Name ["foo.+", "b.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Insensitive)) expect_column_names ["foo_1", "foo_2", "bar", "Baz", "foo", "ab.+123", "abcd123"] <| table.reorder_columns (By_Name ["foo.+", "b.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Insensitive))
expect_column_names ["bar", "foo", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123"] <| table.reorder_columns (By_Index [1, 0]) position=Before_Other_Columns expect_column_names ["bar", "foo", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123"] <| table.reorder_columns (By_Index [1, 0]) Position.Before_Other_Columns
expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] <| table.reorder_columns (By_Index [0]) position=After_Other_Columns expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] <| table.reorder_columns (By_Index [0]) Position.After_Other_Columns
column1 = table.at "foo_1" column1 = table.at "foo_1"
column2 = table.at "Baz" column2 = table.at "Baz"
expect_column_names ["foo_1", "Baz", "foo", "bar", "foo_2", "ab.+123", "abcd123"] <| table.reorder_columns (By_Column [column1, column2]) expect_column_names ["foo_1", "Baz", "foo", "bar", "foo_2", "ab.+123", "abcd123"] <| table.reorder_columns (By_Column [column1, column2])
Test.specify "should correctly handle regex matching" <| Test.specify "should correctly handle regex matching" <|
expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] <| table.reorder_columns (By_Name ["foo"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Sensitive)) position=After_Other_Columns expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] <| table.reorder_columns (By_Name ["foo"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Sensitive)) Position.After_Other_Columns
rest = ["foo", "bar", "Baz", "foo_1", "foo_2"] rest = ["foo", "bar", "Baz", "foo_1", "foo_2"]
expect_column_names ["ab.+123", "abcd123"]+rest <| table.reorder_columns (By_Name ["a.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Sensitive)) expect_column_names ["ab.+123", "abcd123"]+rest <| table.reorder_columns (By_Name ["a.*"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Sensitive))
expect_column_names ["ab.+123", "abcd123"]+rest <| table.reorder_columns (By_Name ["ab.+123"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Sensitive)) expect_column_names ["ab.+123", "abcd123"]+rest <| table.reorder_columns (By_Name ["ab.+123"] (Regex_Matcher.Regex_Matcher_Data case_sensitivity=Case_Sensitivity.Sensitive))
@ -379,21 +374,21 @@ spec prefix table_builder test_selection pending=Nothing =
Test.specify "should correctly handle problems: duplicate indices" <| Test.specify "should correctly handle problems: duplicate indices" <|
selector = By_Index [0, 0, 0] selector = By_Index [0, 0, 0]
action = table.reorder_columns selector position=After_Other_Columns on_problems=_ action = table.reorder_columns selector Position.After_Other_Columns on_problems=_
tester = expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] tester = expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"]
problems = [Duplicate_Column_Selectors_Data [0, 0]] problems = [Duplicate_Column_Selectors_Data [0, 0]]
Problems.test_problem_handling action problems tester Problems.test_problem_handling action problems tester
Test.specify "should correctly handle problems: aliased indices" <| Test.specify "should correctly handle problems: aliased indices" <|
selector = By_Index [0, -7, -6, 1] selector = By_Index [0, -7, -6, 1]
action = table.reorder_columns selector position=After_Other_Columns on_problems=_ action = table.reorder_columns selector Position.After_Other_Columns on_problems=_
tester = expect_column_names ["Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo", "bar"] tester = expect_column_names ["Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo", "bar"]
problems = [Input_Indices_Already_Matched_Data [-7, 1]] problems = [Input_Indices_Already_Matched_Data [-7, 1]]
Problems.test_problem_handling action problems tester Problems.test_problem_handling action problems tester
Test.specify "should correctly handle problems: duplicate names" <| Test.specify "should correctly handle problems: duplicate names" <|
selector = By_Name ["foo", "foo"] selector = By_Name ["foo", "foo"]
action = table.reorder_columns selector position=After_Other_Columns on_problems=_ action = table.reorder_columns selector Position.After_Other_Columns on_problems=_
tester = expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] tester = expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"]
problems = [Duplicate_Column_Selectors_Data ["foo"]] problems = [Duplicate_Column_Selectors_Data ["foo"]]
Problems.test_problem_handling action problems tester Problems.test_problem_handling action problems tester
@ -401,7 +396,7 @@ spec prefix table_builder test_selection pending=Nothing =
Test.specify "should correctly handle problems: unmatched names" <| Test.specify "should correctly handle problems: unmatched names" <|
weird_name = '.*?-!@#!"' weird_name = '.*?-!@#!"'
selector = By_Name ["foo", "hmm", weird_name] selector = By_Name ["foo", "hmm", weird_name]
action = table.reorder_columns selector position=After_Other_Columns on_problems=_ action = table.reorder_columns selector Position.After_Other_Columns on_problems=_
tester = expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] tester = expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"]
problems = [Missing_Input_Columns_Data ["hmm", weird_name]] problems = [Missing_Input_Columns_Data ["hmm", weird_name]]
Problems.test_problem_handling action problems tester Problems.test_problem_handling action problems tester
@ -409,7 +404,7 @@ spec prefix table_builder test_selection pending=Nothing =
Test.specify "should correctly handle problems: duplicate columns" <| Test.specify "should correctly handle problems: duplicate columns" <|
foo = table.at "foo" foo = table.at "foo"
selector = By_Column [foo, foo] selector = By_Column [foo, foo]
action = table.reorder_columns selector position=After_Other_Columns on_problems=_ action = table.reorder_columns selector Position.After_Other_Columns on_problems=_
tester = expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] tester = expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"]
problems = [Duplicate_Column_Selectors_Data ["foo"]] problems = [Duplicate_Column_Selectors_Data ["foo"]]
Problems.test_problem_handling action problems tester Problems.test_problem_handling action problems tester
@ -421,13 +416,13 @@ spec prefix table_builder test_selection pending=Nothing =
bar = table.at "bar" bar = table.at "bar"
selector = By_Column [bar, weird_column, foo] selector = By_Column [bar, weird_column, foo]
action = table.reorder_columns selector position=After_Other_Columns on_problems=_ action = table.reorder_columns selector Position.After_Other_Columns on_problems=_
tester = expect_column_names ["Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "bar", "foo"] tester = expect_column_names ["Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "bar", "foo"]
problems = [Missing_Input_Columns_Data ["weird_column"]] problems = [Missing_Input_Columns_Data ["weird_column"]]
Problems.test_problem_handling action problems tester Problems.test_problem_handling action problems tester
Test.specify "should correctly handle multiple problems" <| Test.specify "should correctly handle multiple problems" <|
action = table.reorder_columns (By_Index [0, -7, 0, 100]) position=After_Other_Columns on_problems=_ action = table.reorder_columns (By_Index [0, -7, 0, 100]) Position.After_Other_Columns on_problems=_
problems = [Column_Indexes_Out_Of_Range_Data [100], Duplicate_Column_Selectors_Data [0], Input_Indices_Already_Matched_Data [-7]] problems = [Column_Indexes_Out_Of_Range_Data [100], Duplicate_Column_Selectors_Data [0], Input_Indices_Already_Matched_Data [-7]]
tester = expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] tester = expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"]
Problems.test_problem_handling action problems tester Problems.test_problem_handling action problems tester

View File

@ -1,8 +1,6 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table, Column, Delimited, Column_Selector
from Standard.Table import Column, Delimited
from Standard.Table.Data.Column_Selector import By_Index
import Standard.Test import Standard.Test
@ -17,7 +15,7 @@ spec =
Test.group "Table.from Text" <| Test.group "Table.from Text" <|
Test.specify "should create a table from a textual CSV" <| Test.specify "should create a table from a textual CSV" <|
file_contents = (enso_project.data / "simple_empty.csv") . read_text file_contents = (enso_project.data / "simple_empty.csv") . read_text
table = Table.Table.from file_contents (format = Delimited ",") table = Table.from file_contents (format = Delimited ",")
table.should_equal expected_table table.should_equal expected_table
Test.group "File.read (Delimited)" <| Test.group "File.read (Delimited)" <|
@ -37,13 +35,13 @@ spec =
c_6 = ["Column_6", ['1', '2', '3', '4', '5', '6.25', '7', 'osiem']] c_6 = ["Column_6", ['1', '2', '3', '4', '5', '6.25', '7', 'osiem']]
expected = Table.new [c_1, c_3, c_4, c_5, c_6] expected = Table.new [c_1, c_3, c_4, c_5, c_6]
varied_column.select_columns (By_Index [0, 2, 3, 4, 5]) . should_equal expected varied_column.select_columns (Column_Selector.By_Index [0, 2, 3, 4, 5]) . should_equal expected
Test.specify "should handle duplicated columns" <| Test.specify "should handle duplicated columns" <|
csv = """ csv = """
name,x,y,x,y name,x,y,x,y
foo,10,20,30,20 foo,10,20,30,20
t = Table.Table.from csv (format = Delimited ",") t = Table.from csv (format = Delimited ",")
t.columns.map .name . should_equal ['name', 'x', 'y', 'x_1', 'y_1'] t.columns.map .name . should_equal ['name', 'x', 'y', 'x_1', 'y_1']
Test.group 'Writing' <| Test.group 'Writing' <|

View File

@ -1,52 +1,32 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table, Column, Data_Formatter, Quote_Style
from Standard.Table import Column, Data_Formatter_Data, Quote_Style
from Standard.Table.Errors import all from Standard.Table.Errors import all
import Standard.Test import Standard.Test
import Standard.Test.Problems import Standard.Test.Problems
# TODO Dubious constructor export
from project.Data_Formatter_Spec.Custom_Type import all
from project.Data_Formatter_Spec.Custom_Type export all
type Custom_Type type Custom_Type
Custom_Type_Data field Value field
# TODO Dubious constructor export
from project.Data_Formatter_Spec.Custom_Type_With_To_Text import all
from project.Data_Formatter_Spec.Custom_Type_With_To_Text export all
type Custom_Type_With_To_Text type Custom_Type_With_To_Text
Custom_Type_With_To_Text_Data field Value field
to_text : Text to_text : Text
to_text self = "[CUSTOM = " + self.field.to_text + "]" to_text self = "[CUSTOM = " + self.field.to_text + "]"
# TODO Dubious constructor export
from project.Data_Formatter_Spec.Custom_Type_With_Error import all
from project.Data_Formatter_Spec.Custom_Type_With_Error export all
type Custom_Type_With_Error type Custom_Type_With_Error
to_text : Text to_text : Text
to_text self = Error.throw (Illegal_State_Error_Data "foo_error") to_text self = Error.throw (Illegal_State_Error_Data "foo_error")
# TODO Dubious constructor export
from project.Data_Formatter_Spec.Custom_Type_With_Panic import all
from project.Data_Formatter_Spec.Custom_Type_With_Panic export all
type Custom_Type_With_Panic type Custom_Type_With_Panic
Custom_Type_With_Panic_Data
to_text : Text to_text : Text
to_text self = Panic.throw (Illegal_State_Error_Data "foo_panic") to_text self = Panic.throw (Illegal_State_Error_Data "foo_panic")
spec = spec =
Test.group "DataFormatter.parse" <| Test.group "DataFormatter.parse" <|
Test.specify "should parse numbers" <| Test.specify "should parse numbers" <|
formatter = Data_Formatter_Data formatter = Data_Formatter.Value
formatter.parse "123" . should_equal 123 formatter.parse "123" . should_equal 123
formatter.parse "1000000" . should_equal 1000000 formatter.parse "1000000" . should_equal 1000000
formatter.parse "1000000.0" . should_equal 1000000.0 formatter.parse "1000000.0" . should_equal 1000000.0
@ -61,7 +41,7 @@ spec =
formatter.parse "NaN" . is_nan . should_be_true formatter.parse "NaN" . is_nan . should_be_true
Test.specify "should allow customizing the decimal point and thousand separator" <| Test.specify "should allow customizing the decimal point and thousand separator" <|
formatter = Data_Formatter_Data thousand_separator="_" decimal_point="," formatter = Data_Formatter.Value thousand_separator="_" decimal_point=","
formatter.parse "123" . should_equal 123 formatter.parse "123" . should_equal 123
formatter.parse "1_000_000" . should_equal 1000000 formatter.parse "1_000_000" . should_equal 1000000
formatter.parse "1_000_000_000" . should_equal (1000 * 1000 * 1000) formatter.parse "1_000_000_000" . should_equal (1000 * 1000 * 1000)
@ -73,8 +53,8 @@ spec =
formatter.parse "1,0001" . should_equal 1.0001 formatter.parse "1,0001" . should_equal 1.0001
Test.specify "should support exponential notation, but only if explicitly enabled" <| Test.specify "should support exponential notation, but only if explicitly enabled" <|
plain_formatter = Data_Formatter_Data plain_formatter = Data_Formatter.Value
exponential_formatter = Data_Formatter_Data allow_exponential_notation=True exponential_formatter = Data_Formatter.Value allow_exponential_notation=True
plain_formatter.parse "1E3" . should_equal "1E3" plain_formatter.parse "1E3" . should_equal "1E3"
r1 = plain_formatter.parse "1E3" Decimal r1 = plain_formatter.parse "1E3" Decimal
@ -91,27 +71,27 @@ spec =
exponential_formatter.parse "1.2E-3" Decimal . should_equal 0.0012 exponential_formatter.parse "1.2E-3" Decimal . should_equal 0.0012
Test.specify "handle leading zeros, only if enabled" <| Test.specify "handle leading zeros, only if enabled" <|
Data_Formatter_Data.parse "0100" . should_equal "0100" Data_Formatter.Value.parse "0100" . should_equal "0100"
Data_Formatter_Data.parse "000" . should_equal "000" Data_Formatter.Value.parse "000" . should_equal "000"
Data_Formatter_Data.parse "000.0" . should_equal "000.0" Data_Formatter.Value.parse "000.0" . should_equal "000.0"
formatter = Data_Formatter_Data allow_leading_zeros=True formatter = Data_Formatter.Value allow_leading_zeros=True
formatter.parse "0100" . should_equal 100 formatter.parse "0100" . should_equal 100
formatter.parse "000" . should_equal 0 formatter.parse "000" . should_equal 0
formatter.parse "000.0" . should_equal 0.0 formatter.parse "000.0" . should_equal 0.0
Test.specify "should parse booleans" <| Test.specify "should parse booleans" <|
formatter = Data_Formatter_Data formatter = Data_Formatter.Value
formatter.parse "True" . should_equal True formatter.parse "True" . should_equal True
formatter.parse "False" . should_equal False formatter.parse "False" . should_equal False
Test.specify "should allow custom boolean formats" <| Test.specify "should allow custom boolean formats" <|
formatter = Data_Formatter_Data true_values=["YES", "1", "true"] false_values=["NO", "0", "false"] formatter = Data_Formatter.Value true_values=["YES", "1", "true"] false_values=["NO", "0", "false"]
formatter.parse "YES" . should_equal True formatter.parse "YES" . should_equal True
formatter.parse "NO" . should_equal False formatter.parse "NO" . should_equal False
(Data_Formatter_Data true_values=[] false_values=[]).parse "True" datatype=Boolean . should_equal Nothing (Data_Formatter.Value true_values=[] false_values=[]).parse "True" datatype=Boolean . should_equal Nothing
Test.specify "should parse dates" <| Test.specify "should parse dates" <|
formatter = Data_Formatter_Data formatter = Data_Formatter.Value
formatter.parse "2022-01-01" . should_equal (Date.new 2022) formatter.parse "2022-01-01" . should_equal (Date.new 2022)
formatter.parse "2020-05-07" datatype=Date . should_equal (Date.new 2020 5 7) formatter.parse "2020-05-07" datatype=Date . should_equal (Date.new 2020 5 7)
formatter.parse "1999-01-01 00:00:00" . should_equal (Date_Time.new 1999) formatter.parse "1999-01-01 00:00:00" . should_equal (Date_Time.new 1999)
@ -130,7 +110,7 @@ spec =
formatter.parse "30:00:65" . should_equal "30:00:65" formatter.parse "30:00:65" . should_equal "30:00:65"
Test.specify "should fallback to Text" <| Test.specify "should fallback to Text" <|
formatter = Data_Formatter_Data formatter = Data_Formatter.Value
formatter.parse "Text" . should_equal "Text" formatter.parse "Text" . should_equal "Text"
complex_text = """ complex_text = """
Text with such 'quotes' and also "that" and `that` Text with such 'quotes' and also "that" and `that`
@ -139,10 +119,10 @@ spec =
Test.group "DataFormatter.format" <| Test.group "DataFormatter.format" <|
Test.specify "should handle Nothing" <| Test.specify "should handle Nothing" <|
Data_Formatter_Data.format Nothing . should_equal Nothing Data_Formatter.Value.format Nothing . should_equal Nothing
Test.specify "should format numbers" <| Test.specify "should format numbers" <|
formatter = Data_Formatter_Data formatter = Data_Formatter.Value
formatter.format 123 . should_equal "123" formatter.format 123 . should_equal "123"
formatter.format 1000000 . should_equal "1000000" formatter.format 1000000 . should_equal "1000000"
formatter.format 1000000.0 . should_equal "1000000.0" formatter.format 1000000.0 . should_equal "1000000.0"
@ -155,7 +135,7 @@ spec =
formatter.format (Number.nan) . should_equal "NaN" formatter.format (Number.nan) . should_equal "NaN"
Test.specify "should allow customizing the decimal point and thousand separator" <| Test.specify "should allow customizing the decimal point and thousand separator" <|
formatter = Data_Formatter_Data thousand_separator="_" decimal_point="," formatter = Data_Formatter.Value thousand_separator="_" decimal_point=","
formatter.format 123 . should_equal "123" formatter.format 123 . should_equal "123"
formatter.format 1000000 . should_equal "1_000_000" formatter.format 1000000 . should_equal "1_000_000"
formatter.format (1000 * 1000 * 1000) . should_equal "1_000_000_000" formatter.format (1000 * 1000 * 1000) . should_equal "1_000_000_000"
@ -167,18 +147,18 @@ spec =
formatter.format 1.0001 . should_equal "1,0001" formatter.format 1.0001 . should_equal "1,0001"
Test.specify "should format booleans" <| Test.specify "should format booleans" <|
formatter = Data_Formatter_Data formatter = Data_Formatter.Value
formatter.format True . should_equal "True" formatter.format True . should_equal "True"
formatter.format False . should_equal "False" formatter.format False . should_equal "False"
Test.specify "should allow custom boolean formats" <| Test.specify "should allow custom boolean formats" <|
formatter = Data_Formatter_Data true_values=["YES", "1", "true"] false_values=["NO", "0", "false"] formatter = Data_Formatter.Value true_values=["YES", "1", "true"] false_values=["NO", "0", "false"]
formatter.format True . should_equal "YES" formatter.format True . should_equal "YES"
formatter.format False . should_equal "NO" formatter.format False . should_equal "NO"
(Data_Formatter_Data true_values=[] false_values=[]).format True . should_fail_with Illegal_Argument_Error_Data (Data_Formatter.Value true_values=[] false_values=[]).format True . should_fail_with Illegal_Argument_Error_Data
Test.specify "should format dates" <| Test.specify "should format dates" <|
formatter = Data_Formatter_Data formatter = Data_Formatter.Value
formatter.format (Date.new 2022) . should_equal "2022-01-01" formatter.format (Date.new 2022) . should_equal "2022-01-01"
formatter.format (Date_Time.new 1999) . should_equal "1999-01-01 00:00:00" formatter.format (Date_Time.new 1999) . should_equal "1999-01-01 00:00:00"
formatter.format (Date_Time.new 1999 zone=Time_Zone.utc) . should_equal "1999-01-01 00:00:00" formatter.format (Date_Time.new 1999 zone=Time_Zone.utc) . should_equal "1999-01-01 00:00:00"
@ -186,14 +166,14 @@ spec =
formatter.format (Time_Of_Day.new) . should_equal "00:00:00" formatter.format (Time_Of_Day.new) . should_equal "00:00:00"
Test.specify "should allow custom date formats" <| Test.specify "should allow custom date formats" <|
formatter = Data_Formatter_Data date_formats=["E, d MMM y", "d MMM y[ G]"] datetime_formats=["dd/MM/yyyy HH:mm [z]"] time_formats=["h:mma"] datetime_locale=Locale.uk formatter = Data_Formatter.Value date_formats=["E, d MMM y", "d MMM y[ G]"] datetime_formats=["dd/MM/yyyy HH:mm [z]"] time_formats=["h:mma"] datetime_locale=Locale.uk
formatter.format (Date.new 2022 06 21) . should_equal "Tue, 21 Jun 2022" formatter.format (Date.new 2022 06 21) . should_equal "Tue, 21 Jun 2022"
formatter.format (Date_Time.new 1999 02 03 04 56 11 zone=Time_Zone.utc) . should_equal "03/02/1999 04:56 UTC" formatter.format (Date_Time.new 1999 02 03 04 56 11 zone=Time_Zone.utc) . should_equal "03/02/1999 04:56 UTC"
formatter.format (Date_Time.new 1999 02 03 04 56 11 zone=(Time_Zone.parse "America/Los_Angeles")) . should_equal "03/02/1999 04:56 GMT-08:00" formatter.format (Date_Time.new 1999 02 03 04 56 11 zone=(Time_Zone.parse "America/Los_Angeles")) . should_equal "03/02/1999 04:56 GMT-08:00"
formatter.format (Time_Of_Day.new 13 55) . should_equal "1:55pm" formatter.format (Time_Of_Day.new 13 55) . should_equal "1:55pm"
Test.specify "should act as identity on Text" <| Test.specify "should act as identity on Text" <|
formatter = Data_Formatter_Data formatter = Data_Formatter.Value
formatter.format "Text" . should_equal "Text" formatter.format "Text" . should_equal "Text"
complex_text = """ complex_text = """
Text with such 'quotes' and also "that" and `that` Text with such 'quotes' and also "that" and `that`
@ -201,19 +181,19 @@ spec =
formatter.format complex_text . should_equal complex_text formatter.format complex_text . should_equal complex_text
Test.specify "should work with custom types, falling back to the `.to_text` method" <| Test.specify "should work with custom types, falling back to the `.to_text` method" <|
formatter = Data_Formatter_Data thousand_separator="_" formatter = Data_Formatter.Value thousand_separator="_"
formatter.format (Custom_Type_Data 42) . should_equal "(Custom_Type_Data 42)" formatter.format (Custom_Type.Value 42) . should_equal "(Custom_Type.Value 42)"
# We fallback to `to_text`, so obviously the nested numbers will not know about our formatting settings. # We fallback to `to_text`, so obviously the nested numbers will not know about our formatting settings.
formatter.format (Custom_Type_With_To_Text_Data 1000) . should_equal "[CUSTOM = 1000]" formatter.format (Custom_Type_With_To_Text.Value 1000) . should_equal "[CUSTOM = 1000]"
Test.specify "should correctly pass through errors from custom type's `.to_text` method" pending="TODO: figure out the desired behavior, see: https://www.pivotaltracker.com/story/show/182522644" <| Test.specify "should correctly pass through errors from custom type's `.to_text` method" pending="TODO: figure out the desired behavior, see: https://www.pivotaltracker.com/story/show/182522644" <|
formatter = Data_Formatter_Data formatter = Data_Formatter.Value
formatter.format Custom_Type_With_Error . should_fail_with Illegal_State_Error_Data formatter.format Custom_Type_With_Error . should_fail_with Illegal_State_Error_Data
Test.expect_panic_with (formatter.format Custom_Type_With_Panic) Illegal_State_Error_Data Test.expect_panic_with (formatter.format Custom_Type_With_Panic) Illegal_State_Error_Data
Test.group "DataFormatter builders" <| Test.group "DataFormatter builders" <|
# We create a formatter with all non-default values to ensure that the builders keep the existing values of other properties instead of switching to the constructor's defaults. # We create a formatter with all non-default values to ensure that the builders keep the existing values of other properties instead of switching to the constructor's defaults.
formatter_1 = Data_Formatter_Data trim_values=False allow_leading_zeros=True decimal_point=',' thousand_separator='_' allow_exponential_notation=True datetime_formats=["yyyy/MM/dd HH:mm:ss"] date_formats=["dd/MM/yyyy"] time_formats=["HH/mm/ss"] datetime_locale=Locale.uk true_values=["YES"] false_values=["NO"] formatter_1 = Data_Formatter.Value trim_values=False allow_leading_zeros=True decimal_point=',' thousand_separator='_' allow_exponential_notation=True datetime_formats=["yyyy/MM/dd HH:mm:ss"] date_formats=["dd/MM/yyyy"] time_formats=["HH/mm/ss"] datetime_locale=Locale.uk true_values=["YES"] false_values=["NO"]
Test.specify "should allow changing number formatting settings" <| Test.specify "should allow changing number formatting settings" <|
formatter_2 = formatter_1.with_number_formatting decimal_point="*" formatter_2 = formatter_1.with_number_formatting decimal_point="*"
formatter_2.decimal_point . should_equal "*" formatter_2.decimal_point . should_equal "*"

View File

@ -1,8 +1,7 @@
from Standard.Base import all from Standard.Base import all
from Standard.Table import Sort_Column, Sort_Column_Selector from Standard.Table import Sort_Column, Sort_Column_Selector, Column_Selector
from Standard.Table.Data.Column_Selector import By_Name from Standard.Table.Data.Aggregate_Column.Aggregate_Column import all
from Standard.Table.Data.Aggregate_Column import all
from Standard.Table.Errors import No_Input_Columns_Selected, Missing_Input_Columns_Data, No_Such_Column_Error_Data from Standard.Table.Errors import No_Input_Columns_Selected, Missing_Input_Columns_Data, No_Such_Column_Error_Data
from Standard.Database import all from Standard.Database import all
@ -43,7 +42,7 @@ spec =
Test.group "[Codegen] Basic Select" <| Test.group "[Codegen] Basic Select" <|
Test.specify "should select columns from a table" <| Test.specify "should select columns from a table" <|
t1.to_sql.prepare . should_equal ['SELECT "T1"."A" AS "A", "T1"."B" AS "B", "T1"."C" AS "C" FROM "T1" AS "T1"', []] t1.to_sql.prepare . should_equal ['SELECT "T1"."A" AS "A", "T1"."B" AS "B", "T1"."C" AS "C" FROM "T1" AS "T1"', []]
t2 = t1.select_columns (By_Name ["C", "B", "undefined"]) reorder=True t2 = t1.select_columns (Column_Selector.By_Name ["C", "B", "undefined"]) reorder=True
t2.to_sql.prepare . should_equal ['SELECT "T1"."C" AS "C", "T1"."B" AS "B" FROM "T1" AS "T1"', []] t2.to_sql.prepare . should_equal ['SELECT "T1"."C" AS "C", "T1"."B" AS "B" FROM "T1" AS "T1"', []]
foo = t1.at "A" . rename "FOO" foo = t1.at "A" . rename "FOO"
@ -60,7 +59,7 @@ spec =
t2.to_sql.prepare . should_equal ['SELECT "T1"."A" AS "A", "T1"."B" AS "B", "T1"."C" AS "C" FROM "T1" AS "T1" LIMIT 5', []] t2.to_sql.prepare . should_equal ['SELECT "T1"."A" AS "A", "T1"."B" AS "B", "T1"."C" AS "C" FROM "T1" AS "T1" LIMIT 5', []]
Test.specify "should work correctly when there are no columns" <| Test.specify "should work correctly when there are no columns" <|
empty = t1.select_columns (By_Name []) empty = t1.select_columns (Column_Selector.By_Name [])
json = Json.from_pairs [["query", Nothing], ["message", "The table has no columns so a query cannot be generated."]] json = Json.from_pairs [["query", Nothing], ["message", "The table has no columns so a query cannot be generated."]]
empty.to_json . should_equal json empty.to_json . should_equal json
empty.column_count . should_equal 0 empty.column_count . should_equal 0

View File

@ -1,9 +1,7 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table as Materialized_Table from Standard.Table import Table, Sort_Column, Column_Selector, Sort_Column_Selector
from Standard.Table import Sort_Column, Sort_Column_Selector from Standard.Table.Data.Aggregate_Column.Aggregate_Column import all
from Standard.Table.Data.Column_Selector import By_Name
from Standard.Table.Data.Aggregate_Column import all
from Standard.Table.Errors import No_Input_Columns_Selected, Missing_Input_Columns_Data from Standard.Table.Errors import No_Input_Columns_Selected, Missing_Input_Columns_Data
from Standard.Database import all from Standard.Database import all
@ -24,7 +22,7 @@ spec prefix connection pending=Nothing =
tables_to_clean.append name tables_to_clean.append name
table table
t1 = upload "T1" (Materialized_Table.new [["a", [1, 4]], ["b", [2, 5]], ["c", [3, 6]]]) t1 = upload "T1" (Table.new [["a", [1, 4]], ["b", [2, 5]], ["c", [3, 6]]])
Test.group prefix+"Basic Table Access" pending=pending <| Test.group prefix+"Basic Table Access" pending=pending <|
Test.specify "should allow to materialize tables and columns into local memory" <| Test.specify "should allow to materialize tables and columns into local memory" <|
df = t1.read df = t1.read
@ -56,17 +54,17 @@ spec prefix connection pending=Nothing =
ix2.name . should_equal 'a' ix2.name . should_equal 'a'
ix2.to_vector . should_equal [1, 4] ix2.to_vector . should_equal [1, 4]
Test.specify "should work correctly when there are no columns" <| Test.specify "should work correctly when there are no columns" <|
empty = t1.select_columns (By_Name []) empty = t1.select_columns []
empty.read.column_count . should_equal 0 empty.read.column_count . should_equal 0
empty.read.row_count . should_equal empty.row_count empty.read.row_count . should_equal empty.row_count
Test.specify "should handle bigger result sets" <| Test.specify "should handle bigger result sets" <|
n = 1000 n = 1000
original = Materialized_Table.new [["a", Vector.new n ix->ix], ["b", Vector.new n ix-> ix * 3.1415926], ["c", Vector.new n ix-> ix.to_text]] original = Table.new [["a", Vector.new n ix->ix], ["b", Vector.new n ix-> ix * 3.1415926], ["c", Vector.new n ix-> ix.to_text]]
table = upload "Big" original table = upload "Big" original
table.read.row_count . should_equal n table.read.row_count . should_equal n
Test.group prefix+"Mapping Operations" pending=pending <| Test.group prefix+"Mapping Operations" pending=pending <|
t2 = upload "T2" <| Materialized_Table.new [["x", [1, 4, 5, Nothing]], ["y", [2, 3, 5, Nothing]], ["b", [False, False, True, Nothing]]] t2 = upload "T2" <| Table.new [["x", [1, 4, 5, Nothing]], ["y", [2, 3, 5, Nothing]], ["b", [False, False, True, Nothing]]]
x = t2.at "x" x = t2.at "x"
y = t2.at "y" y = t2.at "y"
b = t2.at "b" b = t2.at "b"
@ -98,7 +96,7 @@ spec prefix connection pending=Nothing =
x.is_missing.to_vector . should_equal [False, False, False, True] x.is_missing.to_vector . should_equal [False, False, False, True]
(x == Nothing).to_vector . should_equal [Nothing, Nothing, Nothing, Nothing] (x == Nothing).to_vector . should_equal [Nothing, Nothing, Nothing, Nothing]
t3 = upload "T3" <| Materialized_Table.new [["s1", ["foobar", "bar", "baz", Nothing]], ["s2", ["foo", "ar", "a", Nothing]]] t3 = upload "T3" <| Table.new [["s1", ["foobar", "bar", "baz", Nothing]], ["s2", ["foo", "ar", "a", Nothing]]]
s1 = t3.at "s1" s1 = t3.at "s1"
s2 = t3.at "s2" s2 = t3.at "s2"
Test.specify "should handle Text operations" <| Test.specify "should handle Text operations" <|
@ -126,8 +124,8 @@ spec prefix connection pending=Nothing =
t2.at "c" . to_vector . should_equal [3] t2.at "c" . to_vector . should_equal [3]
Test.group prefix+"Joining Tables" pending=pending <| Test.group prefix+"Joining Tables" pending=pending <|
a = upload "TA" <| Materialized_Table.new [["x", [0, 1, 7, 3, 6]], ["y", ["foo", "bar", "baz", "spam", "eggs"]]] a = upload "TA" <| Table.new [["x", [0, 1, 7, 3, 6]], ["y", ["foo", "bar", "baz", "spam", "eggs"]]]
b = upload "TB" <| Materialized_Table.new [["w", [6, 3, 5, 5, 3, 3]], ["z", ["foo", "foo", "bar", "spam", "bar", "eggs"]]] b = upload "TB" <| Table.new [["w", [6, 3, 5, 5, 3, 3]], ["z", ["foo", "foo", "bar", "spam", "bar", "eggs"]]]
## The tests below use `sort`, because the SQL backend is not guaranteed ## The tests below use `sort`, because the SQL backend is not guaranteed
to return the rows in any particular order. This is the `sort` from to return the rows in any particular order. This is the `sort` from
@ -162,20 +160,20 @@ spec prefix connection pending=Nothing =
r_2.columns.map .name . should_equal ['y_old', 'y_new'] r_2.columns.map .name . should_equal ['y_old', 'y_new']
Test.specify "should correctly handle multi-joins" <| Test.specify "should correctly handle multi-joins" <|
ta = upload "M_TA" <| Materialized_Table.new [["id", [0, 1]], ["name", ["Foo", "Hmm"]]] ta = upload "M_TA" <| Table.new [["id", [0, 1]], ["name", ["Foo", "Hmm"]]]
tb = upload "M_TB" <| Materialized_Table.new [["id", [2, 0]], ["name", ["Bar", "Hmm"]]] tb = upload "M_TB" <| Table.new [["id", [2, 0]], ["name", ["Bar", "Hmm"]]]
tc = upload "M_TC" <| Materialized_Table.new [["id_a", [0, 1]], ["id_b", [2, 0]]] tc = upload "M_TC" <| Table.new [["id_a", [0, 1]], ["id_b", [2, 0]]]
ta_2 = ta.set_index "id" ta_2 = ta.set_index "id"
tb_2 = tb.set_index "id" tb_2 = tb.set_index "id"
res = (tc.join ta_2 on="id_a") . join tb_2 on="id_b" left_suffix="_a" right_suffix="_b" res = (tc.join ta_2 on="id_a") . join tb_2 on="id_b" left_suffix="_a" right_suffix="_b"
sel = res.select_columns (By_Name ["name_a", "name_b"]) sel = res.select_columns (Column_Selector.By_Name ["name_a", "name_b"])
df = sel.read . order_by (Sort_Column_Selector.By_Name [Sort_Column.Name "name_a"]) df = sel.read . order_by (Sort_Column_Selector.By_Name [Sort_Column.Name "name_a"])
df . at "name_a" . to_vector . should_equal ["Foo", "Hmm"] df . at "name_a" . to_vector . should_equal ["Foo", "Hmm"]
df . at "name_b" . to_vector . should_equal ["Bar", "Hmm"] df . at "name_b" . to_vector . should_equal ["Bar", "Hmm"]
Test.group prefix+"Missing Values" pending=pending <| Test.group prefix+"Missing Values" pending=pending <|
t4 = upload "T4" <| t4 = upload "T4" <|
Materialized_Table.new [["a", [0, 1, Nothing, 42, Nothing]], ["b", [True, Nothing, True, False, Nothing]], ["c", ["", "foo", "bar", Nothing, Nothing]]] Table.new [["a", [0, 1, Nothing, 42, Nothing]], ["b", [True, Nothing, True, False, Nothing]], ["c", ["", "foo", "bar", Nothing, Nothing]]]
Test.specify "fill_missing should replace nulls" <| Test.specify "fill_missing should replace nulls" <|
t4.at 'a' . fill_missing 10 . to_vector . should_equal [0, 1, 10, 42, 10] t4.at 'a' . fill_missing 10 . to_vector . should_equal [0, 1, 10, 42, 10]
t4.at 'b' . fill_missing False . to_vector . should_equal [True, False, True, False, False] t4.at 'b' . fill_missing False . to_vector . should_equal [True, False, True, False, False]
@ -196,7 +194,7 @@ spec prefix connection pending=Nothing =
Test.specify "drop_missing_columns should drop columns that contain at least one missing row in a Table" <| Test.specify "drop_missing_columns should drop columns that contain at least one missing row in a Table" <|
t5 = upload "T5" <| t5 = upload "T5" <|
Materialized_Table.new [["a", [1, 2, 3]], ["b", [True, False, Nothing]], ["c", ["foo", Nothing, "aaa"]]] Table.new [["a", [1, 2, 3]], ["b", [True, False, Nothing]], ["c", ["foo", Nothing, "aaa"]]]
r = t5.drop_missing_columns r = t5.drop_missing_columns
r.columns.map .name . should_equal ["a"] r.columns.map .name . should_equal ["a"]
@ -209,7 +207,7 @@ spec prefix connection pending=Nothing =
Test.group prefix+"Column-wide statistics" pending=pending <| Test.group prefix+"Column-wide statistics" pending=pending <|
Test.specify 'should allow computing basic column-wide stats' <| Test.specify 'should allow computing basic column-wide stats' <|
t7 = upload "T7" <| t7 = upload "T7" <|
Materialized_Table.new [['price', [0.4, 3.5, Nothing, 6.7, Nothing, 97, Nothing]]] Table.new [['price', [0.4, 3.5, Nothing, 6.7, Nothing, 97, Nothing]]]
price = t7.at 'price' price = t7.at 'price'
price.sum.should_equal 107.6 epsilon=eps price.sum.should_equal 107.6 epsilon=eps
price.min.should_equal 0.4 epsilon=eps price.min.should_equal 0.4 epsilon=eps
@ -218,7 +216,7 @@ spec prefix connection pending=Nothing =
Test.group prefix+"Sorting" pending=pending <| Test.group prefix+"Sorting" pending=pending <|
df = upload "clothes" <| df = upload "clothes" <|
Materialized_Table.new [["id", [1,2,3,4,5,6]], ["name", ["shoes","trousers","dress","skirt","blouse","t-shirt"]], ["quantity", [20,10,20,10,30,30]], ["rating", [3.0,Nothing,7.3,3.0,2.2,Nothing]], ["price", [37.2,42.1,64.1,87.4,13.5,64.2]]] Table.new [["id", [1,2,3,4,5,6]], ["name", ["shoes","trousers","dress","skirt","blouse","t-shirt"]], ["quantity", [20,10,20,10,30,30]], ["rating", [3.0,Nothing,7.3,3.0,2.2,Nothing]], ["price", [37.2,42.1,64.1,87.4,13.5,64.2]]]
Test.specify "should allow sorting by a single column name" <| Test.specify "should allow sorting by a single column name" <|
r_1 = df.order_by (Sort_Column_Selector.By_Name [Sort_Column.Name 'quantity']) r_1 = df.order_by (Sort_Column_Selector.By_Name [Sort_Column.Name 'quantity'])
@ -251,7 +249,7 @@ spec prefix connection pending=Nothing =
bools = [False, False, True, True, False] bools = [False, False, True, True, False]
texts = ["foo", "foo", "bar", "baz", "spam"] texts = ["foo", "foo", "bar", "baz", "spam"]
df = upload "T8" <| df = upload "T8" <|
Materialized_Table.new [["ord", [0,3,2,4,1]], ["ints", ints], ["reals", reals], ["bools", bools], ["texts", texts]] Table.new [["ord", [0,3,2,4,1]], ["ints", ints], ["reals", reals], ["bools", bools], ["texts", texts]]
r = df.order_by (Sort_Column_Selector.By_Name [Sort_Column.Name 'ord']) r = df.order_by (Sort_Column_Selector.By_Name [Sort_Column.Name 'ord'])
r.at 'ints' . to_vector . should_equal [1, 5, 3, 2, 4] r.at 'ints' . to_vector . should_equal [1, 5, 3, 2, 4]
@ -277,7 +275,7 @@ spec prefix connection pending=Nothing =
Test.group prefix+"Index" pending=pending <| Test.group prefix+"Index" pending=pending <|
t0 = upload "Tix" <| t0 = upload "Tix" <|
Materialized_Table.new [["ix", [1,2,3]], ["c1", [4,5,6]]] Table.new [["ix", [1,2,3]], ["c1", [4,5,6]]]
t = t0.set_index 'ix' t = t0.set_index 'ix'
Test.specify "should be accessible by `at` like other columns" <| Test.specify "should be accessible by `at` like other columns" <|
t.at 'ix' . to_vector . should_equal t.index.to_vector t.at 'ix' . to_vector . should_equal t.index.to_vector
@ -310,7 +308,7 @@ spec prefix connection pending=Nothing =
insert ["zzzz", 0, 0] insert ["zzzz", 0, 0]
insert ["zzzz", Nothing, Nothing] insert ["zzzz", Nothing, Nothing]
t = upload "T9" <| t = upload "T9" <|
Materialized_Table.new [["name", builders.at 0 . to_vector], ["price", builders.at 1 . to_vector], ["quantity", builders.at 2 . to_vector]] Table.new [["name", builders.at 0 . to_vector], ["price", builders.at 1 . to_vector], ["quantity", builders.at 2 . to_vector]]
## A helper which makes sure that the groups in a materialized ## A helper which makes sure that the groups in a materialized
(InMemory) table are ordered according to a specified column or list (InMemory) table are ordered according to a specified column or list

View File

@ -1,18 +1,14 @@
from Standard.Base import all from Standard.Base import all
from Standard.Database import SQL_Query, Raw_SQL, Table_Name
import Standard.Table.Data.Table as Materialized_Table import Standard.Table.Data.Table as Materialized_Table
from Standard.Database import SQL_Query, Raw_SQL, Table_Name
import Standard.Database.Data.Table as Database_Table import Standard.Database.Data.Table as Database_Table
from Standard.Database.Data.SQL import Statement, SQL_Type from Standard.Database.Data.SQL import Statement, SQL_Type
import Standard.Database.Internal.IR import Standard.Database.Internal.IR
# TODO Dubious constructor export
from project.Database.Helpers.Fake_Test_Connection.Fake_Test_Connection import all
from project.Database.Helpers.Fake_Test_Connection.Fake_Test_Connection export all
type Fake_Test_Connection type Fake_Test_Connection
# type Fake_Test_Connection_Data (tables : Map Text (Vector [Text, SQL_Type])) (dialect : Text) # type Fake_Test_Connection.Value (tables : Map Text (Vector [Text, SQL_Type])) (dialect : Text)
Fake_Test_Connection_Data tables dialect Value tables dialect
## Set up a query returning a Table object, which can be used to work with data within the database or load it into memory. ## Set up a query returning a Table object, which can be used to work with data within the database or load it into memory.
@ -36,7 +32,7 @@ type Fake_Test_Connection
If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query. If supplied as `Text`, the name is checked against the `tables` list to determine if it is a table or a query.
- alias: optionally specify a friendly alias for the query. - alias: optionally specify a friendly alias for the query.
- limit: the maximum number of rows to return (default 1000). - limit: the maximum number of rows to return (default 1000).
read : Text | SQL_Query -> Text -> Integer | Nothing -> Table read : Text | SQL_Query -> Text -> Integer | Nothing -> Materialized_Table.Table
read self _ _="" _=Nothing = read self _ _="" _=Nothing =
Error.throw "Materialization not supported on fake connection." Error.throw "Materialization not supported on fake connection."
@ -51,4 +47,4 @@ type Fake_Test_Connection
## PRIVATE ## PRIVATE
make dialect tables = make dialect tables =
Fake_Test_Connection_Data tables dialect Fake_Test_Connection.Value tables dialect

View File

@ -4,8 +4,8 @@ import Standard.Base.System.Platform
import Standard.Base.System.Process import Standard.Base.System.Process
from Standard.Base.System.Process.Exit_Code import Exit_Success from Standard.Base.System.Process.Exit_Code import Exit_Success
import Standard.Table as Materialized_Table from Standard.Table import Table
from Standard.Table.Data.Aggregate_Column import all hiding First from Standard.Table.Data.Aggregate_Column.Aggregate_Column import all hiding First
import Standard.Database import Standard.Database
from Standard.Database import all from Standard.Database import all
@ -160,7 +160,7 @@ run_tests connection db_name pending=Nothing =
name_counter . put ix+1 name_counter . put ix+1
name = Name_Generator.random_name "table_"+ix.to_text name = Name_Generator.random_name "table_"+ix.to_text
in_mem_table = Materialized_Table.new columns in_mem_table = Table.new columns
case connection.upload_table name in_mem_table of case connection.upload_table name in_mem_table of
table -> table ->
tables.append name tables.append name
@ -173,10 +173,10 @@ run_tests connection db_name pending=Nothing =
Common_Spec.spec prefix connection pending=pending Common_Spec.spec prefix connection pending=pending
postgres_specific_spec connection db_name pending=pending postgres_specific_spec connection db_name pending=pending
common_selection = Common_Table_Spec.Test_Selection_Data supports_case_sensitive_columns=True order_by_unicode_normalization_by_default=True take_drop=False allows_mixed_type_comparisons=False common_selection = Common_Table_Spec.Test_Selection.Config supports_case_sensitive_columns=True order_by_unicode_normalization_by_default=True take_drop=False allows_mixed_type_comparisons=False
Common_Table_Spec.spec prefix table_builder test_selection=common_selection pending=pending Common_Table_Spec.spec prefix table_builder test_selection=common_selection pending=pending
selection = Aggregate_Spec.Test_Selection_Data first_last_row_order=False aggregation_problems=False date_support=False selection = Aggregate_Spec.Test_Selection.Config first_last_row_order=False aggregation_problems=False date_support=False
agg_in_memory_table = (enso_project.data / "data.csv") . read agg_in_memory_table = (enso_project.data / "data.csv") . read
agg_table = connection.upload_table (Name_Generator.random_name "Agg1") agg_in_memory_table agg_table = connection.upload_table (Name_Generator.random_name "Agg1") agg_in_memory_table
tables.append agg_table.name tables.append agg_table.name

View File

@ -1,7 +1,7 @@
from Standard.Base import all from Standard.Base import all
import Standard.Base.Runtime.Ref import Standard.Base.Runtime.Ref
import Standard.Table as Materialized_Table from Standard.Table import Table
import Standard.Database import Standard.Database
from Standard.Database import all from Standard.Database import all
@ -42,7 +42,7 @@ run_tests connection pending=Nothing =
name_counter . put ix+1 name_counter . put ix+1
name = Name_Generator.random_name "table_"+ix.to_text name = Name_Generator.random_name "table_"+ix.to_text
in_mem_table = Materialized_Table.new columns in_mem_table = Table.new columns
case connection.upload_table name in_mem_table of case connection.upload_table name in_mem_table of
table -> table ->
tables.append name tables.append name
@ -55,10 +55,10 @@ run_tests connection pending=Nothing =
Common_Spec.spec prefix connection pending=pending Common_Spec.spec prefix connection pending=pending
redshift_specific_spec connection pending=pending redshift_specific_spec connection pending=pending
common_selection = Common_Table_Spec.Test_Selection_Data supports_case_sensitive_columns=False order_by=False take_drop=False common_selection = Common_Table_Spec.Test_Selection.Config supports_case_sensitive_columns=False order_by=False take_drop=False
Common_Table_Spec.spec prefix table_builder test_selection=common_selection pending=pending Common_Table_Spec.spec prefix table_builder test_selection=common_selection pending=pending
selection = Aggregate_Spec.Test_Selection_Data text_concat=False text_shortest_longest=False first_last=False first_last_row_order=False multi_distinct=False aggregation_problems=False date_support=False selection = Aggregate_Spec.Test_Selection.Config text_concat=False text_shortest_longest=False first_last=False first_last_row_order=False multi_distinct=False aggregation_problems=False date_support=False
agg_in_memory_table = (enso_project.data / "data.csv") . read agg_in_memory_table = (enso_project.data / "data.csv") . read
agg_table = connection.upload_table (Name_Generator.random_name "Agg1") agg_in_memory_table agg_table = connection.upload_table (Name_Generator.random_name "Agg1") agg_in_memory_table
tables.append agg_table.name tables.append agg_table.name

View File

@ -1,7 +1,7 @@
from Standard.Base import all from Standard.Base import all
import Standard.Base.Runtime.Ref import Standard.Base.Runtime.Ref
import Standard.Table as Materialized_Table from Standard.Table import Table
import Standard.Database import Standard.Database
from Standard.Database import all from Standard.Database import all
@ -104,13 +104,13 @@ sqlite_spec connection prefix =
name_counter . put ix+1 name_counter . put ix+1
name = Name_Generator.random_name "table_"+ix.to_text name = Name_Generator.random_name "table_"+ix.to_text
in_mem_table = Materialized_Table.new columns in_mem_table = Table.new columns
connection.upload_table name in_mem_table connection.upload_table name in_mem_table
materialize = .read materialize = .read
Common_Spec.spec prefix connection Common_Spec.spec prefix connection
sqlite_specific_spec connection sqlite_specific_spec connection
common_selection = Common_Table_Spec.Test_Selection_Data supports_case_sensitive_columns=False order_by=True natural_ordering=False case_insensitive_ordering=True case_insensitive_ascii_only=True take_drop=False common_selection = Common_Table_Spec.Test_Selection.Config supports_case_sensitive_columns=False order_by=True natural_ordering=False case_insensitive_ordering=True case_insensitive_ascii_only=True take_drop=False
Common_Table_Spec.spec prefix table_builder test_selection=common_selection Common_Table_Spec.spec prefix table_builder test_selection=common_selection
## For now `advanced_stats`, `first_last`, `text_shortest_longest` and ## For now `advanced_stats`, `first_last`, `text_shortest_longest` and
@ -121,7 +121,7 @@ sqlite_spec connection prefix =
- creating complex nested queries using NTILE to compute the stats, - creating complex nested queries using NTILE to compute the stats,
- compiling SQLite library on our own and adding native extensions for - compiling SQLite library on our own and adding native extensions for
the missing statistics. the missing statistics.
selection = Aggregate_Spec.Test_Selection_Data advanced_stats=False text_shortest_longest=False first_last=False first_last_row_order=False multi_distinct=False aggregation_problems=False nan=False date_support=False selection = Aggregate_Spec.Test_Selection.Config advanced_stats=False text_shortest_longest=False first_last=False first_last_row_order=False multi_distinct=False aggregation_problems=False nan=False date_support=False
agg_in_memory_table = (enso_project.data / "data.csv") . read agg_in_memory_table = (enso_project.data / "data.csv") . read
agg_table = connection.upload_table (Name_Generator.random_name "Agg1") agg_in_memory_table agg_table = connection.upload_table (Name_Generator.random_name "Agg1") agg_in_memory_table
empty_agg_table = connection.upload_table (Name_Generator.random_name "Agg_Empty") (agg_in_memory_table.take (First 0)) empty_agg_table = connection.upload_table (Name_Generator.random_name "Agg_Empty") (agg_in_memory_table.take (First 0))

View File

@ -1,7 +1,6 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table, Column, Data_Formatter, Quote_Style, Delimited
from Standard.Table import Column, Data_Formatter_Data, Quote_Style, Delimited
from Standard.Table.Errors import all from Standard.Table.Errors import all
import Standard.Test import Standard.Test
@ -130,7 +129,7 @@ spec =
text = lines.join '\n' text = lines.join '\n'
text.write file text.write file
format = Delimited ',' headers=False value_formatter=(Data_Formatter_Data trim_values=False) format = Delimited ',' headers=False value_formatter=(Data_Formatter.Value trim_values=False)
reference_table = Table.new [["Column_1", ["a", "d", "1"]], ["Column_2", ["b", "e", "2"]], ["Column_3", ["c", "f", "3"]]] reference_table = Table.new [["Column_1", ["a", "d", "1"]], ["Column_2", ["b", "e", "2"]], ["Column_3", ["c", "f", "3"]]]
collapsed_table = Table.new <| collapsed_table = Table.new <|
@ -326,7 +325,7 @@ spec =
t.at "QuotedNumbers" . to_vector . should_equal ["1", "2", Nothing, "34"] t.at "QuotedNumbers" . to_vector . should_equal ["1", "2", Nothing, "34"]
t.at "Mixed Types" . to_vector . should_equal ["33", Nothing, "45", "True"] t.at "Mixed Types" . to_vector . should_equal ["33", Nothing, "45", "True"]
t2 = (enso_project.data / "data_small.csv") . read (Delimited "," headers=True value_formatter=(Data_Formatter_Data allow_leading_zeros=True)) t2 = (enso_project.data / "data_small.csv") . read (Delimited "," headers=True value_formatter=(Data_Formatter.Value allow_leading_zeros=True))
t2.at "Leading0s" . to_vector . should_equal [1, 2, 123, Nothing] t2.at "Leading0s" . to_vector . should_equal [1, 2, 123, Nothing]
Test.specify "should be able to detect types automatically" <| Test.specify "should be able to detect types automatically" <|
@ -345,14 +344,14 @@ spec =
a,b,c a,b,c
1,2,3 1,2,3
4,5,6 4,5,6
t1 = Table.Table.from text1 (format = Delimited ",") t1 = Table.from text1 (format = Delimited ",")
t1.columns.map .name . should_equal ["a", "b", "c"] t1.columns.map .name . should_equal ["a", "b", "c"]
t1.at "a" . to_vector . should_equal [1, 4] t1.at "a" . to_vector . should_equal [1, 4]
t1.at "b" . to_vector . should_equal [2, 5] t1.at "b" . to_vector . should_equal [2, 5]
t1.at "c" . to_vector . should_equal [3, 6] t1.at "c" . to_vector . should_equal [3, 6]
text2 = 'a\tb\n1\t2\n3\t4' text2 = 'a\tb\n1\t2\n3\t4'
t2 = Table.Table.from text2 t2 = Table.from text2
t2.columns.map .name . should_equal ["a", "b"] t2.columns.map .name . should_equal ["a", "b"]
t2.at "a" . to_vector . should_equal [1, 3] t2.at "a" . to_vector . should_equal [1, 3]
t2.at "b" . to_vector . should_equal [2, 4] t2.at "b" . to_vector . should_equal [2, 4]
@ -385,7 +384,7 @@ spec =
Delimited ',' . with_parsing . should_equal (Delimited ',') Delimited ',' . with_parsing . should_equal (Delimited ',')
Delimited ',' . without_parsing . should_equal (Delimited ',' value_formatter=Nothing) Delimited ',' . without_parsing . should_equal (Delimited ',' value_formatter=Nothing)
custom_formatter = Data_Formatter_Data true_values=["A", "B", "C"] false_values=["D", "E", "F"] custom_formatter = Data_Formatter.Value true_values=["A", "B", "C"] false_values=["D", "E", "F"]
Delimited ',' . with_parsing custom_formatter . should_equal (Delimited ',' value_formatter=custom_formatter) Delimited ',' . with_parsing custom_formatter . should_equal (Delimited ',' value_formatter=custom_formatter)
Delimited ',' row_limit=456 . without_parsing . should_equal (Delimited ',' value_formatter=Nothing row_limit=456) Delimited ',' row_limit=456 . without_parsing . should_equal (Delimited ',' value_formatter=Nothing row_limit=456)

View File

@ -2,23 +2,16 @@ from Standard.Base import all
import Standard.Base.System import Standard.Base.System
from Standard.Base.Error.Problem_Behavior import all from Standard.Base.Error.Problem_Behavior import all
import Standard.Table from Standard.Table import Table, Column, Data_Formatter, Quote_Style, Column_Name_Mapping, Match_Columns, Delimited
from Standard.Table import Column, Data_Formatter, Data_Formatter_Data, Quote_Style, Column_Name_Mapping, Match_Columns, Delimited
from Standard.Table.Errors import all from Standard.Table.Errors import all
from Standard.Table.Data.Column_Selector import By_Name
from Standard.Table.Errors import Column_Count_Mismatch_Data, Column_Name_Mismatch_Data
import Standard.Test import Standard.Test
import Standard.Test.Problems import Standard.Test.Problems
from project.Util import all from project.Util import all
# TODO Dubious constructor export
from project.Delimited_Write_Spec.My_Type import all
from project.Delimited_Write_Spec.My_Type export all
type My_Type type My_Type
My_Type_Data x Value x
to_text : Text to_text : Text
to_text self = "[[[My Type :: " + self.x.to_text + "]]]" to_text self = "[[[My Type :: " + self.x.to_text + "]]]"
@ -32,7 +25,7 @@ spec =
line_ending_pairs = [[Line_Ending_Style.Unix, '\n'], [Line_Ending_Style.Windows, '\r\n'], [Line_Ending_Style.Mac_Legacy, '\r']] line_ending_pairs = [[Line_Ending_Style.Unix, '\n'], [Line_Ending_Style.Windows, '\r\n'], [Line_Ending_Style.Mac_Legacy, '\r']]
Test.group "Delimited File Writing" <| Test.group "Delimited File Writing" <|
Test.specify "should correctly write a simple table" <| Test.specify "should correctly write a simple table" <|
table = Table.new [["A", [1,2,3]], ["B", [1.0,1.5,2.2]], ["C", ["x","y","z"]], ["D", ["a", 2, My_Type_Data 10]]] table = Table.new [["A", [1,2,3]], ["B", [1.0,1.5,2.2]], ["C", ["x","y","z"]], ["D", ["a", 2, My_Type.Value 10]]]
file = (enso_project.data / "transient" / "written.csv") file = (enso_project.data / "transient" / "written.csv")
file.delete_if_exists file.delete_if_exists
table.write file on_problems=Report_Error . should_succeed table.write file on_problems=Report_Error . should_succeed
@ -67,7 +60,7 @@ spec =
file.delete file.delete
Test.specify 'should quote values that contain the delimiter or quotes, in the [,""] variant' <| Test.specify 'should quote values that contain the delimiter or quotes, in the [,""] variant' <|
data_formatter = Data_Formatter_Data decimal_point="," data_formatter = Data_Formatter.Value decimal_point=","
table = Table.new [['The Column "Name"', ["foo","'bar'",'"baz"', 'one, two, three']], ["Hello, Column?", [1.0, 1000000.5, 2.2, -1.5]]] table = Table.new [['The Column "Name"', ["foo","'bar'",'"baz"', 'one, two, three']], ["Hello, Column?", [1.0, 1000000.5, 2.2, -1.5]]]
file = (enso_project.data / "transient" / "quotes1.csv") file = (enso_project.data / "transient" / "quotes1.csv")
file.delete_if_exists file.delete_if_exists
@ -83,7 +76,7 @@ spec =
file.delete file.delete
Test.specify 'should quote values that contain the delimiter or quotes, in the [;\\\"] variant' <| Test.specify 'should quote values that contain the delimiter or quotes, in the [;\\\"] variant' <|
data_formatter = Data_Formatter_Data thousand_separator="'" data_formatter = Data_Formatter.Value thousand_separator="'"
table = Table.new [['"A"', ["foo",'!"baz" ', 'one, two, three', "a;b; c ", "a\b"]], ["B", [1000000.5, 1000.0, 0.0, -1.2, Nothing]]] table = Table.new [['"A"', ["foo",'!"baz" ', 'one, two, three', "a;b; c ", "a\b"]], ["B", [1000000.5, 1000.0, 0.0, -1.2, Nothing]]]
file = (enso_project.data / "transient" / "quotes2.csv") file = (enso_project.data / "transient" / "quotes2.csv")
file.delete_if_exists file.delete_if_exists
@ -100,7 +93,7 @@ spec =
file.delete file.delete
Test.specify "should quote values that contain the delimiter or quotes, in the [\t''] variant" <| Test.specify "should quote values that contain the delimiter or quotes, in the [\t''] variant" <|
data_formatter = Data_Formatter_Data thousand_separator="'" data_formatter = Data_Formatter.Value thousand_separator="'"
table = Table.new [['"A"', [Nothing,"The 'thing'.", 'one, "two", three', 'a\tb']], ["B\C", [1000000.5, 1000.0, Nothing, -1.2]]] table = Table.new [['"A"', [Nothing,"The 'thing'.", 'one, "two", three', 'a\tb']], ["B\C", [1000000.5, 1000.0, Nothing, -1.2]]]
file = (enso_project.data / "transient" / "quotes3.csv") file = (enso_project.data / "transient" / "quotes3.csv")
file.delete_if_exists file.delete_if_exists
@ -151,7 +144,7 @@ spec =
file.delete file.delete
Test.specify 'should not quote values if quoting is disabled' <| Test.specify 'should not quote values if quoting is disabled' <|
format = Delimited "," value_formatter=(Data_Formatter_Data decimal_point=",") . without_quotes format = Delimited "," value_formatter=(Data_Formatter.Value decimal_point=",") . without_quotes
table = Table.new [['The Column "Name"', ["foo","'bar'",'"baz"', 'one, two, three']], ["Hello, Column?", [1.0, 1000000.5, 2.2, -1.5]]] table = Table.new [['The Column "Name"', ["foo","'bar'",'"baz"', 'one, two, three']], ["Hello, Column?", [1.0, 1000000.5, 2.2, -1.5]]]
file = (enso_project.data / "transient" / "quote_disabled.csv") file = (enso_project.data / "transient" / "quote_disabled.csv")
file.delete_if_exists file.delete_if_exists
@ -167,8 +160,8 @@ spec =
file.delete file.delete
Test.specify 'should allow to always quote text and custom values, but for non-text primitves only if absolutely necessary' <| Test.specify 'should allow to always quote text and custom values, but for non-text primitves only if absolutely necessary' <|
format = Delimited "," value_formatter=(Data_Formatter_Data thousand_separator='"' date_formats=["E, d MMM y"]) . with_quotes always_quote=True quote_escape='\\' format = Delimited "," value_formatter=(Data_Formatter.Value thousand_separator='"' date_formats=["E, d MMM y"]) . with_quotes always_quote=True quote_escape='\\'
table = Table.new [['The Column "Name"', ["foo","'bar'",'"baz"', 'one, two, three']], ["B", [1.0, 1000000.5, 2.2, -1.5]], ["C", ["foo", My_Type_Data 44, (Date.new 2022 06 21), 42]], ["D", [1,2,3,4000]], ["E", [Nothing, (Time_Of_Day.new 13 55), Nothing, Nothing]]] table = Table.new [['The Column "Name"', ["foo","'bar'",'"baz"', 'one, two, three']], ["B", [1.0, 1000000.5, 2.2, -1.5]], ["C", ["foo", My_Type.Value 44, (Date.new 2022 06 21), 42]], ["D", [1,2,3,4000]], ["E", [Nothing, (Time_Of_Day.new 13 55), Nothing, Nothing]]]
file = (enso_project.data / "transient" / "quote_always.csv") file = (enso_project.data / "transient" / "quote_always.csv")
file.delete_if_exists file.delete_if_exists
table.write file format on_problems=Report_Error . should_succeed table.write file format on_problems=Report_Error . should_succeed

View File

@ -3,10 +3,8 @@ from Standard.Base import all
from Standard.Base.System.File import File_Already_Exists_Error from Standard.Base.System.File import File_Already_Exists_Error
from Standard.Base.Error.Problem_Behavior import all from Standard.Base.Error.Problem_Behavior import all
import Standard.Table from Standard.Table import Table, Match_Columns, Column_Name_Mapping, Excel, Excel_Range, Data_Formatter, Sheet_Names, Range_Names, Worksheet, Cell_Range, Delimited, Column_Selector
from Standard.Table import Match_Columns, Column_Name_Mapping, Excel, Excel_Range, Data_Formatter_Data, Sheet_Names, Range_Names, Worksheet, Cell_Range, Delimited
from Standard.Table.Data.Column_Selector import By_Index
from Standard.Table.Errors import Invalid_Output_Column_Names_Data, Duplicate_Output_Column_Names_Data, Invalid_Location_Data, Range_Exceeded_Data, Existing_Data_Data, Column_Count_Mismatch_Data, Column_Name_Mismatch_Data from Standard.Table.Errors import Invalid_Output_Column_Names_Data, Duplicate_Output_Column_Names_Data, Invalid_Location_Data, Range_Exceeded_Data, Existing_Data_Data, Column_Count_Mismatch_Data, Column_Name_Mismatch_Data
import Standard.Test import Standard.Test
@ -71,12 +69,12 @@ spec_write suffix test_sheet_name =
for these tests. This should ideally be re-enabled with the for these tests. This should ideally be re-enabled with the
completion of the following story: completion of the following story:
https://www.pivotaltracker.com/story/show/181755990 https://www.pivotaltracker.com/story/show/181755990
no_dates = Delimited "," value_formatter=(Data_Formatter_Data date_formats=[] time_formats=[] datetime_formats=[]) no_dates = Delimited "," value_formatter=(Data_Formatter.Value date_formats=[] time_formats=[] datetime_formats=[])
out = enso_project.data / ('out.' + suffix) out = enso_project.data / ('out.' + suffix)
out_bak = enso_project.data / ('out.' + suffix + '.bak') out_bak = enso_project.data / ('out.' + suffix + '.bak')
table = enso_project.data/'varied_column.csv' . read (format = no_dates) table = enso_project.data/'varied_column.csv' . read (format = no_dates)
clothes = enso_project.data/'clothes.csv' . read (format = no_dates) clothes = enso_project.data/'clothes.csv' . read (format = no_dates)
sub_clothes = clothes.select_columns (By_Index [0, 1]) sub_clothes = clothes.select_columns (Column_Selector.By_Index [0, 1])
Test.specify 'should write a table to non-existent file as a new sheet with headers' <| Test.specify 'should write a table to non-existent file as a new sheet with headers' <|
out.delete_if_exists out.delete_if_exists
@ -190,7 +188,7 @@ spec_write suffix test_sheet_name =
extra_another = Table.new [['AA', ['d', 'e']], ['BB',[4, 5]], ['CC',[True, False]], ['DD', ['2022-01-20', '2022-01-21']]] extra_another = Table.new [['AA', ['d', 'e']], ['BB',[4, 5]], ['CC',[True, False]], ['DD', ['2022-01-20', '2022-01-21']]]
expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]] expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]]
extra_another.write out (Excel (Worksheet "Another")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed extra_another.write out (Excel (Worksheet "Another")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed
written = out.read (Excel (Worksheet "Another")) . select_columns (By_Index [0, 1, 2]) written = out.read (Excel (Worksheet "Another")) . select_columns (Column_Selector.By_Index [0, 1, 2])
written.should_equal expected written.should_equal expected
out.delete_if_exists out.delete_if_exists
@ -200,7 +198,7 @@ spec_write suffix test_sheet_name =
extra_another = Table.new [['A', ['d', 'e']], ['B',[4, 5]], ['C',[True, False]], ['D', ['2022-01-20', '2022-01-21']]] extra_another = Table.new [['A', ['d', 'e']], ['B',[4, 5]], ['C',[True, False]], ['D', ['2022-01-20', '2022-01-21']]]
expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]] expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]]
extra_another.write out (Excel (Worksheet "Another")) on_existing_file=Existing_File_Behavior.Append match_columns=Match_Columns.By_Position on_problems=Report_Error . should_succeed extra_another.write out (Excel (Worksheet "Another")) on_existing_file=Existing_File_Behavior.Append match_columns=Match_Columns.By_Position on_problems=Report_Error . should_succeed
written = out.read (Excel (Worksheet "Another")) . select_columns (By_Index [0, 1, 2]) written = out.read (Excel (Worksheet "Another")) . select_columns (Column_Selector.By_Index [0, 1, 2])
written.should_equal expected written.should_equal expected
out.delete_if_exists out.delete_if_exists
@ -210,7 +208,7 @@ spec_write suffix test_sheet_name =
extra_another = Table.new [['CC',[True, False]], ['BB',[4, 5]], ['AA', ['d', 'e']], ['DD', ['2022-01-20', '2022-01-21']]] extra_another = Table.new [['CC',[True, False]], ['BB',[4, 5]], ['AA', ['d', 'e']], ['DD', ['2022-01-20', '2022-01-21']]]
expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]] expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]]
extra_another.write out (Excel (Worksheet "Another")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed extra_another.write out (Excel (Worksheet "Another")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed
written = out.read (Excel (Worksheet "Another")) . select_columns (By_Index [0, 1, 2]) written = out.read (Excel (Worksheet "Another")) . select_columns (Column_Selector.By_Index [0, 1, 2])
written.should_equal expected written.should_equal expected
out.delete_if_exists out.delete_if_exists
@ -220,7 +218,7 @@ spec_write suffix test_sheet_name =
extra_another = Table.new [['AA', ['d', 'e']], ['BB',[4, 5]], ['CC',[True, False]], ['DD', ['2022-01-20', '2022-01-21']]] extra_another = Table.new [['AA', ['d', 'e']], ['BB',[4, 5]], ['CC',[True, False]], ['DD', ['2022-01-20', '2022-01-21']]]
expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]] expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]]
extra_another.write out (Excel (Cell_Range "Another!A1")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed extra_another.write out (Excel (Cell_Range "Another!A1")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed
written = out.read (Excel (Worksheet "Another")) . select_columns (By_Index [0, 1, 2]) written = out.read (Excel (Worksheet "Another")) . select_columns (Column_Selector.By_Index [0, 1, 2])
written.should_equal expected written.should_equal expected
out.delete_if_exists out.delete_if_exists
@ -230,7 +228,7 @@ spec_write suffix test_sheet_name =
extra_another = Table.new [['A', ['d', 'e']], ['B',[4, 5]], ['C',[True, False]], ['D', ['2022-01-20', '2022-01-21']]] extra_another = Table.new [['A', ['d', 'e']], ['B',[4, 5]], ['C',[True, False]], ['D', ['2022-01-20', '2022-01-21']]]
expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]] expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]]
extra_another.write out (Excel (Cell_Range "Another!A1")) on_existing_file=Existing_File_Behavior.Append match_columns=Match_Columns.By_Position on_problems=Report_Error . should_succeed extra_another.write out (Excel (Cell_Range "Another!A1")) on_existing_file=Existing_File_Behavior.Append match_columns=Match_Columns.By_Position on_problems=Report_Error . should_succeed
written = out.read (Excel (Worksheet "Another")) . select_columns (By_Index [0, 1, 2]) written = out.read (Excel (Worksheet "Another")) . select_columns (Column_Selector.By_Index [0, 1, 2])
written.should_equal expected written.should_equal expected
out.delete_if_exists out.delete_if_exists
@ -240,7 +238,7 @@ spec_write suffix test_sheet_name =
extra_another = Table.new [['CC',[True, False]], ['BB',[4, 5]], ['AA', ['d', 'e']], ['DD', ['2022-01-20', '2022-01-21']]] extra_another = Table.new [['CC',[True, False]], ['BB',[4, 5]], ['AA', ['d', 'e']], ['DD', ['2022-01-20', '2022-01-21']]]
expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]] expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]]
extra_another.write out (Excel (Cell_Range "Another!A1")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed extra_another.write out (Excel (Cell_Range "Another!A1")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed
written = out.read (Excel (Worksheet "Another")) . select_columns (By_Index [0, 1, 2]) written = out.read (Excel (Worksheet "Another")) . select_columns (Column_Selector.By_Index [0, 1, 2])
written.should_equal expected written.should_equal expected
out.delete_if_exists out.delete_if_exists
@ -250,7 +248,7 @@ spec_write suffix test_sheet_name =
extra_another = Table.new [['AA', ['d', 'e']], ['BB', [4, 5]], ['CC', [True, False]], ['DD', ['2022-01-20', '2022-01-21']]] extra_another = Table.new [['AA', ['d', 'e']], ['BB', [4, 5]], ['CC', [True, False]], ['DD', ['2022-01-20', '2022-01-21']]]
expected = Table.new [['AA', ['a', 'b', 'c', 'd', 'e']], ['BB', [1, 2, 3, 4, 5]], ['CC', [True, False, False, True, False]]] expected = Table.new [['AA', ['a', 'b', 'c', 'd', 'e']], ['BB', [1, 2, 3, 4, 5]], ['CC', [True, False, False, True, False]]]
extra_another.write out (Excel (Cell_Range "Another!A1:D6")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed extra_another.write out (Excel (Cell_Range "Another!A1:D6")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed
written = out.read (Excel (Worksheet "Another")) . select_columns (By_Index [0, 1, 2]) written = out.read (Excel (Worksheet "Another")) . select_columns (Column_Selector.By_Index [0, 1, 2])
written.should_equal expected written.should_equal expected
out.delete_if_exists out.delete_if_exists
@ -260,7 +258,7 @@ spec_write suffix test_sheet_name =
extra_another = Table.new [['A', ['d', 'e']], ['B',[4, 5]], ['C',[True, False]], ['D', ['2022-01-20', '2022-01-21']]] extra_another = Table.new [['A', ['d', 'e']], ['B',[4, 5]], ['C',[True, False]], ['D', ['2022-01-20', '2022-01-21']]]
expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]] expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]]
extra_another.write out (Excel (Cell_Range "Another!A1:D6")) on_existing_file=Existing_File_Behavior.Append match_columns=Match_Columns.By_Position on_problems=Report_Error . should_succeed extra_another.write out (Excel (Cell_Range "Another!A1:D6")) on_existing_file=Existing_File_Behavior.Append match_columns=Match_Columns.By_Position on_problems=Report_Error . should_succeed
written = out.read (Excel (Worksheet "Another")) . select_columns (By_Index [0, 1, 2]) written = out.read (Excel (Worksheet "Another")) . select_columns (Column_Selector.By_Index [0, 1, 2])
written.should_equal expected written.should_equal expected
out.delete_if_exists out.delete_if_exists
@ -270,7 +268,7 @@ spec_write suffix test_sheet_name =
extra_another = Table.new [['AA', ['d', 'e']], ['BB',[4, 5]], ['CC',[True, False]], ['DD', ['2022-01-20', '2022-01-21']]] extra_another = Table.new [['AA', ['d', 'e']], ['BB',[4, 5]], ['CC',[True, False]], ['DD', ['2022-01-20', '2022-01-21']]]
expected = Table.new [['AA', ['f', 'g', 'h', 'd', 'e']], ['BB',[1, 2, 3, 4, 5]], ['CC',[True, False, False, True, False]]] expected = Table.new [['AA', ['f', 'g', 'h', 'd', 'e']], ['BB',[1, 2, 3, 4, 5]], ['CC',[True, False, False, True, False]]]
extra_another.write out (Excel (Cell_Range "Random!K9")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed extra_another.write out (Excel (Cell_Range "Random!K9")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed
written = out.read (Excel (Cell_Range "Random!K9")) . select_columns (By_Index [0, 1, 2]) written = out.read (Excel (Cell_Range "Random!K9")) . select_columns (Column_Selector.By_Index [0, 1, 2])
written.should_equal expected written.should_equal expected
out.delete_if_exists out.delete_if_exists
@ -280,7 +278,7 @@ spec_write suffix test_sheet_name =
extra_another = Table.new [['AA', ['d', 'e']], ['BB',[4, 5]], ['AA_1',[True, False]], ['BB_1', ['2022-01-20', '2022-01-21']]] extra_another = Table.new [['AA', ['d', 'e']], ['BB',[4, 5]], ['AA_1',[True, False]], ['BB_1', ['2022-01-20', '2022-01-21']]]
expected = Table.new [['AA', ['f', 'g', 'h', 'd', 'e']], ['BB',[1, 2, 3, 4, 5]], ['AA_1',[True, False, False, True, False]]] expected = Table.new [['AA', ['f', 'g', 'h', 'd', 'e']], ['BB',[1, 2, 3, 4, 5]], ['AA_1',[True, False, False, True, False]]]
extra_another.write out (Excel (Cell_Range "Random!S3")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed extra_another.write out (Excel (Cell_Range "Random!S3")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed
written = out.read (Excel (Cell_Range "Random!S3")) . select_columns (By_Index [0, 1, 2]) written = out.read (Excel (Cell_Range "Random!S3")) . select_columns (Column_Selector.By_Index [0, 1, 2])
written.should_equal expected written.should_equal expected
out.delete_if_exists out.delete_if_exists
@ -290,7 +288,7 @@ spec_write suffix test_sheet_name =
extra_another = Table.new [['A', ['d', 'e']], ['B',[4, 5]], ['C',[True, False]], ['D', ['2022-01-20', '2022-01-21']]] extra_another = Table.new [['A', ['d', 'e']], ['B',[4, 5]], ['C',[True, False]], ['D', ['2022-01-20', '2022-01-21']]]
expected = Table.new [['AA', ['f', 'g', 'h', 'd', 'e']], ['BB',[1, 2, 3, 4, 5]], ['CC',[True, False, False, True, False]]] expected = Table.new [['AA', ['f', 'g', 'h', 'd', 'e']], ['BB',[1, 2, 3, 4, 5]], ['CC',[True, False, False, True, False]]]
extra_another.write out (Excel (Cell_Range "Random!K9")) on_existing_file=Existing_File_Behavior.Append match_columns=Match_Columns.By_Position on_problems=Report_Error . should_succeed extra_another.write out (Excel (Cell_Range "Random!K9")) on_existing_file=Existing_File_Behavior.Append match_columns=Match_Columns.By_Position on_problems=Report_Error . should_succeed
written = out.read (Excel (Cell_Range "Random!K9")) . select_columns (By_Index [0, 1, 2]) written = out.read (Excel (Cell_Range "Random!K9")) . select_columns (Column_Selector.By_Index [0, 1, 2])
written.should_equal expected written.should_equal expected
out.delete_if_exists out.delete_if_exists
@ -300,7 +298,7 @@ spec_write suffix test_sheet_name =
extra_another = Table.new [['CC',[True, False]], ['BB',[4, 5]], ['AA', ['d', 'e']], ['DD', ['2022-01-20', '2022-01-21']]] extra_another = Table.new [['CC',[True, False]], ['BB',[4, 5]], ['AA', ['d', 'e']], ['DD', ['2022-01-20', '2022-01-21']]]
expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]] expected = Table.new [['AA', ['a','b','c','d', 'e']], ['BB',[1,2,3,4,5]], ['CC',[True, False, False, True, False]]]
extra_another.write out (Excel (Cell_Range "Another!A1:D6")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed extra_another.write out (Excel (Cell_Range "Another!A1:D6")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed
written = out.read (Excel (Worksheet "Another")) . select_columns (By_Index [0, 1, 2]) written = out.read (Excel (Worksheet "Another")) . select_columns (Column_Selector.By_Index [0, 1, 2])
written.should_equal expected written.should_equal expected
out.delete_if_exists out.delete_if_exists

View File

@ -1,5 +1,5 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table
import Standard.Test import Standard.Test

View File

@ -1,7 +1,6 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table, Data_Formatter
from Standard.Table import Data_Formatter
from Standard.Table.Data.Table import Empty_Error from Standard.Table.Data.Table import Empty_Error
from Standard.Table.Data.Column_Type_Selection import Column_Type_Selection, Auto from Standard.Table.Data.Column_Type_Selection import Column_Type_Selection, Auto
from Standard.Table.Errors import Invalid_Format, Leading_Zeros, Missing_Input_Columns, Column_Indexes_Out_Of_Range, Duplicate_Type_Selector from Standard.Table.Errors import Invalid_Format, Leading_Zeros, Missing_Input_Columns, Column_Indexes_Out_Of_Range, Duplicate_Type_Selector

View File

@ -1,8 +1,7 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table, Column, Delimited, Data_Formatter
from Standard.Table import Column, Delimited, Data_Formatter_Data import Standard.Table.Data.Storage.Storage
import Standard.Table.Data.Storage
import Standard.Test import Standard.Test
from project.Util import all from project.Util import all
@ -46,7 +45,7 @@ spec =
Test.specify "should serialise dates with format" <| Test.specify "should serialise dates with format" <|
test_table = Table.new [c_from] test_table = Table.new [c_from]
expected_text = 'From\n04.05.1979\n28.11.1990\n02.05.1997\n27.06.2007\n11.05.2010\n13.07.2016\n24.07.2019\n' expected_text = 'From\n04.05.1979\n28.11.1990\n02.05.1997\n27.06.2007\n11.05.2010\n13.07.2016\n24.07.2019\n'
data_formatter = Data_Formatter_Data . with_datetime_formats date_formats=["dd.MM.yyyy"] data_formatter = Data_Formatter.Value.with_datetime_formats date_formats=["dd.MM.yyyy"]
delimited = Text.from test_table format=(Delimited "," value_formatter=data_formatter line_endings=Line_Ending_Style.Unix) delimited = Text.from test_table format=(Delimited "," value_formatter=data_formatter line_endings=Line_Ending_Style.Unix)
delimited.should_equal expected_text delimited.should_equal expected_text

View File

@ -1,13 +1,11 @@
from Standard.Base import all from Standard.Base import all
from Standard.Base.Error.Problem_Behavior import Report_Error from Standard.Base.Error.Problem_Behavior import Report_Error
import Standard.Table from Standard.Table import Table, Column, Sort_Column, Column_Selector, Sort_Column_Selector, Aggregate_Column
from Standard.Table import Column, Sort_Column, Sort_Column_Selector, Aggregate_Column from Standard.Table.Data.Aggregate_Column.Aggregate_Column import all hiding First, Last
from Standard.Table.Data.Aggregate_Column import all hiding First, Last
from Standard.Table.Data.Table import Empty_Error from Standard.Table.Data.Table import Empty_Error
from Standard.Table.Errors import Invalid_Output_Column_Names_Data, Duplicate_Output_Column_Names_Data, No_Input_Columns_Selected, Missing_Input_Columns_Data, No_Such_Column_Error_Data from Standard.Table.Errors import Invalid_Output_Column_Names_Data, Duplicate_Output_Column_Names_Data, No_Input_Columns_Selected, Missing_Input_Columns_Data, No_Such_Column_Error_Data
import Standard.Table.Data.Storage from Standard.Table.Data.Storage import Storage
from Standard.Table.Data.Column_Selector import By_Name
from Standard.Table.Errors import Floating_Point_Grouping_Data from Standard.Table.Errors import Floating_Point_Grouping_Data
from Standard.Table.Data.Filter_Condition import Filter_Condition from Standard.Table.Data.Filter_Condition import Filter_Condition
@ -19,21 +17,17 @@ import Standard.Test.Problems
import project.Common_Table_Spec import project.Common_Table_Spec
from project.Util import all from project.Util import all
# TODO Dubious constructor export
from project.Table_Spec.My import all
from project.Table_Spec.My export all
type My type My
My_Data x y Data x y
My.== self that = case that of == self that = case that of
My_Data x1 y1 -> (self.x + self.y) == (x1 + y1) My.Data x1 y1 -> (self.x + self.y) == (x1 + y1)
_ -> False _ -> False
My.compare_to self that = self.x+self.y . compare_to that.x+that.y compare_to self that = self.x+self.y . compare_to that.x+that.y
My.frobnicate self = case self of frobnicate self = case self of
My_Data x1 y1 -> My_Data y1 x1 My.Data x1 y1 -> My.Data y1 x1
spec = spec =
Test.group "JSON construction" <| Test.group "JSON construction" <|
@ -98,7 +92,7 @@ spec =
ints = ["ints", [Nothing, 1, 2, 4]] ints = ["ints", [Nothing, 1, 2, 4]]
doubles = ["doubles", [0.0, 1.5, Nothing, 2.0]] doubles = ["doubles", [0.0, 1.5, Nothing, 2.0]]
doubles_and_ints = ["doubles_and_ints", [0, 1.5, Nothing, 2]] doubles_and_ints = ["doubles_and_ints", [0, 1.5, Nothing, 2]]
custom_objects = ["custom_objects", [My_Data 1 2, My_Data 3 4, Nothing, Nothing]] custom_objects = ["custom_objects", [My.Data 1 2, My.Data 3 4, Nothing, Nothing]]
dates = ["dates", [Nothing, Date.new 2000, Date.new 2022 8 20, Date.new 1999 1 1]] dates = ["dates", [Nothing, Date.new 2000, Date.new 2022 8 20, Date.new 1999 1 1]]
times = ["times", [Time_Of_Day.new 18 00, Time_Of_Day.new 1 2 34, Nothing, Time_Of_Day.new]] times = ["times", [Time_Of_Day.new 18 00, Time_Of_Day.new 1 2 34, Nothing, Time_Of_Day.new]]
datetimes = ["datetimes", [Date_Time.new 2000, Date_Time.new 1999 1 2 3 4 5, Nothing, Date_Time.new 2022 8 27 11 22 25]] datetimes = ["datetimes", [Date_Time.new 2000, Date_Time.new 1999 1 2 3 4 5, Nothing, Date_Time.new 2022 8 27 11 22 25]]
@ -161,7 +155,7 @@ spec =
col_1 = Column.from_vector 'x' [1, 2, 3] col_1 = Column.from_vector 'x' [1, 2, 3]
col_1.to_vector.reduce (+) . should_equal 6 col_1.to_vector.reduce (+) . should_equal 6
col_2 = Column.from_vector 'y' [My_Data 1 2, My_Data 2 3] col_2 = Column.from_vector 'y' [My.Data 1 2, My.Data 2 3]
col_2.to_vector.map (my -> my.x + my.y) . should_equal [3, 5] col_2.to_vector.map (my -> my.x + my.y) . should_equal [3, 5]
col_3 = Column.from_vector 'z' [False, True, False] col_3 = Column.from_vector 'z' [False, True, False]
@ -177,8 +171,8 @@ spec =
c_dec.map (+ 1.5) . to_vector . should_equal [3.4, 3.5, 2.7, 7.1, 3.4] c_dec.map (+ 1.5) . to_vector . should_equal [3.4, 3.5, 2.7, 7.1, 3.4]
c_bool = Column.from_vector 'x' [True, False, Nothing, True, False] c_bool = Column.from_vector 'x' [True, False, Nothing, True, False]
c_bool.map (_.to_text) . to_vector . should_equal ["True", "False", Nothing, "True", "False"] c_bool.map (_.to_text) . to_vector . should_equal ["True", "False", Nothing, "True", "False"]
c_any = Column.from_vector 'x' [My_Data 1 6, My_Data 6 3, My_Data 2 5, My_Data 3 4, My_Data 200 300] c_any = Column.from_vector 'x' [My.Data 1 6, My.Data 6 3, My.Data 2 5, My.Data 3 4, My.Data 200 300]
c_any.map (_.frobnicate) . to_vector . should_equal [My_Data 6 1, My_Data 3 6, My_Data 5 2, My_Data 4 3, My_Data 300 200] c_any.map (_.frobnicate) . to_vector . should_equal [My.Data 6 1, My.Data 3 6, My.Data 5 2, My.Data 4 3, My.Data 300 200]
Test.specify "should correctly handle storage of results" <| Test.specify "should correctly handle storage of results" <|
c_int = Column.from_vector 'year' [2022, 2000, 1999] c_int = Column.from_vector 'year' [2022, 2000, 1999]
@ -214,8 +208,8 @@ spec =
(c_dec == 1.9).to_vector.should_equal [True, False, False, False, True] (c_dec == 1.9).to_vector.should_equal [True, False, False, False, True]
c_bool = Column.from_vector 'x' [True, False, Nothing, True, False] c_bool = Column.from_vector 'x' [True, False, Nothing, True, False]
(c_bool == False).to_vector.should_equal [False, True, Nothing, False, True] (c_bool == False).to_vector.should_equal [False, True, Nothing, False, True]
c_any = Column.from_vector 'x' [My_Data 1 6, My_Data 6 3, My_Data 2 5, My_Data 3 4, My_Data 200 300] c_any = Column.from_vector 'x' [My.Data 1 6, My.Data 6 3, My.Data 2 5, My.Data 3 4, My.Data 200 300]
(c_any == My_Data 7 0).to_vector.should_equal [True, False, True, True, False] (c_any == My.Data 7 0).to_vector.should_equal [True, False, True, True, False]
Test.specify "should switch between maps and zips based on argument type" <| Test.specify "should switch between maps and zips based on argument type" <|
a = Column.from_vector 'x' [0, 1, 7, 3, 6] a = Column.from_vector 'x' [0, 1, 7, 3, 6]
@ -447,7 +441,7 @@ spec =
Test.specify 'should respect defined comparison operations for custom types' <| Test.specify 'should respect defined comparison operations for custom types' <|
c_1 = ['id', [1, 2, 3, 4, 5, 6]] c_1 = ['id', [1, 2, 3, 4, 5, 6]]
c_2 = ['val', [My_Data 1 2, My_Data 3 4, My_Data 2 1, My_Data 5 2, My_Data 7 0, My_Data 4 -1]] c_2 = ['val', [My.Data 1 2, My.Data 3 4, My.Data 2 1, My.Data 5 2, My.Data 7 0, My.Data 4 -1]]
df = Table.new [c_1, c_2] df = Table.new [c_1, c_2]
r = df.order_by (Sort_Column_Selector.By_Name ['val']) r = df.order_by (Sort_Column_Selector.By_Name ['val'])
r.at 'id' . to_vector . should_equal [1,3,6,2,4,5] r.at 'id' . to_vector . should_equal [1,3,6,2,4,5]
@ -468,7 +462,7 @@ spec =
dates = [Date.new 2020, Date.new 1999, Date.new 2000 10 3, Date.new 1999 12 31, Date.new 2000 2 7] dates = [Date.new 2020, Date.new 1999, Date.new 2000 10 3, Date.new 1999 12 31, Date.new 2000 2 7]
times = [Time_Of_Day.new 12, Time_Of_Day.new 1 30 40, Time_Of_Day.new 23 59 59, Time_Of_Day.new 12 30 0, Time_Of_Day.new 10 20 30] times = [Time_Of_Day.new 12, Time_Of_Day.new 1 30 40, Time_Of_Day.new 23 59 59, Time_Of_Day.new 12 30 0, Time_Of_Day.new 10 20 30]
datetimes = [Date_Time.new 2020 1 1 12, Date_Time.new 1999 1 1 1 30 40, Date_Time.new 2000 10 3 23 59 59, Date_Time.new 1999 12 31 12 30 0, Date_Time.new 2000 10 3 10 20 30] datetimes = [Date_Time.new 2020 1 1 12, Date_Time.new 1999 1 1 1 30 40, Date_Time.new 2000 10 3 23 59 59, Date_Time.new 1999 12 31 12 30 0, Date_Time.new 2000 10 3 10 20 30]
objs = [My_Data 100 2, My_Data 2 3, My_Data 6 7, My_Data 8 9, My_Data 10 30] objs = [My.Data 100 2, My.Data 2 3, My.Data 6 7, My.Data 8 9, My.Data 10 30]
mixed_dates = [Date.new 1999 1 2, Date_Time.new 1999 1 2 3 40, Date.new 1999 1 2, Date_Time.new 1999 1 2 3 40, Date.new 2000] mixed_dates = [Date.new 1999 1 2, Date_Time.new 1999 1 2 3 40, Date.new 1999 1 2, Date_Time.new 1999 1 2 3 40, Date.new 2000]
df = Table.new [['ord', ord], ['ints', ints], ['reals', reals], ['bools', bools], ['texts', texts], ['objs', objs], ['dates', dates], ['times', times], ['datetimes', datetimes], ['mixed_dates', mixed_dates]] df = Table.new [['ord', ord], ['ints', ints], ['reals', reals], ['bools', bools], ['texts', texts], ['objs', objs], ['dates', dates], ['times', times], ['datetimes', datetimes], ['mixed_dates', mixed_dates]]
@ -486,7 +480,7 @@ spec =
r.at 'texts' . to_vector . should_equal ['foo', 'spam', 'bar', 'foo', 'baz'] r.at 'texts' . to_vector . should_equal ['foo', 'spam', 'bar', 'foo', 'baz']
df.at 'texts' . to_vector . should_equal texts df.at 'texts' . to_vector . should_equal texts
r.at 'objs' . to_vector . should_equal [My_Data 100 2, My_Data 10 30, My_Data 6 7, My_Data 2 3, My_Data 8 9] r.at 'objs' . to_vector . should_equal [My.Data 100 2, My.Data 10 30, My.Data 6 7, My.Data 2 3, My.Data 8 9]
df.at 'objs' . to_vector . should_equal objs df.at 'objs' . to_vector . should_equal objs
r.at 'dates' . to_vector . should_equal [Date.new 2020, Date.new 2000 2 7, Date.new 2000 10 3, Date.new 1999, Date.new 1999 12 31] r.at 'dates' . to_vector . should_equal [Date.new 2020, Date.new 2000 2 7, Date.new 2000 10 3, Date.new 1999, Date.new 1999 12 31]
@ -512,7 +506,7 @@ spec =
r4.at 'ints' . to_vector . should_equal [2, 4, 5, 3, 1] r4.at 'ints' . to_vector . should_equal [2, 4, 5, 3, 1]
r5 = df.order_by (Sort_Column_Selector.By_Name ['objs']) r5 = df.order_by (Sort_Column_Selector.By_Name ['objs'])
r5.at 'objs' . to_vector . should_equal [My_Data 2 3, My_Data 6 7, My_Data 8 9, My_Data 10 30, My_Data 100 2] r5.at 'objs' . to_vector . should_equal [My.Data 2 3, My.Data 6 7, My.Data 8 9, My.Data 10 30, My.Data 100 2]
r5.at 'ints' . to_vector . should_equal [2, 3, 4, 5, 1] r5.at 'ints' . to_vector . should_equal [2, 3, 4, 5, 1]
r6 = df.order_by (Sort_Column_Selector.By_Name ['mixed_dates']) r6 = df.order_by (Sort_Column_Selector.By_Name ['mixed_dates'])
@ -532,15 +526,15 @@ spec =
r_3.to_vector.should_equal [Nothing,Nothing,8,7,4,1] r_3.to_vector.should_equal [Nothing,Nothing,8,7,4,1]
Test.specify 'should respect defined comparison operations for custom types' <| Test.specify 'should respect defined comparison operations for custom types' <|
c = Column.from_vector 'foo' [My_Data 1 2, My_Data 3 4, My_Data 2 1, My_Data 5 2, My_Data 7 0, My_Data 4 -1] c = Column.from_vector 'foo' [My.Data 1 2, My.Data 3 4, My.Data 2 1, My.Data 5 2, My.Data 7 0, My.Data 4 -1]
r = c.sort r = c.sort
r.to_vector.should_equal [My_Data 1 2, My_Data 2 1, My_Data 4 -1, My_Data 3 4, My_Data 5 2, My_Data 7 0] r.to_vector.should_equal [My.Data 1 2, My.Data 2 1, My.Data 4 -1, My.Data 3 4, My.Data 5 2, My.Data 7 0]
Test.specify 'should allow passing a custom comparator' <| Test.specify 'should allow passing a custom comparator' <|
c = Column.from_vector 'foo' [My_Data 1 2, My_Data 2 5, My_Data 3 4, My_Data 6 3, Nothing, My_Data 1 0] c = Column.from_vector 'foo' [My.Data 1 2, My.Data 2 5, My.Data 3 4, My.Data 6 3, Nothing, My.Data 1 0]
cmp a b = (a.x-a.y).abs . compare_to (b.x-b.y).abs cmp a b = (a.x-a.y).abs . compare_to (b.x-b.y).abs
r = c.sort comparator=cmp r = c.sort comparator=cmp
r.to_vector.should_equal [My_Data 1 2, My_Data 3 4, My_Data 1 0, My_Data 2 5, My_Data 6 3, Nothing] r.to_vector.should_equal [My.Data 1 2, My.Data 3 4, My.Data 1 0, My.Data 2 5, My.Data 6 3, Nothing]
Test.specify 'should handle Unicode characters correctly' <| Test.specify 'should handle Unicode characters correctly' <|
c = Column.from_vector 'c' ['z', 'a', 'd', 'f', 's', 'e\u0301', 'ś', 'ą', 's\u0301', 'w', 'b'] c = Column.from_vector 'c' ['z', 'a', 'd', 'f', 's', 'e\u0301', 'ś', 'ą', 's\u0301', 'w', 'b']
@ -677,7 +671,7 @@ spec =
t_3 = Table.new [c_3_1, c_3_2, c_3_3] t_3 = Table.new [c_3_1, c_3_2, c_3_3]
t_3.default_visualization.should_equal Visualization.Id.table t_3.default_visualization.should_equal Visualization.Id.table
selection = Common_Table_Spec.Test_Selection_Data supports_case_sensitive_columns=True order_by=True natural_ordering=True case_insensitive_ordering=True order_by_unicode_normalization_by_default=True selection = Common_Table_Spec.Test_Selection.Config supports_case_sensitive_columns=True order_by=True natural_ordering=True case_insensitive_ordering=True order_by_unicode_normalization_by_default=True
Common_Table_Spec.spec "[In-Memory] " table_builder=Table.new test_selection=selection Common_Table_Spec.spec "[In-Memory] " table_builder=Table.new test_selection=selection
Test.group "Use First Row As Names" <| Test.group "Use First Row As Names" <|
@ -729,7 +723,7 @@ spec =
mixed = ["mixed", [1, "a", "a", 1]] mixed = ["mixed", [1, "a", "a", 1]]
ints = ["ints", [0, 1, 1, 0]] ints = ["ints", [0, 1, 1, 0]]
floats = ["floats", [0.1, 1.0, 2.0, 1.5]] floats = ["floats", [0.1, 1.0, 2.0, 1.5]]
objects = ["objects", [My_Data 0 1, My_Data 0 1, My_Data 2 2, My_Data 2 2]] objects = ["objects", [My.Data 0 1, My.Data 0 1, My.Data 2 2, My.Data 2 2]]
table = Table.new [dates, texts, mixed, ints, floats, objects] table = Table.new [dates, texts, mixed, ints, floats, objects]
t1 = table.aggregate [Group_By "dates", Shortest "texts", Aggregate_Column.First "texts", Aggregate_Column.First "objects", Aggregate_Column.First "ints", Aggregate_Column.Last "mixed"] t1 = table.aggregate [Group_By "dates", Shortest "texts", Aggregate_Column.First "texts", Aggregate_Column.First "objects", Aggregate_Column.First "ints", Aggregate_Column.Last "mixed"]
@ -770,12 +764,12 @@ spec =
c = ["C", [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]] c = ["C", [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]]
t = Table.new [a, b, c] t = Table.new [a, b, c]
r1 = t.distinct (By_Name ["A"]) on_problems=Report_Error r1 = t.distinct (Column_Selector.By_Name ["A"]) on_problems=Report_Error
r1.at "A" . to_vector . should_equal ["a"] r1.at "A" . to_vector . should_equal ["a"]
r1.at "B" . to_vector . should_equal [1] r1.at "B" . to_vector . should_equal [1]
r1.at "C" . to_vector . should_equal [0.1] r1.at "C" . to_vector . should_equal [0.1]
r2 = t.distinct (By_Name ["A", "B"]) on_problems=Report_Error r2 = t.distinct (Column_Selector.By_Name ["A", "B"]) on_problems=Report_Error
r2.at "A" . to_vector . should_equal ["a", "a"] r2.at "A" . to_vector . should_equal ["a", "a"]
r2.at "B" . to_vector . should_equal [1, 2] r2.at "B" . to_vector . should_equal [1, 2]
r2.at "C" . to_vector . should_equal [0.1, 0.3] r2.at "C" . to_vector . should_equal [0.1, 0.3]
@ -794,7 +788,7 @@ spec =
a = ["A", ["a", Nothing, "b", "a", "b", Nothing, "a", "b"]] a = ["A", ["a", Nothing, "b", "a", "b", Nothing, "a", "b"]]
b = ["B", [1, 2, 3, 4, 5, 6, 7, 8]] b = ["B", [1, 2, 3, 4, 5, 6, 7, 8]]
t = Table.new [a, b] t = Table.new [a, b]
r = t.distinct (By_Name ["A"]) on_problems=Report_Error r = t.distinct (Column_Selector.By_Name ["A"]) on_problems=Report_Error
r.at "A" . to_vector . should_equal ["a", Nothing, "b"] r.at "A" . to_vector . should_equal ["a", Nothing, "b"]
r.at "B" . to_vector . should_equal [1, 2, 3] r.at "B" . to_vector . should_equal [1, 2, 3]
@ -806,11 +800,11 @@ spec =
x = ["X", ['A', 'a', 'enso', 'śledź', 'Enso', 'A', 's\u0301ledz\u0301']] x = ["X", ['A', 'a', 'enso', 'śledź', 'Enso', 'A', 's\u0301ledz\u0301']]
y = ["Y", [1, 2, 3, 4, 5, 6, 7]] y = ["Y", [1, 2, 3, 4, 5, 6, 7]]
t1 = Table.new [x, y] t1 = Table.new [x, y]
d1 = t1.distinct (By_Name ["X"]) on_problems=Report_Error d1 = t1.distinct (Column_Selector.By_Name ["X"]) on_problems=Report_Error
d1.at "X" . to_vector . should_equal ['A', 'a', 'enso', 'śledź', 'Enso'] d1.at "X" . to_vector . should_equal ['A', 'a', 'enso', 'śledź', 'Enso']
d1.at "Y" . to_vector . should_equal [1, 2, 3, 4, 5] d1.at "Y" . to_vector . should_equal [1, 2, 3, 4, 5]
d2 = t1.distinct (By_Name ["X"]) case_sensitivity=Case_Sensitivity.Insensitive on_problems=Report_Error d2 = t1.distinct (Column_Selector.By_Name ["X"]) case_sensitivity=Case_Sensitivity.Insensitive on_problems=Report_Error
d2.at "X" . to_vector . should_equal ['A', 'enso', 'śledź'] d2.at "X" . to_vector . should_equal ['A', 'enso', 'śledź']
d2.at "Y" . to_vector . should_equal [1, 3, 4] d2.at "Y" . to_vector . should_equal [1, 3, 4]
@ -836,16 +830,16 @@ spec =
t = Table.new [["A", [1, 2, 1, 1]]] t = Table.new [["A", [1, 2, 1, 1]]]
test table = table.should_equal t test table = table.should_equal t
action1 = t.distinct (By_Name []) on_problems=_ action1 = t.distinct (Column_Selector.By_Name []) on_problems=_
problems1 = [No_Input_Columns_Selected] problems1 = [No_Input_Columns_Selected]
Problems.test_problem_handling action1 problems1 test Problems.test_problem_handling action1 problems1 test
action2 = t.distinct (By_Name ["mismatched"]) on_problems=_ action2 = t.distinct (Column_Selector.By_Name ["mismatched"]) on_problems=_
problems2 = [Missing_Input_Columns_Data ["mismatched"], No_Input_Columns_Selected] problems2 = [Missing_Input_Columns_Data ["mismatched"], No_Input_Columns_Selected]
Problems.test_problem_handling action2 problems2 test Problems.test_problem_handling action2 problems2 test
Test.specify "until hashing is supported, should throw an error when trying to aggregate a custom object" <| Test.specify "until hashing is supported, should throw an error when trying to aggregate a custom object" <|
t = Table.new [["X", [My_Data 1 2, My_Data 3 4, My_Data 1 2]]] t = Table.new [["X", [My.Data 1 2, My.Data 3 4, My.Data 1 2]]]
t.distinct . should_fail_with Illegal_Argument_Error_Data t.distinct . should_fail_with Illegal_Argument_Error_Data
Test.specify "should group by all columns by default" <| Test.specify "should group by all columns by default" <|
@ -871,20 +865,20 @@ spec =
t3.at "X" . to_vector . should_equal [5, 5, 1] t3.at "X" . to_vector . should_equal [5, 5, 1]
Test.specify "by custom object comparisons" <| Test.specify "by custom object comparisons" <|
t = Table.new [["ix", [1, 2, 3, 4, 5]], ["X", [My_Data 1 2, My_Data 300 400, My_Data 100 200, My_Data 5 6, My_Data 7 8]]] t = Table.new [["ix", [1, 2, 3, 4, 5]], ["X", [My.Data 1 2, My.Data 300 400, My.Data 100 200, My.Data 5 6, My.Data 7 8]]]
t1 = t.filter "X" (Filter_Condition.Between (My_Data 10 20) (My_Data 300 400)) t1 = t.filter "X" (Filter_Condition.Between (My.Data 10 20) (My.Data 300 400))
t1.at "ix" . to_vector . should_equal [2, 3] t1.at "ix" . to_vector . should_equal [2, 3]
t1.at "X" . to_vector . should_equal [My_Data 300 400, My_Data 100 200] t1.at "X" . to_vector . should_equal [My.Data 300 400, My.Data 100 200]
t.filter "X" (Filter_Condition.Less than=(My_Data 5 6)) . at "X" . to_vector . should_equal [My_Data 1 2] t.filter "X" (Filter_Condition.Less than=(My.Data 5 6)) . at "X" . to_vector . should_equal [My.Data 1 2]
t.filter "X" (Filter_Condition.Equal_Or_Less than=(My_Data 5 6)) . at "X" . to_vector . should_equal [My_Data 1 2, My_Data 5 6] t.filter "X" (Filter_Condition.Equal_Or_Less than=(My.Data 5 6)) . at "X" . to_vector . should_equal [My.Data 1 2, My.Data 5 6]
t.filter "X" (Filter_Condition.Greater than=(My_Data 5 6)) . at "X" . to_vector . should_equal [My_Data 300 400, My_Data 100 200, My_Data 7 8] t.filter "X" (Filter_Condition.Greater than=(My.Data 5 6)) . at "X" . to_vector . should_equal [My.Data 300 400, My.Data 100 200, My.Data 7 8]
t.filter "X" (Filter_Condition.Equal_Or_Greater than=(My_Data 5 6)) . at "X" . to_vector . should_equal [My_Data 300 400, My_Data 100 200, My_Data 5 6, My_Data 7 8] t.filter "X" (Filter_Condition.Equal_Or_Greater than=(My.Data 5 6)) . at "X" . to_vector . should_equal [My.Data 300 400, My.Data 100 200, My.Data 5 6, My.Data 7 8]
t.filter "X" (Filter_Condition.Equal to=(My_Data 2 1)) . at "X" . to_vector . should_equal [My_Data 1 2] t.filter "X" (Filter_Condition.Equal to=(My.Data 2 1)) . at "X" . to_vector . should_equal [My.Data 1 2]
t.filter "X" (Filter_Condition.Equal to=42) . at "X" . to_vector . should_equal [] t.filter "X" (Filter_Condition.Equal to=42) . at "X" . to_vector . should_equal []
c = Column.from_vector "Y" [My_Data 2 1, My_Data 400 300, My_Data 101 202, My_Data 10 10, My_Data 15 0] c = Column.from_vector "Y" [My.Data 2 1, My.Data 400 300, My.Data 101 202, My.Data 10 10, My.Data 15 0]
t.filter "X" (Filter_Condition.Equal to=c) . at "X" . to_vector . should_equal [My_Data 1 2, My_Data 300 400, My_Data 7 8] t.filter "X" (Filter_Condition.Equal to=c) . at "X" . to_vector . should_equal [My.Data 1 2, My.Data 300 400, My.Data 7 8]
t.filter "X" (Filter_Condition.Less than=c) . at "X" . to_vector . should_equal [My_Data 100 200, My_Data 5 6] t.filter "X" (Filter_Condition.Less than=c) . at "X" . to_vector . should_equal [My.Data 100 200, My.Data 5 6]
t.filter "X" (Filter_Condition.Greater than=c) . at "X" . to_vector . should_equal [] t.filter "X" (Filter_Condition.Greater than=c) . at "X" . to_vector . should_equal []
Test.specify "by a boolean mask of varying length" <| Test.specify "by a boolean mask of varying length" <|

View File

@ -1,7 +1,6 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table, Delimited, Column, Data_Formatter
from Standard.Table import Delimited, Column, Data_Formatter
import Standard.Table.Data.Storage import Standard.Table.Data.Storage
import Standard.Test import Standard.Test

View File

@ -1,7 +1,6 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table, Delimited, Column, Data_Formatter
from Standard.Table import Delimited, Column, Data_Formatter
import Standard.Table.Data.Storage import Standard.Table.Data.Storage
import Standard.Test import Standard.Test

View File

@ -1,6 +1,6 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table.Internal.Unique_Name_Strategy import Standard.Table.Internal.Unique_Name_Strategy.Unique_Name_Strategy
import Standard.Test import Standard.Test

View File

@ -1,18 +1,17 @@
from Standard.Base import all from Standard.Base import all
import Standard.Base.System import Standard.Base.System
import Standard.Table from Standard.Table import Table, Column
from Standard.Table import Column
import Standard.Test import Standard.Test
Table.Table.should_equal self expected = Table.should_equal self expected =
self_cols = self.columns self_cols = self.columns
that_cols = expected.columns that_cols = expected.columns
self_cols.map .name . should_equal (that_cols.map .name) frames_to_skip=1 self_cols.map .name . should_equal (that_cols.map .name) frames_to_skip=1
self_cols.map .to_vector . should_equal (that_cols.map .to_vector) frames_to_skip=1 self_cols.map .to_vector . should_equal (that_cols.map .to_vector) frames_to_skip=1
Column.Column.should_equal self expected = Column.should_equal self expected =
if self.name != expected.name then if self.name != expected.name then
Test.fail "Expected column name "+expected.name+", but got "+self.name+"." Test.fail "Expected column name "+expected.name+", but got "+self.name+"."
if self.length != expected.length then if self.length != expected.length then

View File

@ -1,7 +1,6 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table
import Standard.Visualization.Geo_Map import Standard.Visualization.Geo_Map
import Standard.Test import Standard.Test

View File

@ -4,7 +4,7 @@ from Standard.Table import Column
import Standard.Test import Standard.Test
Column.Column.expect : Text -> Vector -> Test.Success Column.expect : Text -> Vector -> Test.Success
Column.Column.expect self name contents = Column.expect self name contents =
self.name.should_equal name self.name.should_equal name
self.to_vector.should_equal contents self.to_vector.should_equal contents

View File

@ -1,6 +1,6 @@
from Standard.Base import all from Standard.Base import all
import Standard.Table from Standard.Table import Table
import Standard.Visualization.Helpers import Standard.Visualization.Helpers

View File

@ -1,7 +1,6 @@
from Standard.Base import all from Standard.Base import all
from Standard.Table import Table, Column from Standard.Table import Table, Column
import Standard.Table
import Standard.Visualization.Histogram import Standard.Visualization.Histogram

View File

@ -1,7 +1,6 @@
from Standard.Base import all from Standard.Base import all
from Standard.Table import Table, Column from Standard.Table import Table, Column
import Standard.Table
import Standard.Visualization.Scatter_Plot import Standard.Visualization.Scatter_Plot

View File

@ -1,11 +1,10 @@
from Standard.Base import all from Standard.Base import all
from Standard.Table import Table, Aggregate_Column from Standard.Table import Table, Aggregate_Column
import Standard.Table
from Standard.Database import SQLite from Standard.Database import SQLite
import Standard.Database import Standard.Database
import Standard.Database.Data.Table as Database_Table import Standard.Database.Data.Table.Table as Database_Table
import Standard.Visualization.Table.Visualization as Visualization import Standard.Visualization.Table.Visualization as Visualization