syntax = "proto3";

package ultipa;


// The ultipa service definition.
service UltipaRpcs {
    // Sends a greeting
    rpc SayHello (HelloUltipaRequest) returns (HelloUltipaReply) {}
    // Query
    rpc Query (QueryRequest) returns (stream QueryReply) {}
    // 插入点
    rpc InsertNodes (InsertNodesRequest) returns (InsertNodesReply) {}
    // 插入边
    rpc InsertEdges (InsertEdgesRequest) returns (InsertEdgesReply) {}
}

service UltipaControls{
    // Sends a greeting
    rpc SayHello (HelloUltipaRequest) returns (HelloUltipaReply) {}
    // 用户设置(用于存储用户配置信息,用户自主控制)
    rpc UserSetting (UserSettingRequest) returns (UserSettingReply) {}
    // query扩展，以下命令在此接口执行执行 top, kill show().* stats
    rpc QueryEx (QueryRequest) returns (stream QueryReply) {}
    // 导出点,边数据
    rpc Export (ExportRequest) returns (stream ExportReply) {}
    // 下载算法生成文件
    rpc DownloadFile (DownloadFileRequest) returns (stream DownloadFileReply) {}
    // 算法安装
    rpc InstallAlgo (stream InstallAlgoRequest) returns (InstallAlgoReply){}

    // 算法卸载
    rpc UninstallAlgo (UninstallAlgoRequest) returns (UninstallAlgoReply){}
    // 算法回退
    rpc RollbackAlgo (RollbackAlgoRequest) returns (RollbackAlgoReply){}
    // 仅鉴权
    rpc Authenticate (AuthenticateRequest) returns (AuthenticateReply){}
}

message HelloUltipaRequest {
    string name = 1;
}

message HelloUltipaReply {
    Status status = 1;
    string message = 2;
}

enum QueryType {
    QUERY_UNSET = 0;
    UQL = 1;
    GQL = 2;
}

/*
*query_text : ab.src(1).dest(2).depth(1).limit(10).select(*)
*query_type : UQL or GQL
*db_name : default
*timeout  1s 单位:秒
*/

message QueryRequest {
    string query_text = 1;
    QueryType query_type = 2;
    uint32 timeout = 3;
    string graph_name = 4;
    string user_name = 5;
    uint32 thread_num = 6;
    string tz = 7;
    string tz_offset = 8;
}

enum ResultType {
    RESULT_TYPE_UNSET = 0;
    RESULT_TYPE_PATH = 1;
    RESULT_TYPE_NODE = 2;
    RESULT_TYPE_EDGE = 3;
    RESULT_TYPE_ATTR = 4;
    RESULT_TYPE_TABLE = 5;
}

message ResultAlias {
    string alias = 1;
    ResultType result_type = 2;
}

message QueryReply {
    Status status = 1;
    int32 total_time_cost = 2;
    int32 engine_time_cost = 3;

    repeated ResultAlias alias = 4;
    repeated PathAlias paths = 5;
    repeated NodeAlias nodes = 6;
    repeated EdgeAlias edges = 7;
    repeated AttrAlias attrs = 8;
    repeated Table tables = 10;

    Table statistics = 11;
    ExplainPlan explain_plan = 12;
}

message PathAlias {
    repeated Path paths = 1;
    string alias = 2;
}

message EdgeAlias {
    EntityTable edge_table = 1;
    string alias = 2;
}

message NodeAlias {
    EntityTable node_table = 1;
    string alias = 2;
}
//key = alias.name, value = ly
message AttrAlias {
    string alias = 1;
    Attr attr = 2;
}

message Attr {
    PropertyType value_type = 1;
    repeated bytes values = 2;
}

message AttrListData {
    ResultType type = 1;
    EntityTable nodes = 2;
    EntityTable edges = 3;
    repeated Path paths = 4;
    repeated Attr attrs = 5;
    bool is_null = 6;
}

message AttrMapData {
    Attr key = 1;
    Attr value = 2;
    bool is_null = 3;
}

message UserSettingRequest {
    enum OPTION {
        OPT_GET = 0;
        OPT_SET = 1;
    }
    string user_name = 1;
    OPTION opt = 2;
    //key
    string type = 3;
    //value
    string data = 4;
}

message UserSettingReply {
    Status status = 1;
    string data = 2;
}

//下载算法生成文件
message DownloadFileRequest {
    string file_name = 1;
}
message DownloadFileReply {
    Status status = 1;
    int32 total_size = 2;
    bytes chunk = 3;
}

//导出数据
// limit < 0 全量导出
// limit >= 0 导出limit条
//limit abandon
message ExportRequest {
    DBType db_type = 1;
    int32 limit = 2;
    repeated string select_properties = 3;
    string schema = 4;
    string graph = 5;
}

message ExportReply {
    Status status = 1;
    EntityTable node_table = 2;
    EntityTable edge_table = 3;
}

enum InsertType {
    NORMAL = 0;
    OVERWRITE = 1;
    UPSERT = 2;
}

message InsertNodesRequest {
    EntityTable node_table = 1;
    //if true return ids
    bool silent = 2;
    string graph_name = 3;
    InsertType insert_type = 4;
    bool internal = 5;  //for internal usage
    repeated string projections = 6; //for internal usage
    repeated uint32 indexes = 7; //for internal usage
}


message InsertNodesReply {
    Status status = 1;
    int32 time_cost = 2;
    int32 engine_time_cost = 3;
    repeated uint64 uuids = 4 [jstype = JS_STRING];
    repeated string ids = 5;
    repeated uint32 ignore_indexes = 6;
    repeated uint32 ignore_error_code = 7;
    EntityTable nodes = 8; //for internal usage
}

message InsertEdgesRequest {
    EntityTable edge_table = 1;
    //if true return ids
    bool silent = 2;
    string graph_name = 3;
    bool create_node_if_not_exist = 4;
    InsertType insert_type = 5;
    repeated string projections = 6; //for internal usage
    repeated uint32 indexes = 7; //for internal usage
}

message InsertEdgesReply {
    Status status = 1;
    int32 time_cost = 2;
    int32 engine_time_cost = 3;
    repeated uint64 uuids = 4 [jstype = JS_STRING]; //deprecated
    repeated uint32 ignore_indexes = 5;
    repeated uint32 ignore_error_code = 6;
    EntityTable edges = 7;
}

message WithServer {
    string hdc_server_name = 1;
}
message InstallAlgoRequest {
    string file_name = 1;
    string md5 = 2;
    bytes chunk = 3;
    WithServer with_server = 4;
}

message InstallAlgoReply {
    Status status = 1;
}

message UninstallAlgoRequest {
    string algo_name = 1;
    WithServer with_server = 2;
}

message UninstallAlgoReply {
    Status status = 1;
}

message RollbackAlgoRequest {
    string algo_name = 1;
    WithServer with_server = 2;
}

message RollbackAlgoReply {
    Status status = 1;
}

enum PropertyType {
    UNSET = 0;
    INT32 = 1;
    UINT32 = 2;
    INT64 = 3;
    UINT64 = 4;
    FLOAT = 5;
    DOUBLE = 6;
    STRING = 7;
    DATETIME = 8;
    TIMESTAMP = 9;
    TEXT = 10;
    BLOB = 11;
    POINT = 12;
    DECIMAL = 13;
    LIST = 14;
    SET = 15;
    MAP = 16;
    NULL_ = 17;
    BOOL = 18;
}

enum ErrorCode {
    SUCCESS = 0;
    FAILED = 1;
    PARAM_ERROR = 2;
    BASE_DB_ERROR = 3;
    ENGINE_ERROR = 4;
    SYSTEM_ERROR = 5;
    SYNTAX_ERROR = 6;
    PERMISSION_DENIED = 7;
    DUPLICATE_ID = 8;

    //for internal usage
    RAFT_REDIRECT = 10001;
    RAFT_LEADER_NOT_YET_ELECTED = 10002;
    RAFT_LOG_ERROR = 10003;
    NOT_RAFT_MODE = 10004;
    RAFT_NO_AVAILABLE_FOLLOWERS = 10005;
    RAFT_NO_AVAILABLE_ALGO_SERVERS = 10006;

}

message Status {
    ErrorCode error_code = 1;
    string msg = 2;
    ClusterInfo cluster_info = 3; //for internal usage
}

enum FollowerRole {
    ROLE_UNSET = 0;
    ROLE_READABLE = 1;
    ROLE_ALGO_EXECUTABLE = 2;
    ROLE_LEARNER = 4;
}

message RaftFollower {
    string address = 1;
    int32 role = 2;
    ServerStatus status = 3;
    string stream_address = 4;
}

enum ServerStatus {
    SERVER_STATUS_UNSET = 0;
    ALIVE = 1;
    DEAD = 2;
}

message ClusterInfo {
    string redirect = 1;
    string leader_address = 2;
    repeated RaftFollower followers = 3;
    string leader_stream_address = 4;
}


enum DBType {
    DBNODE = 0;
    DBEDGE = 1;
    DBGLOBAL = 2;
}

message Path {
    EntityTable node_table = 1;
    EntityTable edge_table = 2;
    bool is_null = 3;
}

message Table {
    string table_name = 1;
    repeated Header headers = 2;
    repeated TableRow table_rows = 3;
}

message TableRow {
    repeated bytes values = 1;
}

message EntityTable {
    repeated Schema schemas = 1;
    repeated EntityRow entity_rows = 3;
}

message EntityRow {
    uint64 uuid = 1 [jstype = JS_STRING];
    string id = 2;
    string schema_name = 3;
    uint64 from_uuid = 4 [jstype = JS_STRING];
    uint64 to_uuid = 5 [jstype = JS_STRING];
    string from_id = 6;
    string to_id = 7;
    repeated bytes values = 8;
    bool is_null = 9;
    uint32 schema_id = 10;
    uint32 from_schema_id = 11;
    uint32 to_schema_id = 12;
}

message Schema {
    string schema_name = 1;
    repeated Property properties = 2;
    uint32 schema_id = 3;
}

message Property {
    string property_name = 1;
    PropertyType property_type = 2;
    repeated PropertyType sub_types = 3;
    uint32 property_id = 4; //for internal usage
}

message Header {
    string property_name = 1;
    PropertyType property_type = 2;
}

message Value {
    string key = 1;
    string value = 2;
}

//for rpc insert
message ListData {
    repeated bytes values = 1;
    bool is_null = 2;
}
message SetData {
    repeated bytes values = 1;
    bool is_null = 2;
}
message MapValue {
    bytes key = 1;
    bytes value = 2;
}
message MapData {
    repeated MapValue values = 1;
    bool is_null = 2;
}


enum JOB_STATUS {
    JOB_PENDING = 0;
    JOB_COMPUTING = 1;
    JOB_WRITING = 2;
    JOB_DONE = 3;
    JOB_FAILED = 4;
    JOB_STOPPED = 5;
}

message ExplainPlan {
    // 先序遍历结果
    repeated PlanNode plan_nodes = 1;
}

message PlanNode {
    string alias = 1;
    uint32 children_num = 2;

    string query_text = 3;
    string infos = 4;
}

enum AuthenticateType {
    PERMISSION_TYPE_UNSET = 0;
    PERMISSION_TYPE_UQL = 1;
    PERMISSION_TYPE_GQL = 2;
    PERMISSION_TYPE_INSERTNODES = 3;
    PERMISSION_TYPE_INSERTEDGES = 4;
    PERMISSION_TYPE_EXPORT = 5;
    PERMISSION_TYPE_DOWNLOADFILE = 6;
    PERMISSION_TYPE_INSTALLALGO = 7;
    PERMISSION_TYPE_UNINSTALLALGO = 8;
    PERMISSION_TYPE_ROLLBACKALGO = 9;
}

message AuthenticateRequest {
    AuthenticateType type = 1;
    string query_text = 2;
}

message AuthenticateReply {
    Status status = 1;
}

message MigrationData {
    bytes key = 1;
    bytes value = 2;
}
message MigrationDataArray {
    repeated MigrationData datas = 1;
}



message GetLeaderRequest {
    string graph_name = 1;
}

message GetLeaderReply {
    Status status = 1;
}
