-
Notifications
You must be signed in to change notification settings - Fork 1
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
Adds support to Postgres #44
Conversation
9558e5b
to
cb76924
Compare
cb76924
to
911a817
Compare
c7a3638
to
8bd78dc
Compare
ffd9512
to
ba83f79
Compare
Are we merging this at some point? @swampie @pditommaso @tcrespog |
It's okay for me (I approved it). Should we wait for @swampie and @pditommaso to check it? Please, Matteo & Paolo, let us know. |
while( itr.hasNext() ) { | ||
Path it = itr.next(); | ||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get(path))) { | ||
for (Path it : stream) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WHat's the value of this change? don't see related to the support for Postgress
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from clarity, it uses try with resources which automatically closes the stream after usage.
public static class Builder { | ||
private String driverName; | ||
private Driver driver; | ||
private String url; | ||
private String user; | ||
private String password; | ||
private String dialectName; | ||
private Dialect dialect; | ||
private String locations; | ||
private ClassLoader classLoader; | ||
private Pattern pattern; | ||
|
||
public Builder withDriver(String driverName) { | ||
this.driverName = driverName; | ||
return this; | ||
} | ||
|
||
public Builder withUrl(String url) { | ||
this.url = url; | ||
return this; | ||
} | ||
|
||
public Builder withUser(String user) { | ||
this.user = user; | ||
return this; | ||
} | ||
|
||
public Builder withPassword(String password) { | ||
this.password = password; | ||
return this; | ||
} | ||
|
||
public Builder withDialect(String dialectName) { | ||
this.dialectName = dialectName; | ||
return this; | ||
} | ||
|
||
public Builder withLocations(String locations) { | ||
this.locations = locations; | ||
return this; | ||
} | ||
|
||
public Builder withClassLoader(ClassLoader loader) { | ||
this.classLoader = loader; | ||
return this; | ||
} | ||
|
||
public Builder withPattern(String pattern) { | ||
if(pattern != null && !pattern.isEmpty()) | ||
this.pattern = Pattern.compile(pattern); | ||
return this; | ||
} | ||
|
||
public MigTool build() { | ||
this.driver = driverName != null ? Driver.fromDriverName(driverName) : Driver.fromUrl(url); | ||
this.dialect = dialectName != null ? Dialect.fromDialectName(dialectName) : Dialect.fromUrl(url); | ||
return new MigTool(this); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bit useless. It was avoid on purpose to not implement the builder pattern because it's just redundant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two main points for this change:
- As it is, although it looks like a builder pattern, it is not which is confusing.
- The app will fail to run if we do not set up the url first, since there are other fields that depend on it.
migtool/src/main/java/io/seqera/migtool/App.java
Lines 50 to 52 in c131b38
.withUrl(url) .withDialect(dialect!=null ? dialect : dialectFromUrl(url)) .withDriver(driver!=null ? driver : driverFromUrl(url))
It might "work" in this case since we receive the url as a parameter and configure it directly with those parameters, but to instantiate MigTool from another application without a cli (like the seqera compute manager service), this is just a source of potential issues and bugs (as it happened, hence the change).
* Since the other dialects supported allow the use of backticks, only two builders are added | ||
* {@link PostgresQueryBuilder} and {@link NotPostgresQueryBuilder}. | ||
**/ | ||
public abstract class DialectQueryBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found this solution overkill. It would be enough to have a driver pattern having a default implementation (a couple of methods) covering the current statement and the version for Postgres.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is a driver pattern? Could you provide an example of what you mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That kind of things that's simpler to implement, that to describe. If we want to adhere to GoF definition, it would be a template pattern, but also Jdbc driver using a similar approach, this is why I had used that term.
Compare this implementation with the one in this PR (I hadn't time to add tests)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered this approach, but I don't like it because the common SQL needs to be duplicated in both implementations. Meaning that if we need to change one of the queries in one place, we need to change it in both files (Default and Postgres).
In the end, we also needed to add 3 classes here, so I don't see what we gained using this approach. :)
And this is not a template pattern. As I explain here.
I am proposing a solution now that solves both issues: the one regarding being overkill (since we only have 2 implementations) and the one that implies having the sql string repeated in the subclasses.
Would this be acceptable in your opinion? I think it merges the best of both worlds @pditommaso .
import jakarta.annotation.Nullable; | ||
import java.util.List; | ||
|
||
public enum Dialect { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what value adds Dialect
and Driver
as enum. it would make more sense to implement a driver pattern that can both the type and the method specialisation for the statement specific for postgres. Likely it would require a Driver
interface, plus an abstract implementation for the common stuff, and concrete class for each support DB.
An alternative approach could be using a delegate pattern and passing the concrete class as "argument"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that any approach is better than having the names of the drivers/dialects hardcoded as strings, so I just typed them. An enum seemed simple enough for this purpose.
An alternative approach could be using a delegate pattern and passing the concrete class as "argument"
Why are we trying to find alternative approaches here? What is the issue with this one? There are multiple ways of solving the same thing, and as I said, this is already an improvement over what we had.
@pditommaso Could you review my comments please? |
Added jakarta annotations; added new constructor to be compatible with Java; changed the visibility of a method, to avoid the need of extending the base class just to use it
faf697f
to
9b14cd3
Compare
@@ -40,6 +40,16 @@ static Language from(String fileName) { | |||
boolean isPatch; | |||
boolean isOverride; | |||
|
|||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example this is missing @pditommaso , otherwise it won't work from Java...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this related to Postgres?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry Pedro, I'm closing in favour of #49. While I'm sure this work correctly, I believe is not a good PR because it conflates together many different things: support for Postres, support for Java, general refactoring, unnecessary complexity, changes the MigTool public API, etc. Why I think this is bad:
I don't want to be further pedantic, but I'b be happy to discuss more if needed. |
This point I can agree with. Some changes are unrelated to Postgres and were done just to make it easier to implement that change. I can split this in different PR's if this is the issue. Three PR's refactors with:
But this is by no means a radical refactor, this is just a cleanup.
I don't think hardcoded strings and methods that do 3 or 4 things at the same time, can be considered simplicity.
I think an enum to replace hardcoded Strings and encapsulate behaviours that right now exist on a static helper class, is not "for no reason" and removes complexity, does not increase it. 🤷🏻♂️
I don't think that I am the one missing this point here 👼🏻 The PR already has several approvals from other team members... Actually me and @tcrespog had discussed these improvements together, in a collaborative way...
I could give you all the reasons in the world that it would not have made a difference, so I don't think it is worth discussing more, you are right @pditommaso 🥲 |
Description
Adds support for
postgres
driver:Caveats
Backticks are a non-standard used by MySQL. Postgres does not support them by default.