-
Notifications
You must be signed in to change notification settings - Fork 122
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
feat: add support for Proto Columns DDL #2277
feat: add support for Proto Columns DDL #2277
Conversation
Warning: This pull request is touching the following templated files:
|
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClient.java
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClient.java
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/Database.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/Type.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java
Show resolved
Hide resolved
google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITProtoColumnTest.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITProtoColumnTest.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITProtoColumnTest.java
Show resolved
Hide resolved
google-cloud-spanner/src/test/java/com/google/cloud/spanner/it/ITProtoColumnTest.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java
Outdated
Show resolved
Hide resolved
@Override | ||
public Builder setProtoDescriptors(String filePath) throws IOException { | ||
Preconditions.checkState(filePath.length() != 0, "Input File Path cannot be empty."); | ||
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(filePath); |
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.
It looks like the method only support reading files from Project Resources
. If yes please clarify it in java doc.
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.
Added in java doc
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 Project Resources a good default?
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.
Yes. Having the resources with in the class path can help users provide a relative file path as input and Project resources directory is a good place to maintain all these files.
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.
While I understand the argument that having the proto descriptors in the resources directory of your project makes sense, I'm not sure that this will work as expected in all cases. This code does not live in the project of the end user, but in the client library. In an end user project, the client library will be one of many dependencies packaged as a jar. Will this always include the resources of directories of the end user project? What if that project uses multiple class loaders? I'm afraid that this could cause unexpected behavior.
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.
@olavloite
My understanding here is class loader can find a resource if it is there in the classpath and resources directory would always be a part of the classpath. I tried this with a small demo application and it works fine.
However, I am not aware of the behaviour if there are any custom/multiple class loaders. I would need some time to analyse the behaviour in this case.
In the interest of time, I am planning to remove this overload that accepts a file path as argument and take it separately in another PR.
Can you please let me know your views here?
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 removing this for now is a good choice. People can easily use resources from their class path using the overload that takes an InputStream
by calling getResourceAsStream()
themselves.
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.
Removed the overload changes.
google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/spi/v1/GapicSpannerRpc.java
Show resolved
Hide resolved
google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseTest.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java
Outdated
Show resolved
Hide resolved
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.
LGTM
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java
Outdated
Show resolved
Hide resolved
@Override | ||
public Builder setProtoDescriptors(String filePath) throws IOException { | ||
Preconditions.checkState(filePath.length() != 0, "Input File Path cannot be empty."); | ||
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(filePath); |
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 Project Resources a good default?
} | ||
|
||
@Override | ||
public Builder setProtoDescriptors(String filePath) throws IOException { |
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.
Do we have a precedence of reading file on user's behalf? What about other Google Cloud client libraries. Are we reading files in the recommended way in case there is one?
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.
User's can read the file on their end and pass in the byte[] or InputStream as input to the setProtoDescriptors
method. Alternatively, we also add another overloaded method that accepts the file path as input.
google-cloud-spanner/src/main/java/com/google/cloud/spanner/Database.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseAdminClient.java
Outdated
Show resolved
Hide resolved
* one. This must be unique within a database abd must be a valid identifier | ||
* [a-zA-Z][a-zA-Z0-9_]*. | ||
*/ | ||
public OperationFuture<Void, UpdateDatabaseDdlMetadata> updateDdl( |
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, I didn't notice this during the last review, but this seems a little strange. It is a method in the Database
class and takes a Database
instance as an argument. Why does it not just operate on this database?
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.
The reason it cannot operate on this database is because a user cannot set ProtoDescriptor
directly to Database Class as setProtoDescriptors
method belongs to Database.Builder
. Below is a small example to illustrate this,
Database database = client.getDatabase(INSTANCE_ID, DB_ID);
// If a user wants to update the ProtoDescriptor field then,
// the below line cannot be written as setProtoDescriptors method does not belong to Database class.
database.setProtoDescriptors("descriptors.pb");
// This does not update proto descriptor in the database because the field was not updated.
database.updateDdl(Collections.singletonList("DROP TABLE Singer"), null);
So a new Database instance has to be passed to update the ProtoDescriptor field. However, I agree that this is incorrect and confusing at same time.
Another Approach
@olavloite Please validate if below is more meaningful to do.
Expose a new method toBuilder()
in Database.java
that return a Builder of that Database
instance. This allows users to setProtoDescriptor
by calling the builder.
The change in Database.java
is
public class Database extends DatabaseInfo {
public Builder toBuilder() {
return new Builder(this);
}
public OperationFuture<Void, UpdateDatabaseDdlMetadata> updateDdl(
Iterable<String> statements, String operationId) throws SpannerException {
// The updateDatabaseDdl is called with 'this' as argument instead of instance(), database()
return dbClient.updateDatabaseDdl(this, statements, operationId);
}
}
The user can use it like below
Database database = client.getDatabase(INSTANCE_ID, DB_ID);
// The below database instance has the updated ProtoDescriptor field
database = database.toBuilder().setProtoDescriptors("descriptors.pb").build();
// Update works fine
database.updateDdl(Collections.singletonList("DROP TABLE Singer"), null);
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.
Hmmm.... If the protoDescriptors
field is not something that is actually part of the Database
class and thereby also not stored with the database, and is only needed for the update method, then we need to add it as an argument to the method afte rall. Other approaches would be non-idiomatic Java.
So the signature of the method would then become Database#updateDatabaseDdl(Iterable<String> statements, String protoDescriptors, String operationId)
. Another option would be to create a DatabaseUpdateOptions
class that contains all possible update options, the first one being protoDescriptors
(that would make it more easily reusable for additional options in the future).
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 agree with you @olavloite. Creating a new DatabaseUpdateOptions
class that can update options will help us reuse in future. I will take this effort as part of the next PR. I will tag this comment in the other PR later to understand the need of that change.
@Override | ||
public Builder setProtoDescriptors(String filePath) throws IOException { | ||
Preconditions.checkState(filePath.length() != 0, "Input File Path cannot be empty."); | ||
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(filePath); |
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.
While I understand the argument that having the proto descriptors in the resources directory of your project makes sense, I'm not sure that this will work as expected in all cases. This code does not live in the project of the end user, but in the client library. In an end user project, the client library will be one of many dependencies packaged as a jar. Will this always include the resources of directories of the end user project? What if that project uses multiple class loaders? I'm afraid that this could cause unexpected behavior.
…th as input to avoid unexpected issues
* feat: Support for Proto Messages & Enums (#2155) * feat: Importing Proto Changes Commit will be reverted, once PROTO changes are available publicly. * feat: Proto Message Implementation * feat: Adding support for enum * feat: Code refactoring Adding default implementation for newly added methods ByteArray compatability changes for Proto Messages * docs: Adding Java docs for all the newly added methods. * test: Sample Proto & Generated classes for unit test * feat: Adding bytes/proto & int64/enum compatability Adding Additional check for ChecksumResultSet * test: Adding unit tests * test: Adding unit tests for ValueBinder.java * feat: refactoring to add support for getValue & other minor changes * feat: Minor refactoring 1. Adding docs and formatting the code. 2. Adding additional methods for enum and message which accepts descriptors. * feat: Adding bytes/message & int64/enum compatability in Value * refactor: Minor refactoring * feat: Adding Proto Array Implementation * test: Implementing unit tests for array of protos and enums * refactor: adding clirr ignores * feat: Adding support for enum as Primary Key * feat: Code Review Changes, minor refactoring and adding docs * feat: Addressing review comments -Modified Docs/Comments -Minor Refactoring * refactor: Using Column instead of column to avoid test failures * feat: Minor refactoring -code review comments -adding function docs * samples: Adding samples for updating & querying Proto messages & enums (#2211) * samples: Adding samples for updating & querying Proto messages & enums * style: linting * style: linting * docs: Adding function and class doc * test: Proto Column Integration tests (#2212) * test: Adding Integration tests for Proto Messages & Enums * test: Adding additional test for Parameterized Queries, Primary Keys & Invalid Wire type errors. * style: Formatting * style: Formatting * test: Updating instance and db name * test: Adding inter compatability check while writing data * Configured jitpack.yml to use OpenJDK 11 (#2218) Co-authored-by: Pavol Juhos <[email protected]> * feat: add support for Proto Columns DDL (#2277) * feat: add code changes and tests for Proto columns DDL support * feat: add auto generated code * feat: code changes and tests for Proto columns DDL support * feat: add descriptors file * feat: code refactoring * feat: Integration tests and code refactoring * feat: code refactoring * feat: unit tests and clirr differences * feat: lint changes * feat: code refactor * feat: code refactoring * feat: code refactoring * feat: code refactoring * feat: add java docs to new methods * feat: lint formatting * feat: lint formatting changes * feat: lint formatting * feat: lint formatting * feat: test exception cases * feat: code refactoring * feat: add java docs and refactoring * feat: add java docs * feat: java docs refactor * feat: remove overload method setProtoDescriptors that accepts file path as input to avoid unexpected issues * feat: remove updateDdl method overload to update proto descriptor * teat: update pom file to run tests on cloud-devel region temporarily to validate main branch update * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * fix: revert host changes in pom.xml file * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat(spanner): revert autogenerated code * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat(spanner): remove samples * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat(spanner): remove clirr * feat(spanner): skip emulator test * feat(spanner): clirr * feat(spanner): fix javadoc * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat(spanner): fix javadoc * feat(spanner): fix javadoc * feat(spanner): fix javadoc * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat(spanner): fix emulator skip * build: ignore all changes in v1 package * feat(spanner): add optimizations to deserialize proto messages * feat(spanner): remove TODO * feat(spanner): remove TODO --------- Co-authored-by: Gaurav Purohit <[email protected]> Co-authored-by: Pavol Juhos <[email protected]> Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> Co-authored-by: Knut Olav Løite <[email protected]>
* feat: Support for Proto Messages & Enums (#2155) * feat: Importing Proto Changes Commit will be reverted, once PROTO changes are available publicly. * feat: Proto Message Implementation * feat: Adding support for enum * feat: Code refactoring Adding default implementation for newly added methods ByteArray compatability changes for Proto Messages * docs: Adding Java docs for all the newly added methods. * test: Sample Proto & Generated classes for unit test * feat: Adding bytes/proto & int64/enum compatability Adding Additional check for ChecksumResultSet * test: Adding unit tests * test: Adding unit tests for ValueBinder.java * feat: refactoring to add support for getValue & other minor changes * feat: Minor refactoring 1. Adding docs and formatting the code. 2. Adding additional methods for enum and message which accepts descriptors. * feat: Adding bytes/message & int64/enum compatability in Value * refactor: Minor refactoring * feat: Adding Proto Array Implementation * test: Implementing unit tests for array of protos and enums * refactor: adding clirr ignores * feat: Adding support for enum as Primary Key * feat: Code Review Changes, minor refactoring and adding docs * feat: Addressing review comments -Modified Docs/Comments -Minor Refactoring * refactor: Using Column instead of column to avoid test failures * feat: Minor refactoring -code review comments -adding function docs * samples: Adding samples for updating & querying Proto messages & enums (#2211) * samples: Adding samples for updating & querying Proto messages & enums * style: linting * style: linting * docs: Adding function and class doc * test: Proto Column Integration tests (#2212) * test: Adding Integration tests for Proto Messages & Enums * test: Adding additional test for Parameterized Queries, Primary Keys & Invalid Wire type errors. * style: Formatting * style: Formatting * test: Updating instance and db name * test: Adding inter compatability check while writing data * Configured jitpack.yml to use OpenJDK 11 (#2218) Co-authored-by: Pavol Juhos <[email protected]> * feat: add support for Proto Columns DDL (#2277) * feat: add code changes and tests for Proto columns DDL support * feat: add auto generated code * feat: code changes and tests for Proto columns DDL support * feat: add descriptors file * feat: code refactoring * feat: Integration tests and code refactoring * feat: code refactoring * feat: unit tests and clirr differences * feat: lint changes * feat: code refactor * feat: code refactoring * feat: code refactoring * feat: code refactoring * feat: add java docs to new methods * feat: lint formatting * feat: lint formatting changes * feat: lint formatting * feat: lint formatting * feat: test exception cases * feat: code refactoring * feat: add java docs and refactoring * feat: add java docs * feat: java docs refactor * feat: remove overload method setProtoDescriptors that accepts file path as input to avoid unexpected issues * feat: remove updateDdl method overload to update proto descriptor * teat: update pom file to run tests on cloud-devel region temporarily to validate main branch update * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * fix: revert host changes in pom.xml file * feat: add support for Proto Columns to Connection API * feat: add client side statement support for proto descriptor * feat: update existing unit tests to include proto descriptorss argument * feat: code refactor for client side statements * feat: add unit tests * feat: code refactoring for file path client statement * test: add integration test for DDL * fix: comment refactoring * feat: move proto descriptor file read logic to ConnectionImpl file to fix autogenerated client side statement tests * feat: add autogenerated test for new proto columns client side statements * feat: add unit tests to verify proto descriptor set via filepath * feat: add review comments * feat: add client side statement to show proto descriptors file path * fix: remove proto descriptors file extension validation * feat: comment refactor * feat: address review comments * feat: update tests and revert autogenerated code * chore: revert autogenerated coee * chore: revert autogenerated code * chore: revert autogenerated code * chore: lint format * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: regenerate descriptors file * chore: update schema * chore: update base64 value for protodescriptor * chore: update copyright year --------- Co-authored-by: Gaurav Purohit <[email protected]> Co-authored-by: Pavol Juhos <[email protected]> Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
This PR adds feature support for Proto Columns DDL with supporting integration tests.