// 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.cloud.clouddms.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/clouddms/v1/clouddms_resources.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.CloudDms.V1";
option go_package = "cloud.google.com/go/clouddms/apiv1/clouddmspb;clouddmspb";
option java_multiple_files = true;
option java_outer_classname = "ConversionWorkspaceResourcesProto";
option java_package = "com.google.cloud.clouddms.v1";
option php_namespace = "Google\\Cloud\\CloudDms\\V1";
option ruby_package = "Google::Cloud::CloudDMS::V1";

// The type and version of a source or destination database.
message DatabaseEngineInfo {
  // Required. Engine type.
  DatabaseEngine engine = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Engine named version, for example 12.c.1.
  string version = 2 [(google.api.field_behavior) = REQUIRED];
}

// The main conversion workspace resource entity.
message ConversionWorkspace {
  option (google.api.resource) = {
    type: "datamigration.googleapis.com/ConversionWorkspace"
    pattern: "projects/{project}/locations/{location}/conversionWorkspaces/{conversion_workspace}"
    plural: "conversionWorkspaces"
    singular: "conversionWorkspace"
  };

  // Full name of the workspace resource, in the form of:
  // projects/{project}/locations/{location}/conversionWorkspaces/{conversion_workspace}.
  string name = 1;

  // Required. The source engine details.
  DatabaseEngineInfo source = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The destination engine details.
  DatabaseEngineInfo destination = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. A generic list of settings for the workspace.
  // The settings are database pair dependant and can indicate default behavior
  // for the mapping rules engine or turn on or off specific features.
  // Such examples can be: convert_foreign_key_to_interleave=true,
  // skip_triggers=false, ignore_non_table_synonyms=true
  map<string, string> global_settings = 4
      [(google.api.field_behavior) = OPTIONAL];

  // Output only. Whether the workspace has uncommitted changes (changes which
  // were made after the workspace was committed).
  bool has_uncommitted_changes = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The latest commit ID.
  string latest_commit_id = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp when the workspace was committed.
  google.protobuf.Timestamp latest_commit_time = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp when the workspace resource was created.
  google.protobuf.Timestamp create_time = 9
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp when the workspace resource was last updated.
  google.protobuf.Timestamp update_time = 10
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. The display name for the workspace.
  string display_name = 11 [(google.api.field_behavior) = OPTIONAL];
}

// Execution log of a background job.
message BackgroundJobLogEntry {
  // Final state after a job completes.
  enum JobCompletionState {
    // The status is not specified. This state is used when job is not yet
    // finished.
    JOB_COMPLETION_STATE_UNSPECIFIED = 0;

    // Success.
    SUCCEEDED = 1;

    // Error.
    FAILED = 2;
  }

  // Details regarding a Seed background job.
  message SeedJobDetails {
    // Output only. The connection profile which was used for the seed job.
    string connection_profile = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Details regarding an Import Rules background job.
  message ImportRulesJobDetails {
    // Output only. File names used for the import rules job.
    repeated string files = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The requested file format.
    ImportRulesFileFormat file_format = 2
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Details regarding a Convert background job.
  message ConvertJobDetails {
    // Output only. AIP-160 based filter used to specify the entities to convert
    string filter = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Details regarding an Apply background job.
  message ApplyJobDetails {
    // Output only. The connection profile which was used for the apply job.
    string connection_profile = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. AIP-160 based filter used to specify the entities to apply
    string filter = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // The background job log entry ID.
  string id = 1;

  // The type of job that was executed.
  BackgroundJobType job_type = 2;

  // The timestamp when the background job was started.
  google.protobuf.Timestamp start_time = 3;

  // The timestamp when the background job was finished.
  google.protobuf.Timestamp finish_time = 4;

  // Output only. Job completion state, i.e. the final state after the job
  // completed.
  JobCompletionState completion_state = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Job completion comment, such as how many entities were seeded,
  // how many warnings were found during conversion, and similar information.
  string completion_comment = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Whether the client requested the conversion workspace to be
  // committed after a successful completion of the job.
  bool request_autocommit = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  oneof job_details {
    // Output only. Seed job details.
    SeedJobDetails seed_job_details = 100
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Import rules job details.
    ImportRulesJobDetails import_rules_job_details = 101
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Convert job details.
    ConvertJobDetails convert_job_details = 102
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Apply job details.
    ApplyJobDetails apply_job_details = 103
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }
}

// A filter defining the entities that a mapping rule should be applied to.
// When more than one field is specified, the rule is applied only to
// entities which match all the fields.
message MappingRuleFilter {
  // Optional. The rule should be applied to entities whose parent entity
  // (fully qualified name) matches the given value.
  // For example, if the rule applies to a table entity, the expected value
  // should be a schema (schema). If the rule applies to a column or index
  // entity, the expected value can be either a schema (schema) or a table
  // (schema.table)
  string parent_entity = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The rule should be applied to entities whose non-qualified name
  // starts with the given prefix.
  string entity_name_prefix = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The rule should be applied to entities whose non-qualified name
  // ends with the given suffix.
  string entity_name_suffix = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The rule should be applied to entities whose non-qualified name
  // contains the given string.
  string entity_name_contains = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The rule should be applied to specific entities defined by their
  // fully qualified names.
  repeated string entities = 5 [(google.api.field_behavior) = OPTIONAL];
}

// Definition of a transformation that is to be applied to a group of entities
// in the source schema. Several such transformations can be applied to an
// entity sequentially to define the corresponding entity in the target schema.
message MappingRule {
  option (google.api.resource) = {
    type: "datamigration.googleapis.com/MappingRule"
    pattern: "projects/{project}/locations/{location}/conversionWorkspaces/{conversion_workspace}/mappingRules/{mapping_rule}"
    plural: "mappingRules"
    singular: "mappingRule"
  };

  // The current mapping rule state such as enabled, disabled or deleted.
  enum State {
    // The state of the mapping rule is unknown.
    STATE_UNSPECIFIED = 0;

    // The rule is enabled.
    ENABLED = 1;

    // The rule is disabled.
    DISABLED = 2;

    // The rule is logically deleted.
    DELETED = 3;
  }

  // Full name of the mapping rule resource, in the form of:
  // projects/{project}/locations/{location}/conversionWorkspaces/{set}/mappingRule/{rule}.
  string name = 1;

  // Optional. A human readable name
  string display_name = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The mapping rule state
  State state = 3 [(google.api.field_behavior) = OPTIONAL];

  // Required. The rule scope
  DatabaseEntityType rule_scope = 4 [(google.api.field_behavior) = REQUIRED];

  // Required. The rule filter
  MappingRuleFilter filter = 5 [(google.api.field_behavior) = REQUIRED];

  // Required. The order in which the rule is applied. Lower order rules are
  // applied before higher value rules so they may end up being overridden.
  int64 rule_order = 6 [(google.api.field_behavior) = REQUIRED];

  // Output only. The revision ID of the mapping rule.
  // A new revision is committed whenever the mapping rule is changed in any
  // way. The format is an 8-character hexadecimal string.
  string revision_id = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The timestamp that the revision was created.
  google.protobuf.Timestamp revision_create_time = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // The rule specific details.
  oneof details {
    // Optional. Rule to specify how a single entity should be renamed.
    SingleEntityRename single_entity_rename = 102
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Rule to specify how multiple entities should be renamed.
    MultiEntityRename multi_entity_rename = 103
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Rule to specify how multiple entities should be relocated into
    // a different schema.
    EntityMove entity_move = 105 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Rule to specify how a single column is converted.
    SingleColumnChange single_column_change = 106
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Rule to specify how multiple columns should be converted to a
    // different data type.
    MultiColumnDatatypeChange multi_column_data_type_change = 107
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Rule to specify how the data contained in a column should be
    // transformed (such as trimmed, rounded, etc) provided that the data meets
    // certain criteria.
    ConditionalColumnSetValue conditional_column_set_value = 108
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Rule to specify how multiple tables should be converted with an
    // additional rowid column.
    ConvertRowIdToColumn convert_rowid_column = 114
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Rule to specify the primary key for a table
    SetTablePrimaryKey set_table_primary_key = 115
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Rule to specify how a single package is converted.
    SinglePackageChange single_package_change = 116
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Rule to change the sql code for an entity, for example,
    // function, procedure.
    SourceSqlChange source_sql_change = 117
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Rule to specify the list of columns to include or exclude from
    // a table.
    FilterTableColumns filter_table_columns = 118
        [(google.api.field_behavior) = OPTIONAL];
  }
}

// Options to configure rule type SingleEntityRename.
// The rule is used to rename an entity.
//
// The rule filter field can refer to only one entity.
//
// The rule scope can be one of: Database, Schema, Table, Column, Constraint,
// Index, View, Function, Stored Procedure, Materialized View, Sequence, UDT,
// Synonym
message SingleEntityRename {
  // Required. The new name of the destination entity
  string new_name = 1 [(google.api.field_behavior) = REQUIRED];
}

// Options to configure rule type MultiEntityRename.
// The rule is used to rename multiple entities.
//
// The rule filter field can refer to one or more entities.
//
// The rule scope can be one of: Database, Schema, Table, Column, Constraint,
// Index, View, Function, Stored Procedure, Materialized View, Sequence, UDT
message MultiEntityRename {
  // Optional. The pattern used to generate the new entity's name. This pattern
  // must include the characters '{name}', which will be replaced with the name
  // of the original entity. For example, the pattern 't_{name}' for an entity
  // name jobs would be converted to 't_jobs'.
  //
  // If unspecified, the default value for this field is '{name}'
  string new_name_pattern = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Additional transformation that can be done on the source entity
  // name before it is being used by the new_name_pattern, for example lower
  // case. If no transformation is desired, use NO_TRANSFORMATION
  EntityNameTransformation source_name_transformation = 2
      [(google.api.field_behavior) = OPTIONAL];
}

// Options to configure rule type EntityMove.
// The rule is used to move an entity to a new schema.
//
// The rule filter field can refer to one or more entities.
//
// The rule scope can be one of: Table, Column, Constraint, Index, View,
// Function, Stored Procedure, Materialized View, Sequence, UDT
message EntityMove {
  // Required. The new schema
  string new_schema = 1 [(google.api.field_behavior) = REQUIRED];
}

// Options to configure rule type SingleColumnChange.
// The rule is used to change the properties of a column.
//
// The rule filter field can refer to one entity.
//
// The rule scope can be one of: Column.
//
// When using this rule, if a field is not specified than the destination
// column's configuration will be the same as the one in the source column..
message SingleColumnChange {
  // Optional. Column data type name.
  string data_type = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Charset override - instead of table level charset.
  string charset = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Collation override - instead of table level collation.
  string collation = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Column length - e.g. 50 as in varchar (50) - when relevant.
  int64 length = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Column precision - e.g. 8 as in double (8,2) - when relevant.
  int32 precision = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Column scale - e.g. 2 as in double (8,2) - when relevant.
  int32 scale = 6 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Column fractional seconds precision - e.g. 2 as in timestamp (2)
  // - when relevant.
  int32 fractional_seconds_precision = 7
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Is the column of array type.
  bool array = 8 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The length of the array, only relevant if the column type is an
  // array.
  int32 array_length = 9 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Is the column nullable.
  bool nullable = 10 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Is the column auto-generated/identity.
  bool auto_generated = 11 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Is the column a UDT (User-defined Type).
  bool udt = 12 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Custom engine specific features.
  google.protobuf.Struct custom_features = 13
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Specifies the list of values allowed in the column.
  repeated string set_values = 14 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Comment associated with the column.
  string comment = 15 [(google.api.field_behavior) = OPTIONAL];
}

// Options to configure rule type MultiColumnDatatypeChange.
// The rule is used to change the data type and associated properties of
// multiple columns at once.
//
// The rule filter field can refer to one or more entities.
//
// The rule scope can be one of:Column.
//
// This rule requires additional filters to be specified beyond the basic rule
// filter field, which is the source data type, but the rule supports additional
// filtering capabilities such as the minimum and maximum field length. All
// additional filters which are specified are required to be met in order for
// the rule to be applied (logical AND between the fields).
message MultiColumnDatatypeChange {
  // Required. Filter on source data type.
  string source_data_type_filter = 1 [(google.api.field_behavior) = REQUIRED];

  // Filter on source column parameters.
  oneof source_filter {
    // Optional. Filter for text-based data types like varchar.
    SourceTextFilter source_text_filter = 100
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Filter for fixed point number data types such as
    // NUMERIC/NUMBER.
    SourceNumericFilter source_numeric_filter = 101
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Required. New data type.
  string new_data_type = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. Column length - e.g. varchar (50) - if not specified and relevant
  // uses the source column length.
  int64 override_length = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Column scale - when relevant - if not specified and relevant
  // uses the source column scale.
  int32 override_scale = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Column precision - when relevant - if not specified and relevant
  // uses the source column precision.
  int32 override_precision = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Column fractional seconds precision - used only for timestamp
  // based datatypes - if not specified and relevant uses the source column
  // fractional seconds precision.
  int32 override_fractional_seconds_precision = 6
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Custom engine specific features.
  google.protobuf.Struct custom_features = 7
      [(google.api.field_behavior) = OPTIONAL];
}

// Filter for text-based data types like varchar.
message SourceTextFilter {
  // Optional. The filter will match columns with length greater than or equal
  // to this number.
  int64 source_min_length_filter = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The filter will match columns with length smaller than or equal
  // to this number.
  int64 source_max_length_filter = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Filter for fixed point number data types such as NUMERIC/NUMBER
message SourceNumericFilter {
  // Optional. The filter will match columns with scale greater than or equal to
  // this number.
  int32 source_min_scale_filter = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The filter will match columns with scale smaller than or equal to
  // this number.
  int32 source_max_scale_filter = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The filter will match columns with precision greater than or
  // equal to this number.
  int32 source_min_precision_filter = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The filter will match columns with precision smaller than or
  // equal to this number.
  int32 source_max_precision_filter = 4
      [(google.api.field_behavior) = OPTIONAL];

  // Required. Enum to set the option defining the datatypes numeric filter has
  // to be applied to
  NumericFilterOption numeric_filter_option = 5
      [(google.api.field_behavior) = REQUIRED];
}

// Options to configure rule type ConditionalColumnSetValue.
// The rule is used to transform the data which is being replicated/migrated.
//
// The rule filter field can refer to one or more entities.
//
// The rule scope can be one of: Column.
message ConditionalColumnSetValue {
  oneof source_filter {
    // Optional. Optional filter on source column length. Used for text based
    // data types like varchar.
    SourceTextFilter source_text_filter = 100
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Optional filter on source column precision and scale. Used for
    // fixed point numbers such as NUMERIC/NUMBER data types.
    SourceNumericFilter source_numeric_filter = 101
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Required. Description of data transformation during migration.
  ValueTransformation value_transformation = 1
      [(google.api.field_behavior) = REQUIRED];

  // Optional. Custom engine specific features.
  google.protobuf.Struct custom_features = 2
      [(google.api.field_behavior) = OPTIONAL];
}

// Description of data transformation during migration as part of the
// ConditionalColumnSetValue.
message ValueTransformation {
  oneof filter {
    // Optional. Value is null
    google.protobuf.Empty is_null = 100
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Value is found in the specified list.
    ValueListFilter value_list = 101 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Filter on relation between source value and compare value of
    // type integer.
    IntComparisonFilter int_comparison = 102
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Filter on relation between source value and compare value of
    // type double.
    DoubleComparisonFilter double_comparison = 103
        [(google.api.field_behavior) = OPTIONAL];
  }

  oneof action {
    // Optional. Set to null
    google.protobuf.Empty assign_null = 200
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Set to a specific value (value is converted to fit the target
    // data type)
    AssignSpecificValue assign_specific_value = 201
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Set to min_value - if integer or numeric, will use
    // int.minvalue, etc
    google.protobuf.Empty assign_min_value = 202
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Set to max_value - if integer or numeric, will use
    // int.maxvalue, etc
    google.protobuf.Empty assign_max_value = 203
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Allows the data to change scale
    RoundToScale round_scale = 204 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Applies a hash function on the data
    ApplyHash apply_hash = 205 [(google.api.field_behavior) = OPTIONAL];
  }
}

// Options to configure rule type ConvertROWIDToColumn.
// The rule is used to add column rowid to destination tables based on an Oracle
// rowid function/property.
//
// The rule filter field can refer to one or more entities.
//
// The rule scope can be one of: Table.
//
// This rule requires additional filter to be specified beyond the basic rule
// filter field, which is whether or not to work on tables which already have a
// primary key defined.
message ConvertRowIdToColumn {
  // Required. Only work on tables without primary key defined
  bool only_if_no_primary_key = 1 [(google.api.field_behavior) = REQUIRED];
}

// Options to configure rule type SetTablePrimaryKey.
// The rule is used to specify the columns and name to configure/alter the
// primary key of a table.
//
// The rule filter field can refer to one entity.
//
// The rule scope can be one of: Table.
message SetTablePrimaryKey {
  // Required. List of column names for the primary key
  repeated string primary_key_columns = 1
      [(google.api.field_behavior) = REQUIRED];

  // Optional. Name for the primary key
  string primary_key = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Options to configure rule type SinglePackageChange.
// The rule is used to alter the sql code for a package entities.
//
// The rule filter field can refer to one entity.
//
// The rule scope can be: Package
message SinglePackageChange {
  // Optional. Sql code for package description
  string package_description = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Sql code for package body
  string package_body = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Options to configure rule type SourceSqlChange.
// The rule is used to alter the sql code for database entities.
//
// The rule filter field can refer to one entity.
//
// The rule scope can be: StoredProcedure, Function, Trigger, View
message SourceSqlChange {
  // Required. Sql code for source (stored procedure, function, trigger or view)
  string sql_code = 1 [(google.api.field_behavior) = REQUIRED];
}

// Options to configure rule type FilterTableColumns.
// The rule is used to filter the list of columns to include or exclude from a
// table.
//
// The rule filter field can refer to one entity.
//
// The rule scope can be: Table
//
// Only one of the two lists can be specified for the rule.
message FilterTableColumns {
  // Optional. List of columns to be included for a particular table.
  repeated string include_columns = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. List of columns to be excluded for a particular table.
  repeated string exclude_columns = 2 [(google.api.field_behavior) = OPTIONAL];
}

// A list of values to filter by in ConditionalColumnSetValue
message ValueListFilter {
  // Required. Indicates whether the filter matches rows with values that are
  // present in the list or those with values not present in it.
  ValuePresentInList value_present_list = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. The list to be used to filter by
  repeated string values = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Whether to ignore case when filtering by values. Defaults to
  // false
  bool ignore_case = 3 [(google.api.field_behavior) = REQUIRED];
}

// Filter based on relation between source value and compare value of type
// integer in ConditionalColumnSetValue
message IntComparisonFilter {
  // Required. Relation between source value and compare value
  ValueComparison value_comparison = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Integer compare value to be used
  int64 value = 2 [(google.api.field_behavior) = REQUIRED];
}

// Filter based on relation between source
// value and compare value of type double in ConditionalColumnSetValue
message DoubleComparisonFilter {
  // Required. Relation between source value and compare value
  ValueComparison value_comparison = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Double compare value to be used
  double value = 2 [(google.api.field_behavior) = REQUIRED];
}

// Set to a specific value (value is converted to fit the target data type)
message AssignSpecificValue {
  // Required. Specific value to be assigned
  string value = 1 [(google.api.field_behavior) = REQUIRED];
}

// Apply a hash function on the value.
message ApplyHash {
  oneof hash_function {
    // Optional. Generate UUID from the data's byte array
    google.protobuf.Empty uuid_from_bytes = 100
        [(google.api.field_behavior) = OPTIONAL];
  }
}

// This allows the data to change scale, for example if the source is 2 digits
// after the decimal point, specify round to scale value = 2. If for example the
// value needs to be converted to an integer, use round to scale value = 0.
message RoundToScale {
  // Required. Scale value to be used
  int32 scale = 1 [(google.api.field_behavior) = REQUIRED];
}

// The base entity type for all the database related entities.
// The message contains the entity name, the name of its parent, the entity
// type, and the specific details per entity type.
message DatabaseEntity {
  // The type of database entities tree.
  enum TreeType {
    // Tree type unspecified.
    TREE_TYPE_UNSPECIFIED = 0;

    // Tree of entities loaded from a source database.
    SOURCE = 1;

    // Tree of entities converted from the source tree using the mapping rules.
    DRAFT = 2;

    // Tree of entities observed on the destination database.
    DESTINATION = 3;
  }

  // The short name (e.g. table name) of the entity.
  string short_name = 1;

  // The full name of the parent entity (e.g. schema name).
  string parent_entity = 2;

  // The type of tree the entity belongs to.
  TreeType tree = 3;

  // The type of the database entity (table, view, index, ...).
  DatabaseEntityType entity_type = 4;

  // Details about entity mappings.
  // For source tree entities, this holds the draft entities which were
  // generated by the mapping rules.
  // For draft tree entities, this holds the source entities which were
  // converted to form the draft entity.
  // Destination entities will have no mapping details.
  repeated EntityMapping mappings = 5;

  // Details about the entity DDL script. Multiple DDL scripts are provided for
  // child entities such as a table entity will have one DDL for the table with
  // additional DDLs for each index, constraint and such.
  repeated EntityDdl entity_ddl = 6;

  // Details about the various issues found for the entity.
  repeated EntityIssue issues = 7;

  // The specific body for each entity type.
  oneof entity_body {
    // Database.
    DatabaseInstanceEntity database = 101;

    // Schema.
    SchemaEntity schema = 102;

    // Table.
    TableEntity table = 103;

    // View.
    ViewEntity view = 104;

    // Sequence.
    SequenceEntity sequence = 105;

    // Stored procedure.
    StoredProcedureEntity stored_procedure = 106;

    // Function.
    FunctionEntity database_function = 107;

    // Synonym.
    SynonymEntity synonym = 108;

    // Package.
    PackageEntity database_package = 109;

    // UDT.
    UDTEntity udt = 110;

    // Materialized view.
    MaterializedViewEntity materialized_view = 111;
  }
}

// DatabaseInstance acts as a parent entity to other database entities.
message DatabaseInstanceEntity {
  // Custom engine specific features.
  google.protobuf.Struct custom_features = 1;
}

// Schema typically has no parent entity, but can have a parent entity
// DatabaseInstance (for database engines which support it).  For some database
// engines, the terms  schema and user can be used interchangeably when they
// refer to a namespace or a collection of other database entities. Can store
// additional information which is schema specific.
message SchemaEntity {
  // Custom engine specific features.
  google.protobuf.Struct custom_features = 1;
}

// Table's parent is a schema.
message TableEntity {
  // Table columns.
  repeated ColumnEntity columns = 1;

  // Table constraints.
  repeated ConstraintEntity constraints = 2;

  // Table indices.
  repeated IndexEntity indices = 3;

  // Table triggers.
  repeated TriggerEntity triggers = 4;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 5;

  // Comment associated with the table.
  string comment = 6;
}

// Column is not used as an independent entity, it is retrieved as part of a
// Table entity.
message ColumnEntity {
  // Column name.
  string name = 1;

  // Column data type.
  string data_type = 2;

  // Charset override - instead of table level charset.
  string charset = 3;

  // Collation override - instead of table level collation.
  string collation = 4;

  // Column length - e.g. varchar (50).
  int64 length = 5;

  // Column precision - when relevant.
  int32 precision = 6;

  // Column scale - when relevant.
  int32 scale = 7;

  // Column fractional second precision - used for timestamp based datatypes.
  int32 fractional_seconds_precision = 8;

  // Is the column of array type.
  bool array = 9;

  // If the column is array, of which length.
  int32 array_length = 10;

  // Is the column nullable.
  bool nullable = 11;

  // Is the column auto-generated/identity.
  bool auto_generated = 12;

  // Is the column a UDT.
  bool udt = 13;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 14;

  // Specifies the list of values allowed in the column.
  // Only used for set data type.
  repeated string set_values = 15;

  // Comment associated with the column.
  string comment = 16;

  // Column order in the table.
  int32 ordinal_position = 17;

  // Default value of the column.
  string default_value = 18;
}

// Constraint is not used as an independent entity, it is retrieved
// as part of another entity such as Table or View.
message ConstraintEntity {
  // The name of the table constraint.
  string name = 1;

  // Type of constraint, for example unique, primary key, foreign key (currently
  // only primary key is supported).
  string type = 2;

  // Table columns used as part of the Constraint, for example primary key
  // constraint should list the columns which constitutes the key.
  repeated string table_columns = 3;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 4;

  // Reference columns which may be associated with the constraint. For example,
  // if the constraint is a FOREIGN_KEY, this represents the list of full names
  // of referenced columns by the foreign key.
  repeated string reference_columns = 5;

  // Reference table which may be associated with the constraint. For example,
  // if the constraint is a FOREIGN_KEY, this represents the list of full name
  // of the referenced table by the foreign key.
  string reference_table = 6;

  // Table which is associated with the constraint. In case the constraint
  // is defined on a table, this field is left empty as this information is
  // stored in parent_name. However, if constraint is defined on a view, this
  // field stores the table name on which the view is defined.
  string table_name = 7;
}

// Index is not used as an independent entity, it is retrieved as part of a
// Table entity.
message IndexEntity {
  // The name of the index.
  string name = 1;

  // Type of index, for example B-TREE.
  string type = 2;

  // Table columns used as part of the Index, for example B-TREE index should
  // list the columns which constitutes the index.
  repeated string table_columns = 3;

  // Boolean value indicating whether the index is unique.
  bool unique = 4;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 5;
}

// Trigger is not used as an independent entity, it is retrieved as part of a
// Table entity.
message TriggerEntity {
  // The name of the trigger.
  string name = 1;

  // The DML, DDL, or database events that fire the trigger, for example
  // INSERT, UPDATE.
  repeated string triggering_events = 2;

  // Indicates when the trigger fires, for example BEFORE STATEMENT, AFTER EACH
  // ROW.
  string trigger_type = 3;

  // The SQL code which creates the trigger.
  string sql_code = 4;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 5;
}

// View's parent is a schema.
message ViewEntity {
  // The SQL code which creates the view.
  string sql_code = 1;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 2;

  // View constraints.
  repeated ConstraintEntity constraints = 3;
}

// Sequence's parent is a schema.
message SequenceEntity {
  // Increment value for the sequence.
  int64 increment = 1;

  // Start number for the sequence represented as bytes to accommodate large.
  // numbers
  bytes start_value = 2;

  // Maximum number for the sequence represented as bytes to accommodate large.
  // numbers
  bytes max_value = 3;

  // Minimum number for the sequence represented as bytes to accommodate large.
  // numbers
  bytes min_value = 4;

  // Indicates whether the sequence value should cycle through.
  bool cycle = 5;

  // Indicates number of entries to cache / precreate.
  int64 cache = 6;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 7;
}

// Stored procedure's parent is a schema.
message StoredProcedureEntity {
  // The SQL code which creates the stored procedure.
  string sql_code = 1;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 2;
}

// Function's parent is a schema.
message FunctionEntity {
  // The SQL code which creates the function.
  string sql_code = 1;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 2;
}

// MaterializedView's parent is a schema.
message MaterializedViewEntity {
  // The SQL code which creates the view.
  string sql_code = 1;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 2;
}

// Synonym's parent is a schema.
message SynonymEntity {
  // The name of the entity for which the synonym is being created (the source).
  string source_entity = 1;

  // The type of the entity for which the synonym is being created
  // (usually a table or a sequence).
  DatabaseEntityType source_type = 2;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 3;
}

// Package's parent is a schema.
message PackageEntity {
  // The SQL code which creates the package.
  string package_sql_code = 1;

  // The SQL code which creates the package body. If the package specification
  // has cursors or subprograms, then the package body is mandatory.
  string package_body = 2;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 3;
}

// UDT's parent is a schema.
message UDTEntity {
  // The SQL code which creates the udt.
  string udt_sql_code = 1;

  // The SQL code which creates the udt body.
  string udt_body = 2;

  // Custom engine specific features.
  google.protobuf.Struct custom_features = 3;
}

// Details of the mappings of a database entity.
message EntityMapping {
  // Source entity full name.
  // The source entity can also be a column, index or constraint using the
  // same naming notation schema.table.column.
  string source_entity = 1;

  // Target entity full name.
  // The draft entity can also include a column, index or constraint using the
  // same naming notation schema.table.column.
  string draft_entity = 2;

  // Type of source entity.
  DatabaseEntityType source_type = 4;

  // Type of draft entity.
  DatabaseEntityType draft_type = 5;

  // Entity mapping log entries.
  // Multiple rules can be effective and contribute changes to a converted
  // entity, such as a rule can handle the entity name, another rule can handle
  // an entity type. In addition, rules which did not change the entity are also
  // logged along with the reason preventing them to do so.
  repeated EntityMappingLogEntry mapping_log = 3;
}

// A single record of a rule which was used for a mapping.
message EntityMappingLogEntry {
  // Which rule caused this log entry.
  string rule_id = 1;

  // Rule revision ID.
  string rule_revision_id = 2;

  // Comment.
  string mapping_comment = 3;
}

// A single DDL statement for a specific entity
message EntityDdl {
  // Type of DDL (Create, Alter).
  string ddl_type = 1;

  // The name of the database entity the ddl refers to.
  string entity = 2;

  // The actual ddl code.
  string ddl = 3;

  // The entity type (if the DDL is for a sub entity).
  DatabaseEntityType entity_type = 4;

  // EntityIssues found for this ddl.
  repeated string issue_id = 100;
}

// Issue related to the entity.
message EntityIssue {
  // Type of issue.
  enum IssueType {
    // Unspecified issue type.
    ISSUE_TYPE_UNSPECIFIED = 0;

    // Issue originated from the DDL
    ISSUE_TYPE_DDL = 1;

    // Issue originated during the apply process
    ISSUE_TYPE_APPLY = 2;

    // Issue originated during the convert process
    ISSUE_TYPE_CONVERT = 3;
  }

  // Severity of issue.
  enum IssueSeverity {
    // Unspecified issue severity
    ISSUE_SEVERITY_UNSPECIFIED = 0;

    // Info
    ISSUE_SEVERITY_INFO = 1;

    // Warning
    ISSUE_SEVERITY_WARNING = 2;

    // Error
    ISSUE_SEVERITY_ERROR = 3;
  }

  // Issue position.
  message Position {
    // Issue line number
    int32 line = 1;

    // Issue column number
    int32 column = 2;

    // Issue offset
    int32 offset = 3;

    // Issue length
    int32 length = 4;
  }

  // Unique Issue ID.
  string id = 1;

  // The type of the issue.
  IssueType type = 2;

  // Severity of the issue
  IssueSeverity severity = 3;

  // Issue detailed message
  string message = 4;

  // Error/Warning code
  string code = 5;

  // The ddl which caused the issue, if relevant.
  optional string ddl = 6;

  // The position of the issue found, if relevant.
  optional Position position = 7;

  // The entity type (if the DDL is for a sub entity).
  DatabaseEntityType entity_type = 8;
}

// Enum used by ValueListFilter to indicate whether the source value is in the
// supplied list
enum ValuePresentInList {
  // Value present in list unspecified
  VALUE_PRESENT_IN_LIST_UNSPECIFIED = 0;

  // If the source value is in the supplied list at value_list
  VALUE_PRESENT_IN_LIST_IF_VALUE_LIST = 1;

  // If the source value is not in the supplied list at value_list
  VALUE_PRESENT_IN_LIST_IF_VALUE_NOT_LIST = 2;
}

// The type of database entities supported,
enum DatabaseEntityType {
  // Unspecified database entity type.
  DATABASE_ENTITY_TYPE_UNSPECIFIED = 0;

  // Schema.
  DATABASE_ENTITY_TYPE_SCHEMA = 1;

  // Table.
  DATABASE_ENTITY_TYPE_TABLE = 2;

  // Column.
  DATABASE_ENTITY_TYPE_COLUMN = 3;

  // Constraint.
  DATABASE_ENTITY_TYPE_CONSTRAINT = 4;

  // Index.
  DATABASE_ENTITY_TYPE_INDEX = 5;

  // Trigger.
  DATABASE_ENTITY_TYPE_TRIGGER = 6;

  // View.
  DATABASE_ENTITY_TYPE_VIEW = 7;

  // Sequence.
  DATABASE_ENTITY_TYPE_SEQUENCE = 8;

  // Stored Procedure.
  DATABASE_ENTITY_TYPE_STORED_PROCEDURE = 9;

  // Function.
  DATABASE_ENTITY_TYPE_FUNCTION = 10;

  // Synonym.
  DATABASE_ENTITY_TYPE_SYNONYM = 11;

  // Package.
  DATABASE_ENTITY_TYPE_DATABASE_PACKAGE = 12;

  // UDT.
  DATABASE_ENTITY_TYPE_UDT = 13;

  // Materialized View.
  DATABASE_ENTITY_TYPE_MATERIALIZED_VIEW = 14;

  // Database.
  DATABASE_ENTITY_TYPE_DATABASE = 15;
}

// Entity Name Transformation Types
enum EntityNameTransformation {
  // Entity name transformation unspecified.
  ENTITY_NAME_TRANSFORMATION_UNSPECIFIED = 0;

  // No transformation.
  ENTITY_NAME_TRANSFORMATION_NO_TRANSFORMATION = 1;

  // Transform to lower case.
  ENTITY_NAME_TRANSFORMATION_LOWER_CASE = 2;

  // Transform to upper case.
  ENTITY_NAME_TRANSFORMATION_UPPER_CASE = 3;

  // Transform to capitalized case.
  ENTITY_NAME_TRANSFORMATION_CAPITALIZED_CASE = 4;
}

// The types of jobs that can be executed in the background.
enum BackgroundJobType {
  // Unspecified background job type.
  BACKGROUND_JOB_TYPE_UNSPECIFIED = 0;

  // Job to seed from the source database.
  BACKGROUND_JOB_TYPE_SOURCE_SEED = 1;

  // Job to convert the source database into a draft of the destination
  // database.
  BACKGROUND_JOB_TYPE_CONVERT = 2;

  // Job to apply the draft tree onto the destination.
  BACKGROUND_JOB_TYPE_APPLY_DESTINATION = 3;

  // Job to import and convert mapping rules from an external source such as an
  // ora2pg config file.
  BACKGROUND_JOB_TYPE_IMPORT_RULES_FILE = 5;
}

// The format for the import rules file.
enum ImportRulesFileFormat {
  // Unspecified rules format.
  IMPORT_RULES_FILE_FORMAT_UNSPECIFIED = 0;

  // HarbourBridge session file.
  IMPORT_RULES_FILE_FORMAT_HARBOUR_BRIDGE_SESSION_FILE = 1;

  // Ora2Pg configuration file.
  IMPORT_RULES_FILE_FORMAT_ORATOPG_CONFIG_FILE = 2;
}

// Enum used by IntComparisonFilter and DoubleComparisonFilter to indicate the
// relation between source value and compare value.
enum ValueComparison {
  // Value comparison unspecified.
  VALUE_COMPARISON_UNSPECIFIED = 0;

  // Value is smaller than the Compare value.
  VALUE_COMPARISON_IF_VALUE_SMALLER_THAN = 1;

  // Value is smaller or equal than the Compare value.
  VALUE_COMPARISON_IF_VALUE_SMALLER_EQUAL_THAN = 2;

  // Value is larger than the Compare value.
  VALUE_COMPARISON_IF_VALUE_LARGER_THAN = 3;

  // Value is larger or equal than the Compare value.
  VALUE_COMPARISON_IF_VALUE_LARGER_EQUAL_THAN = 4;
}

// Specifies the columns on which numeric filter needs to be applied.
enum NumericFilterOption {
  // Numeric filter option unspecified
  NUMERIC_FILTER_OPTION_UNSPECIFIED = 0;

  // Numeric filter option that matches all numeric columns.
  NUMERIC_FILTER_OPTION_ALL = 1;

  // Numeric filter option that matches columns having numeric datatypes with
  // specified precision and scale within the limited range of filter.
  NUMERIC_FILTER_OPTION_LIMIT = 2;

  // Numeric filter option that matches only the numeric columns with no
  // precision and scale specified.
  NUMERIC_FILTER_OPTION_LIMITLESS = 3;
}
