Skip to content

Introduce database import and export protocol messages #224

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Jun 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions grpc/java/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ java_grpc_library(
"//proto:server-proto",
"//proto:user-proto",
"//proto:database-proto",
"//proto:migration-proto",
"//proto:error-proto",
"//proto:answer-proto",
"//proto:concept-proto",
"//proto:connection-proto",
Expand Down
2 changes: 2 additions & 0 deletions grpc/nodejs/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ ts_grpc_compile(
"//proto:server-proto",
"//proto:user-proto",
"//proto:database-proto",
"//proto:migration-proto",
"//proto:error-proto",
"//proto:answer-proto",
"//proto:concept-proto",
"//proto:connection-proto",
Expand Down
2 changes: 2 additions & 0 deletions grpc/rust/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ rust_tonic_compile(
"//proto:server-proto",
"//proto:user-proto",
"//proto:database-proto",
"//proto:migration-proto",
"//proto:error-proto",
"//proto:answer-proto",
"//proto:concept-proto",
"//proto:connection-proto",
Expand Down
2 changes: 2 additions & 0 deletions grpc/rust/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ fn main() -> std::io::Result<()> {
"../../proto/concept.proto",
"../../proto/connection.proto",
"../../proto/database.proto",
"../../proto/error.proto",
"../../proto/migration.proto",
"../../proto/options.proto",
"../../proto/query.proto",
"../../proto/server.proto",
Expand Down
18 changes: 17 additions & 1 deletion proto/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ proto_library(
proto_library(
name = "database-proto",
srcs = [":database.proto"],
deps = [
":migration-proto",
],
)

proto_library(
name = "migration-proto",
srcs = [":migration.proto"],
deps = [":concept-proto"],
)

proto_library(
Expand Down Expand Up @@ -70,17 +79,24 @@ proto_library(
srcs = ["query.proto"],
deps = [
":answer-proto",
":options-proto",
":concept-proto",
":error-proto",
":options-proto",
],
)

proto_library(
name = "error-proto",
srcs = ["error.proto"],
)

proto_library(
name = "transaction-proto",
srcs = ["transaction.proto"],
deps = [
":answer-proto",
":concept-proto",
":error-proto",
":options-proto",
":query-proto",
]
Expand Down
1 change: 0 additions & 1 deletion proto/answer.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ package typedb.protocol;

message ConceptRow {
repeated RowEntry row = 1;
// Explainables explainables = 2;
}

message RowEntry {
Expand Down
18 changes: 0 additions & 18 deletions proto/concept.proto
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,16 @@ message Thing {

message Entity {
bytes iid = 1;
// TODO: not sure we should include types by default, since now they can get quite large with annotations included in every single response!
// perhaps it's a query option?
optional EntityType entity_type = 2;
}

message Relation {
bytes iid = 1;
// TODO: not sure we should include types by default, since now they can get quite large with annotations included in every single response!
// perhaps it's a query option?
optional RelationType relation_type = 2;
}

message Attribute {
bytes iid = 1;
// TODO: not sure we should include types by default, since now they can get quite large with annotations included in every single response!
// perhaps it's a query option?
optional AttributeType attribute_type = 2;
Value value = 3;
}
Expand All @@ -57,7 +51,6 @@ message Value {
Decimal decimal = 4;
string string = 5;
Date date = 6;
// time since epoch in milliseconds
Datetime datetime = 7;
Datetime_TZ datetime_tz = 8;
Duration duration = 9;
Expand Down Expand Up @@ -152,14 +145,3 @@ message ValueType {
string name = 1;
};
}

message Annotation {
oneof annotation {
Key key = 1;
Unique unique = 2;
// TODO
}

message Key {}
message Unique {}
}
34 changes: 26 additions & 8 deletions proto/database.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ syntax = "proto3";

package typedb.protocol;

import "proto/migration.proto";

message DatabaseManager {

message Get {
message Req {
string name = 1;
}

message Res {
DatabaseReplicas database = 1;
}
Expand All @@ -28,6 +31,7 @@ message DatabaseManager {
message Req {
string name = 1;
}

message Res {
bool contains = 1;
}
Expand All @@ -37,10 +41,21 @@ message DatabaseManager {
message Req {
string name = 1;
}

message Res {
DatabaseReplicas database = 1;
}
}

message Import {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've placed all migration-related messages in a single file, so it's "encapsulated". However, this introduces an additional layer of optional client and server in Rust while unpacking this message, so it's a little irritating. Not sure if it's worth it or not. I like this design more, I guess.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like what you have here, very readable

message Client {
Migration.Import.Client client = 1;
}

message Server {
Migration.Import.Server server = 1;
}
}
}

message DatabaseReplicas {
Expand All @@ -62,6 +77,7 @@ message Database {
message Req {
string name = 1;
}

message Res {
string schema = 1;
}
Expand All @@ -71,19 +87,21 @@ message Database {
message Req {
string name = 1;
}

message Res {
string schema = 1;
}
}

// message RuleSchema {
// message Req {
// string name = 1;
// }
// message Res {
// string schema = 1;
// }
// }
message Export {
message Req {
Migration.Export.Req req = 1;
}

message Server {
Migration.Export.Server server = 1;
}
}

message Delete {
message Req {
Expand Down
15 changes: 15 additions & 0 deletions proto/error.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

syntax = "proto3";

package typedb.protocol;

// This is an emulation of the google ErrorDetails message. Generally, ErrorDetails are submitted via the GRPC error
// mechanism, but a manual error sending is required in streams
message Error {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was planning to reuse this error, but I understood that I don't need non-terminal errors in my protocol. However, I think that it's reasonable to generalize error messages for the whole TypeDB protocol.

string error_code = 1;
string domain = 2;
repeated string stack_trace = 3;
}
144 changes: 144 additions & 0 deletions proto/migration.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

syntax = "proto3";

package typedb.protocol;

import "proto/concept.proto";

message Migration {
message Export {
message Req {
string name = 1;
}

message Server {
oneof server {
InitialRes initial_res = 1;
ResPart res_part = 2;
Done done = 3;
}
}

message InitialRes {
string schema = 1;
}

message ResPart {
repeated Item items = 1;
}

message Done {}
}

message Import {
message Client {
oneof client {
InitialReq initial_req = 1;
ReqPart req_part = 2;
Done done = 3;
}

message InitialReq {
string name = 1;
string schema = 2;
}

message ReqPart {
repeated Item items = 1;
}

message Done { }
}

message Server {
Done done = 1;

message Done { }
}
}

// _ _____ _____ _____ _ _ _____ ___ ___ _ _ _
// / \|_ _|_ _| ____| \ | |_ _|_ _/ _ \| \ | | |
// / _ \ | | | | | _| | \| | | | | | | | | \| | |
// / ___ \| | | | | |___| |\ | | | | | |_| | |\ |_|
// /_/ \_\_| |_| |_____|_| \_| |_| |___\___/|_| \_(_)
//
// ATTENTION: the messages below are used to import multiple versions of TypeDB.
// DO NOT reorder or delete existing and reserved indices. Be careful while extending this.
//
Comment on lines +69 to +71
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bigger please!! like we had it in server - this is very dangerous

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ASCII art here we go???

//               _  _____ _____ _____ _   _ _____ ___ ___  _   _ _
//              / \|_   _|_   _| ____| \ | |_   _|_ _/ _ \| \ | | |
//             / _ \ | |   | | |  _| |  \| | | |  | | | | |  \| | |
//            / ___ \| |   | | | |___| |\  | | |  | | |_| | |\  |_|
//           /_/   \_\_|   |_| |_____|_| \_| |_| |___\___/|_| \_(_)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's do it :D


message Item {
oneof item {
Attribute attribute = 1;
Entity entity = 2;
Relation relation = 3;

Header header = 15;
Checksums checksums = 16;
}

message Entity {
string id = 1;
string label = 2;
repeated OwnedAttribute attributes = 3;
}

message Attribute {
string id = 1;
string label = 2;
repeated OwnedAttribute attributes = 3; // empty in 3.x, used for backwards compatibility
MigrationValue value = 4;
}

message Relation {
string id = 1;
string label = 2;
repeated OwnedAttribute attributes = 3;
repeated Role roles = 4;
message Role {
string label = 1;
repeated Player players = 2;
message Player {
string id = 1;
}
}
}

message OwnedAttribute {
string id = 1;
}

message Header {
string typedb_version = 1;
string original_database = 2;
}

message Checksums {
int64 entity_count = 1;
int64 attribute_count = 2;
int64 relation_count = 3;
int64 role_count = 4;
int64 ownership_count = 5;
reserved 6; // was deleted and cannot be used until a breaking change occurs
}
}

message MigrationValue {
oneof value {
string string = 1;
bool boolean = 2;
int64 integer = 3;
double double = 4;
int64 datetime_millis = 5; // compatibility with 2.x, milliseconds since epoch
Value.Decimal decimal = 6;
Value.Date date = 8;
Value.Datetime datetime = 9;
Value.Datetime_TZ datetime_tz = 10;
Value.Duration duration = 11;
Value.Struct struct = 12;
}
}
}
9 changes: 1 addition & 8 deletions proto/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ syntax = "proto3";

import "proto/answer.proto";
import "proto/options.proto";
import "proto/error.proto";

package typedb.protocol;

Expand Down Expand Up @@ -69,11 +70,3 @@ message Query {
}
}
}

// This is an emulation of the google ErrorDetails message. Sometimes we submit ErrorDetails via the GRPC error mechanism
// and sometimes (in streams) we have to manually send errors
message Error {
string error_code = 1;
string domain = 2;
repeated string stack_trace = 3;
}
Loading