diff --git a/distribution/lib/Standard/AWS/0.0.0-dev/src/Database/Redshift/Redshift_Details.enso b/distribution/lib/Standard/AWS/0.0.0-dev/src/Database/Redshift/Redshift_Details.enso index dd95e19db147..779555cb5763 100644 --- a/distribution/lib/Standard/AWS/0.0.0-dev/src/Database/Redshift/Redshift_Details.enso +++ b/distribution/lib/Standard/AWS/0.0.0-dev/src/Database/Redshift/Redshift_Details.enso @@ -68,9 +68,7 @@ type Redshift_Details # TODO [RW] can we inherit these from postgres? encoding = parse_postgres_encoding (get_encoding_name jdbc_connection) - entity_naming_properties = Entity_Naming_Properties.from_jdbc_connection jdbc_connection encoding is_case_sensitive=True - - Connection.new jdbc_connection Redshift_Dialect.redshift Postgres_Type_Mapping entity_naming_properties + Connection.new jdbc_connection Redshift_Dialect.redshift Postgres_Type_Mapping (Entity_Naming_Properties.from_jdbc_connection jdbc_connection encoding is_case_sensitive=True) ## --- private: true diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Connection.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Connection.enso index f2a7174bc11e..789ac339d987 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Connection.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Connection.enso @@ -10,6 +10,7 @@ from Standard.Base.Metadata.Choice import Option from Standard.Base.Metadata.Widget import File_Browse, Single_Choice, Text_Input, Vector_Editor import Standard.Table.Internal.Column_Naming_Helper.Column_Naming_Helper +import Standard.Table.Internal.Unique_Name_Strategy.Unique_Name_Strategy import Standard.Table.Rows_To_Read.Rows_To_Read from Standard.Table import Table @@ -27,7 +28,6 @@ import project.Internal.JDBC_Connection.JDBC_Connection import project.Internal.SQL_Type_Reference.SQL_Type_Reference import project.Internal.SQL_Warning_Helper import project.Internal.Statement_Setter.Statement_Setter -import project.Internal.Table_Naming_Helper.Table_Naming_Helper import project.SQL.SQL_Statement import project.SQL.SQL_Type import project.SQL_Query.SQL_Query @@ -66,7 +66,15 @@ type Connection to the user, but are used internally by the dry-run system. - `data_link_setup`: an optional setup allowing for saving the connection as a data link. - Value jdbc_connection dialect type_mapping (statement_setter:Statement_Setter) (entity_naming_properties : Entity_Naming_Properties) (supports_large_update : Ref Boolean) (hidden_table_registry : Hidden_Table_Registry.Hidden_Table_Registry) (data_link_setup : Data_Link_Setup | Nothing = Nothing) + Value + jdbc_connection + dialect + type_mapping + (statement_setter:Statement_Setter) + (~entity_naming_properties) + (supports_large_update : Ref Boolean) + (hidden_table_registry : Hidden_Table_Registry.Hidden_Table_Registry) + (data_link_setup : Data_Link_Setup | Nothing = Nothing) ## --- private: true @@ -88,7 +96,7 @@ type Connection `executeLargeUpdate`. - `statement_setter`: a helper for setting parameters on prepared statements. - new jdbc_connection:JDBC_Connection dialect type_mapping entity_naming_properties:Entity_Naming_Properties (data_link_setup : Data_Link_Setup | Nothing = Nothing) (try_large_update : Boolean = True) (statement_setter : Statement_Setter = Statement_Setter.default) -> Connection = + new jdbc_connection:JDBC_Connection dialect type_mapping ~entity_naming_properties (data_link_setup : Data_Link_Setup | Nothing = Nothing) (try_large_update : Boolean = True) (statement_setter : Statement_Setter = Statement_Setter.default) -> Connection = registry = Hidden_Table_Registry.new Connection.Value jdbc_connection dialect type_mapping statement_setter entity_naming_properties (Ref.new try_large_update) registry data_link_setup @@ -510,23 +518,6 @@ type Connection Hidden_Table_Registry.run_maintenance_table_cleanup self self.jdbc_connection.run_maintenance_action_if_possible callback - ## --- - private: true - --- - Returns a helper for checking and generating table names. - table_naming_helper : Table_Naming_Helper - table_naming_helper self = Table_Naming_Helper.Value self - - ## --- - private: true - --- - Returns a helper for checking and generating column names. - column_naming_helper : Column_Naming_Helper - column_naming_helper self = - column_naming_properties = self.entity_naming_properties.for_column_names - generated_column_naming_properties = self.entity_naming_properties.for_generated_column_names - Column_Naming_Helper.Value column_naming_properties generated_column_naming_properties - ## --- private: true --- @@ -675,3 +666,19 @@ get_tables_advanced jdbc_connection name_like:Text|Nothing database:Text|Nothing renamed = table.rename_columns name_dict error_on_missing_columns=False on_problems=..Ignore if all_fields then renamed else renamed.select_columns ["Database", "Schema", "Name", "Type", "Description"] + +## --- + private: true + --- + Converts a Connection to a Column_Naming_Helper +Column_Naming_Helper.from (that:Connection) = + column_naming_properties = that.entity_naming_properties.for_column_names + generated_column_naming_properties = that.entity_naming_properties.for_generated_column_names + Column_Naming_Helper.Value column_naming_properties generated_column_naming_properties + +## --- + private: true + --- + Converts a Connection to a column Unique_Name_Strategy +Unique_Name_Strategy.from (that:Connection) = + Unique_Name_Strategy.new that.entity_naming_properties.for_column_names diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Postgres_Connection.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Postgres_Connection.enso index e40a4db5e5f8..e3f20d5ea904 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Postgres_Connection.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/Postgres_Connection.enso @@ -45,9 +45,7 @@ type Postgres_Connection quoted we have full case sensitivity and can distinguish columns `A` from `a` as different. Our generator is supposed to always quote identifiers - entity_naming_properties = Entity_Naming_Properties.from_jdbc_connection jdbc_connection encoding is_case_sensitive=True - - Postgres_Connection.Value (Connection.new jdbc_connection Dialect.postgres Postgres_Type_Mapping entity_naming_properties data_link_setup) make_new + Postgres_Connection.Value (Connection.new jdbc_connection Dialect.postgres Postgres_Type_Mapping (Entity_Naming_Properties.from_jdbc_connection jdbc_connection encoding is_case_sensitive=True) data_link_setup) make_new ## --- private: true @@ -66,7 +64,7 @@ type Postgres_Connection immediately instead of waiting for them to be automatically released. The connection is not usable afterwards. close : Nothing - close self = self.connection.close + close self = self.base_connection.close ## --- icon: metadata @@ -74,14 +72,14 @@ type Postgres_Connection Returns the list of databases (or catalogs) for the connection. databases : Vector Text databases self = - self.connection.read_text_column "select datname from pg_database where datname not in ('template0', 'template1')" "datname" + self.base_connection.read_text_column "select datname from pg_database where datname not in ('template0', 'template1')" "datname" ## --- icon: metadata --- Returns the name of the current database (or catalog). database : Text - database self = self.connection.database + database self = self.base_connection.database ## --- icon: data_input @@ -102,14 +100,14 @@ type Postgres_Connection Returns the list of schemas for the connection within the current database (or catalog). schemas : Vector Text - schemas self = self.connection.schemas + schemas self = self.base_connection.schemas ## --- icon: metadata --- Returns the name of the current schema. schema : Text - schema self = self.connection.schema + schema self = self.base_connection.schema ## --- icon: data_input @@ -130,7 +128,7 @@ type Postgres_Connection --- Gets a list of the table types. table_types : Vector Text - table_types self = self.connection.table_types + table_types self = self.base_connection.table_types ## --- group: Standard.Base.Metadata @@ -160,7 +158,7 @@ type Postgres_Connection @schema (make_schema_selector include_any=True) tables : Text -> Text -> Text -> Vector -> Boolean -> Table tables self name_like=Nothing database=self.database schema=Nothing types=self.dialect.default_table_types all_fields=False = - self.connection.tables name_like database schema types all_fields + self.base_connection.tables name_like database schema types all_fields ## --- aliases: [import, load, open, read, sql] @@ -210,7 +208,7 @@ type Postgres_Connection @limit Rows_To_Read.default_widget read : SQL_Query -> Rows_To_Read -> Table ! Table_Not_Found read self query:SQL_Query (limit : Rows_To_Read = ..First_With_Warning 1000) = - self.connection.read query limit + self.base_connection.read query limit ## --- group: Standard.Base.Output @@ -297,7 +295,7 @@ type Postgres_Connection @limit Rows_To_Read.default_widget execute_query : Text | SQL_Statement -> Rows_To_Read -> Boolean -> Table execute_query self query (limit : Rows_To_Read = ..First_With_Warning 1000) write_operation:Boolean=True = - self.connection.execute_query query limit write_operation + self.base_connection.execute_query query limit write_operation ## --- advanced: true @@ -314,7 +312,7 @@ type Postgres_Connection representing the query to execute. execute_update : Text | SQL_Statement -> Integer execute_update self query = - self.connection.execute_update query + self.base_connection.execute_update query ## --- private: true @@ -331,31 +329,31 @@ type Postgres_Connection representing the query to execute. execute : Text | SQL_Statement -> Integer execute self query = - self.connection.execute query + self.base_connection.execute query ## --- private: true --- Access the dialect. - dialect self = self.connection.dialect + dialect self = self.base_connection.dialect ## --- private: true --- Access the Type Mapping. - type_mapping self = self.connection.type_mapping + type_mapping self = self.base_connection.type_mapping ## --- private: true --- Access the Statement Setter. - statement_setter self = self.connection.statement_setter + statement_setter self = self.base_connection.statement_setter ## --- private: true --- Access the underlying JDBC connection. - jdbc_connection self = self.connection.jdbc_connection + jdbc_connection self = self.base_connection.jdbc_connection ## --- private: true @@ -368,7 +366,7 @@ type Postgres_Connection does not exist. Defaults to `False`. drop_table : Text -> Boolean -> Nothing drop_table self table_name if_exists=False = - self.connection.drop_table table_name if_exists + self.base_connection.drop_table table_name if_exists ## --- private: true @@ -379,7 +377,7 @@ type Postgres_Connection - `table_name`: the name of the table to truncate. truncate_table : Text -> Nothing ! Table_Not_Found truncate_table self table_name = - self.connection.truncate_table table_name + self.base_connection.truncate_table table_name ## --- private: true @@ -419,10 +417,10 @@ type Postgres_Connection Converts this value to a JSON serializable object. to_js_object : JS_Object to_js_object self = - JS_Object.from_pairs <| [["type", "Postgres_Connection"], ["links", self.connection.tables.at "Name" . to_vector]] + JS_Object.from_pairs <| [["type", "Postgres_Connection"], ["links", self.tables.at "Name" . to_vector]] ## --- private: true --- Table_Viz_Data.from (that:Postgres_Connection) = - Connections_Helpers.get_table_viz_data (that.connection.tables.at "Name" . to_vector) + Connections_Helpers.get_table_viz_data (that.tables.at "Name" . to_vector) diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/SQLite_Connection.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/SQLite_Connection.enso index cc5ae4686191..989f13283e18 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/SQLite_Connection.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Connection/SQLite_Connection.enso @@ -54,7 +54,7 @@ type SQLite_Connection immediately instead of waiting for them to be automatically released. The connection is not usable afterwards. close : Nothing - close self = self.connection.close + close self = self.base_connection.close ## --- icon: metadata @@ -68,7 +68,7 @@ type SQLite_Connection --- Returns the name of the current database (or catalog). database : Text - database self = self.connection.database + database self = self.base_connection.database ## --- icon: data_input @@ -96,7 +96,7 @@ type SQLite_Connection --- Returns the name of the current schema. schema : Text - schema self = self.connection.schema + schema self = self.base_connection.schema ## --- icon: data_input @@ -117,7 +117,7 @@ type SQLite_Connection --- Gets a list of the table types table_types : Vector Text - table_types self = self.connection.table_types + table_types self = self.base_connection.table_types ## --- group: Standard.Base.Metadata @@ -147,7 +147,7 @@ type SQLite_Connection @schema (make_schema_selector include_any=True) tables : Text -> Text -> Text -> Vector -> Boolean -> Table tables self name_like=Nothing database=self.database schema=Nothing types=self.dialect.default_table_types all_fields=False = - self.connection.tables name_like database schema types all_fields + self.base_connection.tables name_like database schema types all_fields ## --- aliases: [import, load, open, read, sql] @@ -197,7 +197,7 @@ type SQLite_Connection @limit Rows_To_Read.default_widget read : SQL_Query -> Rows_To_Read -> Table ! Table_Not_Found read self query:SQL_Query (limit : Rows_To_Read = ..First_With_Warning 1000) = - self.connection.read query limit + self.base_connection.read query limit ## --- group: Standard.Base.Output @@ -284,7 +284,7 @@ type SQLite_Connection @limit Rows_To_Read.default_widget execute_query : Text | SQL_Statement -> Rows_To_Read -> Boolean -> Table execute_query self query (limit : Rows_To_Read = ..First_With_Warning 1000) write_operation:Boolean=True = - self.connection.execute_query query limit write_operation + self.base_connection.execute_query query limit write_operation ## --- advanced: true @@ -301,7 +301,7 @@ type SQLite_Connection representing the query to execute. execute_update : Text | SQL_Statement -> Integer execute_update self query = - self.connection.execute_update query + self.base_connection.execute_update query ## --- private: true @@ -318,31 +318,31 @@ type SQLite_Connection representing the query to execute. execute : Text | SQL_Statement -> Integer execute self query = - self.connection.execute query + self.base_connection.execute query ## --- private: true --- Access the dialect. - dialect self = self.connection.dialect + dialect self = self.base_connection.dialect ## --- private: true --- Access the Type Mapping. - type_mapping self = self.connection.type_mapping + type_mapping self = self.base_connection.type_mapping ## --- private: true --- Access the Statement Setter. - statement_setter self = self.connection.statement_setter + statement_setter self = self.base_connection.statement_setter ## --- private: true --- Access the underlying JDBC connection. - jdbc_connection self = self.connection.jdbc_connection + jdbc_connection self = self.base_connection.jdbc_connection ## --- private: true @@ -355,7 +355,7 @@ type SQLite_Connection does not exist. Defaults to `False`. drop_table : Text -> Boolean -> Nothing drop_table self table_name if_exists=False = - self.connection.drop_table table_name if_exists + self.base_connection.drop_table table_name if_exists ## --- private: true @@ -366,7 +366,7 @@ type SQLite_Connection - `table_name`: the name of the table to truncate. truncate_table : Text -> Nothing ! Table_Not_Found truncate_table self table_name = - self.connection.truncate_table table_name + self.base_connection.truncate_table table_name ## --- private: true @@ -392,7 +392,7 @@ type SQLite_Connection _ = schema_name wrapped_name = self.dialect.wrap_identifier table_name query = SQL_Builder.code "pragma table_info(" ++ wrapped_name ++ ")" - info_table = self.connection.read_statement query.build + info_table = self.base_connection.read_statement query.build ## The `pk` field is non-zero if the columns is part of the primary key. The column value indicates the position in the key. See: https://www.sqlite.org/pragma.html#pragma_table_info @@ -405,10 +405,10 @@ type SQLite_Connection Converts this value to a JSON serializable object. to_js_object : JS_Object to_js_object self = - JS_Object.from_pairs <| [["type", "SQLite_Connection"], ["links", self.connection.tables.at "Name" . to_vector]] + JS_Object.from_pairs <| [["type", "SQLite_Connection"], ["links", self.tables.at "Name" . to_vector]] ## --- private: true --- Table_Viz_Data.from (that:SQLite_Connection) = - Connections_Helpers.get_table_viz_data (that.connection.tables.at "Name" . to_vector) + Connections_Helpers.get_table_viz_data (that.tables.at "Name" . to_vector) diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/DB_Column.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/DB_Column.enso index c6aaba436652..b07d24d37616 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/DB_Column.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/DB_Column.enso @@ -10,6 +10,7 @@ import project.Internal.DB_Column_Implementation.DB_Column_Implementation import project.Internal.IR.SQL_IR_Expression.SQL_IR_Expression import project.Internal.IR.SQL_IR_Source.SQL_IR_Source import project.Internal.SQL_Type_Reference.SQL_Type_Reference +import project.Internal.Table_Naming_Helper.Table_Naming_Helper import project.Internal.Type_Refinements.DB_Column_Refinements import project.SQL.SQL_Statement @@ -86,7 +87,7 @@ type DB_Column use_ctes = self.connection.dialect.flagged ..Supports_Nested_With_Clause if use_ctes.not then callback self else - binder = self.connection.base_connection.table_naming_helper.generate_random_table_name + binder = Table_Naming_Helper.new self.connection . generate_random_table_name ref_expression = SQL_IR_Expression.Let_Ref name binder self.expression ref_column = DB_Column.new binder self.connection self.sql_type_reference ref_expression self.context diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/DB_Table.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/DB_Table.enso index 9411442900a2..04f48a8478f5 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/DB_Table.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/DB_Table.enso @@ -19,6 +19,7 @@ import Standard.Table.Internal.Match_Columns_Helpers import Standard.Table.Internal.Problem_Builder.Problem_Builder import Standard.Table.Internal.Replace_Helpers import Standard.Table.Internal.Table_Helpers +import Standard.Table.Internal.Unique_Name_Strategy.Unique_Name_Strategy import Standard.Table.Internal.Value_Type_Helpers import Standard.Table.Internal.Widget_Helpers from Standard.Table import Column, Table @@ -317,16 +318,16 @@ make_table : Connection -> Text -> Vector -> SQL_IR_Source -> Problem_Behavior - make_table connection table_name columns ctx on_problems = if columns.is_empty then Error.throw (Illegal_State.Error "Unexpectedly attempting to create a Database Table with no columns. This is a bug in the Database library.") else problem_builder = Problem_Builder.new - column_names_validator = connection.base_connection.column_naming_helper.create_unique_name_strategy + unique_name_strategy = connection.base_connection.to Unique_Name_Strategy cols = columns.map p-> raw_name = p.first sql_type = p.second # We ensure that the name used in the Enso table is a valid name for Enso column and is unique, possibly changing the input name slightly. - enso_name = column_names_validator.make_unique raw_name + enso_name = unique_name_strategy.make_unique raw_name # The expression keeps the original 'raw' name coming from the database. expression = SQL_IR_Expression.Column table_name raw_name Internal_Column.Value enso_name (SQL_Type_Reference.from_constant sql_type) expression - problem_builder.report_unique_name_strategy column_names_validator + problem_builder.report_unique_name_strategy unique_name_strategy # We do not want to stop the table from being fetched, so we report the issues as warnings. problem_builder.attach_problems_before on_problems <| DB_Table.new table_name connection cols ctx diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Common/Database_Join_Helper.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Common/Database_Join_Helper.enso index cf3f75ece939..6729831d5903 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Common/Database_Join_Helper.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Common/Database_Join_Helper.enso @@ -3,6 +3,7 @@ import Standard.Base.Errors.Illegal_State.Illegal_State from Standard.Base.Errors.Common import Floating_Point_Equality import Standard.Table.Internal.Join_Helpers +import Standard.Table.Internal.Unique_Name_Strategy.Unique_Name_Strategy from Standard.Table import Join_Kind, Table import project.Connection.Connection.Connection @@ -12,6 +13,7 @@ import project.Internal.IR.Internal_Column.Internal_Column import project.Internal.IR.SQL_IR_Expression.SQL_IR_Expression import project.Internal.IR.SQL_IR_From_Part.SQL_IR_From_Part import project.Internal.SQL_Type_Reference.SQL_Type_Reference +import project.Internal.Table_Naming_Helper.Table_Naming_Helper ## --- private: true @@ -87,23 +89,20 @@ type Join_Subquery_Setup --- prepare_subqueries : Connection -> Table & DB_Table -> Table & DB_Table -> Boolean -> Boolean -> Pair Join_Subquery_Setup prepare_subqueries connection left right needs_left_indicator needs_right_indicator = - table_naming_helper = connection.base_connection.table_naming_helper - column_naming_helper = connection.base_connection.column_naming_helper - ## If a self-join, make sure we are able to distinguish the left and right tables. - table_name_deduplicator = table_naming_helper.create_unique_name_strategy + table_name_deduplicator = Table_Naming_Helper.new connection . create_unique_name_strategy left_alias = table_name_deduplicator.make_unique left.name right_alias = table_name_deduplicator.make_unique right.name left_indicators = if needs_left_indicator.not then [] else - renamer = column_naming_helper.create_unique_name_strategy + renamer = connection.base_connection.to Unique_Name_Strategy renamer.mark_used (left.internal_columns.map .name) # This is an operation, not a constant to avoid adding unnecessary interpolations to the query. [Internal_Column.Value (renamer.make_unique "left_indicator") SQL_Type_Reference.null (SQL_IR_Expression.Literal "TRUE")] right_indicators = if needs_right_indicator.not then [] else - renamer = column_naming_helper.create_unique_name_strategy + renamer = connection.base_connection.to Unique_Name_Strategy renamer.mark_used (right.internal_columns.map .name) [Internal_Column.Value (renamer.make_unique "right_indicator") SQL_Type_Reference.null (SQL_IR_Expression.Literal "TRUE")] diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Common/Lookup_Query_Helper.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Common/Lookup_Query_Helper.enso index 433d7c997bc1..fca2c836416b 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Common/Lookup_Query_Helper.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Common/Lookup_Query_Helper.enso @@ -4,6 +4,7 @@ from Standard.Base.Runtime import assert import Standard.Table.Internal.Lookup_Helpers import Standard.Table.Internal.Lookup_Helpers.Lookup_Column +import Standard.Table.Internal.Unique_Name_Strategy.Unique_Name_Strategy from Standard.Table import Join_Kind, Table, Value_Type from Standard.Table.Errors import all @@ -14,6 +15,7 @@ import project.Internal.IR.SQL_IR_From_Part.SQL_IR_From_Part import project.Internal.IR.SQL_IR_Source.SQL_IR_Source import project.Internal.IR.SQL_Join_Kind.SQL_Join_Kind import project.Internal.SQL_Type_Reference.SQL_Type_Reference +import project.Internal.Table_Naming_Helper.Table_Naming_Helper from project.Internal.Upload.Helpers.Check_Queries import check_for_null_keys ## --- @@ -25,8 +27,7 @@ build_lookup_query : DB_Table -> Table & DB_Table -> (Vector (Integer | Text | R build_lookup_query base_table lookup_table key_columns add_new_columns allow_unmatched_rows on_problems:Problem_Behavior = lookup_columns = Lookup_Helpers.prepare_columns_for_lookup base_table lookup_table key_columns add_new_columns allow_unmatched_rows on_problems lookup_columns.if_not_error <| check_initial_invariants base_table lookup_table lookup_columns allow_unmatched_rows <| - column_naming_helper = base_table.connection.base_connection.column_naming_helper - unique_name_strategy = column_naming_helper.create_unique_name_strategy + unique_name_strategy = base_table.connection.base_connection.to Unique_Name_Strategy unique_name_strategy.mark_used base_table.column_names unique_name_strategy.mark_used lookup_table.column_names @@ -157,7 +158,7 @@ type Lookup_Subquery_Setup lookup join query (it translates the source columns valid in the input contexts, to the external join context). prepare_subqueries base_table lookup_table lookup_columns unique_name_strategy = - table_name_deduplicator = base_table.connection.base_connection.table_naming_helper.create_unique_name_strategy + table_name_deduplicator = Table_Naming_Helper.new base_table.connection . create_unique_name_strategy self_alias = table_name_deduplicator.make_unique base_table.name lookup_alias = table_name_deduplicator.make_unique lookup_table.name new_table_name = table_name_deduplicator.make_unique <| diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/DB_Column_Implementation.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/DB_Column_Implementation.enso index 69c1a5bc3618..12a6a0cfd220 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/DB_Column_Implementation.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/DB_Column_Implementation.enso @@ -502,7 +502,8 @@ type DB_Column_Implementation default_row_limit_for_read = ..First_With_Warning 1000 -naming_helper this_column = (this_column:DB_Column).connection.base_connection.column_naming_helper +naming_helper this_column = + (this_column:DB_Column).connection.base_connection.to Column_Naming_Helper ## --- private: true diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/DB_Table_Implementation.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/DB_Table_Implementation.enso index e93775b88d35..30f5a4e3c41c 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/DB_Table_Implementation.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/DB_Table_Implementation.enso @@ -25,6 +25,7 @@ import Standard.Table.Columns_To_Keep.Columns_To_Keep import Standard.Table.Expression.Expression import Standard.Table.Grouping_Method.Grouping_Method import Standard.Table.Internal.Add_Row_Number +import Standard.Table.Internal.Column_Naming_Helper.Column_Naming_Helper import Standard.Table.Internal.Column_Type_Helpers import Standard.Table.Internal.Constant_Column.Constant_Column import Standard.Table.Internal.Display_Helpers @@ -65,6 +66,7 @@ import project.Internal.IR.SQL_IR_Source.SQL_IR_Source import project.Internal.IR.SQL_IR_Statement.SQL_IR_Statement import project.Internal.IR.SQL_Join_Kind.SQL_Join_Kind import project.Internal.SQL_Type_Reference.SQL_Type_Reference +import project.Internal.Table_Naming_Helper.Table_Naming_Helper import project.Internal.Take_Drop_Helpers import project.Internal.Telemetry import project.Internal.Type_Refinements.DB_Table_Refinements @@ -371,7 +373,7 @@ type DB_Table_Implementation make_table_from_vectors (this_table : Table & DB_Table) column_vectors column_names = Feature.Make_Table_From.if_supported_else_throw this_table.connection.dialect "make_table_from_vectors" <| - literal_table_name = this_table.connection.base_connection.table_naming_helper.generate_random_table_name "enso-literal-" + literal_table_name = Table_Naming_Helper.new this_table.connection . generate_random_table_name "enso-literal-" make_literal_table this_table.connection column_vectors column_names literal_table_name make_constant_column (this_table : Table & DB_Table) value = @@ -537,7 +539,7 @@ type DB_Table_Implementation [c.name, c.expression] SQL_IR_Statement.Select pairs t.context - table_name_deduplicator = this_table.connection.base_connection.table_naming_helper.create_unique_name_strategy + table_name_deduplicator = Table_Naming_Helper.new this_table.connection . create_unique_name_strategy table_name_deduplicator.mark_used (all_tables.map .name) union_alias = table_name_deduplicator.make_unique <| all_tables.map .name . join "_" @@ -700,7 +702,8 @@ type DB_Table_Implementation ## --- private: true --- - column_naming_helper (this_table : Table & DB_Table) = this_table.connection.base_connection.column_naming_helper + column_naming_helper (this_table : Table & DB_Table) = + this_table.connection.base_connection.to Column_Naming_Helper to_text (this_table : Table & DB_Table) = "(Database Table "+this_table.name.to_text+")" @@ -794,7 +797,7 @@ _join_or_cross_join (this_table : Table & DB_Table) (right : Table & DB_Table) j True can_proceed.if_not_error <| left = this_table - table_name_deduplicator = this_table.connection.base_connection.table_naming_helper.create_unique_name_strategy + table_name_deduplicator = Table_Naming_Helper.new this_table.connection . create_unique_name_strategy table_name_deduplicator.mark_used [left.name, right.name] new_table_name = table_name_deduplicator.make_unique <| left.name + "_" + right.name @@ -811,8 +814,7 @@ _join_or_cross_join (this_table : Table & DB_Table) (right : Table & DB_Table) j join_resolution = Database_Join_Helper.make_join_helpers left right left_setup.column_mapping right_setup.column_mapping . resolve on on_problems right_columns_to_drop = if join_kind == Join_Kind.Inner then join_resolution.redundant_column_names else [] - column_naming_helper = this_table.connection.base_connection.column_naming_helper - result_columns = Database_Join_Helper.select_columns_for_join column_naming_helper join_kind left_setup.new_columns right_setup.new_columns right_columns_to_drop right_prefix problem_builder + result_columns = Database_Join_Helper.select_columns_for_join this_table.column_naming_helper join_kind left_setup.new_columns right_setup.new_columns right_columns_to_drop right_prefix problem_builder ## TODO proper equality of nulls in join conditions, see: https://www.pivotaltracker.com/story/show/184109759 diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso index 31361f23184b..37e4f621a35f 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Postgres/Postgres_Dialect.enso @@ -35,6 +35,7 @@ import project.Internal.Replace_Params.Replace_Params import project.Internal.SQL_Part.SQL_Part import project.Internal.SQL_Type_Mapping.SQL_Type_Mapping import project.Internal.SQL_Type_Reference.SQL_Type_Reference +import project.Internal.Table_Naming_Helper.Table_Naming_Helper import project.SQL.SQL_Builder import project.SQL.SQL_Fragment import project.SQL.SQL_Statement @@ -153,7 +154,7 @@ type Postgres_Dialect prepare_distinct : DB_Table -> Vector -> Case_Sensitivity -> Problem_Builder -> Table & DB_Table prepare_distinct self table key_columns case_sensitivity problem_builder = table_connection = Internals_Access.get_connection table - table_name_deduplicator = table_connection.base_connection.table_naming_helper.create_unique_name_strategy + table_name_deduplicator = Table_Naming_Helper.new table_connection . create_unique_name_strategy table_name_deduplicator.mark_used table.name inner_table_alias = table_name_deduplicator.make_unique table.name+"_inner" setup = table.context.as_subquery inner_table_alias [table.internal_columns] diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso index 7861089ffdac..e1b90e0345bf 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/SQLite/SQLite_Dialect.enso @@ -33,6 +33,7 @@ import project.Internal.SQL_Part.SQL_Part import project.Internal.SQL_Type_Mapping.SQL_Type_Mapping import project.Internal.SQL_Type_Reference.SQL_Type_Reference import project.Internal.SQLite.SQLite_Error_Mapper.SQLite_Error_Mapper +import project.Internal.Table_Naming_Helper.Table_Naming_Helper import project.SQL.SQL_Builder import project.SQL.SQL_Statement import project.SQL.SQL_Type @@ -163,7 +164,7 @@ type SQLite_Dialect prepare_distinct : DB_Table -> Vector -> Case_Sensitivity -> Problem_Builder -> Table & DB_Table prepare_distinct self table key_columns case_sensitivity problem_builder = table_connection = Internals_Access.get_connection table - table_name_deduplicator = table_connection.base_connection.table_naming_helper.create_unique_name_strategy + table_name_deduplicator = Table_Naming_Helper.new table_connection . create_unique_name_strategy table_name_deduplicator.mark_used table.name inner_table_alias = table_name_deduplicator.make_unique table.name+"_inner" setup = table.context.as_subquery inner_table_alias [table.internal_columns] diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Table_Naming_Helper.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Table_Naming_Helper.enso index 217774432df4..b8bfa151f7b4 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Table_Naming_Helper.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Table_Naming_Helper.enso @@ -1,3 +1,5 @@ +private + from Standard.Base import all import Standard.Base.Errors.Illegal_State.Illegal_State @@ -5,6 +7,8 @@ import Standard.Table.Internal.Naming_Properties.Naming_Properties import Standard.Table.Internal.Unique_Name_Strategy.Unique_Name_Strategy from Standard.Table.Errors import Name_Too_Long +import project.Connection.Connection.Connection + polyglot java import org.enso.base.Text_Utils ## --- @@ -15,14 +19,21 @@ type Table_Naming_Helper ## --- private: true --- - Value connection + private Value connection:Connection + + ## --- + private + --- + new : Connection -> Table_Naming_Helper + new connection = + Table_Naming_Helper.Value connection.base_connection ## --- private: true --- naming_properties : Naming_Properties naming_properties self = - self.connection.base_connection.entity_naming_properties.for_table_names + self.connection.entity_naming_properties.for_table_names ## --- private: true diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Create.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Create.enso index f23b3809af17..c63fd2073a6c 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Create.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Create.enso @@ -2,6 +2,7 @@ from Standard.Base import all import Standard.Base.Errors.Common.Dry_Run_Operation import Standard.Base.Runtime.Context +import project.Internal.Table_Naming_Helper.Table_Naming_Helper from project.Errors import Table_Already_Exists from project.Internal.Upload.Operations.Upload_Table import create_table_structure, resolve_temp_table_name @@ -23,7 +24,7 @@ from project.Internal.Upload.Operations.Upload_Table import create_table_structu create_table_implementation connection table_name structure primary_key temporary allow_existing on_problems:Problem_Behavior = connection.base_connection.maybe_run_maintenance resolved_table_name = resolve_temp_table_name connection temporary table_name - table_naming_helper = connection.base_connection.table_naming_helper + table_naming_helper = Table_Naming_Helper.new connection on_exists = if allow_existing then connection.query (..Table_Name resolved_table_name) else Error.throw (Table_Already_Exists.Error resolved_table_name) table_naming_helper.verify_table_name resolved_table_name <| diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Delete.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Delete.enso index ece2b9eb4fd7..cabfa2d0a033 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Delete.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Delete.enso @@ -10,6 +10,7 @@ from Standard.Table import Join_Kind, Table import project.DB_Table.DB_Table import project.Internal.DDL_Transaction import project.Internal.IR.SQL_IR_Statement.SQL_IR_Statement +import project.Internal.Table_Naming_Helper.Table_Naming_Helper from project.Errors import SQL_Error from project.Internal.Upload.Helpers.Argument_Checks import check_delete_rows_arguments from project.Internal.Upload.Helpers.Check_Queries import check_duplicate_key_matches_for_delete, check_for_null_keys @@ -75,7 +76,7 @@ type Delete_Rows_Source --- prepare connection (key_values_to_delete : Table) key_columns = prepared_table = common_preprocess_source_table key_values_to_delete key_columns - tmp_table_name = connection.base_connection.table_naming_helper.generate_random_table_name "enso-temp-keys-table-" + tmp_table_name = Table_Naming_Helper.new connection . generate_random_table_name "enso-temp-keys-table-" copied_table = create_table_upload_operation prepared_table connection tmp_table_name primary_key=key_columns temporary=True remove_after_transaction=True on_problems=Problem_Behavior.Report_Error row_limit=Nothing Delete_Rows_Source.Temporary_DB_Table copied_table tmp_table_name @@ -120,7 +121,7 @@ type Delete_Rows_Dry_Run_Source _ : DB_Table -> Delete_Rows_Dry_Run_Source.Existing_DB_Query (prepared_table : DB_Table & Table) _ : In_Memory_Table -> - tmp_table_name = connection.base_connection.table_naming_helper.generate_random_table_name "enso-temp-keys-table-" + tmp_table_name = Table_Naming_Helper.new connection . generate_random_table_name "enso-temp-keys-table-" upload_recipe = create_table_upload_operation prepared_table connection tmp_table_name primary_key=key_columns temporary=True remove_after_transaction=True structure_hint=Nothing on_problems=Problem_Behavior.Report_Error row_limit=dry_run_row_limit row_limit_exceeded = prepared_table.row_count > dry_run_row_limit dry_run_message_suffix = case row_limit_exceeded of diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Select_Into.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Select_Into.enso index 334dc93e67f7..a348df86eccc 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Select_Into.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Select_Into.enso @@ -5,6 +5,7 @@ import Standard.Base.Errors.Common.Dry_Run_Operation import Standard.Base.Runtime.Context import project.Internal.DDL_Transaction +import project.Internal.Table_Naming_Helper.Table_Naming_Helper from project.Errors import SQL_Error, Table_Already_Exists from project.Internal.Upload.Helpers.Constants import dry_run_row_limit from project.Internal.Upload.Helpers.Error_Helpers import handle_upload_errors @@ -16,7 +17,7 @@ from project.Internal.Upload.Operations.Upload_Table import create_table_upload_ select_into_table_implementation source_table connection table_name primary_key temporary on_problems:Problem_Behavior = connection.base_connection.maybe_run_maintenance resolved_table_name = resolve_temp_table_name connection temporary table_name - table_naming_helper = connection.base_connection.table_naming_helper + table_naming_helper = Table_Naming_Helper.new connection table_naming_helper.verify_table_name resolved_table_name <| Panic.recover SQL_Error <| handle_upload_errors <| real_target_already_exists = connection.base_connection.table_exists resolved_table_name diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Update.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Update.enso index 5950bbacbc7f..9202ef4aa873 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Update.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Update.enso @@ -12,6 +12,7 @@ import project.DB_Table.DB_Table import project.Internal.DDL_Transaction import project.Internal.In_Transaction.In_Transaction import project.Internal.IR.SQL_IR_Statement.SQL_IR_Statement +import project.Internal.Table_Naming_Helper.Table_Naming_Helper import project.Update_Action.Update_Action from project.Errors import Rows_Already_Present, SQL_Error, Unmatched_Rows from project.Internal.Upload.Helpers.Argument_Checks import all @@ -29,7 +30,7 @@ common_update_table (source_table : Table) (target_table : Table) update_action Panic.recover SQL_Error <| handle_upload_errors <| effective_key_columns = if key_columns.is_nothing then [] else key_columns check_update_arguments_structure_match source_table target_table:(Table & DB_Table) effective_key_columns update_action error_on_missing_columns on_problems <| - tmp_table_name = connection.base_connection.table_naming_helper.generate_random_table_name "enso-temp-source-table-" + tmp_table_name = Table_Naming_Helper.new connection . generate_random_table_name "enso-temp-source-table-" dry_run = Context.Output.is_enabled.not row_limit = if dry_run then dry_run_row_limit else Nothing structure_hint = target_table.select_columns source_table.column_names reorder=True . columns . map c-> diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Upload_Table.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Upload_Table.enso index c73249623f49..3dd231b90fbc 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Upload_Table.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Internal/Upload/Operations/Upload_Table.enso @@ -5,6 +5,7 @@ import Standard.Base.Errors.Illegal_Argument.Illegal_Argument import Standard.Base.Errors.Illegal_State.Illegal_State import Standard.Table.In_Memory_Table.In_Memory_Table +import Standard.Table.Internal.Column_Naming_Helper.Column_Naming_Helper from Standard.Table import Table import project.Column_Description.Column_Description @@ -27,7 +28,7 @@ from project.Internal.Upload.Helpers.SQL_Helpers import make_batched_insert_temp create_table_structure connection table_name structure primary_key temporary on_problems:Problem_Behavior -> Text = aligned_structure = align_structure connection structure resolved_primary_key = resolve_primary_key aligned_structure primary_key - validate_structure connection.base_connection.column_naming_helper aligned_structure <| + validate_structure (connection.base_connection.to Column_Naming_Helper) aligned_structure <| create_table_statement = prepare_create_table_statement connection table_name aligned_structure resolved_primary_key temporary on_problems update_result = create_table_statement.if_not_error <| log_sql_if_enabled connection.jdbc_connection create_table_statement.to_text diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/SQL_Query.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/SQL_Query.enso index ad0343a910b7..98cf1fe920ce 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/SQL_Query.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/SQL_Query.enso @@ -9,6 +9,7 @@ import project.Errors.Table_Not_Found import project.Internal.IR.SQL_IR_Source.SQL_IR_Source import project.Internal.IR.SQL_IR_Statement.SQL_IR_Statement import project.Internal.Statement_Setter.Statement_Setter +import project.Internal.Table_Naming_Helper.Table_Naming_Helper import project.SQL.SQL_Statement from project.Internal.JDBC_Connection import handle_sql_errors @@ -26,8 +27,7 @@ type SQL_Query --- to_db_table self connection alias:Text = alias.if_not_error <| case self of SQL_Query.Table_Name name -> - table_naming_helper = connection.base_connection.table_naming_helper - table_naming_helper.verify_table_name name <| + Table_Naming_Helper.new connection . verify_table_name name <| make_table_for_name connection name "" alias SQL_Query.Raw_SQL raw_sql -> handle_sql_errors <| connection.dialect.ensure_query_has_no_holes connection.jdbc_connection raw_sql . if_not_error <| @@ -46,8 +46,7 @@ type SQL_Query_With_Schema --- to_db_table self connection alias:Text = alias.if_not_error <| case self of SQL_Query_With_Schema.Table_Name name schema -> - table_naming_helper = connection.base_connection.table_naming_helper - table_naming_helper.verify_table_name name <| + Table_Naming_Helper.new connection . verify_table_name name <| make_table_for_name connection name schema alias SQL_Query_With_Schema.Raw_SQL raw_sql -> handle_sql_errors <| connection.dialect.ensure_query_has_no_holes connection.jdbc_connection raw_sql . if_not_error <| diff --git a/distribution/lib/Standard/DuckDB/0.0.0-dev/src/DuckDB_Connection.enso b/distribution/lib/Standard/DuckDB/0.0.0-dev/src/DuckDB_Connection.enso index d66b2eb6ffab..77cc462ddbe2 100644 --- a/distribution/lib/Standard/DuckDB/0.0.0-dev/src/DuckDB_Connection.enso +++ b/distribution/lib/Standard/DuckDB/0.0.0-dev/src/DuckDB_Connection.enso @@ -80,21 +80,21 @@ type DuckDB_Connection immediately instead of waiting for them to be automatically released. The connection is not usable afterwards. close : Nothing - close self = self.connection.close + close self = self.base_connection.close ## --- icon: metadata --- Returns the list of databases (or catalogs) for the connection. databases : Vector Text - databases self = self.connection.databases + databases self = self.base_connection.databases ## --- icon: metadata --- Returns the name of the current database (or catalog). database : Text - database self = self.connection.database + database self = self.base_connection.database ## --- icon: data_input @@ -115,14 +115,14 @@ type DuckDB_Connection Returns the list of schemas for the connection within the current database (or catalog). schemas : Vector Text - schemas self = self.connection.schemas.distinct + schemas self = self.base_connection.schemas.distinct ## --- icon: metadata --- Returns the name of the current schema. schema : Text - schema self = self.connection.schema + schema self = self.base_connection.schema ## --- icon: data_input @@ -143,7 +143,7 @@ type DuckDB_Connection --- Gets a list of the table types. table_types : Vector Text - table_types self = self.connection.table_types + table_types self = self.base_connection.table_types ## --- group: Standard.Base.Metadata @@ -175,7 +175,7 @@ type DuckDB_Connection tables self name_like:Text="" database:Text=self.database schema:Text=self.schema types=["BASE TABLE", "VIEW"] all_fields=False = parsed_database = if database == "*" then Nothing else (if database == "" then self.database else database) parsed_schema = if schema == "*" then Nothing else (if schema == "" then self.schema else schema) - self.connection.tables (if name_like == "" then Nothing else name_like) parsed_database parsed_schema types all_fields + self.base_connection.tables (if name_like == "" then Nothing else name_like) parsed_database parsed_schema types all_fields ## --- aliases: [import, load, open, read, sql] @@ -316,7 +316,7 @@ type DuckDB_Connection @limit Rows_To_Read.default_widget execute_query : Text | SQL_Statement -> Rows_To_Read -> Boolean -> Table execute_query self query (limit : Rows_To_Read = ..First_With_Warning 1000) write_operation:Boolean=True = - self.connection.execute_query query limit write_operation + self.base_connection.execute_query query limit write_operation ## --- advanced: true @@ -333,7 +333,7 @@ type DuckDB_Connection representing the query to execute. execute_update : Text | SQL_Statement -> Integer execute_update self query = - self.connection.execute_update query + self.base_connection.execute_update query ## --- private: true @@ -350,31 +350,31 @@ type DuckDB_Connection representing the query to execute. execute : Text | SQL_Statement -> Integer execute self query = - self.connection.execute query + self.base_connection.execute query ## --- private: true --- Access the dialect. - dialect self = self.connection.dialect + dialect self = self.base_connection.dialect ## --- private: true --- Access the Type Mapping. - type_mapping self = self.connection.type_mapping + type_mapping self = self.base_connection.type_mapping ## --- private: true --- Access the Statement Setter. - statement_setter self = self.connection.statement_setter + statement_setter self = self.base_connection.statement_setter ## --- private: true --- Access the underlying JDBC connection. - jdbc_connection self = self.connection.jdbc_connection + jdbc_connection self = self.base_connection.jdbc_connection ## --- private: true @@ -387,7 +387,7 @@ type DuckDB_Connection does not exist. Defaults to `False`. drop_table : Text -> Boolean -> Nothing drop_table self table_name if_exists=False = - self.connection.drop_table table_name if_exists + self.base_connection.drop_table table_name if_exists ## --- private: true @@ -398,7 +398,7 @@ type DuckDB_Connection - `table_name`: the name of the table to truncate. truncate_table : Text -> Nothing ! Table_Not_Found truncate_table self table_name = - self.connection.truncate_table table_name + self.base_connection.truncate_table table_name ## --- private: true @@ -429,7 +429,7 @@ type DuckDB_Connection Converts this value to a JSON serializable object. to_js_object : JS_Object to_js_object self = - JS_Object.from_pairs <| [["type", "DuckDB_Connection"], ["links", self.connection.tables.at "Name" . to_vector]] + JS_Object.from_pairs <| [["type", "DuckDB_Connection"], ["links", self.tables.at "Name" . to_vector]] ## --- private: true diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Connection/SQLServer_Query.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Connection/SQLServer_Query.enso index a311b3d884b7..838dd3688cb1 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Connection/SQLServer_Query.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Connection/SQLServer_Query.enso @@ -1,8 +1,7 @@ from Standard.Base import all import Standard.Database.SQL_Query.SQL_Query -from Standard.Database.Internal.JDBC_Connection import handle_sql_errors -from Standard.Database.SQL_Query import make_table_for_name, make_table_from_query +import Standard.Database.SQL_Query.SQL_Query_With_Schema type SQLServer_Query ## Query a whole table or view. @@ -14,14 +13,11 @@ type SQLServer_Query ## --- private: true --- - to_db_table self connection alias:Text = alias.if_not_error <| case self of - SQLServer_Query.Table_Name name schema -> - table_naming_helper = connection.base_connection.table_naming_helper - table_naming_helper.verify_table_name name <| - make_table_for_name connection name schema alias - SQLServer_Query.Raw_SQL raw_sql -> handle_sql_errors <| - connection.dialect.ensure_query_has_no_holes connection.jdbc_connection raw_sql . if_not_error <| - make_table_from_query connection raw_sql alias + to_db_table self connection alias:Text = + base_query = case self of + SQLServer_Query.Table_Name name schema -> SQL_Query_With_Schema.Table_Name name schema + SQLServer_Query.Raw_SQL raw_sql -> SQL_Query.Raw_SQL raw_sql + base_query.to_db_table connection alias SQLServer_Query.from (that:Text) = SQLServer_Query.Table_Name that diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso index 31f6771e5365..9ef5681620b5 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/Internal/SQLServer_Dialect.enso @@ -6,6 +6,7 @@ import Standard.Base.Errors.Illegal_State.Illegal_State import Standard.Base.Errors.Unimplemented.Unimplemented import Standard.Table.Internal.Problem_Builder.Problem_Builder +import Standard.Table.Internal.Unique_Name_Strategy.Unique_Name_Strategy from Standard.Table import Aggregate_Column, Column, Table, Value_Type from Standard.Table.Aggregate_Column.Aggregate_Column import all from Standard.Table.Errors import Inexact_Type_Coercion @@ -166,9 +167,9 @@ type SQLServer_Dialect prepare_distinct : DB_Table -> Vector -> Case_Sensitivity -> Problem_Builder -> Table & DB_Table prepare_distinct self table key_columns case_sensitivity problem_builder = table_connection = Internals_Access.get_connection table - table_name_deduplicator = table_connection.base_connection.table_naming_helper.create_unique_name_strategy - table_name_deduplicator.mark_used table.name - inner_table_alias = table_name_deduplicator.make_unique table.name+"_inner" + unique_name_strategy = Unique_Name_Strategy.new table_connection.base_connection.entity_naming_properties.for_table_names + unique_name_strategy.mark_used table.name + inner_table_alias = unique_name_strategy.make_unique table.name+"_inner" setup = table.context.as_subquery inner_table_alias [table.internal_columns] new_columns = setup.new_columns.first column_mapping = Dictionary.from_vector <| new_columns.map c-> [c.name, c] diff --git a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/SQLServer_Connection.enso b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/SQLServer_Connection.enso index 986d0e9a6dca..0a88733d0efd 100644 --- a/distribution/lib/Standard/Microsoft/0.0.0-dev/src/SQLServer_Connection.enso +++ b/distribution/lib/Standard/Microsoft/0.0.0-dev/src/SQLServer_Connection.enso @@ -60,11 +60,15 @@ type SQLServer_Connection props = properties_as_java_props properties JDBCProxy.getConnection url props jdbc_connection = JDBC_Connection.from_java sql_exception=SQLException java_connection - jdbc_entity_naming_properties = Entity_Naming_Properties.from_jdbc_connection jdbc_connection is_case_sensitive=True + ## jdbc reports table name length limit as 128, but it actually seems to be 116 for temp tables so we override it - limited = Encoding_Limited_Naming_Properties.Instance Encoding.utf_8 limit=116 is_case_sensitive=True - modified_entity_naming_properties = Entity_Naming_Properties.Value for_table_names=limited for_column_names=jdbc_entity_naming_properties.for_column_names for_generated_column_names=jdbc_entity_naming_properties.for_generated_column_names - SQLServer_Connection.Value (Connection.new jdbc_connection SQLServer_Dialect.sqlserver SQLServer_Type_Mapping modified_entity_naming_properties data_link_setup statement_setter=SQLServer_Type_Mapping.statement_setter) make_new + make_entity_naming_properties = + jdbc_entity_naming_properties = Entity_Naming_Properties.from_jdbc_connection jdbc_connection is_case_sensitive=True + limited = Encoding_Limited_Naming_Properties.Instance Encoding.utf_8 limit=116 is_case_sensitive=True + Entity_Naming_Properties.Value for_table_names=limited for_column_names=jdbc_entity_naming_properties.for_column_names for_generated_column_names=jdbc_entity_naming_properties.for_generated_column_names + + base_connection = Connection.new jdbc_connection SQLServer_Dialect.sqlserver SQLServer_Type_Mapping make_entity_naming_properties data_link_setup statement_setter=SQLServer_Type_Mapping.statement_setter + SQLServer_Connection.Value base_connection make_new ## --- private: true @@ -83,21 +87,21 @@ type SQLServer_Connection immediately instead of waiting for them to be automatically released. The connection is not usable afterwards. close : Nothing - close self = self.connection.close + close self = self.base_connection.close ## --- icon: metadata --- Returns the list of databases (or catalogs) for the connection. databases : Vector Text - databases self = self.connection.databases + databases self = self.base_connection.databases ## --- icon: metadata --- Returns the name of the current database (or catalog). database : Text - database self = self.connection.database + database self = self.base_connection.database ## --- icon: data_input @@ -119,7 +123,7 @@ type SQLServer_Connection (or catalog). schemas : Vector Text schemas self = - self.connection.read_text_column "select name from sys.schemas" "name" + self.base_connection.read_text_column "select name from sys.schemas" "name" ## --- icon: metadata @@ -127,7 +131,7 @@ type SQLServer_Connection Returns the name of the current schema. schema : Text schema self = - self.connection.schema + self.base_connection.schema ## --- icon: metadata @@ -148,7 +152,7 @@ type SQLServer_Connection --- Gets a list of the table types. table_types : Vector Text - table_types self = self.connection.table_types + table_types self = self.base_connection.table_types ## --- group: Standard.Base.Metadata @@ -181,7 +185,7 @@ type SQLServer_Connection parsed_database = if database == "*" then Nothing else (if database == "" then self.database else database) used_connection = if parsed_database.if_nothing self.database != self.database then self.set_database parsed_database else self parsed_schema = if schema == "*" then Nothing else (if schema == "" then self.schema else schema) - used_connection.connection.tables (if name_like == "" then Nothing else name_like) parsed_database parsed_schema types all_fields + used_connection.base_connection.tables (if name_like == "" then Nothing else name_like) parsed_database parsed_schema types all_fields ## --- aliases: [import, load, open, read, sql] @@ -322,7 +326,7 @@ type SQLServer_Connection @limit Rows_To_Read.default_widget execute_query : Text | SQL_Statement -> Rows_To_Read -> Boolean -> Table execute_query self query (limit : Rows_To_Read = ..First_With_Warning 1000) write_operation:Boolean=True = - self.connection.execute_query query limit write_operation + self.base_connection.execute_query query limit write_operation ## --- advanced: true @@ -339,7 +343,7 @@ type SQLServer_Connection representing the query to execute. execute_update : Text | SQL_Statement -> Integer execute_update self query = - self.connection.execute_update query + self.base_connection.execute_update query ## --- private: true @@ -356,31 +360,31 @@ type SQLServer_Connection representing the query to execute. execute : Text | SQL_Statement -> Integer execute self query = - self.connection.execute query + self.base_connection.execute query ## --- private: true --- Access the dialect. - dialect self = self.connection.dialect + dialect self = self.base_connection.dialect ## --- private: true --- Access the Type Mapping. - type_mapping self = self.connection.type_mapping + type_mapping self = self.base_connection.type_mapping ## --- private: true --- Access the Statement Setter. - statement_setter self = self.connection.statement_setter + statement_setter self = self.base_connection.statement_setter ## --- private: true --- Access the underlying JDBC connection. - jdbc_connection self = self.connection.jdbc_connection + jdbc_connection self = self.base_connection.jdbc_connection ## --- private: true @@ -393,7 +397,7 @@ type SQLServer_Connection does not exist. Defaults to `False`. drop_table : Text -> Boolean -> Nothing drop_table self table_name if_exists=False = - self.connection.drop_table table_name if_exists + self.base_connection.drop_table table_name if_exists ## --- private: true @@ -404,7 +408,7 @@ type SQLServer_Connection - `table_name`: the name of the table to truncate. truncate_table : Text -> Nothing ! Table_Not_Found truncate_table self table_name = - self.connection.truncate_table table_name + self.base_connection.truncate_table table_name ## --- private: true @@ -444,7 +448,7 @@ type SQLServer_Connection Converts this value to a JSON serializable object. to_js_object : JS_Object to_js_object self = - JS_Object.from_pairs <| [["type", "SQLServer_Connection"], ["links", self.connection.tables.at "Name" . to_vector]] + JS_Object.from_pairs <| [["type", "SQLServer_Connection"], ["links", self.tables.at "Name" . to_vector]] ## --- private: true diff --git a/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso b/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso index c4f461d90459..cef2223de39a 100644 --- a/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso +++ b/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Internal/Snowflake_Dialect.enso @@ -7,6 +7,7 @@ import Standard.Base.Errors.Unimplemented.Unimplemented import Standard.Base.Runtime.Ref.Ref import Standard.Table.Internal.Problem_Builder.Problem_Builder +import Standard.Table.Internal.Unique_Name_Strategy.Unique_Name_Strategy from Standard.Table import Aggregate_Column, Column, Table, Value_Type from Standard.Table.Aggregate_Column.Aggregate_Column import all from Standard.Table.Errors import Inexact_Type_Coercion @@ -163,9 +164,9 @@ type Snowflake_Dialect prepare_distinct : DB_Table -> Vector -> Case_Sensitivity -> Problem_Builder -> Table & DB_Table prepare_distinct self table key_columns case_sensitivity problem_builder = table_connection = Internals_Access.get_connection table - table_name_deduplicator = table_connection.base_connection.table_naming_helper.create_unique_name_strategy - table_name_deduplicator.mark_used table.name - inner_table_alias = table_name_deduplicator.make_unique table.name+"_inner" + unique_name_strategy = Unique_Name_Strategy.new table_connection.base_connection.entity_naming_properties.for_table_names + unique_name_strategy.mark_used table.name + inner_table_alias = unique_name_strategy.make_unique table.name+"_inner" setup = (Internals_Access.get_context table).as_subquery inner_table_alias [Internals_Access.internal_columns table] new_columns = setup.new_columns.first column_mapping = Dictionary.from_vector <| new_columns.map c-> [c.name, c] diff --git a/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Snowflake_Connection.enso b/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Snowflake_Connection.enso index 13656b9e6b08..7c59313e7dd3 100644 --- a/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Snowflake_Connection.enso +++ b/distribution/lib/Standard/Snowflake/0.0.0-dev/src/Snowflake_Connection.enso @@ -61,8 +61,7 @@ type Snowflake_Connection ## As long as names are quoted, the Snowflake SQL dialect is case sensitive. Our generator always quotes identifiers, so we can rely on the case sensitivity. This is the same as in Postgres. - entity_naming_properties = Entity_Naming_Properties.from_jdbc_connection jdbc_connection is_case_sensitive=True - Snowflake_Connection.Value (Connection.new jdbc_connection Snowflake_Dialect.snowflake Snowflake_Type_Mapping entity_naming_properties data_link_setup statement_setter=Snowflake_Type_Mapping.statement_setter) make_new + Snowflake_Connection.Value (Connection.new jdbc_connection Snowflake_Dialect.snowflake Snowflake_Type_Mapping (Entity_Naming_Properties.from_jdbc_connection jdbc_connection is_case_sensitive=True) data_link_setup statement_setter=Snowflake_Type_Mapping.statement_setter) make_new ## --- private: true @@ -81,7 +80,7 @@ type Snowflake_Connection immediately instead of waiting for them to be automatically released. The connection is not usable afterwards. close : Nothing - close self = self.connection.close + close self = self.base_connection.close ## --- icon: metadata @@ -89,7 +88,7 @@ type Snowflake_Connection Returns the list of warehouses for the connection. warehouses : Vector Text warehouses self = - self.connection.read_text_column "show warehouses" "name" + self.base_connection.read_text_column "show warehouses" "name" ## --- icon: metadata @@ -97,7 +96,7 @@ type Snowflake_Connection Returns the name of the current warehouse. warehouse : Text warehouse self = - vector = self.connection.read_text_column "SELECT current_warehouse() as name" "name" + vector = self.base_connection.read_text_column "SELECT current_warehouse() as name" "name" vector.first ## --- @@ -118,14 +117,14 @@ type Snowflake_Connection --- Returns the list of databases (or catalogs) for the connection. databases : Vector Text - databases self = self.connection.databases + databases self = self.base_connection.databases ## --- icon: metadata --- Returns the name of the current database (or catalog). database : Text - database self = self.connection.database + database self = self.base_connection.database ## --- icon: data_input @@ -147,14 +146,14 @@ type Snowflake_Connection (or catalog). schemas : Vector Text schemas self = - self.connection.read_text_column "show schemas in database" "name" + self.base_connection.read_text_column "show schemas in database" "name" ## --- icon: metadata --- Returns the name of the current schema. schema : Text - schema self = self.connection.schema + schema self = self.base_connection.schema ## --- icon: data_input @@ -175,7 +174,7 @@ type Snowflake_Connection --- Gets a list of the table types. table_types : Vector Text - table_types self = self.connection.table_types + table_types self = self.base_connection.table_types ## --- group: Standard.Base.Metadata @@ -207,7 +206,7 @@ type Snowflake_Connection tables self name_like:Text="" database:Text=self.database schema:Text=self.schema types=["TABLE", "VIEW"] all_fields=False = parsed_database = if database == "*" then Nothing else (if database == "" then self.database else database) parsed_schema = if schema == "*" then Nothing else (if schema == "" then self.schema else schema) - self.connection.tables (if name_like == "" then Nothing else name_like) parsed_database parsed_schema types all_fields + self.base_connection.tables (if name_like == "" then Nothing else name_like) parsed_database parsed_schema types all_fields ## --- aliases: [import, load, open, read, sql] @@ -257,7 +256,7 @@ type Snowflake_Connection @limit Rows_To_Read.default_widget read : SQL_Query -> Rows_To_Read -> Table ! Table_Not_Found read self query:SQL_Query (limit : Rows_To_Read = ..First_With_Warning 1000) = - self.connection.read query limit + self.base_connection.read query limit ## --- group: Standard.Base.Output @@ -344,7 +343,7 @@ type Snowflake_Connection @limit Rows_To_Read.default_widget execute_query : Text | SQL_Statement -> Rows_To_Read -> Boolean -> Table execute_query self query (limit : Rows_To_Read = ..First_With_Warning 1000) write_operation:Boolean=True = - self.connection.execute_query query limit write_operation + self.base_connection.execute_query query limit write_operation ## --- advanced: true @@ -361,7 +360,7 @@ type Snowflake_Connection representing the query to execute. execute_update : Text | SQL_Statement -> Integer execute_update self query = - self.connection.execute_update query + self.base_connection.execute_update query ## --- private: true @@ -378,31 +377,31 @@ type Snowflake_Connection representing the query to execute. execute : Text | SQL_Statement -> Integer execute self query = - self.connection.execute query + self.base_connection.execute query ## --- private: true --- Access the dialect. - dialect self = self.connection.dialect + dialect self = self.base_connection.dialect ## --- private: true --- Access the Type Mapping. - type_mapping self = self.connection.type_mapping + type_mapping self = self.base_connection.type_mapping ## --- private: true --- Access the Statement Setter. - statement_setter self = self.connection.statement_setter + statement_setter self = self.base_connection.statement_setter ## --- private: true --- Access the underlying JDBC connection. - jdbc_connection self = self.connection.jdbc_connection + jdbc_connection self = self.base_connection.jdbc_connection ## --- private: true @@ -415,7 +414,7 @@ type Snowflake_Connection does not exist. Defaults to `False`. drop_table : Text -> Boolean -> Nothing drop_table self table_name if_exists=False = - self.connection.drop_table table_name if_exists + self.base_connection.drop_table table_name if_exists ## --- private: true @@ -426,7 +425,7 @@ type Snowflake_Connection - `table_name`: the name of the table to truncate. truncate_table : Text -> Nothing ! Table_Not_Found truncate_table self table_name = - self.connection.truncate_table table_name + self.base_connection.truncate_table table_name ## --- private: true @@ -466,7 +465,7 @@ type Snowflake_Connection Converts this value to a JSON serializable object. to_js_object : JS_Object to_js_object self = - JS_Object.from_pairs <| [["type", "Snowflake_Connection"], ["links", self.connection.tables.at "Name" . to_vector]] + JS_Object.from_pairs <| [["type", "Snowflake_Connection"], ["links", self.tables.at "Name" . to_vector]] private auth_jdbc_properties credentials = case credentials of Credentials.Username_And_Password username password ->