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

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