-
Notifications
You must be signed in to change notification settings - Fork 453
Fix set/getSchema for DataSources - The Driver ignores the setSchema … #890
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
Conversation
|
Example of Spring Boot DataSource Properties extracted from https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html spring.datasource.driver-class-name= # Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
spring.datasource.password= # Login password of the database.
spring.datasource.schema= # Schema (DDL) script resource references.
spring.datasource.url= # JDBC URL of the database.
spring.datasource.username= # Login username of the database.The driver returns "SELECT SCHEMA_NAME()" and not the value of spring.datasource.schema. |
Codecov Report
@@ Coverage Diff @@
## dev #890 +/- ##
============================================
+ Coverage 48.58% 48.95% +0.36%
- Complexity 2803 2832 +29
============================================
Files 118 118
Lines 27868 27873 +5
Branches 4640 4641 +1
============================================
+ Hits 13541 13644 +103
+ Misses 12131 12118 -13
+ Partials 2196 2111 -85
Continue to review full report at Codecov.
|
|
About the continuous-integration/appveyor/pr — AppVeyor build failed, the log says: I executed the TVPAllTypesTest again successfully, I think it's something about the server environment. How can we execute the continuous-integration/appveyor/pr — AppVeyor again? |
|
@jardelnovaes Thanks for your contribution. I've restarted Appveyor build for you. We are aware of the failure and have recently fixed that random issue. Apologies for any inconvenience. |
|
thank you @cheenamalhotra! |
|
I took a quick glance to the PR, and looks like setting/getting Schema here is only applicable to client side. The server schema could be something else, and the |
|
This is exactly what the Driver should do, I'll explain: PS: You can read the summary at the end or this detailed explanation. Explanation: It's not how the SQL Server works, SQL Server has database (or catalog), owner (or schema) (we can talk about linked server and so on, but I'll simplify) Oracle has the command Sql Server has just the option to permanently change the user default (e.g. If we did it all connection at that server will use that schema and not just that session/client connection, that is what this functionality set/get Schema provides (change just the session/connection). When we have a different schema (not the user default) providers like Hibernate will produces queries with this format When we'd like to use the user default schema we don't need to set the schema property in the connection. If the schema name is wrong or the user doesn't have permissions SQL Server will provide a message like There's no problem to return Summary: |
|
Thanks for explanation! Yes I agree SQL Server has no such functionality for schemas and I do understand how this API But if we try to make this API work just for client interaction purpose, I'm now sure how is this useful as it would also cause JDBC Specifications: |
|
@cheenamalhotra, ufortunately I have to disagree with you in many of your comments, let's go! is functional for other databases as you explained above too. if underlying database cannot support it. it would also cause getSchema() to never return current schema in use by connection (based on logged in user), unless user sets it back to Null not respect JDBC Specifications "Retrieves this Connection object's current schema name." not the one set with setSchema()." //C# example
public class Connection {
private String schema;
public Schema { //get and set are inside the property Schema;
get {
return yourLogic();
}
set {
youtOtherLogic();
schema = value;
}
}
public void test() {
Connection connection = new Connection();
connection.Schema = "mySchema";
Console.WriteLine(connection.Schema);
}
}//Java example
public class Connection {
private String schema;
// here C# is better because keep get and set are inside the property Schema, Java doesn't
public getSchema(){
return yourLogic();
}
public void setSchema(final String value) {
youtOtherLogic();
schema = value;
}
public void test() {
Connection connection = new Connection();
connection.setSchema("mySchema");
System.out.println(connection.getSchema());
}
}EntityFramework has already the schema support! modelBuilder.HasDefaultSchema("MyDefaultDbSchema");Summary: |
|
The EntityFramework6 works with the same idea of my PR. I did know about that when I've code, but it shows that the concept I applied is not wrong. It'll set the schema of Why using .NET the driver should works as expected and using Java shouldn't?
// <summary>
// Gets or sets the default schema name.
// </summary>
public string DefaultSchema { get; set; }
[...]
private void ConfigureDefaultSchema(DbDatabaseMapping databaseMapping)
{
DebugCheck.NotNull(databaseMapping);
databaseMapping.Database.GetEntitySets()
.Where(es => string.IsNullOrWhiteSpace(es.Schema))
.Each(es => es.Schema = DefaultSchema ?? EdmModelExtensions.DefaultSchema);
databaseMapping.Database.Functions
.Where(f => string.IsNullOrWhiteSpace(f.Schema))
.Each(f => f.Schema = DefaultSchema ?? EdmModelExtensions.DefaultSchema);
} |
|
EntityFramework is an extension to ADO.NET (Microsoft.Data.SqlClient) Driver, and not the ADO.NET driver itself. By taking quick glance through, it clearly doesn't look like setting I understand what setters and getters are meant to do, and what I meant was as per JDBC Specs, And as we cannot modify SQL Server's schema in use by the connection, it is controlled by caller (logged in user), |
|
About your comment: And couldn't be. Different from JDBC the .NET SqlConnection has a readonly property called There're the same word for two differents proposals. As you checked the JDBC concept of SQL Server does not support setting Schema on active connection. The EntityFramework (after its 6th version) provides a solution for the schema support problem wich is similar to my contribution. The EF6 solution will provide the use of I agree that the best support is a server command to change de current schema (not the default schema), but unfortunately we don't have this option and a solution like the EF6+ it's better than nothing. Other day I was wondering: Why does community still relies on SQL Server drivers different and not on the
Along this This contribution is a private contribution and I don't like to expose my company name, but this company has many products, has bussiness with Microsoft to develop solutions together, has about 700 employees in 5 countries and are one of the companies that stil relies on other JBDC Drivers. And I thought, how to change it, We should relies more on Microsoft (that is the SQL Server vendor) than relies on other ones. So I saw a performance decrease in the PR #883 that was reverted by the PR #891 after my contributions, nice feeling I started helping to improve the I've been noticed some codes to So I decide to provide a solution for this issue, that fortunately I discovered that is similar to the EF6+ solution, and I openned the PR #890. I disagree with you I sure that there're no reason to not provide this support, on the other hand I can understand you position and I repect it. I'm not the owner of the driver and I'm not have power to decide anything about it, I'm just a contributor that has a dream to make the driver more reliable every day. |
|
Hi @jardelnovaes, Thanks for your contribution. However, I don't think we will merge this PR because this is an incorrect behavioral change. With your changes, if the user (with default schema I think you're putting a lot of emphasis on getSchema and setSchema having to both be functional since we provide implementations for them, but this is just to satisfy the JDBC API requirements - we could be getting rid of setSchema if we weren't required to have it since it's not doing anything right now. However, this shouldn't force the driver into implementing a wrong behavioral change. |
|
Have you ever get this code and tried it? The dbo that you mentioned it's the user default schema and not the current schema (dbo2) in this case. This solution was already tested and worked fine with Spring Boot and other solution that uses DataSource concept. I've already said to not confuse the .Net getSchema (information_schema data, not just the schema name). It's possible to provide this solution, it's similar to EF6+ solution. Finally I've already said that the decision is yours. You can not merge it 'cause you don't want to or 'cause you think differently from EF team and will wait a solution from SQL Server team. But you absolutely cannot say that is a wrong behavior (at least if you know well about jdbc and schema) |
|
Hi @jardelnovaes, Yes, I have tested your code. I don't know how you tested your code, but my previous statement of: still stands. Executing a query off of a statement object doesn't need to execute getSchema - therefore, creating and setting a private variable aside that only gets used when getSchema is called won't be used to execute queries. Are you calling setSchema and then calling getSchema, and then injecting the output from getSchema directly in your query to the server? In this case, you just stored a local string (the string for schema) inside the Connection object. This shouldn't be necessary since you don't need to use a Connection object to set a local variable for yourself. |
|
What ORM did you use in your test? What situation does this PR create a bug or problem? What test failed? No, I don't use the getSchema to create the query 'cause I don't want to recreate the wheels! Who do this are the ORM's providers like Hibernate. Using DataSource with Spring Data for example. Now a days we don't loose time doing thinks that someone already did. We create the queries manually in strict cases not for all application. I won't ask for hibernate team to change it 'cause it already works for Oracle, PostgreSQL and others. You can reject this PR if you don't want it. But you should understand how it will work,it seems you aren't. |
|
Sorry I don't want to loose more time in this discussion. |
|
Hi @jardelnovaes, If you wanted to use a different schema, you need to create a connection with the user that has access to the schema in SQL Server, instead of using setSchema. I hope this clarifies your question. We value your contribution, and please let us know if you have any other suggestions for our driver in the future. |
|
In this case (use the user default schema) nobody needs the schema property, but how do I access a not default schema that the user has access but is not his default schema? Already it seems you aren't understand about the subject. Using EF I have a solution for this situation, but not for this JDBC Driver. As well for Oracle, PostgreSQL. By the way I already closed this PR, I won't loose more time with this. |
|
Apologies for inconvenience. We do understand the issue with ORM Frameworks when it comes to binding configurations with driver APIs. But we have to also consider abiding by JDBC specifications in comparison to other drivers, that can change default schema using Thus, we cannot add this change and also stay compliant to JDBC Specs, in comparison with other JDBC drivers. I hope you understand where we are coming from. On the contrary, we are Open Source driver, and you are free to keep this change in your branch and build driver for your application purpose. You may choose to update your branch when any features are added in our From our side, we are trying to approach SQL Server team to raise this concern of missing feature as not only you, there would be other customers in need for this support, and we understand that. It's just that we cannot add a temporary patch that may be workable for one customer, but may cause issues for other users due to lack of validation and server interaction in these APIs. |
Fix set/getSchema for DataSources - The Driver ignores the setSchema method.
Hello!
I noticed that the Driver doesn't use the schema defined when I'm using DataSource. The getSchema method just execute an
and ignores the values passed in the setSchema method, it´s not compliance with the get/set schema idea of DataSource.
I'm was using a Spring Boot Application and setting multiples datasources in the application.yml file. In this case the user has provileges in the schema, but I can't set the default schema in the Sql Server.
My idea is, if I set the schema programmatically (e.g. application.yml) the Driver should use the value passed in the setSchema. If schema is null then the Driver can use the "SELECT SCHEMA_NAME()"
Usually a DataSource has the follow properties: url, driver-class-name, username and password. Sometime it has the schema property as well.