package tablestore.proto;

message Error {
    required string code = 1;
    optional string message = 2;
}

enum PrimaryKeyType {
    INTEGER = 1;
    STRING = 2;
    BINARY = 3;
}

enum PrimaryKeyOption {
    AUTO_INCREMENT = 1;
}

message PrimaryKeySchema {
    required string name = 1;
    required PrimaryKeyType type = 2;
    optional PrimaryKeyOption option = 3; 
}

message PartitionRange {
    required bytes begin = 1; // encoded as SQLVariant
    required bytes end = 2; // encoded as SQLVariant
}

enum BloomFilterType {
    NONE = 1;
    CELL = 2;
    ROW = 3;
}

message TableOptions {
    optional int32 time_to_live = 1; // 可以动态更改
    optional int32 max_versions = 2; // 可以动态更改
    optional BloomFilterType bloom_filter_type = 3; // 可以动态更改
    optional int32 block_size = 4; // 可以动态更改
    optional int64 deviation_cell_version_in_sec = 5; // 可以动态修改
}

message TableMeta {
    required string table_name = 1;
    repeated PrimaryKeySchema primary_key = 2;
}

/**
 * 表的状态变更只与用户的操作对应，内部的机器failover等状况不对应表的状态变更。
 * 有三个考虑：
 *     一是一般场景下用户只会在做了对表的修改操作后才会去检查表的状态；
 *     二是内部机器failover导致访问异常到用户能够查看到表的状态变更这两个时刻之间会有一段延迟，无法将表的不可服务状态与用户查看到的表的状态完全匹配上。
 *     三是内部机器failover后不能说是表的整个状态变更，而应该是partition的状态变更，对应表的状态就是PARTIAL_FAILOVER，这个partial的粒度无法体现，会让用户更加困惑。
 */
enum TableStatus {
    ACTIVE = 1; // 表处于可服务状态。
    INACTIVE = 2; // 用户通过UnloadTable将表禁用。
    LOADING = 3; // 表正在被创建，partition还未全部加载完毕；或者表刚从INACTIVE状态被Enable。
    UNLOADING = 4; // 表正在被删除（从delete table到partition完全unload的这段期间）或者表从ACTIVE状态被Unload。
    UPDATING = 5; // 表正在被更新（table属性变更、预留吞吐量变更）。
}

enum RowExistenceExpectation {
    IGNORE = 0;
    EXPECT_EXIST = 1;
    EXPECT_NOT_EXIST = 2;
}

message Condition {
    required RowExistenceExpectation row_existence = 1;
    optional bytes column_condition      = 2;
}

message CapacityUnit {
    optional int32 read = 1;
    optional int32 write = 2;
}

message ReservedThroughputDetails {
    required CapacityUnit capacity_unit = 1; // 表当前的预留吞吐量的值。
    required int64 last_increase_time = 2; // 最后一次上调预留吞吐量的时间。
    optional int64 last_decrease_time = 3; // 最后一次下调预留吞吐量的时间。
}

message ReservedThroughput {
    required CapacityUnit capacity_unit = 1;
}

message ConsumedCapacity {
    required CapacityUnit capacity_unit = 1;
}

/* #############################################  CreateTable  ############################################# */
/**
 * table_meta用于存储表中不可更改的schema属性，可以更改的ReservedThroughput和TableOptions独立出来，作为UpdateTable的参数。
 * 加入GlobalIndex和LocalIndex之后，结构会变为：
 * message CreateTableRequest {
 *         required TableMeta table_meta = 1;
 *         required ReservedThroughput reserved_throughput = 2;
 *         required TableOptions table_options = 3;
 *         repeated LocalIndex local_indexes = 4; // LocalIndex不再单独包含ReservedThroughput和TableOptions，其与主表共享配置。
 *         repeated GlobalIndex global_indexes = 5; // GlobalIndex内单独包含ReservedThroughput和TableOptions
 * }
 */
message CreateTableRequest {
    required TableMeta table_meta = 1;
    required ReservedThroughput reserved_throughput = 2; // 未放在TableOptions内，原因是UpdateTableResponse中会返回ReservedThroughputDetails，而TableOptions没有类似的返回结构。
    optional TableOptions table_options = 3;
    repeated PartitionRange partitions = 4;
}

message CreateTableResponse {
}

/* ######################################################################################################### */


/* #############################################  UpdateTable  ############################################# */
message UpdateTableRequest {
    required string table_name = 1;
    optional ReservedThroughput reserved_throughput = 2;
    optional TableOptions table_options = 3;
}

message UpdateTableResponse {
    required ReservedThroughputDetails reserved_throughput_details = 1;
    required TableOptions table_options = 2;
}
/* ######################################################################################################### */

/* #############################################  DescribeTable  ############################################# */
message DescribeTableRequest {
    required string table_name = 1;
}

message DescribeTableResponse {
    required TableMeta table_meta = 1;
    required ReservedThroughputDetails reserved_throughput_details = 2;
    required TableOptions table_options = 3;
    required TableStatus table_status = 4;
    repeated bytes shard_splits = 6;
}
/* ########################################################################################################### */

/* #############################################  ListTable  ############################################# */
message ListTableRequest {
}

/**
 * 当前只返回一个简单的名称列表，需要讨论是否有业务场景需要获取除了表名之外的其他信息。
 * 其他信息可以包含预留吞吐量以及表的状态，这个信息只能是一个粗略的信息，表的详细信息还是需要通过DescribeTable来获取。
 */
message ListTableResponse {
    repeated string table_names = 1;
}
/* ####################################################################################################### */

/* #############################################  DeleteTable  ############################################# */
message DeleteTableRequest {
    required string table_name = 1;
}

message DeleteTableResponse {
}
/* ######################################################################################################### */

/* #############################################  LoadTable  ############################################# */
message LoadTableRequest {
    required string table_name = 1;
}

message LoadTableResponse {
}
/* ######################################################################################################### */

/* #############################################  UnloadTable  ############################################# */
message UnloadTableRequest {
    required string table_name = 1;
}

message UnloadTableResponse {

}
/* ########################################################################################################## */

/**
 * 时间戳的取值最小值为0，最大值为INT64.MAX
 * 1. 若要查询一个范围，则指定start_time和end_time
 * 2. 若要查询一个特定时间戳，则指定specific_time
 */
message TimeRange {
    optional int64 start_time = 1;
    optional int64 end_time = 2;
    optional int64 specific_time = 3;
}

/* #############################################  GetRow  ############################################# */

enum ReturnType {
    RT_NONE = 0;
    RT_PK = 1;
}

message ReturnContent {
    optional ReturnType return_type = 1;
}

/**
 * 1. 支持用户指定版本时间戳范围或者特定的版本时间来读取指定版本的列
 * 2. 目前暂不支持行内的断点
 */
message GetRowRequest {
    required string table_name = 1;
    required bytes primary_key = 2; // encoded as InplaceRowChangeSet, but only has primary key
    repeated string columns_to_get = 3; // 不指定则读出所有的列
    optional TimeRange time_range = 4;
    optional int32 max_versions = 5;
    optional bool cache_blocks = 6 [default = true]; // 本次读出的数据是否进入BlockCache
    optional bytes filter = 7;
    optional string start_column = 8;
    optional string end_column = 9;
    optional bytes token = 10;
}

message GetRowResponse {
    required ConsumedCapacity consumed = 1;
    required bytes row = 2; // encoded as InplaceRowChangeSet
    optional bytes next_token = 3;
}
/* #################################################################################################### */

/* #############################################  UpdateRow  ############################################# */
message UpdateRowRequest {
    required string table_name = 1;
    required bytes row_change = 2;
    required Condition condition = 3;
    optional ReturnContent return_content = 4;
}

message UpdateRowResponse {
    required ConsumedCapacity consumed = 1;
    optional bytes row = 2;
}
/* ####################################################################################################### */

/* #############################################  PutRow  ############################################# */


/**
 * 这里允许用户为每列单独设置timestamp，而不是强制整行统一一个timestamp。
 * 原因是列都是用统一的结构，该结构本身是带timestamp的，其次强制统一timestamp增强了规范性但是丧失了灵活性，且该规范性没有明显的好处，反而带来了结构的复杂。
 */
message PutRowRequest {
    required string table_name = 1;
    required bytes row = 2; // encoded as InplaceRowChangeSet
    required Condition condition = 3;
    optional ReturnContent return_content = 4;
}

message PutRowResponse {
    required ConsumedCapacity consumed = 1;
    optional bytes row = 2; // encoded as InplaceRowChangeSet
}
/* #################################################################################################### */

/* #############################################  DeleteRow  ############################################# */
/**
 * OTS只支持删除该行的所有列所有版本，不支持：
 *  1. 删除所有列的所有小于等于某个版本的所有版本
 */
message DeleteRowRequest {
    required string table_name = 1;
    required bytes primary_key = 2; // encoded as InplaceRowChangeSet, but only has primary key
    required Condition condition = 3;
    optional ReturnContent return_content = 4;
}

message DeleteRowResponse {
    required ConsumedCapacity consumed = 1;
    optional bytes row = 2;
}
/* ####################################################################################################### */

/* #############################################  BatchGetRow  ############################################# */
message TableInBatchGetRowRequest {
    required string table_name = 1;
    repeated bytes primary_key = 2; // encoded as InplaceRowChangeSet, but only has primary key
    repeated bytes token = 3;
    repeated string columns_to_get = 4;  // 不指定则读出所有的列
    optional TimeRange time_range = 5;
    optional int32 max_versions = 6;
    optional bool cache_blocks = 7 [default = true]; // 本次读出的数据是否进入BlockCache
    optional bytes filter = 8;
    optional string start_column = 9;
    optional string end_column = 10;
}

message BatchGetRowRequest {
    repeated TableInBatchGetRowRequest tables = 1;
}

message RowInBatchGetRowResponse {
    required bool is_ok = 1;
    optional Error error = 2;
    optional ConsumedCapacity consumed = 3;
    optional bytes row = 4; // encoded as InplaceRowChangeSet
    optional bytes next_token = 5;
}

message TableInBatchGetRowResponse {
    required string table_name = 1;
    repeated RowInBatchGetRowResponse rows = 2;
}

message BatchGetRowResponse {
    repeated TableInBatchGetRowResponse tables = 1;
}
/* ######################################################################################################### */

/* #############################################  BatchWriteRow  ############################################# */

enum OperationType {
    PUT = 1;
    UPDATE = 2;
    DELETE = 3;
}

message RowInBatchWriteRowRequest {
    required OperationType type = 1;
    required bytes row_change = 2; // encoded as InplaceRowChangeSet
    required Condition condition = 3;
    optional ReturnContent return_content = 4;
}

message TableInBatchWriteRowRequest {
    required string table_name = 1;
    repeated RowInBatchWriteRowRequest rows = 2;
}

message BatchWriteRowRequest {
    repeated TableInBatchWriteRowRequest tables = 1;
}

message RowInBatchWriteRowResponse {
    required bool is_ok = 1;
    optional Error error = 2;
    optional ConsumedCapacity consumed = 3;
    optional bytes row = 4; // encoded as InplaceRowChangeSet
}

message TableInBatchWriteRowResponse {
    required string table_name = 1;
    repeated RowInBatchWriteRowResponse rows = 2;
}

message BatchWriteRowResponse {
    repeated TableInBatchWriteRowResponse tables = 1;
}
/* ########################################################################################################### */

/* #############################################  GetRange  ############################################# */
enum Direction {
    FORWARD = 0;
    BACKWARD = 1;
}

/**
 * HBase支持以下参数：
 *     1. TimeRange或指定time
 *     2. Filter（根据列值或列名来过滤）
 * 我们只支持给同版本的选择条件。
 */
message GetRangeRequest {
    required string table_name = 1;
    required Direction direction = 2;
    repeated string columns_to_get = 3;  // 不指定则读出所有的列
    optional TimeRange time_range = 4;
    optional int32 max_versions = 5;
    optional int32 limit = 6;
    required bytes inclusive_start_primary_key = 7; // encoded as InplaceRowChangeSet, but only has primary key
    required bytes exclusive_end_primary_key = 8; // encoded as InplaceRowChangeSet, but only has primary key
    optional bool cache_blocks = 9 [default = true]; // 本次读出的数据是否进入BlockCache
    optional bytes filter = 10;
    optional string start_column = 11;
    optional string end_column = 12;
    optional bytes token = 13;
}

message GetRangeResponse {
    required ConsumedCapacity consumed = 1;
    required bytes rows = 2; // encoded as InplaceRowChangeSet
    optional bytes next_start_primary_key = 3; // 若为空，则代表数据全部读取完毕. encoded as InplaceRowChangeSet, but only has primary key
    optional bytes next_token = 4;
}
/* ###################################################################################################### */

