From 6580be459d70c37b9377b6dc625f4506159ba22f Mon Sep 17 00:00:00 2001 From: "DESKTOP-K0HCLSG\\tmont" Date: Sat, 7 Sep 2024 10:57:17 -0400 Subject: [PATCH 1/2] Adding Timestamp --- pb/sf/substreams/sink/entity/v1/entity.pb.go | 21 +++++++++++++++++-- .../sf/substreams/sink/entity/v1/entity.proto | 5 +++-- .../src/pb/sf.substreams.sink.entity.v1.rs | 6 ++++-- substreams-entity-change/src/tables.rs | 2 +- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/pb/sf/substreams/sink/entity/v1/entity.pb.go b/pb/sf/substreams/sink/entity/v1/entity.pb.go index 29ebd92..facfa7d 100644 --- a/pb/sf/substreams/sink/entity/v1/entity.pb.go +++ b/pb/sf/substreams/sink/entity/v1/entity.pb.go @@ -215,6 +215,7 @@ type Value struct { // *Value_String_ // *Value_Bytes // *Value_Bool + // *Value_Timestamp // *Value_Array Typed isValue_Typed `protobuf_oneof:"typed"` } @@ -300,6 +301,13 @@ func (x *Value) GetBool() bool { return false } +func (x *Value) GetTimestamp() string { + if x, ok := x.GetTyped().(*Value_Timestamp); ok { + return x.Timestamp + } + return "" +} + func (x *Value) GetArray() *Array { if x, ok := x.GetTyped().(*Value_Array); ok { return x.Array @@ -335,6 +343,10 @@ type Value_Bool struct { Bool bool `protobuf:"varint,6,opt,name=bool,proto3,oneof"` } +type Value_Timestamp struct { + Timestamp string `protobuf:"bytes,7,opt,name=timestamp,proto3,oneof"` +} + type Value_Array struct { Array *Array `protobuf:"bytes,10,opt,name=array,proto3,oneof"` } @@ -351,6 +363,8 @@ func (*Value_Bytes) isValue_Typed() {} func (*Value_Bool) isValue_Typed() {} +func (*Value_Timestamp) isValue_Typed() {} + func (*Value_Array) isValue_Typed() {} type Array struct { @@ -500,7 +514,7 @@ var file_sf_substreams_sink_entity_v1_entity_proto_rawDesc = []byte{ 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x46, 0x49, 0x4e, 0x41, 0x4c, 0x10, 0x04, - 0x22, 0xe9, 0x01, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x05, 0x69, 0x6e, + 0x22, 0x89, 0x02, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x05, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x05, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x20, 0x0a, 0x0a, 0x62, 0x69, 0x67, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x69, 0x67, 0x64, 0x65, 0x63, @@ -510,7 +524,9 @@ var file_sf_substreams_sink_entity_v1_entity_proto_rawDesc = []byte{ 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, - 0x52, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x12, 0x3b, 0x0a, 0x05, 0x61, 0x72, 0x72, 0x61, 0x79, 0x18, + 0x52, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3b, 0x0a, 0x05, 0x61, 0x72, 0x72, 0x61, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x66, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x2e, 0x73, 0x69, 0x6e, 0x6b, 0x2e, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x72, 0x61, 0x79, 0x48, 0x00, 0x52, 0x05, 0x61, 0x72, @@ -664,6 +680,7 @@ func file_sf_substreams_sink_entity_v1_entity_proto_init() { (*Value_String_)(nil), (*Value_Bytes)(nil), (*Value_Bool)(nil), + (*Value_Timestamp)(nil), (*Value_Array)(nil), } file_sf_substreams_sink_entity_v1_entity_proto_msgTypes[4].OneofWrappers = []interface{}{} diff --git a/proto/sf/substreams/sink/entity/v1/entity.proto b/proto/sf/substreams/sink/entity/v1/entity.proto index e77f591..8eb5e0a 100644 --- a/proto/sf/substreams/sink/entity/v1/entity.proto +++ b/proto/sf/substreams/sink/entity/v1/entity.proto @@ -32,8 +32,9 @@ message Value { string string = 4; string bytes = 5; bool bool = 6; - - //reserved 7 to 9; // For future types + string timestamp = 7; + + //reserved 8 to 9; // For future types Array array = 10; } diff --git a/substreams-entity-change/src/pb/sf.substreams.sink.entity.v1.rs b/substreams-entity-change/src/pb/sf.substreams.sink.entity.v1.rs index bd6fd52..d8505a2 100644 --- a/substreams-entity-change/src/pb/sf.substreams.sink.entity.v1.rs +++ b/substreams-entity-change/src/pb/sf.substreams.sink.entity.v1.rs @@ -63,7 +63,7 @@ pub mod entity_change { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Value { - #[prost(oneof="value::Typed", tags="1, 2, 3, 4, 5, 6, 10")] + #[prost(oneof="value::Typed", tags="1, 2, 3, 4, 5, 6, 7, 10")] pub typed: ::core::option::Option, } /// Nested message and enum types in `Value`. @@ -83,7 +83,9 @@ pub mod value { Bytes(::prost::alloc::string::String), #[prost(bool, tag="6")] Bool(bool), - // reserved 7 to 9; // For future types + #[prost(string, tag="7")] + Timestamp(::prost::alloc::string::String), + // reserved 8 to 9; // For future types #[prost(message, tag="10")] Array(super::Array), diff --git a/substreams-entity-change/src/tables.rs b/substreams-entity-change/src/tables.rs index 7aa53b5..4844091 100644 --- a/substreams-entity-change/src/tables.rs +++ b/substreams-entity-change/src/tables.rs @@ -406,7 +406,7 @@ impl ToValue for Vec { impl ToValue for &::prost_types::Timestamp { fn to_value(self) -> Value { Value { - typed: Some(Typed::String(self.to_string())), + typed: Some(Typed::Timestamp(self.seconds.to_string())), } } } From 64e1c020cf78e55bf61b4154a4f48512f496cb8b Mon Sep 17 00:00:00 2001 From: YaroShkvorets Date: Mon, 9 Sep 2024 22:17:37 -0400 Subject: [PATCH 2/2] add timestamp as int64 --- CHANGELOG.md | 4 +++ pb/sf/substreams/sink/entity/v1/entity.pb.go | 8 ++--- .../sf/substreams/sink/entity/v1/entity.proto | 4 +-- .../src/pb/sf.substreams.sink.entity.v1.rs | 4 +-- substreams-entity-change/src/tables.rs | 35 ++++++++++++++++++- 5 files changed, 46 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 324bff1..c5c27e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +Added `Timestamp` type. + ## [1.3.2] Added `ToValue` implementation for for `Vec>` which used to create Graph Node schema object of the form `[Bytes]`. diff --git a/pb/sf/substreams/sink/entity/v1/entity.pb.go b/pb/sf/substreams/sink/entity/v1/entity.pb.go index facfa7d..2385805 100644 --- a/pb/sf/substreams/sink/entity/v1/entity.pb.go +++ b/pb/sf/substreams/sink/entity/v1/entity.pb.go @@ -301,11 +301,11 @@ func (x *Value) GetBool() bool { return false } -func (x *Value) GetTimestamp() string { +func (x *Value) GetTimestamp() int64 { if x, ok := x.GetTyped().(*Value_Timestamp); ok { return x.Timestamp } - return "" + return 0 } func (x *Value) GetArray() *Array { @@ -344,7 +344,7 @@ type Value_Bool struct { } type Value_Timestamp struct { - Timestamp string `protobuf:"bytes,7,opt,name=timestamp,proto3,oneof"` + Timestamp int64 `protobuf:"varint,7,opt,name=timestamp,proto3,oneof"` } type Value_Array struct { @@ -525,7 +525,7 @@ var file_sf_substreams_sink_entity_v1_entity_proto_rawDesc = []byte{ 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x74, 0x69, 0x6d, + 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3b, 0x0a, 0x05, 0x61, 0x72, 0x72, 0x61, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x66, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x2e, 0x73, 0x69, 0x6e, 0x6b, 0x2e, 0x65, 0x6e, 0x74, 0x69, 0x74, diff --git a/proto/sf/substreams/sink/entity/v1/entity.proto b/proto/sf/substreams/sink/entity/v1/entity.proto index 8eb5e0a..599ddd6 100644 --- a/proto/sf/substreams/sink/entity/v1/entity.proto +++ b/proto/sf/substreams/sink/entity/v1/entity.proto @@ -32,8 +32,8 @@ message Value { string string = 4; string bytes = 5; bool bool = 6; - string timestamp = 7; - + int64 timestamp = 7; + //reserved 8 to 9; // For future types Array array = 10; diff --git a/substreams-entity-change/src/pb/sf.substreams.sink.entity.v1.rs b/substreams-entity-change/src/pb/sf.substreams.sink.entity.v1.rs index d8505a2..12b9e81 100644 --- a/substreams-entity-change/src/pb/sf.substreams.sink.entity.v1.rs +++ b/substreams-entity-change/src/pb/sf.substreams.sink.entity.v1.rs @@ -83,8 +83,8 @@ pub mod value { Bytes(::prost::alloc::string::String), #[prost(bool, tag="6")] Bool(bool), - #[prost(string, tag="7")] - Timestamp(::prost::alloc::string::String), + #[prost(int64, tag="7")] + Timestamp(i64), // reserved 8 to 9; // For future types #[prost(message, tag="10")] diff --git a/substreams-entity-change/src/tables.rs b/substreams-entity-change/src/tables.rs index 4844091..31ccaaa 100644 --- a/substreams-entity-change/src/tables.rs +++ b/substreams-entity-change/src/tables.rs @@ -406,7 +406,9 @@ impl ToValue for Vec { impl ToValue for &::prost_types::Timestamp { fn to_value(self) -> Value { Value { - typed: Some(Typed::Timestamp(self.seconds.to_string())), + typed: Some(Typed::Timestamp( + self.seconds * 1_000_000 + self.nanos as i64 / 1000, + )), } } } @@ -471,6 +473,37 @@ mod test { use super::Tables; + #[test] + fn test_timestamp() { + let mut tables = Tables::new(); + tables.create_row("table", "1").set( + "field", + &::prost_types::Timestamp { + seconds: 123, + nanos: 456789000, + }, + ); + + let changes = tables.to_entity_changes(); + assert_eq!(changes.entity_changes.len(), 1); + assert_eq!( + changes.entity_changes[0], + EntityChange { + entity: "table".to_string(), + id: "1".to_string(), + operation: Operation::Create as i32, + fields: vec![Field { + name: "field".to_string(), + new_value: Some(Value { + typed: Some(Typed::Timestamp(123456789)), + }), + ..Default::default() + }], + ..Default::default() + } + ); + } + #[test] fn test_vec_vec_u8() { let mut tables = Tables::new();