From 4d41b11ed4f6378fca83cb6d77ceba732f9ac373 Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Tue, 14 Feb 2017 09:41:59 -0800 Subject: [PATCH] Add Spanner (#256) --- gapic/api/artman_spanner.yaml | 31 ++ gapic/api/artman_spanner_admin_database.yaml | 32 ++ gapic/api/artman_spanner_admin_instance.yaml | 32 ++ .../database/spanner_admin_database.yaml | 39 ++ .../v1/spanner_admin_database_gapic.yaml | 182 +++++++ .../database/v1/spanner_database_admin.proto | 277 +++++++++++ .../instance/spanner_admin_instance.yaml | 39 ++ .../v1/spanner_admin_instance_gapic.yaml | 206 ++++++++ .../instance/v1/spanner_instance_admin.proto | 446 ++++++++++++++++++ google/spanner/spanner.yaml | 56 +++ google/spanner/v1/keys.proto | 162 +++++++ google/spanner/v1/mutation.proto | 92 ++++ google/spanner/v1/query_plan.proto | 128 +++++ google/spanner/v1/result_set.proto | 186 ++++++++ google/spanner/v1/spanner.proto | 348 ++++++++++++++ google/spanner/v1/spanner_gapic.yaml | 177 +++++++ google/spanner/v1/transaction.proto | 373 +++++++++++++++ google/spanner/v1/type.proto | 111 +++++ 18 files changed, 2917 insertions(+) create mode 100644 gapic/api/artman_spanner.yaml create mode 100644 gapic/api/artman_spanner_admin_database.yaml create mode 100644 gapic/api/artman_spanner_admin_instance.yaml create mode 100644 google/spanner/admin/database/spanner_admin_database.yaml create mode 100644 google/spanner/admin/database/v1/spanner_admin_database_gapic.yaml create mode 100644 google/spanner/admin/database/v1/spanner_database_admin.proto create mode 100644 google/spanner/admin/instance/spanner_admin_instance.yaml create mode 100644 google/spanner/admin/instance/v1/spanner_admin_instance_gapic.yaml create mode 100644 google/spanner/admin/instance/v1/spanner_instance_admin.proto create mode 100644 google/spanner/spanner.yaml create mode 100644 google/spanner/v1/keys.proto create mode 100644 google/spanner/v1/mutation.proto create mode 100644 google/spanner/v1/query_plan.proto create mode 100644 google/spanner/v1/result_set.proto create mode 100644 google/spanner/v1/spanner.proto create mode 100644 google/spanner/v1/spanner_gapic.yaml create mode 100644 google/spanner/v1/transaction.proto create mode 100644 google/spanner/v1/type.proto diff --git a/gapic/api/artman_spanner.yaml b/gapic/api/artman_spanner.yaml new file mode 100644 index 00000000..2d8b7e7c --- /dev/null +++ b/gapic/api/artman_spanner.yaml @@ -0,0 +1,31 @@ +common: + api_name: spanner + api_version: v1 + organization_name: google-cloud + proto_deps: + - google-common-protos + import_proto_path: + - ${REPOROOT}/googleapis + src_proto_path: + - ${REPOROOT}/googleapis/google/spanner/v1 + service_yaml: + - ${REPOROOT}/googleapis/google/spanner/spanner.yaml + gapic_api_yaml: + - ${REPOROOT}/googleapis/google/spanner/v1/spanner_gapic.yaml + output_dir: ${REPOROOT}/artman/output +java: + final_repo_dir: ${REPOROOT}/google-cloud-java/google-cloud-spanner +python: + final_repo_dir: ${REPOROOT}/artman/output/gcloud-python-spanner +go: + final_repo_dir: ${REPOROOT}/gapi-spanner-go +csharp: + final_repo_dir: ${REPOROOT}/artman/output/gcloud-csharp-spanner +php: + final_repo_dir: ${REPOROOT}/artman/output/gcloud-php-spanner +ruby: + final_repo_dir: ${REPOROOT}/google-cloud-ruby/google-cloud-spanner + skip_packman: True +nodejs: + final_repo_dir: ${REPOROOT}/google-cloud-node/packages/spanner + skip_packman: True diff --git a/gapic/api/artman_spanner_admin_database.yaml b/gapic/api/artman_spanner_admin_database.yaml new file mode 100644 index 00000000..6acf933f --- /dev/null +++ b/gapic/api/artman_spanner_admin_database.yaml @@ -0,0 +1,32 @@ +common: + api_name: spanner-admin-database + api_version: v1 + organization_name: google-cloud + proto_deps: + - google-common-protos + - google-iam-v1 + import_proto_path: + - ${REPOROOT}/googleapis + src_proto_path: + - ${REPOROOT}/googleapis/google/spanner/admin/database/v1 + service_yaml: + - ${REPOROOT}/googleapis/google/spanner/admin/database/spanner_admin_database.yaml + gapic_api_yaml: + - ${REPOROOT}/googleapis/google/spanner/admin/database/v1/spanner_admin_database_gapic.yaml + output_dir: ${REPOROOT}/artman/output +java: + final_repo_dir: ${REPOROOT}/google-cloud-java/google-cloud-spanner-admin-database +python: + final_repo_dir: ${REPOROOT}/artman/output/gcloud-python-spanner-admin-database +go: + final_repo_dir: ${REPOROOT}/gapi-spanner-admin-database-go +csharp: + final_repo_dir: ${REPOROOT}/artman/output/gcloud-csharp-spanner-admin-database +php: + final_repo_dir: ${REPOROOT}/artman/output/gcloud-php-spanner-admin-database +ruby: + final_repo_dir: ${REPOROOT}/google-cloud-ruby/google-cloud-spanner-admin-database + skip_packman: True +nodejs: + final_repo_dir: ${REPOROOT}/google-cloud-node/packages/spanner-admin-database + skip_packman: True diff --git a/gapic/api/artman_spanner_admin_instance.yaml b/gapic/api/artman_spanner_admin_instance.yaml new file mode 100644 index 00000000..17637738 --- /dev/null +++ b/gapic/api/artman_spanner_admin_instance.yaml @@ -0,0 +1,32 @@ +common: + api_name: spanner-admin-instance + api_version: v1 + organization_name: google-cloud + proto_deps: + - google-common-protos + - google-iam-v1 + import_proto_path: + - ${REPOROOT}/googleapis + src_proto_path: + - ${REPOROOT}/googleapis/google/spanner/admin/instance/v1 + service_yaml: + - ${REPOROOT}/googleapis/google/spanner/admin/instance/spanner_admin_instance.yaml + gapic_api_yaml: + - ${REPOROOT}/googleapis/google/spanner/admin/instance/v1/spanner_admin_instance_gapic.yaml + output_dir: ${REPOROOT}/artman/output +java: + final_repo_dir: ${REPOROOT}/google-cloud-java/google-cloud-spanner-admin-instance +python: + final_repo_dir: ${REPOROOT}/artman/output/gcloud-python-spanner-admin-instance +go: + final_repo_dir: ${REPOROOT}/gapi-spanner-admin-instance-go +csharp: + final_repo_dir: ${REPOROOT}/artman/output/gcloud-csharp-spanner-admin-instance +php: + final_repo_dir: ${REPOROOT}/artman/output/gcloud-php-spanner-admin-instance +ruby: + final_repo_dir: ${REPOROOT}/google-cloud-ruby/google-cloud-spanner-admin-instance + skip_packman: True +nodejs: + final_repo_dir: ${REPOROOT}/google-cloud-node/packages/spanner-admin-instance + skip_packman: True diff --git a/google/spanner/admin/database/spanner_admin_database.yaml b/google/spanner/admin/database/spanner_admin_database.yaml new file mode 100644 index 00000000..cecf32a3 --- /dev/null +++ b/google/spanner/admin/database/spanner_admin_database.yaml @@ -0,0 +1,39 @@ +type: google.api.Service +config_version: 3 +name: spanner.googleapis.com +title: Cloud Spanner Database Admin API + +apis: + - name: google.spanner.admin.database.v1.DatabaseAdmin + mixins: + - name: google.iam.v1.IAMPolicy + +types: + - name: google.spanner.admin.database.v1.CreateDatabaseMetadata + - name: google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata + +authentication: + rules: + - selector: google.spanner.admin.database.v1.Spanner.* + oauth: + canonical_scopes: https://www.googleapis.com/auth/spanner.admin, + https://www.googleapis.com/auth/cloud-platform + +http: + rules: + - selector: google.longrunning.Operations.GetOperation + get: '/v1/{name=projects/*/instances/*/databases/*/operations/*}' + additional_bindings: + - get: '/v1/{name=projects/*/instances/*/operations/*}' + - selector: google.longrunning.Operations.ListOperations + get: '/v1/{name=projects/*/instances/*/databases/*/operations}' + additional_bindings: + - get: '/v1/{name=projects/*/instances/*/operations}' + - selector: google.longrunning.Operations.CancelOperation + post: '/v1/{name=projects/*/instances/*/databases/*/operations/*}:cancel' + additional_bindings: + - post: '/v1/{name=projects/*/instances/*/operations/*}:cancel' + - selector: google.longrunning.Operations.DeleteOperation + delete: '/v1/{name=projects/*/instances/*/databases/*/operations/*}' + additional_bindings: + - delete: '/v1/{name=projects/*/instances/*/operations/*}' diff --git a/google/spanner/admin/database/v1/spanner_admin_database_gapic.yaml b/google/spanner/admin/database/v1/spanner_admin_database_gapic.yaml new file mode 100644 index 00000000..36ee80dc --- /dev/null +++ b/google/spanner/admin/database/v1/spanner_admin_database_gapic.yaml @@ -0,0 +1,182 @@ +type: com.google.api.codegen.ConfigProto +language_settings: + java: + package_name: com.google.cloud.spanner.admin.database.spi.v1 + python: + package_name: google.cloud.gapic.spanner_admin_database.v1 + go: + package_name: cloud.google.com/go/spanner/admin/database/apiv1 + csharp: + package_name: Google.Cloud.Spanner.Admin.Database.V1 + ruby: + package_name: Google::Cloud::Spanner::Admin::Database::V1 + php: + package_name: Google\Cloud\Spanner\Admin\Database\V1 + nodejs: + package_name: spanner-admin-database.v1 + domain_layer_location: google-cloud +license_header: + copyright_file: copyright-google.txt + license_file: license-header-apache-2.0.txt +interfaces: +- name: google.spanner.admin.database.v1.DatabaseAdmin + collections: + - name_pattern: projects/{project}/instances/{instance} + entity_name: instance + - name_pattern: projects/{project}/instances/{instance}/databases/{database} + entity_name: database + retry_codes_def: + - name: idempotent + retry_codes: + - UNAVAILABLE + - DEADLINE_EXCEEDED + - name: non_idempotent + retry_codes: [] + retry_params_def: + - name: default + initial_retry_delay_millis: 1000 + retry_delay_multiplier: 1.3 + max_retry_delay_millis: 32000 + initial_rpc_timeout_millis: 60000 + rpc_timeout_multiplier: 1 + max_rpc_timeout_millis: 60000 + total_timeout_millis: 600000 + methods: + - name: ListDatabases + flattening: + groups: + - parameters: + - parent + required_fields: + - parent + request_object_method: false + page_streaming: + request: + page_size_field: page_size + token_field: page_token + response: + token_field: next_page_token + resources_field: databases + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + parent: instance + timeout_millis: 30000 + - name: CreateDatabase + flattening: + groups: + - parameters: + - parent + - create_statement + required_fields: + - parent + - create_statement + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + parent: instance + timeout_millis: 30000 + long_running: + return_type: google.spanner.admin.database.v1.Database + metadata_type: google.spanner.admin.database.v1.CreateDatabaseMetadata + - name: GetDatabase + flattening: + groups: + - parameters: + - name + required_fields: + - name + request_object_method: false + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + name: database + timeout_millis: 30000 + - name: UpdateDatabaseDdl + flattening: + groups: + - parameters: + - database + - statements + required_fields: + - database + - statements + request_object_method: true + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + database: database + timeout_millis: 30000 + long_running: + return_type: google.protobuf.Empty + metadata_type: google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata + - name: DropDatabase + flattening: + groups: + - parameters: + - database + required_fields: + - database + request_object_method: false + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + database: database + timeout_millis: 30000 + - name: GetDatabaseDdl + flattening: + groups: + - parameters: + - database + required_fields: + - database + request_object_method: false + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + database: database + timeout_millis: 30000 + - name: SetIamPolicy + flattening: + groups: + - parameters: + - resource + - policy + required_fields: + - resource + - policy + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + resource: database + timeout_millis: 30000 + - name: GetIamPolicy + flattening: + groups: + - parameters: + - resource + required_fields: + - resource + request_object_method: false + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + resource: database + timeout_millis: 30000 + - name: TestIamPermissions + flattening: + groups: + - parameters: + - resource + - permissions + required_fields: + - resource + - permissions + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + resource: database + timeout_millis: 30000 diff --git a/google/spanner/admin/database/v1/spanner_database_admin.proto b/google/spanner/admin/database/v1/spanner_database_admin.proto new file mode 100644 index 00000000..a5300716 --- /dev/null +++ b/google/spanner/admin/database/v1/spanner_database_admin.proto @@ -0,0 +1,277 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.spanner.admin.database.v1; + +import "google/api/annotations.proto"; +import "google/api/auth.proto"; +import "google/iam/v1/iam_policy.proto"; +import "google/iam/v1/policy.proto"; +import "google/longrunning/operations.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; + +option csharp_namespace = "Google.Cloud.Spanner.Admin.Database.V1"; +option go_package = "google.golang.org/genproto/googleapis/spanner/admin/database/v1;database"; +option java_multiple_files = true; +option java_outer_classname = "SpannerDatabaseAdminProto"; +option java_package = "com.google.spanner.admin.database.v1"; + + +// Cloud Spanner Database Admin API +// +// The Cloud Spanner Database Admin API can be used to create, drop, and +// list databases. It also enables updating the schema of pre-existing +// databases. +service DatabaseAdmin { + // Lists Cloud Spanner databases. + rpc ListDatabases(ListDatabasesRequest) returns (ListDatabasesResponse) { + option (google.api.http) = { get: "/v1/{parent=projects/*/instances/*}/databases" }; + } + + // Creates a new Cloud Spanner database and starts to prepare it for serving. + // The returned [long-running operation][google.longrunning.Operation] will + // have a name of the format `/operations/` and + // can be used to track preparation of the database. The + // [metadata][google.longrunning.Operation.metadata] field type is + // [CreateDatabaseMetadata][google.spanner.admin.database.v1.CreateDatabaseMetadata]. The + // [response][google.longrunning.Operation.response] field type is + // [Database][google.spanner.admin.database.v1.Database], if successful. + rpc CreateDatabase(CreateDatabaseRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { post: "/v1/{parent=projects/*/instances/*}/databases" body: "*" }; + } + + // Gets the state of a Cloud Spanner database. + rpc GetDatabase(GetDatabaseRequest) returns (Database) { + option (google.api.http) = { get: "/v1/{name=projects/*/instances/*/databases/*}" }; + } + + // Updates the schema of a Cloud Spanner database by + // creating/altering/dropping tables, columns, indexes, etc. The returned + // [long-running operation][google.longrunning.Operation] will have a name of + // the format `/operations/` and can be used to + // track execution of the schema change(s). The + // [metadata][google.longrunning.Operation.metadata] field type is + // [UpdateDatabaseDdlMetadata][google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata]. The operation has no response. + rpc UpdateDatabaseDdl(UpdateDatabaseDdlRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { patch: "/v1/{database=projects/*/instances/*/databases/*}/ddl" body: "*" }; + } + + // Drops (aka deletes) a Cloud Spanner database. + rpc DropDatabase(DropDatabaseRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { delete: "/v1/{database=projects/*/instances/*/databases/*}" }; + } + + // Returns the schema of a Cloud Spanner database as a list of formatted + // DDL statements. This method does not show pending schema updates, those may + // be queried using the [Operations][google.longrunning.Operations] API. + rpc GetDatabaseDdl(GetDatabaseDdlRequest) returns (GetDatabaseDdlResponse) { + option (google.api.http) = { get: "/v1/{database=projects/*/instances/*/databases/*}/ddl" }; + } + + // Sets the access control policy on a database resource. Replaces any + // existing policy. + // + // Authorization requires `spanner.databases.setIamPolicy` permission on + // [resource][google.iam.v1.SetIamPolicyRequest.resource]. + rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest) returns (google.iam.v1.Policy) { + option (google.api.http) = { post: "/v1/{resource=projects/*/instances/*/databases/*}:setIamPolicy" body: "*" }; + } + + // Gets the access control policy for a database resource. Returns an empty + // policy if a database exists but does not have a policy set. + // + // Authorization requires `spanner.databases.getIamPolicy` permission on + // [resource][google.iam.v1.GetIamPolicyRequest.resource]. + rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest) returns (google.iam.v1.Policy) { + option (google.api.http) = { post: "/v1/{resource=projects/*/instances/*/databases/*}:getIamPolicy" body: "*" }; + } + + // Returns permissions that the caller has on the specified database resource. + // + // Attempting this RPC on a non-existent Cloud Spanner database will result in + // a NOT_FOUND error if the user has `spanner.databases.list` permission on + // the containing Cloud Spanner instance. Otherwise returns an empty set of + // permissions. + rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) returns (google.iam.v1.TestIamPermissionsResponse) { + option (google.api.http) = { post: "/v1/{resource=projects/*/instances/*/databases/*}:testIamPermissions" body: "*" }; + } +} + +// A Cloud Spanner database. +message Database { + // Indicates the current state of the database. + enum State { + // Not specified. + STATE_UNSPECIFIED = 0; + + // The database is still being created. Operations on the database may fail + // with `FAILED_PRECONDITION` in this state. + CREATING = 1; + + // The database is fully created and ready for use. + READY = 2; + } + + // Required. The name of the database. Values are of the form + // `projects//instances//databases/`, + // where `` is as specified in the `CREATE DATABASE` + // statement. This name can be passed to other API methods to + // identify the database. + string name = 1; + + // Output only. The current database state. + State state = 2; +} + +// The request for [ListDatabases][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabases]. +message ListDatabasesRequest { + // Required. The instance whose databases should be listed. + // Values are of the form `projects//instances/`. + string parent = 1; + + // Number of databases to be returned in the response. If 0 or less, + // defaults to the server's maximum allowed page size. + int32 page_size = 3; + + // If non-empty, `page_token` should contain a + // [next_page_token][google.spanner.admin.database.v1.ListDatabasesResponse.next_page_token] from a + // previous [ListDatabasesResponse][google.spanner.admin.database.v1.ListDatabasesResponse]. + string page_token = 4; +} + +// The response for [ListDatabases][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabases]. +message ListDatabasesResponse { + // Databases that matched the request. + repeated Database databases = 1; + + // `next_page_token` can be sent in a subsequent + // [ListDatabases][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabases] call to fetch more + // of the matching databases. + string next_page_token = 2; +} + +// The request for [CreateDatabase][google.spanner.admin.database.v1.DatabaseAdmin.CreateDatabase]. +message CreateDatabaseRequest { + // Required. The name of the instance that will serve the new database. + // Values are of the form `projects//instances/`. + string parent = 1; + + // Required. A `CREATE DATABASE` statement, which specifies the ID of the + // new database. The database ID must conform to the regular expression + // `[a-z][a-z0-9_\-]*[a-z0-9]` and be between 2 and 30 characters in length. + string create_statement = 2; + + // An optional list of DDL statements to run inside the newly created + // database. Statements can create tables, indexes, etc. These + // statements execute atomically with the creation of the database: + // if there is an error in any statement, the database is not created. + repeated string extra_statements = 3; +} + +// Metadata type for the operation returned by +// [CreateDatabase][google.spanner.admin.database.v1.DatabaseAdmin.CreateDatabase]. +message CreateDatabaseMetadata { + // The database being created. + string database = 1; +} + +// The request for [GetDatabase][google.spanner.admin.database.v1.DatabaseAdmin.GetDatabase]. +message GetDatabaseRequest { + // Required. The name of the requested database. Values are of the form + // `projects//instances//databases/`. + string name = 1; +} + +// Enqueues the given DDL statements to be applied, in order but not +// necessarily all at once, to the database schema at some point (or +// points) in the future. The server checks that the statements +// are executable (syntactically valid, name tables that exist, etc.) +// before enqueueing them, but they may still fail upon +// later execution (e.g., if a statement from another batch of +// statements is applied first and it conflicts in some way, or if +// there is some data-related problem like a `NULL` value in a column to +// which `NOT NULL` would be added). If a statement fails, all +// subsequent statements in the batch are automatically cancelled. +// +// Each batch of statements is assigned a name which can be used with +// the [Operations][google.longrunning.Operations] API to monitor +// progress. See the +// [operation_id][google.spanner.admin.database.v1.UpdateDatabaseDdlRequest.operation_id] field for more +// details. +message UpdateDatabaseDdlRequest { + // Required. The database to update. + string database = 1; + + // DDL statements to be applied to the database. + repeated string statements = 2; + + // If empty, the new update request is assigned an + // automatically-generated operation ID. Otherwise, `operation_id` + // is used to construct the name of the resulting + // [Operation][google.longrunning.Operation]. + // + // Specifying an explicit operation ID simplifies determining + // whether the statements were executed in the event that the + // [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl] call is replayed, + // or the return value is otherwise lost: the [database][google.spanner.admin.database.v1.UpdateDatabaseDdlRequest.database] and + // `operation_id` fields can be combined to form the + // [name][google.longrunning.Operation.name] of the resulting + // [longrunning.Operation][google.longrunning.Operation]: `/operations/`. + // + // `operation_id` should be unique within the database, and must be + // a valid identifier: `[a-z][a-z0-9_]*`. Note that + // automatically-generated operation IDs always begin with an + // underscore. If the named operation already exists, + // [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl] returns + // `ALREADY_EXISTS`. + string operation_id = 3; +} + +// Metadata type for the operation returned by +// [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl]. +message UpdateDatabaseDdlMetadata { + // The database being modified. + string database = 1; + + // For an update this list contains all the statements. For an + // individual statement, this list contains only that statement. + repeated string statements = 2; + + // Reports the commit timestamps of all statements that have + // succeeded so far, where `commit_timestamps[i]` is the commit + // timestamp for the statement `statements[i]`. + repeated google.protobuf.Timestamp commit_timestamps = 3; +} + +// The request for [DropDatabase][google.spanner.admin.database.v1.DatabaseAdmin.DropDatabase]. +message DropDatabaseRequest { + // Required. The database to be dropped. + string database = 1; +} + +// The request for [GetDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.GetDatabaseDdl]. +message GetDatabaseDdlRequest { + // Required. The database whose schema we wish to get. + string database = 1; +} + +// The response for [GetDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.GetDatabaseDdl]. +message GetDatabaseDdlResponse { + // A list of formatted DDL statements defining the schema of the database + // specified in the request. + repeated string statements = 1; +} diff --git a/google/spanner/admin/instance/spanner_admin_instance.yaml b/google/spanner/admin/instance/spanner_admin_instance.yaml new file mode 100644 index 00000000..acf3d4d6 --- /dev/null +++ b/google/spanner/admin/instance/spanner_admin_instance.yaml @@ -0,0 +1,39 @@ +type: google.api.Service +config_version: 3 +name: spanner.googleapis.com +title: Cloud Spanner Instance Admin API + +apis: + - name: google.spanner.admin.instance.v1.InstanceAdmin + mixins: + - name: google.iam.v1.IAMPolicy + +types: + - name: google.spanner.admin.instance.v1.CreateInstanceMetadata + - name: google.spanner.admin.instance.v1.UpdateInstanceMetadata + +authentication: + rules: + - selector: google.spanner.admin.database.v1.Spanner.* + oauth: + canonical_scopes: https://www.googleapis.com/auth/spanner.admin, + https://www.googleapis.com/auth/cloud-platform + +http: + rules: + - selector: google.longrunning.Operations.GetOperation + get: '/v1/{name=projects/*/instances/*/databases/*/operations/*}' + additional_bindings: + - get: '/v1/{name=projects/*/instances/*/operations/*}' + - selector: google.longrunning.Operations.ListOperations + get: '/v1/{name=projects/*/instances/*/databases/*/operations}' + additional_bindings: + - get: '/v1/{name=projects/*/instances/*/operations}' + - selector: google.longrunning.Operations.CancelOperation + post: '/v1/{name=projects/*/instances/*/databases/*/operations/*}:cancel' + additional_bindings: + - post: '/v1/{name=projects/*/instances/*/operations/*}:cancel' + - selector: google.longrunning.Operations.DeleteOperation + delete: '/v1/{name=projects/*/instances/*/databases/*/operations/*}' + additional_bindings: + - delete: '/v1/{name=projects/*/instances/*/operations/*}' diff --git a/google/spanner/admin/instance/v1/spanner_admin_instance_gapic.yaml b/google/spanner/admin/instance/v1/spanner_admin_instance_gapic.yaml new file mode 100644 index 00000000..cbc99e19 --- /dev/null +++ b/google/spanner/admin/instance/v1/spanner_admin_instance_gapic.yaml @@ -0,0 +1,206 @@ +type: com.google.api.codegen.ConfigProto +language_settings: + java: + package_name: com.google.cloud.spanner.admin.instance.spi.v1 + python: + package_name: google.cloud.gapic.spanner_admin_instance.v1 + go: + package_name: cloud.google.com/go/spanner/admin/instance/apiv1 + csharp: + package_name: Google.Cloud.Spanner.Admin.Instance.V1 + ruby: + package_name: Google::Cloud::Spanner::Admin::Instance::V1 + php: + package_name: Google\Cloud\Spanner\Admin\Instance\V1 + nodejs: + package_name: spanner-admin-instance.v1 + domain_layer_location: google-cloud +license_header: + copyright_file: copyright-google.txt + license_file: license-header-apache-2.0.txt +interfaces: +- name: google.spanner.admin.instance.v1.InstanceAdmin + collections: + - name_pattern: projects/{project} + entity_name: project + - name_pattern: projects/{project}/instanceConfigs/{instance_config} + entity_name: instance_config + - name_pattern: projects/{project}/instances/{instance} + entity_name: instance + retry_codes_def: + - name: idempotent + retry_codes: + - UNAVAILABLE + - DEADLINE_EXCEEDED + - name: non_idempotent + retry_codes: [] + retry_params_def: + - name: default + initial_retry_delay_millis: 1000 + retry_delay_multiplier: 1.3 + max_retry_delay_millis: 32000 + initial_rpc_timeout_millis: 60000 + rpc_timeout_multiplier: 1 + max_rpc_timeout_millis: 60000 + total_timeout_millis: 600000 + methods: + - name: ListInstanceConfigs + flattening: + groups: + - parameters: + - parent + required_fields: + - parent + request_object_method: false + page_streaming: + request: + page_size_field: page_size + token_field: page_token + response: + token_field: next_page_token + resources_field: instance_configs + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + parent: project + timeout_millis: 30000 + - name: GetInstanceConfig + flattening: + groups: + - parameters: + - name + required_fields: + - name + request_object_method: false + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + name: instance_config + timeout_millis: 30000 + - name: ListInstances + flattening: + groups: + - parameters: + - parent + required_fields: + - parent + request_object_method: true + page_streaming: + request: + page_size_field: page_size + token_field: page_token + response: + token_field: next_page_token + resources_field: instances + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + parent: project + timeout_millis: 30000 + - name: GetInstance + flattening: + groups: + - parameters: + - name + required_fields: + - name + request_object_method: false + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + name: instance + timeout_millis: 30000 + - name: CreateInstance + flattening: + groups: + - parameters: + - parent + - instance_id + - instance + required_fields: + - parent + - instance_id + - instance + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + parent: project + timeout_millis: 30000 + long_running: + return_type: google.spanner.admin.instance.v1.Instance + metadata_type: google.spanner.admin.instance.v1.CreateInstanceMetadata + - name: UpdateInstance + flattening: + groups: + - parameters: + - instance + - field_mask + required_fields: + - instance + - field_mask + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + instance.name: instance + timeout_millis: 30000 + long_running: + return_type: google.spanner.admin.instance.v1.Instance + metadata_type: google.spanner.admin.instance.v1.UpdateInstanceMetadata + - name: DeleteInstance + flattening: + groups: + - parameters: + - name + required_fields: + - name + request_object_method: false + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + name: instance + timeout_millis: 30000 + - name: SetIamPolicy + flattening: + groups: + - parameters: + - resource + - policy + required_fields: + - resource + - policy + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + resource: instance + timeout_millis: 30000 + - name: GetIamPolicy + flattening: + groups: + - parameters: + - resource + required_fields: + - resource + request_object_method: false + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + resource: instance + timeout_millis: 30000 + - name: TestIamPermissions + flattening: + groups: + - parameters: + - resource + - permissions + required_fields: + - resource + - permissions + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + resource: instance + timeout_millis: 30000 diff --git a/google/spanner/admin/instance/v1/spanner_instance_admin.proto b/google/spanner/admin/instance/v1/spanner_instance_admin.proto new file mode 100644 index 00000000..d85d781e --- /dev/null +++ b/google/spanner/admin/instance/v1/spanner_instance_admin.proto @@ -0,0 +1,446 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.spanner.admin.instance.v1; + +import "google/api/annotations.proto"; +import "google/api/auth.proto"; +import "google/iam/v1/iam_policy.proto"; +import "google/iam/v1/policy.proto"; +import "google/longrunning/operations.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/field_mask.proto"; +import "google/protobuf/timestamp.proto"; + +option csharp_namespace = "Google.Cloud.Spanner.Admin.Instance.V1"; +option go_package = "google.golang.org/genproto/googleapis/spanner/admin/instance/v1;instance"; +option java_multiple_files = true; +option java_outer_classname = "SpannerInstanceAdminProto"; +option java_package = "com.google.spanner.admin.instance.v1"; + + +// Cloud Spanner Instance Admin API +// +// The Cloud Spanner Instance Admin API can be used to create, delete, +// modify and list instances. Instances are dedicated Cloud Spanner serving +// and storage resources to be used by Cloud Spanner databases. +// +// Each instance has a "configuration", which dictates where the +// serving resources for the Cloud Spanner instance are located (e.g., +// US-central, Europe). Configurations are created by Google based on +// resource availability. +// +// Cloud Spanner billing is based on the instances that exist and their +// sizes. After an instance exists, there are no additional +// per-database or per-operation charges for use of the instance +// (though there may be additional network bandwidth charges). +// Instances offer isolation: problems with databases in one instance +// will not affect other instances. However, within an instance +// databases can affect each other. For example, if one database in an +// instance receives a lot of requests and consumes most of the +// instance resources, fewer resources are available for other +// databases in that instance, and their performance may suffer. +service InstanceAdmin { + // Lists the supported instance configurations for a given project. + rpc ListInstanceConfigs(ListInstanceConfigsRequest) returns (ListInstanceConfigsResponse) { + option (google.api.http) = { get: "/v1/{parent=projects/*}/instanceConfigs" }; + } + + // Gets information about a particular instance configuration. + rpc GetInstanceConfig(GetInstanceConfigRequest) returns (InstanceConfig) { + option (google.api.http) = { get: "/v1/{name=projects/*/instanceConfigs/*}" }; + } + + // Lists all instances in the given project. + rpc ListInstances(ListInstancesRequest) returns (ListInstancesResponse) { + option (google.api.http) = { get: "/v1/{parent=projects/*}/instances" }; + } + + // Gets information about a particular instance. + rpc GetInstance(GetInstanceRequest) returns (Instance) { + option (google.api.http) = { get: "/v1/{name=projects/*/instances/*}" }; + } + + // Creates an instance and begins preparing it to begin serving. The + // returned [long-running operation][google.longrunning.Operation] + // can be used to track the progress of preparing the new + // instance. The instance name is assigned by the caller. If the + // named instance already exists, `CreateInstance` returns + // `ALREADY_EXISTS`. + // + // Immediately upon completion of this request: + // + // * The instance is readable via the API, with all requested attributes + // but no allocated resources. Its state is `CREATING`. + // + // Until completion of the returned operation: + // + // * Cancelling the operation renders the instance immediately unreadable + // via the API. + // * The instance can be deleted. + // * All other attempts to modify the instance are rejected. + // + // Upon completion of the returned operation: + // + // * Billing for all successfully-allocated resources begins (some types + // may have lower than the requested levels). + // * Databases can be created in the instance. + // * The instance's allocated resource levels are readable via the API. + // * The instance's state becomes `READY`. + // + // The returned [long-running operation][google.longrunning.Operation] will + // have a name of the format `/operations/` and + // can be used to track creation of the instance. The + // [metadata][google.longrunning.Operation.metadata] field type is + // [CreateInstanceMetadata][google.spanner.admin.instance.v1.CreateInstanceMetadata]. + // The [response][google.longrunning.Operation.response] field type is + // [Instance][google.spanner.admin.instance.v1.Instance], if successful. + rpc CreateInstance(CreateInstanceRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { post: "/v1/{parent=projects/*}/instances" body: "*" }; + } + + // Updates an instance, and begins allocating or releasing resources + // as requested. The returned [long-running + // operation][google.longrunning.Operation] can be used to track the + // progress of updating the instance. If the named instance does not + // exist, returns `NOT_FOUND`. + // + // Immediately upon completion of this request: + // + // * For resource types for which a decrease in the instance's allocation + // has been requested, billing is based on the newly-requested level. + // + // Until completion of the returned operation: + // + // * Cancelling the operation sets its metadata's + // [cancel_time][google.spanner.admin.instance.v1.UpdateInstanceMetadata.cancel_time], and begins + // restoring resources to their pre-request values. The operation + // is guaranteed to succeed at undoing all resource changes, + // after which point it terminates with a `CANCELLED` status. + // * All other attempts to modify the instance are rejected. + // * Reading the instance via the API continues to give the pre-request + // resource levels. + // + // Upon completion of the returned operation: + // + // * Billing begins for all successfully-allocated resources (some types + // may have lower than the requested levels). + // * All newly-reserved resources are available for serving the instance's + // tables. + // * The instance's new resource levels are readable via the API. + // + // The returned [long-running operation][google.longrunning.Operation] will + // have a name of the format `/operations/` and + // can be used to track the instance modification. The + // [metadata][google.longrunning.Operation.metadata] field type is + // [UpdateInstanceMetadata][google.spanner.admin.instance.v1.UpdateInstanceMetadata]. + // The [response][google.longrunning.Operation.response] field type is + // [Instance][google.spanner.admin.instance.v1.Instance], if successful. + // + // Authorization requires `spanner.instances.update` permission on + // resource [name][google.spanner.admin.instance.v1.Instance.name]. + rpc UpdateInstance(UpdateInstanceRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { patch: "/v1/{instance.name=projects/*/instances/*}" body: "*" }; + } + + // Deletes an instance. + // + // Immediately upon completion of the request: + // + // * Billing ceases for all of the instance's reserved resources. + // + // Soon afterward: + // + // * The instance and *all of its databases* immediately and + // irrevocably disappear from the API. All data in the databases + // is permanently deleted. + rpc DeleteInstance(DeleteInstanceRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { delete: "/v1/{name=projects/*/instances/*}" }; + } + + // Sets the access control policy on an instance resource. Replaces any + // existing policy. + // + // Authorization requires `spanner.instances.setIamPolicy` on + // [resource][google.iam.v1.SetIamPolicyRequest.resource]. + rpc SetIamPolicy(google.iam.v1.SetIamPolicyRequest) returns (google.iam.v1.Policy) { + option (google.api.http) = { post: "/v1/{resource=projects/*/instances/*}:setIamPolicy" body: "*" }; + } + + // Gets the access control policy for an instance resource. Returns an empty + // policy if an instance exists but does not have a policy set. + // + // Authorization requires `spanner.instances.getIamPolicy` on + // [resource][google.iam.v1.GetIamPolicyRequest.resource]. + rpc GetIamPolicy(google.iam.v1.GetIamPolicyRequest) returns (google.iam.v1.Policy) { + option (google.api.http) = { post: "/v1/{resource=projects/*/instances/*}:getIamPolicy" body: "*" }; + } + + // Returns permissions that the caller has on the specified instance resource. + // + // Attempting this RPC on a non-existent Cloud Spanner instance resource will + // result in a NOT_FOUND error if the user has `spanner.instances.list` + // permission on the containing Google Cloud Project. Otherwise returns an + // empty set of permissions. + rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) returns (google.iam.v1.TestIamPermissionsResponse) { + option (google.api.http) = { post: "/v1/{resource=projects/*/instances/*}:testIamPermissions" body: "*" }; + } +} + +// A possible configuration for a Cloud Spanner instance. Configurations +// define the geographic placement of nodes and their replication. +message InstanceConfig { + // A unique identifier for the instance configuration. Values + // are of the form + // `projects//instanceConfigs/[a-z][-a-z0-9]*` + string name = 1; + + // The name of this instance configuration as it appears in UIs. + string display_name = 2; +} + +// An isolated set of Cloud Spanner resources on which databases can be hosted. +message Instance { + // Indicates the current state of the instance. + enum State { + // Not specified. + STATE_UNSPECIFIED = 0; + + // The instance is still being created. Resources may not be + // available yet, and operations such as database creation may not + // work. + CREATING = 1; + + // The instance is fully created and ready to do work such as + // creating databases. + READY = 2; + } + + // Required. A unique identifier for the instance, which cannot be changed + // after the instance is created. Values are of the form + // `projects//instances/[a-z][-a-z0-9]*[a-z0-9]`. The final + // segment of the name must be between 6 and 30 characters in length. + string name = 1; + + // Required. The name of the instance's configuration. Values are of the form + // `projects//instanceConfigs/`. See + // also [InstanceConfig][google.spanner.admin.instance.v1.InstanceConfig] and + // [ListInstanceConfigs][google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs]. + string config = 2; + + // Required. The descriptive name for this instance as it appears in UIs. + // Must be unique per project and between 4 and 30 characters in length. + string display_name = 3; + + // Required. The number of nodes allocated to this instance. + int32 node_count = 5; + + // Output only. The current instance state. For + // [CreateInstance][google.spanner.admin.instance.v1.InstanceAdmin.CreateInstance], the state must be + // either omitted or set to `CREATING`. For + // [UpdateInstance][google.spanner.admin.instance.v1.InstanceAdmin.UpdateInstance], the state must be + // either omitted or set to `READY`. + State state = 6; + + // Cloud Labels are a flexible and lightweight mechanism for organizing cloud + // resources into groups that reflect a customer's organizational needs and + // deployment strategies. Cloud Labels can be used to filter collections of + // resources. They can be used to control how resource metrics are aggregated. + // And they can be used as arguments to policy management rules (e.g. route, + // firewall, load balancing, etc.). + // + // * Label keys must be between 1 and 63 characters long and must conform to + // the following regular expression: `[a-z]([-a-z0-9]*[a-z0-9])?`. + // * Label values must be between 0 and 63 characters long and must conform + // to the regular expression `([a-z]([-a-z0-9]*[a-z0-9])?)?`. + // * No more than 64 labels can be associated with a given resource. + // + // See https://goo.gl/xmQnxf for more information on and examples of labels. + // + // If you plan to use labels in your own code, please note that additional + // characters may be allowed in the future. And so you are advised to use an + // internal label representation, such as JSON, which doesn't rely upon + // specific characters being disallowed. For example, representing labels + // as the string: name + "_" + value would prove problematic if we were to + // allow "_" in a future release. + map labels = 7; +} + +// The request for [ListInstanceConfigs][google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs]. +message ListInstanceConfigsRequest { + // Required. The name of the project for which a list of supported instance + // configurations is requested. Values are of the form + // `projects/`. + string parent = 1; + + // Number of instance configurations to be returned in the response. If 0 or + // less, defaults to the server's maximum allowed page size. + int32 page_size = 2; + + // If non-empty, `page_token` should contain a + // [next_page_token][google.spanner.admin.instance.v1.ListInstanceConfigsResponse.next_page_token] + // from a previous [ListInstanceConfigsResponse][google.spanner.admin.instance.v1.ListInstanceConfigsResponse]. + string page_token = 3; +} + +// The response for [ListInstanceConfigs][google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs]. +message ListInstanceConfigsResponse { + // The list of requested instance configurations. + repeated InstanceConfig instance_configs = 1; + + // `next_page_token` can be sent in a subsequent + // [ListInstanceConfigs][google.spanner.admin.instance.v1.InstanceAdmin.ListInstanceConfigs] call to + // fetch more of the matching instance configurations. + string next_page_token = 2; +} + +// The request for +// [GetInstanceConfigRequest][google.spanner.admin.instance.v1.InstanceAdmin.GetInstanceConfig]. +message GetInstanceConfigRequest { + // Required. The name of the requested instance configuration. Values are of + // the form `projects//instanceConfigs/`. + string name = 1; +} + +// The request for [GetInstance][google.spanner.admin.instance.v1.InstanceAdmin.GetInstance]. +message GetInstanceRequest { + // Required. The name of the requested instance. Values are of the form + // `projects//instances/`. + string name = 1; +} + +// The request for [CreateInstance][google.spanner.admin.instance.v1.InstanceAdmin.CreateInstance]. +message CreateInstanceRequest { + // Required. The name of the project in which to create the instance. Values + // are of the form `projects/`. + string parent = 1; + + // Required. The ID of the instance to create. Valid identifiers are of the + // form `[a-z][-a-z0-9]*[a-z0-9]` and must be between 6 and 30 characters in + // length. + string instance_id = 2; + + // Required. The instance to create. The name may be omitted, but if + // specified must be `/instances/`. + Instance instance = 3; +} + +// The request for [ListInstances][google.spanner.admin.instance.v1.InstanceAdmin.ListInstances]. +message ListInstancesRequest { + // Required. The name of the project for which a list of instances is + // requested. Values are of the form `projects/`. + string parent = 1; + + // Number of instances to be returned in the response. If 0 or less, defaults + // to the server's maximum allowed page size. + int32 page_size = 2; + + // If non-empty, `page_token` should contain a + // [next_page_token][google.spanner.admin.instance.v1.ListInstancesResponse.next_page_token] from a + // previous [ListInstancesResponse][google.spanner.admin.instance.v1.ListInstancesResponse]. + string page_token = 3; + + // An expression for filtering the results of the request. Filter rules are + // case insensitive. The fields eligible for filtering are: + // + // * name + // * display_name + // * labels.key where key is the name of a label + // + // Some examples of using filters are: + // + // * name:* --> The instance has a name. + // * name:Howl --> The instance's name contains the string "howl". + // * name:HOWL --> Equivalent to above. + // * NAME:howl --> Equivalent to above. + // * labels.env:* --> The instance has the label "env". + // * labels.env:dev --> The instance has the label "env" and the value of + // the label contains the string "dev". + // * name:howl labels.env:dev --> The instance's name contains "howl" and + // it has the label "env" with its value + // containing "dev". + string filter = 4; +} + +// The response for [ListInstances][google.spanner.admin.instance.v1.InstanceAdmin.ListInstances]. +message ListInstancesResponse { + // The list of requested instances. + repeated Instance instances = 1; + + // `next_page_token` can be sent in a subsequent + // [ListInstances][google.spanner.admin.instance.v1.InstanceAdmin.ListInstances] call to fetch more + // of the matching instances. + string next_page_token = 2; +} + +// The request for [UpdateInstance][google.spanner.admin.instance.v1.InstanceAdmin.UpdateInstance]. +message UpdateInstanceRequest { + // Required. The instance to update, which must always include the instance + // name. Otherwise, only fields mentioned in [][google.spanner.admin.instance.v1.UpdateInstanceRequest.field_mask] need be included. + Instance instance = 1; + + // Required. A mask specifying which fields in [][google.spanner.admin.instance.v1.UpdateInstanceRequest.instance] should be updated. + // The field mask must always be specified; this prevents any future fields in + // [][google.spanner.admin.instance.v1.Instance] from being erased accidentally by clients that do not know + // about them. + google.protobuf.FieldMask field_mask = 2; +} + +// The request for [DeleteInstance][google.spanner.admin.instance.v1.InstanceAdmin.DeleteInstance]. +message DeleteInstanceRequest { + // Required. The name of the instance to be deleted. Values are of the form + // `projects//instances/` + string name = 1; +} + +// Metadata type for the operation returned by +// [CreateInstance][google.spanner.admin.instance.v1.InstanceAdmin.CreateInstance]. +message CreateInstanceMetadata { + // The instance being created. + Instance instance = 1; + + // The time at which the + // [CreateInstance][google.spanner.admin.instance.v1.InstanceAdmin.CreateInstance] request was + // received. + google.protobuf.Timestamp start_time = 2; + + // The time at which this operation was cancelled. If set, this operation is + // in the process of undoing itself (which is guaranteed to succeed) and + // cannot be cancelled again. + google.protobuf.Timestamp cancel_time = 3; + + // The time at which this operation failed or was completed successfully. + google.protobuf.Timestamp end_time = 4; +} + +// Metadata type for the operation returned by +// [UpdateInstance][google.spanner.admin.instance.v1.InstanceAdmin.UpdateInstance]. +message UpdateInstanceMetadata { + // The desired end state of the update. + Instance instance = 1; + + // The time at which [UpdateInstance][google.spanner.admin.instance.v1.InstanceAdmin.UpdateInstance] + // request was received. + google.protobuf.Timestamp start_time = 2; + + // The time at which this operation was cancelled. If set, this operation is + // in the process of undoing itself (which is guaranteed to succeed) and + // cannot be cancelled again. + google.protobuf.Timestamp cancel_time = 3; + + // The time at which this operation failed or was completed successfully. + google.protobuf.Timestamp end_time = 4; +} diff --git a/google/spanner/spanner.yaml b/google/spanner/spanner.yaml new file mode 100644 index 00000000..b8b5c6d5 --- /dev/null +++ b/google/spanner/spanner.yaml @@ -0,0 +1,56 @@ +# This service config is currently set for generating client libraries for the +# non-admin API. Use the spanner_admin_*.yaml service configs to generate admin +# client libraries. + +type: google.api.Service +config_version: 3 +name: spanner.googleapis.com +title: Google Cloud Spanner API + +apis: + - name: google.spanner.v1.Spanner +# - name: google.longrunning.Operations + +authentication: + rules: + - selector: google.spanner.v1.Spanner.* + oauth: + canonical_scopes: https://www.googleapis.com/auth/spanner.data, + https://www.googleapis.com/auth/cloud-platform + +http: + rules: + - selector: google.longrunning.Operations.GetOperation + get: '/v1/{name=projects/*/instances/*/databases/*/operations/*}' + additional_bindings: + - get: '/v1/{name=projects/*/instances/*/operations/*}' + - selector: google.longrunning.Operations.ListOperations + get: '/v1/{name=projects/*/instances/*/databases/*/operations}' + additional_bindings: + - get: '/v1/{name=projects/*/instances/*/operations}' + - selector: google.longrunning.Operations.CancelOperation + post: '/v1/{name=projects/*/instances/*/databases/*/operations/*}:cancel' + additional_bindings: + - post: '/v1/{name=projects/*/instances/*/operations/*}:cancel' + - selector: google.longrunning.Operations.DeleteOperation + delete: '/v1/{name=projects/*/instances/*/databases/*/operations/*}' + additional_bindings: + - delete: '/v1/{name=projects/*/instances/*/operations/*}' + +documentation: + summary: + This API reference is organized by resource type. Each resource type has one or more data representations and one or more methods. + rules: + - selector: google.iam.v1.SetIamPolicyRequest.resource + description: | + REQUIRED: The Spanner resource for which the policy is being set. The format is `projects//instances/` for instance resources and `projects//instances//databases/` for databases resources. + - selector: google.iam.v1.GetIamPolicyRequest.resource + description: | + REQUIRED: The Spanner resource for which the policy is being retrieved. The format is `projects//instances/` for instance resources and `projects//instances//databases/` for database resources. + - selector: google.iam.v1.TestIamPermissionsRequest.resource + description: | + REQUIRED: The Spanner resource for which permissions are being tested. The format is `projects//instances/` for instance resources and `projects//instances//databases/` for database resources. + - selector: google.iam.v1.TestIamPermissionsRequest.permissions + description: | + REQUIRED: The set of permissions to check for 'resource'. + Permissions with wildcards (such as '*', 'spanner.*', 'spanner.instances.*') are not allowed. diff --git a/google/spanner/v1/keys.proto b/google/spanner/v1/keys.proto new file mode 100644 index 00000000..2bfae631 --- /dev/null +++ b/google/spanner/v1/keys.proto @@ -0,0 +1,162 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.spanner.v1; + +import "google/api/annotations.proto"; +import "google/protobuf/struct.proto"; + +option csharp_namespace = "Google.Cloud.Spanner.V1"; +option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner"; +option java_multiple_files = true; +option java_outer_classname = "KeysProto"; +option java_package = "com.google.spanner.v1"; + + +// KeyRange represents a range of rows in a table or index. +// +// A range has a start key and an end key. These keys can be open or +// closed, indicating if the range includes rows with that key. +// +// Keys are represented by lists, where the ith value in the list +// corresponds to the ith component of the table or index primary key. +// Individual values are encoded as described [here][google.spanner.v1.TypeCode]. +// +// For example, consider the following table definition: +// +// CREATE TABLE UserEvents ( +// UserName STRING(MAX), +// EventDate STRING(10) +// ) PRIMARY KEY(UserName, EventDate); +// +// The following keys name rows in this table: +// +// ["Bob", "2014-09-23"] +// ["Alfred", "2015-06-12"] +// +// Since the `UserEvents` table's `PRIMARY KEY` clause names two +// columns, each `UserEvents` key has two elements; the first is the +// `UserName`, and the second is the `EventDate`. +// +// Key ranges with multiple components are interpreted +// lexicographically by component using the table or index key's declared +// sort order. For example, the following range returns all events for +// user `"Bob"` that occurred in the year 2015: +// +// "start_closed": ["Bob", "2015-01-01"] +// "end_closed": ["Bob", "2015-12-31"] +// +// Start and end keys can omit trailing key components. This affects the +// inclusion and exclusion of rows that exactly match the provided key +// components: if the key is closed, then rows that exactly match the +// provided components are included; if the key is open, then rows +// that exactly match are not included. +// +// For example, the following range includes all events for `"Bob"` that +// occurred during and after the year 2000: +// +// "start_closed": ["Bob", "2000-01-01"] +// "end_closed": ["Bob"] +// +// The next example retrieves all events for `"Bob"`: +// +// "start_closed": ["Bob"] +// "end_closed": ["Bob"] +// +// To retrieve events before the year 2000: +// +// "start_closed": ["Bob"] +// "end_open": ["Bob", "2000-01-01"] +// +// The following range includes all rows in the table: +// +// "start_closed": [] +// "end_closed": [] +// +// This range returns all users whose `UserName` begins with any +// character from A to C: +// +// "start_closed": ["A"] +// "end_open": ["D"] +// +// This range returns all users whose `UserName` begins with B: +// +// "start_closed": ["B"] +// "end_open": ["C"] +// +// Key ranges honor column sort order. For example, suppose a table is +// defined as follows: +// +// CREATE TABLE DescendingSortedTable { +// Key INT64, +// ... +// ) PRIMARY KEY(Key DESC); +// +// The following range retrieves all rows with key values between 1 +// and 100 inclusive: +// +// "start_closed": ["100"] +// "end_closed": ["1"] +// +// Note that 100 is passed as the start, and 1 is passed as the end, +// because `Key` is a descending column in the schema. +message KeyRange { + // The start key must be provided. It can be either closed or open. + oneof start_key_type { + // If the start is closed, then the range includes all rows whose + // first `len(start_closed)` key columns exactly match `start_closed`. + google.protobuf.ListValue start_closed = 1; + + // If the start is open, then the range excludes rows whose first + // `len(start_open)` key columns exactly match `start_open`. + google.protobuf.ListValue start_open = 2; + } + + // The end key must be provided. It can be either closed or open. + oneof end_key_type { + // If the end is closed, then the range includes all rows whose + // first `len(end_closed)` key columns exactly match `end_closed`. + google.protobuf.ListValue end_closed = 3; + + // If the end is open, then the range excludes rows whose first + // `len(end_open)` key columns exactly match `end_open`. + google.protobuf.ListValue end_open = 4; + } +} + +// `KeySet` defines a collection of Cloud Spanner keys and/or key ranges. All +// the keys are expected to be in the same table or index. The keys need +// not be sorted in any particular way. +// +// If the same key is specified multiple times in the set (for example +// if two ranges, two keys, or a key and a range overlap), Cloud Spanner +// behaves as if the key were only specified once. +message KeySet { + // A list of specific keys. Entries in `keys` should have exactly as + // many elements as there are columns in the primary or index key + // with which this `KeySet` is used. Individual key values are + // encoded as described [here][google.spanner.v1.TypeCode]. + repeated google.protobuf.ListValue keys = 1; + + // A list of key ranges. See [KeyRange][google.spanner.v1.KeyRange] for more information about + // key range specifications. + repeated KeyRange ranges = 2; + + // For convenience `all` can be set to `true` to indicate that this + // `KeySet` matches all keys in the table or index. Note that any keys + // specified in `keys` or `ranges` are only yielded once. + bool all = 3; +} diff --git a/google/spanner/v1/mutation.proto b/google/spanner/v1/mutation.proto new file mode 100644 index 00000000..737af54a --- /dev/null +++ b/google/spanner/v1/mutation.proto @@ -0,0 +1,92 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.spanner.v1; + +import "google/api/annotations.proto"; +import "google/protobuf/struct.proto"; +import "google/spanner/v1/keys.proto"; + +option csharp_namespace = "Google.Cloud.Spanner.V1"; +option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner"; +option java_multiple_files = true; +option java_outer_classname = "MutationProto"; +option java_package = "com.google.spanner.v1"; + + +// A modification to one or more Cloud Spanner rows. Mutations can be +// applied to a Cloud Spanner database by sending them in a +// [Commit][google.spanner.v1.Spanner.Commit] call. +message Mutation { + // Arguments to [insert][google.spanner.v1.Mutation.insert], [update][google.spanner.v1.Mutation.update], [insert_or_update][google.spanner.v1.Mutation.insert_or_update], and + // [replace][google.spanner.v1.Mutation.replace] operations. + message Write { + // Required. The table whose rows will be written. + string table = 1; + + // The names of the columns in [table][google.spanner.v1.Mutation.Write.table] to be written. + // + // The list of columns must contain enough columns to allow + // Cloud Spanner to derive values for all primary key columns in the + // row(s) to be modified. + repeated string columns = 2; + + // The values to be written. `values` can contain more than one + // list of values. If it does, then multiple rows are written, one + // for each entry in `values`. Each list in `values` must have + // exactly as many entries as there are entries in [columns][google.spanner.v1.Mutation.Write.columns] + // above. Sending multiple lists is equivalent to sending multiple + // `Mutation`s, each containing one `values` entry and repeating + // [table][google.spanner.v1.Mutation.Write.table] and [columns][google.spanner.v1.Mutation.Write.columns]. Individual values in each list are + // encoded as described [here][google.spanner.v1.TypeCode]. + repeated google.protobuf.ListValue values = 3; + } + + // Arguments to [delete][google.spanner.v1.Mutation.delete] operations. + message Delete { + // Required. The table whose rows will be deleted. + string table = 1; + + // Required. The primary keys of the rows within [table][google.spanner.v1.Mutation.Delete.table] to delete. + KeySet key_set = 2; + } + + // Required. The operation to perform. + oneof operation { + // Insert new rows in a table. If any of the rows already exist, + // the write or transaction fails with error `ALREADY_EXISTS`. + Write insert = 1; + + // Update existing rows in a table. If any of the rows does not + // already exist, the transaction fails with error `NOT_FOUND`. + Write update = 2; + + // Like [insert][google.spanner.v1.Mutation.insert], except that if the row already exists, then + // its column values are overwritten with the ones provided. Any + // column values not explicitly written are preserved. + Write insert_or_update = 3; + + // Like [insert][google.spanner.v1.Mutation.insert], except that if the row already exists, it is + // deleted, and the column values provided are inserted + // instead. Unlike [insert_or_update][google.spanner.v1.Mutation.insert_or_update], this means any values not + // explicitly written become `NULL`. + Write replace = 4; + + // Delete rows from a table. Succeeds whether or not the named + // rows were present. + Delete delete = 5; + } +} diff --git a/google/spanner/v1/query_plan.proto b/google/spanner/v1/query_plan.proto new file mode 100644 index 00000000..b855a8ec --- /dev/null +++ b/google/spanner/v1/query_plan.proto @@ -0,0 +1,128 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.spanner.v1; + +import "google/api/annotations.proto"; +import "google/protobuf/struct.proto"; + +option csharp_namespace = "Google.Cloud.Spanner.V1"; +option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner"; +option java_multiple_files = true; +option java_outer_classname = "QueryPlanProto"; +option java_package = "com.google.spanner.v1"; + + +// Node information for nodes appearing in a [QueryPlan.plan_nodes][google.spanner.v1.QueryPlan.plan_nodes]. +message PlanNode { + // Metadata associated with a parent-child relationship appearing in a + // [PlanNode][google.spanner.v1.PlanNode]. + message ChildLink { + // The node to which the link points. + int32 child_index = 1; + + // The type of the link. For example, in Hash Joins this could be used to + // distinguish between the build child and the probe child, or in the case + // of the child being an output variable, to represent the tag associated + // with the output variable. + string type = 2; + + // Only present if the child node is [SCALAR][google.spanner.v1.PlanNode.Kind.SCALAR] and corresponds + // to an output variable of the parent node. The field carries the name of + // the output variable. + // For example, a `TableScan` operator that reads rows from a table will + // have child links to the `SCALAR` nodes representing the output variables + // created for each column that is read by the operator. The corresponding + // `variable` fields will be set to the variable names assigned to the + // columns. + string variable = 3; + } + + // Condensed representation of a node and its subtree. Only present for + // `SCALAR` [PlanNode(s)][google.spanner.v1.PlanNode]. + message ShortRepresentation { + // A string representation of the expression subtree rooted at this node. + string description = 1; + + // A mapping of (subquery variable name) -> (subquery node id) for cases + // where the `description` string of this node references a `SCALAR` + // subquery contained in the expression subtree rooted at this node. The + // referenced `SCALAR` subquery may not necessarily be a direct child of + // this node. + map subqueries = 2; + } + + // The kind of [PlanNode][google.spanner.v1.PlanNode]. Distinguishes between the two different kinds of + // nodes that can appear in a query plan. + enum Kind { + // Not specified. + KIND_UNSPECIFIED = 0; + + // Denotes a Relational operator node in the expression tree. Relational + // operators represent iterative processing of rows during query execution. + // For example, a `TableScan` operation that reads rows from a table. + RELATIONAL = 1; + + // Denotes a Scalar node in the expression tree. Scalar nodes represent + // non-iterable entities in the query plan. For example, constants or + // arithmetic operators appearing inside predicate expressions or references + // to column names. + SCALAR = 2; + } + + // The `PlanNode`'s index in [node list][google.spanner.v1.QueryPlan.plan_nodes]. + int32 index = 1; + + // Used to determine the type of node. May be needed for visualizing + // different kinds of nodes differently. For example, If the node is a + // [SCALAR][google.spanner.v1.PlanNode.Kind.SCALAR] node, it will have a condensed representation + // which can be used to directly embed a description of the node in its + // parent. + Kind kind = 2; + + // The display name for the node. + string display_name = 3; + + // List of child node `index`es and their relationship to this parent. + repeated ChildLink child_links = 4; + + // Condensed representation for [SCALAR][google.spanner.v1.PlanNode.Kind.SCALAR] nodes. + ShortRepresentation short_representation = 5; + + // Attributes relevant to the node contained in a group of key-value pairs. + // For example, a Parameter Reference node could have the following + // information in its metadata: + // + // { + // "parameter_reference": "param1", + // "parameter_type": "array" + // } + google.protobuf.Struct metadata = 6; + + // The execution statistics associated with the node, contained in a group of + // key-value pairs. Only present if the plan was returned as a result of a + // profile query. For example, number of executions, number of rows/time per + // execution etc. + google.protobuf.Struct execution_stats = 7; +} + +// Contains an ordered list of nodes appearing in the query plan. +message QueryPlan { + // The nodes in the query plan. Plan nodes are returned in pre-order starting + // with the plan root. Each [PlanNode][google.spanner.v1.PlanNode]'s `id` corresponds to its index in + // `plan_nodes`. + repeated PlanNode plan_nodes = 1; +} diff --git a/google/spanner/v1/result_set.proto b/google/spanner/v1/result_set.proto new file mode 100644 index 00000000..6f5e5e9f --- /dev/null +++ b/google/spanner/v1/result_set.proto @@ -0,0 +1,186 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.spanner.v1; + +import "google/api/annotations.proto"; +import "google/protobuf/struct.proto"; +import "google/spanner/v1/query_plan.proto"; +import "google/spanner/v1/transaction.proto"; +import "google/spanner/v1/type.proto"; + +option csharp_namespace = "Google.Cloud.Spanner.V1"; +option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner"; +option java_multiple_files = true; +option java_outer_classname = "ResultSetProto"; +option java_package = "com.google.spanner.v1"; + + +// Results from [Read][google.spanner.v1.Spanner.Read] or +// [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql]. +message ResultSet { + // Metadata about the result set, such as row type information. + ResultSetMetadata metadata = 1; + + // Each element in `rows` is a row whose format is defined by + // [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. The ith element + // in each row matches the ith field in + // [metadata.row_type][google.spanner.v1.ResultSetMetadata.row_type]. Elements are + // encoded based on type as described + // [here][google.spanner.v1.TypeCode]. + repeated google.protobuf.ListValue rows = 2; + + // Query plan and execution statistics for the query that produced this + // result set. These can be requested by setting + // [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode]. + ResultSetStats stats = 3; +} + +// Partial results from a streaming read or SQL query. Streaming reads and +// SQL queries better tolerate large result sets, large rows, and large +// values, but are a little trickier to consume. +message PartialResultSet { + // Metadata about the result set, such as row type information. + // Only present in the first response. + ResultSetMetadata metadata = 1; + + // A streamed result set consists of a stream of values, which might + // be split into many `PartialResultSet` messages to accommodate + // large rows and/or large values. Every N complete values defines a + // row, where N is equal to the number of entries in + // [metadata.row_type.fields][google.spanner.v1.StructType.fields]. + // + // Most values are encoded based on type as described + // [here][google.spanner.v1.TypeCode]. + // + // It is possible that the last value in values is "chunked", + // meaning that the rest of the value is sent in subsequent + // `PartialResultSet`(s). This is denoted by the [chunked_value][google.spanner.v1.PartialResultSet.chunked_value] + // field. Two or more chunked values can be merged to form a + // complete value as follows: + // + // * `bool/number/null`: cannot be chunked + // * `string`: concatenate the strings + // * `list`: concatenate the lists. If the last element in a list is a + // `string`, `list`, or `object`, merge it with the first element in + // the next list by applying these rules recursively. + // * `object`: concatenate the (field name, field value) pairs. If a + // field name is duplicated, then apply these rules recursively + // to merge the field values. + // + // Some examples of merging: + // + // # Strings are concatenated. + // "foo", "bar" => "foobar" + // + // # Lists of non-strings are concatenated. + // [2, 3], [4] => [2, 3, 4] + // + // # Lists are concatenated, but the last and first elements are merged + // # because they are strings. + // ["a", "b"], ["c", "d"] => ["a", "bc", "d"] + // + // # Lists are concatenated, but the last and first elements are merged + // # because they are lists. Recursively, the last and first elements + // # of the inner lists are merged because they are strings. + // ["a", ["b", "c"]], [["d"], "e"] => ["a", ["b", "cd"], "e"] + // + // # Non-overlapping object fields are combined. + // {"a": "1"}, {"b": "2"} => {"a": "1", "b": 2"} + // + // # Overlapping object fields are merged. + // {"a": "1"}, {"a": "2"} => {"a": "12"} + // + // # Examples of merging objects containing lists of strings. + // {"a": ["1"]}, {"a": ["2"]} => {"a": ["12"]} + // + // For a more complete example, suppose a streaming SQL query is + // yielding a result set whose rows contain a single string + // field. The following `PartialResultSet`s might be yielded: + // + // { + // "metadata": { ... } + // "values": ["Hello", "W"] + // "chunked_value": true + // "resume_token": "Af65..." + // } + // { + // "values": ["orl"] + // "chunked_value": true + // "resume_token": "Bqp2..." + // } + // { + // "values": ["d"] + // "resume_token": "Zx1B..." + // } + // + // This sequence of `PartialResultSet`s encodes two rows, one + // containing the field value `"Hello"`, and a second containing the + // field value `"World" = "W" + "orl" + "d"`. + repeated google.protobuf.Value values = 2; + + // If true, then the final value in [values][google.spanner.v1.PartialResultSet.values] is chunked, and must + // be combined with more values from subsequent `PartialResultSet`s + // to obtain a complete field value. + bool chunked_value = 3; + + // Streaming calls might be interrupted for a variety of reasons, such + // as TCP connection loss. If this occurs, the stream of results can + // be resumed by re-sending the original request and including + // `resume_token`. Note that executing any other transaction in the + // same session invalidates the token. + bytes resume_token = 4; + + // Query plan and execution statistics for the query that produced this + // streaming result set. These can be requested by setting + // [ExecuteSqlRequest.query_mode][google.spanner.v1.ExecuteSqlRequest.query_mode] and are sent + // only once with the last response in the stream. + ResultSetStats stats = 5; +} + +// Metadata about a [ResultSet][google.spanner.v1.ResultSet] or [PartialResultSet][google.spanner.v1.PartialResultSet]. +message ResultSetMetadata { + // Indicates the field names and types for the rows in the result + // set. For example, a SQL query like `"SELECT UserId, UserName FROM + // Users"` could return a `row_type` value like: + // + // "fields": [ + // { "name": "UserId", "type": { "code": "INT64" } }, + // { "name": "UserName", "type": { "code": "STRING" } }, + // ] + StructType row_type = 1; + + // If the read or SQL query began a transaction as a side-effect, the + // information about the new transaction is yielded here. + Transaction transaction = 2; +} + +// Additional statistics about a [ResultSet][google.spanner.v1.ResultSet] or [PartialResultSet][google.spanner.v1.PartialResultSet]. +message ResultSetStats { + // [QueryPlan][google.spanner.v1.QueryPlan] for the query associated with this result. + QueryPlan query_plan = 1; + + // Aggregated statistics from the execution of the query. Only present when + // the query is profiled. For example, a query could return the statistics as + // follows: + // + // { + // "rows_returned": "3", + // "elapsed_time": "1.22 secs", + // "cpu_time": "1.19 secs" + // } + google.protobuf.Struct query_stats = 2; +} diff --git a/google/spanner/v1/spanner.proto b/google/spanner/v1/spanner.proto new file mode 100644 index 00000000..80992f00 --- /dev/null +++ b/google/spanner/v1/spanner.proto @@ -0,0 +1,348 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.spanner.v1; + +import "google/api/annotations.proto"; +import "google/api/auth.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; +import "google/spanner/v1/keys.proto"; +import "google/spanner/v1/mutation.proto"; +import "google/spanner/v1/result_set.proto"; +import "google/spanner/v1/transaction.proto"; +import "google/spanner/v1/type.proto"; + +option csharp_namespace = "Google.Cloud.Spanner.V1"; +option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner"; +option java_multiple_files = true; +option java_outer_classname = "SpannerProto"; +option java_package = "com.google.spanner.v1"; + + +// Cloud Spanner API +// +// The Cloud Spanner API can be used to manage sessions and execute +// transactions on data stored in Cloud Spanner databases. +service Spanner { + // Creates a new session. A session can be used to perform + // transactions that read and/or modify data in a Cloud Spanner database. + // Sessions are meant to be reused for many consecutive + // transactions. + // + // Sessions can only execute one transaction at a time. To execute + // multiple concurrent read-write/write-only transactions, create + // multiple sessions. Note that standalone reads and queries use a + // transaction internally, and count toward the one transaction + // limit. + // + // Cloud Spanner limits the number of sessions that can exist at any given + // time; thus, it is a good idea to delete idle and/or unneeded sessions. + // Aside from explicit deletes, Cloud Spanner can delete sessions for which no + // operations are sent for more than an hour. If a session is deleted, + // requests to it return `NOT_FOUND`. + // + // Idle sessions can be kept alive by sending a trivial SQL query + // periodically, e.g., `"SELECT 1"`. + rpc CreateSession(CreateSessionRequest) returns (Session) { + option (google.api.http) = { post: "/v1/{database=projects/*/instances/*/databases/*}/sessions" body: "" }; + } + + // Gets a session. Returns `NOT_FOUND` if the session does not exist. + // This is mainly useful for determining whether a session is still + // alive. + rpc GetSession(GetSessionRequest) returns (Session) { + option (google.api.http) = { get: "/v1/{name=projects/*/instances/*/databases/*/sessions/*}" }; + } + + // Ends a session, releasing server resources associated with it. + rpc DeleteSession(DeleteSessionRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { delete: "/v1/{name=projects/*/instances/*/databases/*/sessions/*}" }; + } + + // Executes an SQL query, returning all rows in a single reply. This + // method cannot be used to return a result set larger than 10 MiB; + // if the query yields more data than that, the query fails with + // a `FAILED_PRECONDITION` error. + // + // Queries inside read-write transactions might return `ABORTED`. If + // this occurs, the application should restart the transaction from + // the beginning. See [Transaction][google.spanner.v1.Transaction] for more details. + // + // Larger result sets can be fetched in streaming fashion by calling + // [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql] instead. + rpc ExecuteSql(ExecuteSqlRequest) returns (ResultSet) { + option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:executeSql" body: "*" }; + } + + // Like [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], except returns the result + // set as a stream. Unlike [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], there + // is no limit on the size of the returned result set. However, no + // individual row in the result set can exceed 100 MiB, and no + // column value can exceed 10 MiB. + rpc ExecuteStreamingSql(ExecuteSqlRequest) returns (stream PartialResultSet) { + option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:executeStreamingSql" body: "*" }; + } + + // Reads rows from the database using key lookups and scans, as a + // simple key/value style alternative to + // [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql]. This method cannot be used to + // return a result set larger than 10 MiB; if the read matches more + // data than that, the read fails with a `FAILED_PRECONDITION` + // error. + // + // Reads inside read-write transactions might return `ABORTED`. If + // this occurs, the application should restart the transaction from + // the beginning. See [Transaction][google.spanner.v1.Transaction] for more details. + // + // Larger result sets can be yielded in streaming fashion by calling + // [StreamingRead][google.spanner.v1.Spanner.StreamingRead] instead. + rpc Read(ReadRequest) returns (ResultSet) { + option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:read" body: "*" }; + } + + // Like [Read][google.spanner.v1.Spanner.Read], except returns the result set as a + // stream. Unlike [Read][google.spanner.v1.Spanner.Read], there is no limit on the + // size of the returned result set. However, no individual row in + // the result set can exceed 100 MiB, and no column value can exceed + // 10 MiB. + rpc StreamingRead(ReadRequest) returns (stream PartialResultSet) { + option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:streamingRead" body: "*" }; + } + + // Begins a new transaction. This step can often be skipped: + // [Read][google.spanner.v1.Spanner.Read], [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] and + // [Commit][google.spanner.v1.Spanner.Commit] can begin a new transaction as a + // side-effect. + rpc BeginTransaction(BeginTransactionRequest) returns (Transaction) { + option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:beginTransaction" body: "*" }; + } + + // Commits a transaction. The request includes the mutations to be + // applied to rows in the database. + // + // `Commit` might return an `ABORTED` error. This can occur at any time; + // commonly, the cause is conflicts with concurrent + // transactions. However, it can also happen for a variety of other + // reasons. If `Commit` returns `ABORTED`, the caller should re-attempt + // the transaction from the beginning, re-using the same session. + rpc Commit(CommitRequest) returns (CommitResponse) { + option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:commit" body: "*" }; + } + + // Rolls back a transaction, releasing any locks it holds. It is a good + // idea to call this for any transaction that includes one or more + // [Read][google.spanner.v1.Spanner.Read] or [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] requests and + // ultimately decides not to commit. + // + // `Rollback` returns `OK` if it successfully aborts the transaction, the + // transaction was already aborted, or the transaction is not + // found. `Rollback` never returns `ABORTED`. + rpc Rollback(RollbackRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { post: "/v1/{session=projects/*/instances/*/databases/*/sessions/*}:rollback" body: "*" }; + } +} + +// The request for [CreateSession][google.spanner.v1.Spanner.CreateSession]. +message CreateSessionRequest { + // Required. The database in which the new session is created. + string database = 1; +} + +// A session in the Cloud Spanner API. +message Session { + // Required. The name of the session. + string name = 1; +} + +// The request for [GetSession][google.spanner.v1.Spanner.GetSession]. +message GetSessionRequest { + // Required. The name of the session to retrieve. + string name = 1; +} + +// The request for [DeleteSession][google.spanner.v1.Spanner.DeleteSession]. +message DeleteSessionRequest { + // Required. The name of the session to delete. + string name = 1; +} + +// The request for [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] and +// [ExecuteStreamingSql][google.spanner.v1.Spanner.ExecuteStreamingSql]. +message ExecuteSqlRequest { + // Mode in which the query must be processed. + enum QueryMode { + // The default mode where only the query result, without any information + // about the query plan is returned. + NORMAL = 0; + + // This mode returns only the query plan, without any result rows or + // execution statistics information. + PLAN = 1; + + // This mode returns both the query plan and the execution statistics along + // with the result rows. + PROFILE = 2; + } + + // Required. The session in which the SQL query should be performed. + string session = 1; + + // The transaction to use. If none is provided, the default is a + // temporary read-only transaction with strong concurrency. + TransactionSelector transaction = 2; + + // Required. The SQL query string. + string sql = 3; + + // The SQL query string can contain parameter placeholders. A parameter + // placeholder consists of `'@'` followed by the parameter + // name. Parameter names consist of any combination of letters, + // numbers, and underscores. + // + // Parameters can appear anywhere that a literal value is expected. The same + // parameter name can be used more than once, for example: + // `"WHERE id > @msg_id AND id < @msg_id + 100"` + // + // It is an error to execute an SQL query with unbound parameters. + // + // Parameter values are specified using `params`, which is a JSON + // object whose keys are parameter names, and whose values are the + // corresponding parameter values. + google.protobuf.Struct params = 4; + + // It is not always possible for Cloud Spanner to infer the right SQL type + // from a JSON value. For example, values of type `BYTES` and values + // of type `STRING` both appear in [params][google.spanner.v1.ExecuteSqlRequest.params] as JSON strings. + // + // In these cases, `param_types` can be used to specify the exact + // SQL type for some or all of the SQL query parameters. See the + // definition of [Type][google.spanner.v1.Type] for more information + // about SQL types. + map param_types = 5; + + // If this request is resuming a previously interrupted SQL query + // execution, `resume_token` should be copied from the last + // [PartialResultSet][google.spanner.v1.PartialResultSet] yielded before the interruption. Doing this + // enables the new SQL query execution to resume where the last one left + // off. The rest of the request parameters must exactly match the + // request that yielded this token. + bytes resume_token = 6; + + // Used to control the amount of debugging information returned in + // [ResultSetStats][google.spanner.v1.ResultSetStats]. + QueryMode query_mode = 7; +} + +// The request for [Read][google.spanner.v1.Spanner.Read] and +// [StreamingRead][google.spanner.v1.Spanner.StreamingRead]. +message ReadRequest { + // Required. The session in which the read should be performed. + string session = 1; + + // The transaction to use. If none is provided, the default is a + // temporary read-only transaction with strong concurrency. + TransactionSelector transaction = 2; + + // Required. The name of the table in the database to be read. + string table = 3; + + // If non-empty, the name of an index on [table][google.spanner.v1.ReadRequest.table]. This index is + // used instead of the table primary key when interpreting [key_set][google.spanner.v1.ReadRequest.key_set] + // and sorting result rows. See [key_set][google.spanner.v1.ReadRequest.key_set] for further information. + string index = 4; + + // The columns of [table][google.spanner.v1.ReadRequest.table] to be returned for each row matching + // this request. + repeated string columns = 5; + + // Required. `key_set` identifies the rows to be yielded. `key_set` names the + // primary keys of the rows in [table][google.spanner.v1.ReadRequest.table] to be yielded, unless [index][google.spanner.v1.ReadRequest.index] + // is present. If [index][google.spanner.v1.ReadRequest.index] is present, then [key_set][google.spanner.v1.ReadRequest.key_set] instead names + // index keys in [index][google.spanner.v1.ReadRequest.index]. + // + // Rows are yielded in table primary key order (if [index][google.spanner.v1.ReadRequest.index] is empty) + // or index key order (if [index][google.spanner.v1.ReadRequest.index] is non-empty). + // + // It is not an error for the `key_set` to name rows that do not + // exist in the database. Read yields nothing for nonexistent rows. + KeySet key_set = 6; + + // If greater than zero, only the first `limit` rows are yielded. If `limit` + // is zero, the default is no limit. + int64 limit = 8; + + // If this request is resuming a previously interrupted read, + // `resume_token` should be copied from the last + // [PartialResultSet][google.spanner.v1.PartialResultSet] yielded before the interruption. Doing this + // enables the new read to resume where the last read left off. The + // rest of the request parameters must exactly match the request + // that yielded this token. + bytes resume_token = 9; +} + +// The request for [BeginTransaction][google.spanner.v1.Spanner.BeginTransaction]. +message BeginTransactionRequest { + // Required. The session in which the transaction runs. + string session = 1; + + // Required. Options for the new transaction. + TransactionOptions options = 2; +} + +// The request for [Commit][google.spanner.v1.Spanner.Commit]. +message CommitRequest { + // Required. The session in which the transaction to be committed is running. + string session = 1; + + // Required. The transaction in which to commit. + oneof transaction { + // Commit a previously-started transaction. + bytes transaction_id = 2; + + // Execute mutations in a temporary transaction. Note that unlike + // commit of a previously-started transaction, commit with a + // temporary transaction is non-idempotent. That is, if the + // `CommitRequest` is sent to Cloud Spanner more than once (for + // instance, due to retries in the application, or in the + // transport library), it is possible that the mutations are + // executed more than once. If this is undesirable, use + // [BeginTransaction][google.spanner.v1.Spanner.BeginTransaction] and + // [Commit][google.spanner.v1.Spanner.Commit] instead. + TransactionOptions single_use_transaction = 3; + } + + // The mutations to be executed when this transaction commits. All + // mutations are applied atomically, in the order they appear in + // this list. + repeated Mutation mutations = 4; +} + +// The response for [Commit][google.spanner.v1.Spanner.Commit]. +message CommitResponse { + // The Cloud Spanner timestamp at which the transaction committed. + google.protobuf.Timestamp commit_timestamp = 1; +} + +// The request for [Rollback][google.spanner.v1.Spanner.Rollback]. +message RollbackRequest { + // Required. The session in which the transaction to roll back is running. + string session = 1; + + // Required. The transaction to roll back. + bytes transaction_id = 2; +} diff --git a/google/spanner/v1/spanner_gapic.yaml b/google/spanner/v1/spanner_gapic.yaml new file mode 100644 index 00000000..4a001bdb --- /dev/null +++ b/google/spanner/v1/spanner_gapic.yaml @@ -0,0 +1,177 @@ +type: com.google.api.codegen.ConfigProto +language_settings: + java: + package_name: com.google.cloud.spanner.spi.v1 + python: + package_name: google.cloud.gapic.spanner.v1 + go: + package_name: cloud.google.com/go/spanner/apiv1 + csharp: + package_name: Google.Cloud.Spanner.V1 + ruby: + package_name: Google::Cloud::Spanner::V1 + php: + package_name: Google\Cloud\Spanner\V1 + nodejs: + package_name: spanner.v1 + domain_layer_location: google-cloud +license_header: + copyright_file: copyright-google.txt + license_file: license-header-apache-2.0.txt +interfaces: +- name: google.spanner.v1.Spanner + collections: + - name_pattern: projects/{project}/instances/{instance}/databases/{database} + entity_name: database + - name_pattern: projects/{project}/instances/{instance}/databases/{database}/sessions/{session} + entity_name: session + retry_codes_def: + - name: idempotent + retry_codes: + - UNAVAILABLE + - DEADLINE_EXCEEDED + - name: non_idempotent + retry_codes: [] + retry_params_def: + - name: default + initial_retry_delay_millis: 1000 + retry_delay_multiplier: 1.3 + max_retry_delay_millis: 32000 + initial_rpc_timeout_millis: 60000 + rpc_timeout_multiplier: 1 + max_rpc_timeout_millis: 60000 + total_timeout_millis: 600000 + methods: + - name: CreateSession + flattening: + groups: + - parameters: + - database + required_fields: + - database + request_object_method: false + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + database: database + timeout_millis: 30000 + - name: GetSession + flattening: + groups: + - parameters: + - name + required_fields: + - name + request_object_method: false + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + name: session + timeout_millis: 30000 + - name: DeleteSession + flattening: + groups: + - parameters: + - name + required_fields: + - name + request_object_method: false + retry_codes_name: idempotent + retry_params_name: default + field_name_patterns: + name: session + timeout_millis: 30000 + - name: ExecuteSql + required_fields: + - session + - sql + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + session: session + timeout_millis: 30000 + - name: ExecuteStreamingSql + required_fields: + - session + - sql + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + session: session + timeout_millis: 30000 + - name: Read + required_fields: + - session + - table + - columns + - key_set + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + session: session + timeout_millis: 30000 + - name: StreamingRead + required_fields: + - session + - table + - columns + - key_set + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + session: session + timeout_millis: 30000 + - name: BeginTransaction + flattening: + groups: + - parameters: + - session + - options + required_fields: + - session + - options + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + session: session + timeout_millis: 30000 + - name: Commit + flattening: + groups: + - parameters: + - session + - transaction_id + - mutations + - parameters: + - session + - single_use_transaction + - mutations + required_fields: + - session + - mutations + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + session: session + timeout_millis: 30000 + - name: Rollback + flattening: + groups: + - parameters: + - session + - transaction_id + required_fields: + - session + - transaction_id + request_object_method: true + retry_codes_name: non_idempotent + retry_params_name: default + field_name_patterns: + session: session + timeout_millis: 30000 diff --git a/google/spanner/v1/transaction.proto b/google/spanner/v1/transaction.proto new file mode 100644 index 00000000..e3ecf678 --- /dev/null +++ b/google/spanner/v1/transaction.proto @@ -0,0 +1,373 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.spanner.v1; + +import "google/api/annotations.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +option csharp_namespace = "Google.Cloud.Spanner.V1"; +option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner"; +option java_multiple_files = true; +option java_outer_classname = "TransactionProto"; +option java_package = "com.google.spanner.v1"; + + +// # Transactions +// +// +// Each session can have at most one active transaction at a time. After the +// active transaction is completed, the session can immediately be +// re-used for the next transaction. It is not necessary to create a +// new session for each transaction. +// +// # Transaction Modes +// +// Cloud Spanner supports two transaction modes: +// +// 1. Locking read-write. This type of transaction is the only way +// to write data into Cloud Spanner. These transactions rely on +// pessimistic locking and, if necessary, two-phase commit. +// Locking read-write transactions may abort, requiring the +// application to retry. +// +// 2. Snapshot read-only. This transaction type provides guaranteed +// consistency across several reads, but does not allow +// writes. Snapshot read-only transactions can be configured to +// read at timestamps in the past. Snapshot read-only +// transactions do not need to be committed. +// +// For transactions that only read, snapshot read-only transactions +// provide simpler semantics and are almost always faster. In +// particular, read-only transactions do not take locks, so they do +// not conflict with read-write transactions. As a consequence of not +// taking locks, they also do not abort, so retry loops are not needed. +// +// Transactions may only read/write data in a single database. They +// may, however, read/write data in different tables within that +// database. +// +// ## Locking Read-Write Transactions +// +// Locking transactions may be used to atomically read-modify-write +// data anywhere in a database. This type of transaction is externally +// consistent. +// +// Clients should attempt to minimize the amount of time a transaction +// is active. Faster transactions commit with higher probability +// and cause less contention. Cloud Spanner attempts to keep read locks +// active as long as the transaction continues to do reads, and the +// transaction has not been terminated by +// [Commit][google.spanner.v1.Spanner.Commit] or +// [Rollback][google.spanner.v1.Spanner.Rollback]. Long periods of +// inactivity at the client may cause Cloud Spanner to release a +// transaction's locks and abort it. +// +// Reads performed within a transaction acquire locks on the data +// being read. Writes can only be done at commit time, after all reads +// have been completed. +// Conceptually, a read-write transaction consists of zero or more +// reads or SQL queries followed by +// [Commit][google.spanner.v1.Spanner.Commit]. At any time before +// [Commit][google.spanner.v1.Spanner.Commit], the client can send a +// [Rollback][google.spanner.v1.Spanner.Rollback] request to abort the +// transaction. +// +// ### Semantics +// +// Cloud Spanner can commit the transaction if all read locks it acquired +// are still valid at commit time, and it is able to acquire write +// locks for all writes. Cloud Spanner can abort the transaction for any +// reason. If a commit attempt returns `ABORTED`, Cloud Spanner guarantees +// that the transaction has not modified any user data in Cloud Spanner. +// +// Unless the transaction commits, Cloud Spanner makes no guarantees about +// how long the transaction's locks were held for. It is an error to +// use Cloud Spanner locks for any sort of mutual exclusion other than +// between Cloud Spanner transactions themselves. +// +// ### Retrying Aborted Transactions +// +// When a transaction aborts, the application can choose to retry the +// whole transaction again. To maximize the chances of successfully +// committing the retry, the client should execute the retry in the +// same session as the original attempt. The original session's lock +// priority increases with each consecutive abort, meaning that each +// attempt has a slightly better chance of success than the previous. +// +// Under some circumstances (e.g., many transactions attempting to +// modify the same row(s)), a transaction can abort many times in a +// short period before successfully committing. Thus, it is not a good +// idea to cap the number of retries a transaction can attempt; +// instead, it is better to limit the total amount of wall time spent +// retrying. +// +// ### Idle Transactions +// +// A transaction is considered idle if it has no outstanding reads or +// SQL queries and has not started a read or SQL query within the last 10 +// seconds. Idle transactions can be aborted by Cloud Spanner so that they +// don't hold on to locks indefinitely. In that case, the commit will +// fail with error `ABORTED`. +// +// If this behavior is undesirable, periodically executing a simple +// SQL query in the transaction (e.g., `SELECT 1`) prevents the +// transaction from becoming idle. +// +// ## Snapshot Read-Only Transactions +// +// Snapshot read-only transactions provides a simpler method than +// locking read-write transactions for doing several consistent +// reads. However, this type of transaction does not support writes. +// +// Snapshot transactions do not take locks. Instead, they work by +// choosing a Cloud Spanner timestamp, then executing all reads at that +// timestamp. Since they do not acquire locks, they do not block +// concurrent read-write transactions. +// +// Unlike locking read-write transactions, snapshot read-only +// transactions never abort. They can fail if the chosen read +// timestamp is garbage collected; however, the default garbage +// collection policy is generous enough that most applications do not +// need to worry about this in practice. +// +// Snapshot read-only transactions do not need to call +// [Commit][google.spanner.v1.Spanner.Commit] or +// [Rollback][google.spanner.v1.Spanner.Rollback] (and in fact are not +// permitted to do so). +// +// To execute a snapshot transaction, the client specifies a timestamp +// bound, which tells Cloud Spanner how to choose a read timestamp. +// +// The types of timestamp bound are: +// +// - Strong (the default). +// - Bounded staleness. +// - Exact staleness. +// +// If the Cloud Spanner database to be read is geographically distributed, +// stale read-only transactions can execute more quickly than strong +// or read-write transaction, because they are able to execute far +// from the leader replica. +// +// Each type of timestamp bound is discussed in detail below. +// +// ### Strong +// +// Strong reads are guaranteed to see the effects of all transactions +// that have committed before the start of the read. Furthermore, all +// rows yielded by a single read are consistent with each other -- if +// any part of the read observes a transaction, all parts of the read +// see the transaction. +// +// Strong reads are not repeatable: two consecutive strong read-only +// transactions might return inconsistent results if there are +// concurrent writes. If consistency across reads is required, the +// reads should be executed within a transaction or at an exact read +// timestamp. +// +// See [TransactionOptions.ReadOnly.strong][google.spanner.v1.TransactionOptions.ReadOnly.strong]. +// +// ### Exact Staleness +// +// These timestamp bounds execute reads at a user-specified +// timestamp. Reads at a timestamp are guaranteed to see a consistent +// prefix of the global transaction history: they observe +// modifications done by all transactions with a commit timestamp <= +// the read timestamp, and observe none of the modifications done by +// transactions with a larger commit timestamp. They will block until +// all conflicting transactions that may be assigned commit timestamps +// <= the read timestamp have finished. +// +// The timestamp can either be expressed as an absolute Cloud Spanner commit +// timestamp or a staleness relative to the current time. +// +// These modes do not require a "negotiation phase" to pick a +// timestamp. As a result, they execute slightly faster than the +// equivalent boundedly stale concurrency modes. On the other hand, +// boundedly stale reads usually return fresher results. +// +// See [TransactionOptions.ReadOnly.read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.read_timestamp] and +// [TransactionOptions.ReadOnly.exact_staleness][google.spanner.v1.TransactionOptions.ReadOnly.exact_staleness]. +// +// ### Bounded Staleness +// +// Bounded staleness modes allow Cloud Spanner to pick the read timestamp, +// subject to a user-provided staleness bound. Cloud Spanner chooses the +// newest timestamp within the staleness bound that allows execution +// of the reads at the closest available replica without blocking. +// +// All rows yielded are consistent with each other -- if any part of +// the read observes a transaction, all parts of the read see the +// transaction. Boundedly stale reads are not repeatable: two stale +// reads, even if they use the same staleness bound, can execute at +// different timestamps and thus return inconsistent results. +// +// Boundedly stale reads execute in two phases: the first phase +// negotiates a timestamp among all replicas needed to serve the +// read. In the second phase, reads are executed at the negotiated +// timestamp. +// +// As a result of the two phase execution, bounded staleness reads are +// usually a little slower than comparable exact staleness +// reads. However, they are typically able to return fresher +// results, and are more likely to execute at the closest replica. +// +// Because the timestamp negotiation requires up-front knowledge of +// which rows will be read, it can only be used with single-use +// read-only transactions. +// +// See [TransactionOptions.ReadOnly.max_staleness][google.spanner.v1.TransactionOptions.ReadOnly.max_staleness] and +// [TransactionOptions.ReadOnly.min_read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.min_read_timestamp]. +// +// ### Old Read Timestamps and Garbage Collection +// +// Cloud Spanner continuously garbage collects deleted and overwritten data +// in the background to reclaim storage space. This process is known +// as "version GC". By default, version GC reclaims versions after they +// are one hour old. Because of this, Cloud Spanner cannot perform reads +// at read timestamps more than one hour in the past. This +// restriction also applies to in-progress reads and/or SQL queries whose +// timestamp become too old while executing. Reads and SQL queries with +// too-old read timestamps fail with the error `FAILED_PRECONDITION`. +message TransactionOptions { + // Options for read-write transactions. + message ReadWrite { + + } + + // Options for read-only transactions. + message ReadOnly { + // How to choose the timestamp for the read-only transaction. + oneof timestamp_bound { + // Read at a timestamp where all previously committed transactions + // are visible. + bool strong = 1; + + // Executes all reads at a timestamp >= `min_read_timestamp`. + // + // This is useful for requesting fresher data than some previous + // read, or data that is fresh enough to observe the effects of some + // previously committed transaction whose timestamp is known. + // + // Note that this option can only be used in single-use transactions. + google.protobuf.Timestamp min_read_timestamp = 2; + + // Read data at a timestamp >= `NOW - max_staleness` + // seconds. Guarantees that all writes that have committed more + // than the specified number of seconds ago are visible. Because + // Cloud Spanner chooses the exact timestamp, this mode works even if + // the client's local clock is substantially skewed from Cloud Spanner + // commit timestamps. + // + // Useful for reading the freshest data available at a nearby + // replica, while bounding the possible staleness if the local + // replica has fallen behind. + // + // Note that this option can only be used in single-use + // transactions. + google.protobuf.Duration max_staleness = 3; + + // Executes all reads at the given timestamp. Unlike other modes, + // reads at a specific timestamp are repeatable; the same read at + // the same timestamp always returns the same data. If the + // timestamp is in the future, the read will block until the + // specified timestamp, modulo the read's deadline. + // + // Useful for large scale consistent reads such as mapreduces, or + // for coordinating many reads against a consistent snapshot of the + // data. + google.protobuf.Timestamp read_timestamp = 4; + + // Executes all reads at a timestamp that is `exact_staleness` + // old. The timestamp is chosen soon after the read is started. + // + // Guarantees that all writes that have committed more than the + // specified number of seconds ago are visible. Because Cloud Spanner + // chooses the exact timestamp, this mode works even if the client's + // local clock is substantially skewed from Cloud Spanner commit + // timestamps. + // + // Useful for reading at nearby replicas without the distributed + // timestamp negotiation overhead of `max_staleness`. + google.protobuf.Duration exact_staleness = 5; + } + + // If true, the Cloud Spanner-selected read timestamp is included in + // the [Transaction][google.spanner.v1.Transaction] message that describes the transaction. + bool return_read_timestamp = 6; + } + + // Required. The type of transaction. + oneof mode { + // Transaction may write. + // + // Authorization to begin a read-write transaction requires + // `spanner.databases.beginOrRollbackReadWriteTransaction` permission + // on the `session` resource. + ReadWrite read_write = 1; + + // Transaction will not write. + // + // Authorization to begin a read-only transaction requires + // `spanner.databases.beginReadOnlyTransaction` permission + // on the `session` resource. + ReadOnly read_only = 2; + } +} + +// A transaction. +message Transaction { + // `id` may be used to identify the transaction in subsequent + // [Read][google.spanner.v1.Spanner.Read], + // [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql], + // [Commit][google.spanner.v1.Spanner.Commit], or + // [Rollback][google.spanner.v1.Spanner.Rollback] calls. + // + // Single-use read-only transactions do not have IDs, because + // single-use transactions do not support multiple requests. + bytes id = 1; + + // For snapshot read-only transactions, the read timestamp chosen + // for the transaction. Not returned by default: see + // [TransactionOptions.ReadOnly.return_read_timestamp][google.spanner.v1.TransactionOptions.ReadOnly.return_read_timestamp]. + google.protobuf.Timestamp read_timestamp = 2; +} + +// This message is used to select the transaction in which a +// [Read][google.spanner.v1.Spanner.Read] or +// [ExecuteSql][google.spanner.v1.Spanner.ExecuteSql] call runs. +// +// See [TransactionOptions][google.spanner.v1.TransactionOptions] for more information about transactions. +message TransactionSelector { + // If no fields are set, the default is a single use transaction + // with strong concurrency. + oneof selector { + // Execute the read or SQL query in a temporary transaction. + // This is the most efficient way to execute a transaction that + // consists of a single SQL query. + TransactionOptions single_use = 1; + + // Execute the read or SQL query in a previously-started transaction. + bytes id = 2; + + // Begin a new transaction and execute this read or SQL query in + // it. The transaction ID of the new transaction is returned in + // [ResultSetMetadata.transaction][google.spanner.v1.ResultSetMetadata.transaction], which is a [Transaction][google.spanner.v1.Transaction]. + TransactionOptions begin = 3; + } +} diff --git a/google/spanner/v1/type.proto b/google/spanner/v1/type.proto new file mode 100644 index 00000000..76a941ff --- /dev/null +++ b/google/spanner/v1/type.proto @@ -0,0 +1,111 @@ +// Copyright 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.spanner.v1; + +import "google/api/annotations.proto"; + +option csharp_namespace = "Google.Cloud.Spanner.V1"; +option go_package = "google.golang.org/genproto/googleapis/spanner/v1;spanner"; +option java_multiple_files = true; +option java_outer_classname = "TypeProto"; +option java_package = "com.google.spanner.v1"; + + +// `Type` indicates the type of a Cloud Spanner value, as might be stored in a +// table cell or returned from an SQL query. +message Type { + // Required. The [TypeCode][google.spanner.v1.TypeCode] for this type. + TypeCode code = 1; + + // If [code][google.spanner.v1.Type.code] == [ARRAY][google.spanner.v1.TypeCode.ARRAY], then `array_element_type` + // is the type of the array elements. + Type array_element_type = 2; + + // If [code][google.spanner.v1.Type.code] == [STRUCT][google.spanner.v1.TypeCode.STRUCT], then `struct_type` + // provides type information for the struct's fields. + StructType struct_type = 3; +} + +// `StructType` defines the fields of a [STRUCT][google.spanner.v1.TypeCode.STRUCT] type. +message StructType { + // Message representing a single field of a struct. + message Field { + // The name of the field. For reads, this is the column name. For + // SQL queries, it is the column alias (e.g., `"Word"` in the + // query `"SELECT 'hello' AS Word"`), or the column name (e.g., + // `"ColName"` in the query `"SELECT ColName FROM Table"`). Some + // columns might have an empty name (e.g., !"SELECT + // UPPER(ColName)"`). Note that a query result can contain + // multiple fields with the same name. + string name = 1; + + // The type of the field. + Type type = 2; + } + + // The list of fields that make up this struct. Order is + // significant, because values of this struct type are represented as + // lists, where the order of field values matches the order of + // fields in the [StructType][google.spanner.v1.StructType]. In turn, the order of fields + // matches the order of columns in a read request, or the order of + // fields in the `SELECT` clause of a query. + repeated Field fields = 1; +} + +// `TypeCode` is used as part of [Type][google.spanner.v1.Type] to +// indicate the type of a Cloud Spanner value. +// +// Each legal value of a type can be encoded to or decoded from a JSON +// value, using the encodings described below. All Cloud Spanner values can +// be `null`, regardless of type; `null`s are always encoded as a JSON +// `null`. +enum TypeCode { + // Not specified. + TYPE_CODE_UNSPECIFIED = 0; + + // Encoded as JSON `true` or `false`. + BOOL = 1; + + // Encoded as `string`, in decimal format. + INT64 = 2; + + // Encoded as `number`, or the strings `"NaN"`, `"Infinity"`, or + // `"-Infinity"`. + FLOAT64 = 3; + + // Encoded as `string` in RFC 3339 timestamp format. The time zone + // must be present, and must be `"Z"`. + TIMESTAMP = 4; + + // Encoded as `string` in RFC 3339 date format. + DATE = 5; + + // Encoded as `string`. + STRING = 6; + + // Encoded as a base64-encoded `string`, as described in RFC 4648, + // section 4. + BYTES = 7; + + // Encoded as `list`, where the list elements are represented + // according to [array_element_type][google.spanner.v1.Type.array_element_type]. + ARRAY = 8; + + // Encoded as `list`, where list element `i` is represented according + // to [struct_type.fields[i]][google.spanner.v1.StructType.fields]. + STRUCT = 9; +}