Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic path to create specific SqlConnectOptions #644

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

aguibert
Copy link
Member

@aguibert aguibert commented May 19, 2020

This improves the driver API so that a specific DB type can be requested using the generic SqlConnectOptions path. This is necessary for situations when A) user does not want a direct dependency on the driver API and B) there may be multiple different drivers on the classpath.

Example usages:

// Request DB2 options specifically by `Driver.KnownDrivers` enum
SqlConnectOptions a = Driver.createOptions(KnownDrivers.DB2);

// Request DB2 options specifically by string driver name
SqlConnectOptions a = Driver.createOptions("DB2");

// Request any available options. If != 1 drivers are found, an error is raised
SqlConnectOptions a = Driver.createOptions(KnownDrivers.ANY_DRIVER);

@vietj
Copy link
Member

vietj commented May 19, 2020

Rather name than kind

@aguibert
Copy link
Member Author

I think name is a bit too ambiguous -- I think people will confuse it with the DB name (.setDatabase(String databaseName)

I chose kind because that is also what Quarkus uses for this sort of setting: https://quarkus.io/guides/all-config#quarkus-datasource_quarkus.datasource.db-kind

Some other options to consider:

  • setDatabaseKind(String)
  • setDatabaseType(String)

@BillyYccc BillyYccc mentioned this pull request May 23, 2020
@vietj
Copy link
Member

vietj commented May 23, 2020

I believe the correct naming to use here is rdbms or dbms

@aguibert
Copy link
Member Author

So @vietj you are suggesting setRDBMS(String)? To me that doesn't imply that we are just setting the type name of the DB. Also, I'd like to keep longer acronyms out of the API.

What about setDatabaseDistributionName(String) or setDatabaseVendorName(String)?

@vietj
Copy link
Member

vietj commented May 26, 2020 via email

@aguibert
Copy link
Member Author

To me setDBMS still seems ambiguious. I would almost expect it to accept a composite object that represents the entire backend DB, not just the type of DB.

How about setDatabaseProtocol(String)?

@BillyYccc any opinion on this one? To recap, the options currently proposed are:

  • setKind(String)
  • setDatabaseKind(String)
  • setDatabaseType(String)
  • setDatabase(String)
  • setDBMS(String)
  • setRDBMS(String)
  • setDatabaseDistributionName(String)
  • setDatabaseProtocol(String)

@BillyYccc
Copy link
Member

How about simply driverName? The database client indeed does not care about what the database server is as long as they're able to communicate with each other via a specific protocol. For example you can use PG client to connect with Postgres or other databases like Cockroach.

@BillyYccc
Copy link
Member

DatabaseProtocol is not a good choice because not all DB protocols are named by the database name such as TDS protocol for MSSQL Server.

@vietj
Copy link
Member

vietj commented May 26, 2020 via email

@aguibert
Copy link
Member Author

aguibert commented May 26, 2020

Sure, I like setDriverName(String).

BTW, the reason I am trying to add this in the first place is so that a user can optionally specify the database type for situations where:

  1. Multiple drivers are on the classpath
  2. Generic properties config are used (i.e. host/port/user/etc)

We need a way to disambiguate which driver to select (without having a direct dependency on the driver-specific API)

@vietj
Copy link
Member

vietj commented May 26, 2020 via email

@vietj
Copy link
Member

vietj commented May 26, 2020 via email

@aguibert
Copy link
Member Author

Ok, sounds like we all agree on driverName 👍

As for where to specify it, SqlConnectOptions currently describe how to connect to the DB, but I don't think it would be much of a stretch to also include driverName in here, especially given that it's an optional setting.
Compared with the tradeoff of overloading Pool#pool, I think adding it to SqlConnectOptions is better, because if we add another overload combination we would go from 3 pool() methods to 6 pool() methods and I think it's confusing to users to have too many overload options.

@vietj
Copy link
Member

vietj commented May 27, 2020

@aguibert I agree for the overloading, another way would be to have a static method that creates SqlConnectOptions for a given name, i.e Pool.create(Driver.connectOptions("mysql").setPort(1234)....., poolOptions))

@vietj
Copy link
Member

vietj commented May 27, 2020

It seems that using plain SqlConnectOptions leads to this issue #660 .

In order to fix the driver name and the reported issue, we need to have SqlConnectOptions an abstract class as it used to be and introduce a static factory method in io.vertx.sqlclient.spi.Driver that will create the right subclass according to the driver name that is wanted.

This will solve this PR and the issue #660 issue.

@aguibert
Copy link
Member Author

If we add the static method for Driver.connectOptions("mysql"), does that imply we would want to turn SqlConnectOptions back into an abstract class then? Otherwise we're not solving the issue for all cases. However, this would be a breaking change that we couldn't make until 4.0.

I suppose we could add the new Driver.connectOptions now, and then turn SqlConnectOptions abstract in 4.0?

@vietj
Copy link
Member

vietj commented May 27, 2020 via email

@aguibert aguibert added the backport required This issue has not been backported yet but needs to be label May 27, 2020
Also deprecate generic construction of SqlConnectOptions
@aguibert
Copy link
Member Author

@vietj ok, I've reworked the PR based on your feedback. I removed the kind property from SqlConnectOptions and added a static Driver#createConnectOptions method. New usage looks like this:

SqlConnectOptions opts = Driver.createConnectOptions(KnownDrivers.DB2);
Pool pool = Pool.pool(opts);

@aguibert aguibert changed the title Add database kind property to SqlConnectOptions Generic path to create specific SqlConnectOptions May 29, 2020
@aguibert aguibert requested a review from vietj May 29, 2020 21:40
@@ -27,6 +35,71 @@
*/
public interface Driver {

public static enum KnownDrivers {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this creates an implicit dependency (yet weak) from sql-client onto the existing implementations. We are actually going to have a JDBC implementation as well that will not be in this GitHub repository, so I think it would be best better to avoid this and have instead each driver define a string constant for this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we add a JDBC implementation in a separate repo we can add another value to this enum, right?
Any other drivers that come along will still work, and will ultimately be able to define what they want their string constants to be.
Mainly I'm just going for user-convenience here by adding "knowledge of" the known implementations, I don't know if you could really call it a dependency

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there isn't much a point of having KnownDrivers enum than having a glorified factory, i.e

if you write

SqlConnectOptions options = Driver.createConnectOptions(Driver.KnownDrivers.POSTGRESQL)

then you can simply write

SqlConnectOptions options = new PgConnectOptions();

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was mainly looking at this from a UX perspective, but since this is just the SPI path (not API) UX is less important because users won't be doing this directly.
I'll go ahead and remove the KnownDrivers enum and associated code

@aguibert
Copy link
Member Author

aguibert commented Jun 4, 2020

Any further comments on this one @vietj or are we good to merge?

@@ -27,6 +33,44 @@
*/
public interface Driver {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add VertxGen annotation to make it work for ReactiveX/etc...

@@ -46,6 +47,7 @@
* @return the connection pool
* @throws ServiceConfigurationError if no compatible drivers are found, or if multiple compatible drivers are found
*/
@GenIgnore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we remove these @GenIgnore annotations ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build was failing saying these were not supported, I can go back and check again, but the whole generation step is an enigma to me

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you push the branch to the upstream repo so that we could try to build that and see what happens?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport required This issue has not been backported yet but needs to be
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants