// 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 `<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: "*" };
  }

  // 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 `<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: "*" };
  }

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

  // 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/<project>/instances/<instance>`.
  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/<project>/instances/<instance>`.
  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/<project>/instances/<instance>/databases/<database>`.
  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]: `<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;
}

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