// Copyright 2023 Google LLC
//
// 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/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.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";
import "google/spanner/admin/database/v1/backup.proto";
import "google/spanner/admin/database/v1/common.proto";

option csharp_namespace = "Google.Cloud.Spanner.Admin.Database.V1";
option go_package = "cloud.google.com/go/spanner/admin/database/apiv1/databasepb;databasepb";
option java_multiple_files = true;
option java_outer_classname = "SpannerDatabaseAdminProto";
option java_package = "com.google.spanner.admin.database.v1";
option php_namespace = "Google\\Cloud\\Spanner\\Admin\\Database\\V1";
option ruby_package = "Google::Cloud::Spanner::Admin::Database::V1";
option (google.api.resource_definition) = {
  type: "spanner.googleapis.com/Instance"
  pattern: "projects/{project}/instances/{instance}"
};

// Cloud Spanner Database Admin API
//
// The Cloud Spanner Database Admin API can be used to:
//   * create, drop, and list databases
//   * update the schema of pre-existing databases
//   * create, delete and list backups for a database
//   * restore a database from an existing backup
service DatabaseAdmin {
  option (google.api.default_host) = "spanner.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform,"
      "https://www.googleapis.com/auth/spanner.admin";

  // Lists Cloud Spanner databases.
  rpc ListDatabases(ListDatabasesRequest) returns (ListDatabasesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/instances/*}/databases"
    };
    option (google.api.method_signature) = "parent";
  }

  // 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 `<database_name>/operations/<operation_id>` 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: "*"
    };
    option (google.api.method_signature) = "parent,create_statement";
    option (google.longrunning.operation_info) = {
      response_type: "google.spanner.admin.database.v1.Database"
      metadata_type: "google.spanner.admin.database.v1.CreateDatabaseMetadata"
    };
  }

  // Gets the state of a Cloud Spanner database.
  rpc GetDatabase(GetDatabaseRequest) returns (Database) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/instances/*/databases/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates a Cloud Spanner database. The returned
  // [long-running operation][google.longrunning.Operation] can be used to track
  // the progress of updating the database. If the named database does not
  // exist, returns `NOT_FOUND`.
  //
  // While the operation is pending:
  //
  //   * The database's
  //     [reconciling][google.spanner.admin.database.v1.Database.reconciling]
  //     field is set to true.
  //   * Cancelling the operation is best-effort. If the cancellation succeeds,
  //     the operation metadata's
  //     [cancel_time][google.spanner.admin.database.v1.UpdateDatabaseMetadata.cancel_time]
  //     is set, the updates are reverted, and the operation terminates with a
  //     `CANCELLED` status.
  //   * New UpdateDatabase requests will return a `FAILED_PRECONDITION` error
  //     until the pending operation is done (returns successfully or with
  //     error).
  //   * Reading the database via the API continues to give the pre-request
  //     values.
  //
  // Upon completion of the returned operation:
  //
  //   * The new values are in effect and readable via the API.
  //   * The database's
  //     [reconciling][google.spanner.admin.database.v1.Database.reconciling]
  //     field becomes false.
  //
  // The returned [long-running operation][google.longrunning.Operation] will
  // have a name of the format
  // `projects/<project>/instances/<instance>/databases/<database>/operations/<operation_id>`
  // and can be used to track the database modification. The
  // [metadata][google.longrunning.Operation.metadata] field type is
  // [UpdateDatabaseMetadata][google.spanner.admin.database.v1.UpdateDatabaseMetadata].
  // The [response][google.longrunning.Operation.response] field type is
  // [Database][google.spanner.admin.database.v1.Database], if successful.
  rpc UpdateDatabase(UpdateDatabaseRequest)
      returns (google.longrunning.Operation) {
    option (google.api.http) = {
      patch: "/v1/{database.name=projects/*/instances/*/databases/*}"
      body: "database"
    };
    option (google.api.method_signature) = "database,update_mask";
    option (google.longrunning.operation_info) = {
      response_type: "Database"
      metadata_type: "UpdateDatabaseMetadata"
    };
  }

  // 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 `<database_name>/operations/<operation_id>` 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: "*"
    };
    option (google.api.method_signature) = "database,statements";
    option (google.longrunning.operation_info) = {
      response_type: "google.protobuf.Empty"
      metadata_type: "google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata"
    };
  }

  // Drops (aka deletes) a Cloud Spanner database.
  // Completed backups for the database will be retained according to their
  // `expire_time`.
  // Note: Cloud Spanner might continue to accept requests for a few seconds
  // after the database has been deleted.
  rpc DropDatabase(DropDatabaseRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{database=projects/*/instances/*/databases/*}"
    };
    option (google.api.method_signature) = "database";
  }

  // 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"
    };
    option (google.api.method_signature) = "database";
  }

  // Sets the access control policy on a database or backup resource.
  // Replaces any existing policy.
  //
  // Authorization requires `spanner.databases.setIamPolicy`
  // permission on [resource][google.iam.v1.SetIamPolicyRequest.resource].
  // For backups, authorization requires `spanner.backups.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: "*"
      additional_bindings {
        post: "/v1/{resource=projects/*/instances/*/backups/*}:setIamPolicy"
        body: "*"
      }
    };
    option (google.api.method_signature) = "resource,policy";
  }

  // Gets the access control policy for a database or backup resource.
  // Returns an empty policy if a database or backup exists but does not have a
  // policy set.
  //
  // Authorization requires `spanner.databases.getIamPolicy` permission on
  // [resource][google.iam.v1.GetIamPolicyRequest.resource].
  // For backups, authorization requires `spanner.backups.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: "*"
      additional_bindings {
        post: "/v1/{resource=projects/*/instances/*/backups/*}:getIamPolicy"
        body: "*"
      }
    };
    option (google.api.method_signature) = "resource";
  }

  // Returns permissions that the caller has on the specified database or backup
  // 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.
  // Calling this method on a backup that does not exist will
  // result in a NOT_FOUND error if the user has
  // `spanner.backups.list` permission on the containing instance.
  rpc TestIamPermissions(google.iam.v1.TestIamPermissionsRequest) returns (google.iam.v1.TestIamPermissionsResponse) {
    option (google.api.http) = {
      post: "/v1/{resource=projects/*/instances/*/databases/*}:testIamPermissions"
      body: "*"
      additional_bindings {
        post: "/v1/{resource=projects/*/instances/*/backups/*}:testIamPermissions"
        body: "*"
      }
      additional_bindings {
        post: "/v1/{resource=projects/*/instances/*/databases/*/databaseRoles/*}:testIamPermissions"
        body: "*"
      }
    };
    option (google.api.method_signature) = "resource,permissions";
  }

  // Starts creating a new Cloud Spanner Backup.
  // The returned backup [long-running operation][google.longrunning.Operation]
  // will have a name of the format
  // `projects/<project>/instances/<instance>/backups/<backup>/operations/<operation_id>`
  // and can be used to track creation of the backup. The
  // [metadata][google.longrunning.Operation.metadata] field type is
  // [CreateBackupMetadata][google.spanner.admin.database.v1.CreateBackupMetadata]. The
  // [response][google.longrunning.Operation.response] field type is
  // [Backup][google.spanner.admin.database.v1.Backup], if successful. Cancelling the returned operation will stop the
  // creation and delete the backup.
  // There can be only one pending backup creation per database. Backup creation
  // of different databases can run concurrently.
  rpc CreateBackup(CreateBackupRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/instances/*}/backups"
      body: "backup"
    };
    option (google.api.method_signature) = "parent,backup,backup_id";
    option (google.longrunning.operation_info) = {
      response_type: "google.spanner.admin.database.v1.Backup"
      metadata_type: "google.spanner.admin.database.v1.CreateBackupMetadata"
    };
  }

  // Starts copying a Cloud Spanner Backup.
  // The returned backup [long-running operation][google.longrunning.Operation]
  // will have a name of the format
  // `projects/<project>/instances/<instance>/backups/<backup>/operations/<operation_id>`
  // and can be used to track copying of the backup. The operation is associated
  // with the destination backup.
  // The [metadata][google.longrunning.Operation.metadata] field type is
  // [CopyBackupMetadata][google.spanner.admin.database.v1.CopyBackupMetadata].
  // The [response][google.longrunning.Operation.response] field type is
  // [Backup][google.spanner.admin.database.v1.Backup], if successful. Cancelling the returned operation will stop the
  // copying and delete the backup.
  // Concurrent CopyBackup requests can run on the same source backup.
  rpc CopyBackup(CopyBackupRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/instances/*}/backups:copy"
      body: "*"
    };
    option (google.api.method_signature) = "parent,backup_id,source_backup,expire_time";
    option (google.longrunning.operation_info) = {
      response_type: "google.spanner.admin.database.v1.Backup"
      metadata_type: "google.spanner.admin.database.v1.CopyBackupMetadata"
    };
  }

  // Gets metadata on a pending or completed [Backup][google.spanner.admin.database.v1.Backup].
  rpc GetBackup(GetBackupRequest) returns (Backup) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/instances/*/backups/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Updates a pending or completed [Backup][google.spanner.admin.database.v1.Backup].
  rpc UpdateBackup(UpdateBackupRequest) returns (Backup) {
    option (google.api.http) = {
      patch: "/v1/{backup.name=projects/*/instances/*/backups/*}"
      body: "backup"
    };
    option (google.api.method_signature) = "backup,update_mask";
  }

  // Deletes a pending or completed [Backup][google.spanner.admin.database.v1.Backup].
  rpc DeleteBackup(DeleteBackupRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/instances/*/backups/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Lists completed and pending backups.
  // Backups returned are ordered by `create_time` in descending order,
  // starting from the most recent `create_time`.
  rpc ListBackups(ListBackupsRequest) returns (ListBackupsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/instances/*}/backups"
    };
    option (google.api.method_signature) = "parent";
  }

  // Create a new database by restoring from a completed backup. The new
  // database must be in the same project and in an instance with the same
  // instance configuration as the instance containing
  // the backup. The returned database [long-running
  // operation][google.longrunning.Operation] has a name of the format
  // `projects/<project>/instances/<instance>/databases/<database>/operations/<operation_id>`,
  // and can be used to track the progress of the operation, and to cancel it.
  // The [metadata][google.longrunning.Operation.metadata] field type is
  // [RestoreDatabaseMetadata][google.spanner.admin.database.v1.RestoreDatabaseMetadata].
  // The [response][google.longrunning.Operation.response] type
  // is [Database][google.spanner.admin.database.v1.Database], if
  // successful. Cancelling the returned operation will stop the restore and
  // delete the database.
  // There can be only one database being restored into an instance at a time.
  // Once the restore operation completes, a new restore operation can be
  // initiated, without waiting for the optimize operation associated with the
  // first restore to complete.
  rpc RestoreDatabase(RestoreDatabaseRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*/instances/*}/databases:restore"
      body: "*"
    };
    option (google.api.method_signature) = "parent,database_id,backup";
    option (google.longrunning.operation_info) = {
      response_type: "google.spanner.admin.database.v1.Database"
      metadata_type: "google.spanner.admin.database.v1.RestoreDatabaseMetadata"
    };
  }

  // Lists database [longrunning-operations][google.longrunning.Operation].
  // A database operation has a name of the form
  // `projects/<project>/instances/<instance>/databases/<database>/operations/<operation>`.
  // The long-running operation
  // [metadata][google.longrunning.Operation.metadata] field type
  // `metadata.type_url` describes the type of the metadata. Operations returned
  // include those that have completed/failed/canceled within the last 7 days,
  // and pending operations.
  rpc ListDatabaseOperations(ListDatabaseOperationsRequest) returns (ListDatabaseOperationsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/instances/*}/databaseOperations"
    };
    option (google.api.method_signature) = "parent";
  }

  // Lists the backup [long-running operations][google.longrunning.Operation] in
  // the given instance. A backup operation has a name of the form
  // `projects/<project>/instances/<instance>/backups/<backup>/operations/<operation>`.
  // The long-running operation
  // [metadata][google.longrunning.Operation.metadata] field type
  // `metadata.type_url` describes the type of the metadata. Operations returned
  // include those that have completed/failed/canceled within the last 7 days,
  // and pending operations. Operations returned are ordered by
  // `operation.metadata.value.progress.start_time` in descending order starting
  // from the most recently started operation.
  rpc ListBackupOperations(ListBackupOperationsRequest) returns (ListBackupOperationsResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/instances/*}/backupOperations"
    };
    option (google.api.method_signature) = "parent";
  }

  // Lists Cloud Spanner database roles.
  rpc ListDatabaseRoles(ListDatabaseRolesRequest) returns (ListDatabaseRolesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*/instances/*/databases/*}/databaseRoles"
    };
    option (google.api.method_signature) = "parent";
  }
}

// Information about the database restore.
message RestoreInfo {
  // The type of the restore source.
  RestoreSourceType source_type = 1;

  // Information about the source used to restore the database.
  oneof source_info {
    // Information about the backup used to restore the database. The backup
    // may no longer exist.
    BackupInfo backup_info = 2;
  }
}

// A Cloud Spanner database.
message Database {
  option (google.api.resource) = {
    type: "spanner.googleapis.com/Database"
    pattern: "projects/{project}/instances/{instance}/databases/{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;

    // The database is fully created and ready for use, but is still
    // being optimized for performance and cannot handle full load.
    //
    // In this state, the database still references the backup
    // it was restore from, preventing the backup
    // from being deleted. When optimizations are complete, the full performance
    // of the database will be restored, and the database will transition to
    // `READY` state.
    READY_OPTIMIZING = 3;
  }

  // Required. The name of the database. Values are of the form
  // `projects/<project>/instances/<instance>/databases/<database>`,
  // where `<database>` is as specified in the `CREATE DATABASE`
  // statement. This name can be passed to other API methods to
  // identify the database.
  string name = 1 [(google.api.field_behavior) = REQUIRED];

  // Output only. The current database state.
  State state = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. If exists, the time at which the database creation started.
  google.protobuf.Timestamp create_time = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Applicable only for restored databases. Contains information
  // about the restore source.
  RestoreInfo restore_info = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. For databases that are using customer managed encryption, this
  // field contains the encryption configuration for the database.
  // For databases that are using Google default or other types of encryption,
  // this field is empty.
  EncryptionConfig encryption_config = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. For databases that are using customer managed encryption, this
  // field contains the encryption information for the database, such as
  // encryption state and the Cloud KMS key versions that are in use.
  //
  // For databases that are using Google default or other types of encryption,
  // this field is empty.
  //
  // This field is propagated lazily from the backend. There might be a delay
  // from when a key version is being used and when it appears in this field.
  repeated EncryptionInfo encryption_info = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The period in which Cloud Spanner retains all versions of data
  // for the database. This is the same as the value of version_retention_period
  // database option set using
  // [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl]. Defaults to 1 hour,
  // if not set.
  string version_retention_period = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Earliest timestamp at which older versions of the data can be
  // read. This value is continuously updated by Cloud Spanner and becomes stale
  // the moment it is queried. If you are using this value to recover data, make
  // sure to account for the time from the moment when the value is queried to
  // the moment when you initiate the recovery.
  google.protobuf.Timestamp earliest_version_time = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The read-write region which contains the database's leader
  // replicas.
  //
  // This is the same as the value of default_leader
  // database option set using DatabaseAdmin.CreateDatabase or
  // DatabaseAdmin.UpdateDatabaseDdl. If not explicitly set, this is empty.
  string default_leader = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The dialect of the Cloud Spanner Database.
  DatabaseDialect database_dialect = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Whether drop protection is enabled for this database. Defaults to false,
  // if not set.
  bool enable_drop_protection = 11;

  // Output only. If true, the database is being updated. If false, there are no
  // ongoing update operations for the database.
  bool reconciling = 12 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// 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/<project>/instances/<instance>`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "spanner.googleapis.com/Instance"
    }
  ];

  // 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/<project>/instances/<instance>`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "spanner.googleapis.com/Instance"
    }
  ];

  // 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.
  // If the database ID is a reserved word or if it contains a hyphen, the
  // database ID must be enclosed in backticks (`` ` ``).
  string create_statement = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. A 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 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The encryption configuration for the database. If this field is not
  // specified, Cloud Spanner will encrypt/decrypt all data at rest using
  // Google default encryption.
  EncryptionConfig encryption_config = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The dialect of the Cloud Spanner Database.
  DatabaseDialect database_dialect = 5 [(google.api.field_behavior) = OPTIONAL];
}

// Metadata type for the operation returned by
// [CreateDatabase][google.spanner.admin.database.v1.DatabaseAdmin.CreateDatabase].
message CreateDatabaseMetadata {
  // The database being created.
  string database = 1 [(google.api.resource_reference) = {
                         type: "spanner.googleapis.com/Database"
                       }];
}

// 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/<project>/instances/<instance>/databases/<database>`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "spanner.googleapis.com/Database"
    }
  ];
}

// The request for
// [UpdateDatabase][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabase].
message UpdateDatabaseRequest {
  // Required. The database to update.
  // The `name` field of the database is of the form
  // `projects/<project>/instances/<instance>/databases/<database>`.
  Database database = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The list of fields to update. Currently, only
  // `enable_drop_protection` field can be updated.
  google.protobuf.FieldMask update_mask = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Metadata type for the operation returned by
// [UpdateDatabase][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabase].
message UpdateDatabaseMetadata {
  // The request for
  // [UpdateDatabase][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabase].
  UpdateDatabaseRequest request = 1;

  // The progress of the
  // [UpdateDatabase][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabase]
  // operation.
  OperationProgress progress = 2;

  // The time at which this operation was cancelled. If set, this operation is
  // in the process of undoing itself (which is best-effort).
  google.protobuf.Timestamp cancel_time = 3;
}

// 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 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "spanner.googleapis.com/Database"
    }
  ];

  // Required. DDL statements to be applied to the database.
  repeated string statements = 2 [(google.api.field_behavior) = REQUIRED];

  // 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]: `<database>/operations/<operation_id>`.
  //
  // `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;
}

// Action information extracted from a DDL statement. This proto is used to
// display the brief info of the DDL statement for the operation
// [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl].
message DdlStatementActionInfo {
  // The action for the DDL statement, e.g. CREATE, ALTER, DROP, GRANT, etc.
  // This field is a non-empty string.
  string action = 1;

  // The entity type for the DDL statement, e.g. TABLE, INDEX, VIEW, etc.
  // This field can be empty string for some DDL statement,
  // e.g. for statement "ANALYZE", `entity_type` = "".
  string entity_type = 2;

  // The entity name(s) being operated on the DDL statement.
  // E.g.
  // 1. For statement "CREATE TABLE t1(...)", `entity_names` = ["t1"].
  // 2. For statement "GRANT ROLE r1, r2 ...", `entity_names` = ["r1", "r2"].
  // 3. For statement "ANALYZE", `entity_names` = [].
  repeated string entity_names = 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 [(google.api.resource_reference) = {
                         type: "spanner.googleapis.com/Database"
                       }];

  // 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;

  // Output only. When true, indicates that the operation is throttled e.g.
  // due to resource constraints. When resources become available the operation
  // will resume and this field will be false again.
  bool throttled = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The progress of the
  // [UpdateDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.UpdateDatabaseDdl]
  // operations. All DDL statements will have continuously updating progress,
  // and `progress[i]` is the operation progress for `statements[i]`. Also,
  // `progress[i]` will have start time and end time populated with commit
  // timestamp of operation, as well as a progress of 100% once the operation
  // has completed.
  repeated OperationProgress progress = 5;

  // The brief action info for the DDL statements.
  // `actions[i]` is the brief info for `statements[i]`.
  repeated DdlStatementActionInfo actions = 6;
}

// The request for [DropDatabase][google.spanner.admin.database.v1.DatabaseAdmin.DropDatabase].
message DropDatabaseRequest {
  // Required. The database to be dropped.
  string database = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "spanner.googleapis.com/Database"
    }
  ];
}

// The request for [GetDatabaseDdl][google.spanner.admin.database.v1.DatabaseAdmin.GetDatabaseDdl].
message GetDatabaseDdlRequest {
  // Required. The database whose schema we wish to get.
  // Values are of the form
  // `projects/<project>/instances/<instance>/databases/<database>`
  string database = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "spanner.googleapis.com/Database"
    }
  ];
}

// 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;
}

// The request for
// [ListDatabaseOperations][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabaseOperations].
message ListDatabaseOperationsRequest {
  // Required. The instance of the database operations.
  // Values are of the form `projects/<project>/instances/<instance>`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "spanner.googleapis.com/Instance"
    }
  ];

  // An expression that filters the list of returned operations.
  //
  // A filter expression consists of a field name, a
  // comparison operator, and a value for filtering.
  // The value must be a string, a number, or a boolean. The comparison operator
  // must be one of: `<`, `>`, `<=`, `>=`, `!=`, `=`, or `:`.
  // Colon `:` is the contains operator. Filter rules are not case sensitive.
  //
  // The following fields in the [Operation][google.longrunning.Operation]
  // are eligible for filtering:
  //
  //   * `name` - The name of the long-running operation
  //   * `done` - False if the operation is in progress, else true.
  //   * `metadata.@type` - the type of metadata. For example, the type string
  //      for [RestoreDatabaseMetadata][google.spanner.admin.database.v1.RestoreDatabaseMetadata] is
  //      `type.googleapis.com/google.spanner.admin.database.v1.RestoreDatabaseMetadata`.
  //   * `metadata.<field_name>` - any field in metadata.value.
  //      `metadata.@type` must be specified first, if filtering on metadata
  //      fields.
  //   * `error` - Error associated with the long-running operation.
  //   * `response.@type` - the type of response.
  //   * `response.<field_name>` - any field in response.value.
  //
  // You can combine multiple expressions by enclosing each expression in
  // parentheses. By default, expressions are combined with AND logic. However,
  // you can specify AND, OR, and NOT logic explicitly.
  //
  // Here are a few examples:
  //
  //   * `done:true` - The operation is complete.
  //   * `(metadata.@type=type.googleapis.com/google.spanner.admin.database.v1.RestoreDatabaseMetadata) AND` \
  //     `(metadata.source_type:BACKUP) AND` \
  //     `(metadata.backup_info.backup:backup_howl) AND` \
  //     `(metadata.name:restored_howl) AND` \
  //     `(metadata.progress.start_time < \"2018-03-28T14:50:00Z\") AND` \
  //     `(error:*)` - Return operations where:
  //     * The operation's metadata type is [RestoreDatabaseMetadata][google.spanner.admin.database.v1.RestoreDatabaseMetadata].
  //     * The database is restored from a backup.
  //     * The backup name contains "backup_howl".
  //     * The restored database's name contains "restored_howl".
  //     * The operation started before 2018-03-28T14:50:00Z.
  //     * The operation resulted in an error.
  string filter = 2;

  // Number of operations 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.ListDatabaseOperationsResponse.next_page_token]
  // from a previous [ListDatabaseOperationsResponse][google.spanner.admin.database.v1.ListDatabaseOperationsResponse] to the
  // same `parent` and with the same `filter`.
  string page_token = 4;
}

// The response for
// [ListDatabaseOperations][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabaseOperations].
message ListDatabaseOperationsResponse {
  // The list of matching database [long-running
  // operations][google.longrunning.Operation]. Each operation's name will be
  // prefixed by the database's name. The operation's
  // [metadata][google.longrunning.Operation.metadata] field type
  // `metadata.type_url` describes the type of the metadata.
  repeated google.longrunning.Operation operations = 1;

  // `next_page_token` can be sent in a subsequent
  // [ListDatabaseOperations][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabaseOperations]
  // call to fetch more of the matching metadata.
  string next_page_token = 2;
}

// The request for
// [RestoreDatabase][google.spanner.admin.database.v1.DatabaseAdmin.RestoreDatabase].
message RestoreDatabaseRequest {
  // Required. The name of the instance in which to create the
  // restored database. This instance must be in the same project and
  // have the same instance configuration as the instance containing
  // the source backup. Values are of the form
  // `projects/<project>/instances/<instance>`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "spanner.googleapis.com/Instance"
    }
  ];

  // Required. The id of the database to create and restore to. This
  // database must not already exist. The `database_id` appended to
  // `parent` forms the full database name of the form
  // `projects/<project>/instances/<instance>/databases/<database_id>`.
  string database_id = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The source from which to restore.
  oneof source {
    // Name of the backup from which to restore.  Values are of the form
    // `projects/<project>/instances/<instance>/backups/<backup>`.
    string backup = 3 [(google.api.resource_reference) = {
                         type: "spanner.googleapis.com/Backup"
                       }];
  }

  // Optional. An encryption configuration describing the encryption type and key
  // resources in Cloud KMS used to encrypt/decrypt the database to restore to.
  // If this field is not specified, the restored database will use
  // the same encryption configuration as the backup by default, namely
  // [encryption_type][google.spanner.admin.database.v1.RestoreDatabaseEncryptionConfig.encryption_type] =
  // `USE_CONFIG_DEFAULT_OR_BACKUP_ENCRYPTION`.
  RestoreDatabaseEncryptionConfig encryption_config = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Encryption configuration for the restored database.
message RestoreDatabaseEncryptionConfig {
  // Encryption types for the database to be restored.
  enum EncryptionType {
    // Unspecified. Do not use.
    ENCRYPTION_TYPE_UNSPECIFIED = 0;

    // This is the default option when
    // [encryption_config][google.spanner.admin.database.v1.RestoreDatabaseEncryptionConfig] is not specified.
    USE_CONFIG_DEFAULT_OR_BACKUP_ENCRYPTION = 1;

    // Use Google default encryption.
    GOOGLE_DEFAULT_ENCRYPTION = 2;

    // Use customer managed encryption. If specified, `kms_key_name` must
    // must contain a valid Cloud KMS key.
    CUSTOMER_MANAGED_ENCRYPTION = 3;
  }

  // Required. The encryption type of the restored database.
  EncryptionType encryption_type = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The Cloud KMS key that will be used to encrypt/decrypt the restored
  // database. This field should be set only when
  // [encryption_type][google.spanner.admin.database.v1.RestoreDatabaseEncryptionConfig.encryption_type] is
  // `CUSTOMER_MANAGED_ENCRYPTION`. Values are of the form
  // `projects/<project>/locations/<location>/keyRings/<key_ring>/cryptoKeys/<kms_key_name>`.
  string kms_key_name = 2 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      type: "cloudkms.googleapis.com/CryptoKey"
    }
  ];
}

// Metadata type for the long-running operation returned by
// [RestoreDatabase][google.spanner.admin.database.v1.DatabaseAdmin.RestoreDatabase].
message RestoreDatabaseMetadata {
  // Name of the database being created and restored to.
  string name = 1 [(google.api.resource_reference) = {
                     type: "spanner.googleapis.com/Database"
                   }];

  // The type of the restore source.
  RestoreSourceType source_type = 2;

  // Information about the source used to restore the database, as specified by
  // `source` in [RestoreDatabaseRequest][google.spanner.admin.database.v1.RestoreDatabaseRequest].
  oneof source_info {
    // Information about the backup used to restore the database.
    BackupInfo backup_info = 3;
  }

  // The progress of the
  // [RestoreDatabase][google.spanner.admin.database.v1.DatabaseAdmin.RestoreDatabase]
  // operation.
  OperationProgress progress = 4;

  // The time at which cancellation of this operation was received.
  // [Operations.CancelOperation][google.longrunning.Operations.CancelOperation]
  // starts asynchronous cancellation on a long-running operation. The server
  // makes a best effort to cancel the operation, but success is not guaranteed.
  // Clients can use
  // [Operations.GetOperation][google.longrunning.Operations.GetOperation] or
  // other methods to check whether the cancellation succeeded or whether the
  // operation completed despite cancellation. On successful cancellation,
  // the operation is not deleted; instead, it becomes an operation with
  // an [Operation.error][google.longrunning.Operation.error] value with a
  // [google.rpc.Status.code][google.rpc.Status.code] of 1, corresponding to `Code.CANCELLED`.
  google.protobuf.Timestamp cancel_time = 5;

  // If exists, the name of the long-running operation that will be used to
  // track the post-restore optimization process to optimize the performance of
  // the restored database, and remove the dependency on the restore source.
  // The name is of the form
  // `projects/<project>/instances/<instance>/databases/<database>/operations/<operation>`
  // where the <database> is the name of database being created and restored to.
  // The metadata type of the  long-running operation is
  // [OptimizeRestoredDatabaseMetadata][google.spanner.admin.database.v1.OptimizeRestoredDatabaseMetadata]. This long-running operation will be
  // automatically created by the system after the RestoreDatabase long-running
  // operation completes successfully. This operation will not be created if the
  // restore was not successful.
  string optimize_database_operation_name = 6;
}

// Metadata type for the long-running operation used to track the progress
// of optimizations performed on a newly restored database. This long-running
// operation is automatically created by the system after the successful
// completion of a database restore, and cannot be cancelled.
message OptimizeRestoredDatabaseMetadata {
  // Name of the restored database being optimized.
  string name = 1 [(google.api.resource_reference) = {
                     type: "spanner.googleapis.com/Database"
                   }];

  // The progress of the post-restore optimizations.
  OperationProgress progress = 2;
}

// Indicates the type of the restore source.
enum RestoreSourceType {
  // No restore associated.
  TYPE_UNSPECIFIED = 0;

  // A backup was used as the source of the restore.
  BACKUP = 1;
}

// A Cloud Spanner database role.
message DatabaseRole {
  option (google.api.resource) = {
    type: "spanner.googleapis.com/DatabaseRole"
    pattern: "projects/{project}/instances/{instance}/databases/{database}/databaseRoles/{role}"
  };

  // Required. The name of the database role. Values are of the form
  // `projects/<project>/instances/<instance>/databases/<database>/databaseRoles/
  // {role}`, where `<role>` is as specified in the `CREATE ROLE`
  // DDL statement. This name can be passed to Get/Set IAMPolicy methods to
  // identify the database role.
  string name = 1 [(google.api.field_behavior) = REQUIRED];
}

// The request for [ListDatabaseRoles][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabaseRoles].
message ListDatabaseRolesRequest {
  // Required. The database whose roles should be listed.
  // Values are of the form
  // `projects/<project>/instances/<instance>/databases/<database>/databaseRoles`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "spanner.googleapis.com/Database"
    }
  ];

  // Number of database roles 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.database.v1.ListDatabaseRolesResponse.next_page_token] from a
  // previous [ListDatabaseRolesResponse][google.spanner.admin.database.v1.ListDatabaseRolesResponse].
  string page_token = 3;
}

// The response for [ListDatabaseRoles][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabaseRoles].
message ListDatabaseRolesResponse {
  // Database roles that matched the request.
  repeated DatabaseRole database_roles = 1;

  // `next_page_token` can be sent in a subsequent
  // [ListDatabaseRoles][google.spanner.admin.database.v1.DatabaseAdmin.ListDatabaseRoles]
  // call to fetch more of the matching roles.
  string next_page_token = 2;
}
