From 6dca056d2f67198432a28253344f48fe6b0680cf Mon Sep 17 00:00:00 2001 From: Gregory Michael Travis Date: Thu, 6 Mar 2025 13:38:20 -0500 Subject: [PATCH] Allow generic JDBC connection through `Database.connect` (#12331) Adds `Generic_JDBC_Details` and `GenericJDBCConnectionDetailsImpl`. --- CHANGELOG.md | 2 ++ .../docs/api/JDBC/Generic_JDBC_Connection.md | 4 +++ .../src/JDBC/Generic_JDBC_Connection.enso | 21 +++++++++++++++ .../Standard/Database/0.0.0-dev/src/Main.enso | 1 + .../GenericJDBCConnectionDetailsImpl.java | 26 +++++++++++++++++++ test/Generic_JDBC_Tests/src/H2_Spec.enso | 7 +++++ 6 files changed, 61 insertions(+) create mode 100644 std-bits/database/src/main/java/org/enso/database/jdbc/GenericJDBCConnectionDetailsImpl.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b2095944d19..117ea0ce0d14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,7 @@ - [Support for Regular Expressions in Enso Expressions.][12320] - [Support for pi() and e() in Enso Expressions.][12367] - [xlsx reader now does not read empty rows from the end of a worksheet][12345] +- [Generic JDBC connections can be created with `Database.connect`.][12331] [11926]: https://github.com/enso-org/enso/pull/11926 [12031]: https://github.com/enso-org/enso/pull/12031 @@ -93,6 +94,7 @@ [12300]: https://github.com/enso-org/enso/pull/12300 [12297]: https://github.com/enso-org/enso/pull/12297 [12320]: https://github.com/enso-org/enso/pull/12320 +[12331]: https://github.com/enso-org/enso/pull/12331 [12367]: https://github.com/enso-org/enso/pull/12367 [12345]: https://github.com/enso-org/enso/pull/12345 diff --git a/distribution/lib/Standard/Database/0.0.0-dev/docs/api/JDBC/Generic_JDBC_Connection.md b/distribution/lib/Standard/Database/0.0.0-dev/docs/api/JDBC/Generic_JDBC_Connection.md index a4121b56b092..ebb818986237 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/docs/api/JDBC/Generic_JDBC_Connection.md +++ b/distribution/lib/Standard/Database/0.0.0-dev/docs/api/JDBC/Generic_JDBC_Connection.md @@ -12,3 +12,7 @@ - quote_literal self literal:Standard.Base.Data.Text.Text -> Standard.Base.Data.Text.Text - read self sql_query:Standard.Database.SQL_Query.SQL_Query= -> Standard.Table.Table.Table - with_metadata self f:Standard.Base.Any.Any -> Standard.Base.Any.Any +- type Generic_JDBC_Details + - Value url:Standard.Base.Data.Text.Text + - connect self options:Standard.Base.Any.Any -> Standard.Base.Any.Any + - resolve constructor:Standard.Base.Any.Any -> Standard.Base.Any.Any diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/JDBC/Generic_JDBC_Connection.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/JDBC/Generic_JDBC_Connection.enso index 4209503f09ee..327572ff6f0c 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/JDBC/Generic_JDBC_Connection.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/JDBC/Generic_JDBC_Connection.enso @@ -2,10 +2,12 @@ from Standard.Base import all import Standard.Base.Errors.Common.Forbidden_Operation import Standard.Base.Errors.Common.Missing_Argument +import Standard.Base.Errors.Common.Type_Error import Standard.Base.Runtime.Context from Standard.Table import Table +import project.Connection.Connection_Options.Connection_Options import project.Internal.Column_Fetcher as Column_Fetcher_Module import project.Internal.JDBC_Connection import project.Internal.SQL_Warning_Helper @@ -37,6 +39,7 @@ type Generic_JDBC_Connection Arguments: - url: The JDBC URL describing the database to connect to. + - properties: A vector of properties for the connection. > Example Connect to an H2 database instance. (This requires that you have the H2 @@ -287,6 +290,24 @@ type Generic_JDBC_Connection self.jdbc_connection.with_connection connection-> connection.createStatement.enquoteLiteral literal +type Generic_JDBC_Details + Value url:Text + + ## PRIVATE + Attempt to resolve the constructor. + resolve : Function -> Generic_JDBC_Details | Nothing + resolve constructor = + Panic.catch Type_Error (constructor:Generic_JDBC_Details) _->Nothing + + ## PRIVATE + Build the Connection resource. + + Arguments: + - options: Overrides for the connection properties. + connect : Connection_Options -> Generic_JDBC_Connection + connect self options = + Generic_JDBC_Connection.connect self.url options.options + ## PRVIATE Convert a JDBC ResultSet to a Table using the fallback fetcher. private rs_to_table_ rs = diff --git a/distribution/lib/Standard/Database/0.0.0-dev/src/Main.enso b/distribution/lib/Standard/Database/0.0.0-dev/src/Main.enso index e3b9d20960af..95743e4f17c7 100644 --- a/distribution/lib/Standard/Database/0.0.0-dev/src/Main.enso +++ b/distribution/lib/Standard/Database/0.0.0-dev/src/Main.enso @@ -17,6 +17,7 @@ export project.Extensions.Upload_In_Memory_Table.select_into_database_table export project.Extensions.Upload_In_Memory_Table.update_rows export project.JDBC.Generic_JDBC_Connection.Generic_JDBC_Connection +export project.JDBC.Generic_JDBC_Connection.Generic_JDBC_Details export project.SQL_Query.SQL_Query diff --git a/std-bits/database/src/main/java/org/enso/database/jdbc/GenericJDBCConnectionDetailsImpl.java b/std-bits/database/src/main/java/org/enso/database/jdbc/GenericJDBCConnectionDetailsImpl.java new file mode 100644 index 000000000000..122769e0c620 --- /dev/null +++ b/std-bits/database/src/main/java/org/enso/database/jdbc/GenericJDBCConnectionDetailsImpl.java @@ -0,0 +1,26 @@ +package org.enso.database.jdbc; + +import org.enso.database.DatabaseConnectionDetailsSPI; + +@org.openide.util.lookup.ServiceProvider(service = DatabaseConnectionDetailsSPI.class) +public final class GenericJDBCConnectionDetailsImpl extends DatabaseConnectionDetailsSPI { + @Override + protected String getModuleName() { + return "Standard.Database.JDBC.Generic_JDBC_Connection"; + } + + @Override + protected String getTypeName() { + return "Generic_JDBC_Details"; + } + + @Override + protected String getCodeForDefaultConstructor() { + return "(Generic_JDBC_Details.Value)"; + } + + @Override + protected String getUserFacingConnectionName() { + return "JDBC"; + } +} diff --git a/test/Generic_JDBC_Tests/src/H2_Spec.enso b/test/Generic_JDBC_Tests/src/H2_Spec.enso index 018175ec822a..3591344ff502 100644 --- a/test/Generic_JDBC_Tests/src/H2_Spec.enso +++ b/test/Generic_JDBC_Tests/src/H2_Spec.enso @@ -3,8 +3,10 @@ from Standard.Base import all import Standard.Test.Spec_Result.Spec_Result from Standard.Test import all +import Standard.Database.Connection.Database import Standard.Database.Errors.SQL_Error import Standard.Database.JDBC.Generic_JDBC_Connection.Generic_JDBC_Connection +import Standard.Database.JDBC.Generic_JDBC_Connection.Generic_JDBC_Details import Standard.Database.SQL_Query.SQL_Query import project.Generic_JDBC_Connection_Spec @@ -59,6 +61,11 @@ add_specs suite_builder = lower x = x.to_case ..Lower + group_builder.specify "should be able to create a connection via Database.connect" <| + config.with_database url-> + conn = Database.connect (Generic_JDBC_Details.Value url) + conn.should_be_a Generic_JDBC_Connection + group_builder.specify "should be able to get table info" <| with_connection conn-> cleanup_tables conn ["foo", "bar"] <| conn.execute "create table foo (a int, b text)"