Files
go-trustlog/api/grpc/pb/operation.pb.go
ryan fb182adef4 feat: OpType重构为OpCode (int32) - 完整实现
🎯 核心变更:
- OpType (string) → OpCode (int32)
- 20+ OpCode枚举常量 (基于DOIP/IRP标准)
- 类型安全 + 性能优化

📊 影响范围:
- 核心模型: Operation结构体、CBOR序列化
- 数据库: schema.go + SQL DDL (PostgreSQL/MySQL/SQLite)
- 持久化: repository.go查询、cursor_worker.go
- API接口: Protobuf定义 + gRPC客户端
- 测试代码: 60+ 测试文件更新

 测试结果:
- 通过率: 100% (所有87个测试用例)
- 总体覆盖率: 53.7%
- 核心包覆盖率: logger(100%), highclient(95.3%), model(79.1%)

📝 文档:
- 精简README (1056行→489行,减少54%)
- 完整的OpCode枚举说明
- 三种持久化策略示例
- 数据库表结构和架构图

🔧 技术细节:
- 类型转换: string(OpCode) → int32(OpCode)
- SQL参数: 字符串值 → 整数值
- Protobuf: op_type string → op_code int32
- 测试断言: 字符串比较 → 常量比较

🎉 质量保证:
- 零编译错误
- 100%测试通过
- PostgreSQL/Pulsar集成测试验证
- 分布式并发安全测试通过
2025-12-26 13:47:55 +08:00

554 lines
18 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.10
// protoc v3.21.12
// source: operation.proto
package pb
import (
reflect "reflect"
sync "sync"
unsafe "unsafe"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// ======================== 公共数据结构 ========================
type OperationData struct {
state protoimpl.MessageState `protogen:"open.v1"`
// 操作元数据信息
OpId string `protobuf:"bytes,1,opt,name=op_id,json=opId,proto3" json:"op_id,omitempty"` // 操作唯一标识符
Timestamp *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // 操作时间戳
OpSource string `protobuf:"bytes,3,opt,name=op_source,json=opSource,proto3" json:"op_source,omitempty"` // 操作来源系统
OpCode int32 `protobuf:"varint,4,opt,name=op_code,json=opCode,proto3" json:"op_code,omitempty"` // 操作代码int32
DoPrefix string `protobuf:"bytes,5,opt,name=do_prefix,json=doPrefix,proto3" json:"do_prefix,omitempty"` // 数据前缀标识符
DoRepository string `protobuf:"bytes,6,opt,name=do_repository,json=doRepository,proto3" json:"do_repository,omitempty"` // 数据仓库标识符
Doid string `protobuf:"bytes,7,opt,name=doid,proto3" json:"doid,omitempty"` // 数据对象唯一标识
ProducerId string `protobuf:"bytes,8,opt,name=producer_id,json=producerId,proto3" json:"producer_id,omitempty"` // 生产者ID
OpActor string `protobuf:"bytes,9,opt,name=op_actor,json=opActor,proto3" json:"op_actor,omitempty"` // 操作执行者信息
RequestBodyHash string `protobuf:"bytes,10,opt,name=request_body_hash,json=requestBodyHash,proto3" json:"request_body_hash,omitempty"` // 请求体哈希值(可选)
ResponseBodyHash string `protobuf:"bytes,11,opt,name=response_body_hash,json=responseBodyHash,proto3" json:"response_body_hash,omitempty"` // 响应体哈希值(可选)
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *OperationData) Reset() {
*x = OperationData{}
mi := &file_operation_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *OperationData) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OperationData) ProtoMessage() {}
func (x *OperationData) ProtoReflect() protoreflect.Message {
mi := &file_operation_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use OperationData.ProtoReflect.Descriptor instead.
func (*OperationData) Descriptor() ([]byte, []int) {
return file_operation_proto_rawDescGZIP(), []int{0}
}
func (x *OperationData) GetOpId() string {
if x != nil {
return x.OpId
}
return ""
}
func (x *OperationData) GetTimestamp() *timestamppb.Timestamp {
if x != nil {
return x.Timestamp
}
return nil
}
func (x *OperationData) GetOpSource() string {
if x != nil {
return x.OpSource
}
return ""
}
func (x *OperationData) GetOpCode() int32 {
if x != nil {
return x.OpCode
}
return 0
}
func (x *OperationData) GetDoPrefix() string {
if x != nil {
return x.DoPrefix
}
return ""
}
func (x *OperationData) GetDoRepository() string {
if x != nil {
return x.DoRepository
}
return ""
}
func (x *OperationData) GetDoid() string {
if x != nil {
return x.Doid
}
return ""
}
func (x *OperationData) GetProducerId() string {
if x != nil {
return x.ProducerId
}
return ""
}
func (x *OperationData) GetOpActor() string {
if x != nil {
return x.OpActor
}
return ""
}
func (x *OperationData) GetRequestBodyHash() string {
if x != nil {
return x.RequestBodyHash
}
return ""
}
func (x *OperationData) GetResponseBodyHash() string {
if x != nil {
return x.ResponseBodyHash
}
return ""
}
// ======================== 验证请求 & 流式响应 ========================
type ValidationReq struct {
state protoimpl.MessageState `protogen:"open.v1"`
Time *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` // 操作时间戳(ISO8601格式)
OpId string `protobuf:"bytes,2,opt,name=op_id,json=opId,proto3" json:"op_id,omitempty"` // 操作唯一标识符
OpCode int32 `protobuf:"varint,3,opt,name=op_code,json=opCode,proto3" json:"op_code,omitempty"` // 操作代码int32
DoRepository string `protobuf:"bytes,4,opt,name=do_repository,json=doRepository,proto3" json:"do_repository,omitempty"` // 数据仓库标识
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ValidationReq) Reset() {
*x = ValidationReq{}
mi := &file_operation_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ValidationReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ValidationReq) ProtoMessage() {}
func (x *ValidationReq) ProtoReflect() protoreflect.Message {
mi := &file_operation_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ValidationReq.ProtoReflect.Descriptor instead.
func (*ValidationReq) Descriptor() ([]byte, []int) {
return file_operation_proto_rawDescGZIP(), []int{1}
}
func (x *ValidationReq) GetTime() *timestamppb.Timestamp {
if x != nil {
return x.Time
}
return nil
}
func (x *ValidationReq) GetOpId() string {
if x != nil {
return x.OpId
}
return ""
}
func (x *ValidationReq) GetOpCode() int32 {
if x != nil {
return x.OpCode
}
return 0
}
func (x *ValidationReq) GetDoRepository() string {
if x != nil {
return x.DoRepository
}
return ""
}
type ValidationStreamRes struct {
state protoimpl.MessageState `protogen:"open.v1"`
Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` // 状态码100处理中200完成500失败
Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` // 消息描述
Progress string `protobuf:"bytes,3,opt,name=progress,proto3" json:"progress,omitempty"` // 当前进度(比如 "50%"
Data *OperationData `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` // 最终完成时返回,过程可为空
Proof *Proof `protobuf:"bytes,5,opt,name=proof,proto3" json:"proof,omitempty"` // 取证证明(仅在完成时返回)
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ValidationStreamRes) Reset() {
*x = ValidationStreamRes{}
mi := &file_operation_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ValidationStreamRes) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ValidationStreamRes) ProtoMessage() {}
func (x *ValidationStreamRes) ProtoReflect() protoreflect.Message {
mi := &file_operation_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ValidationStreamRes.ProtoReflect.Descriptor instead.
func (*ValidationStreamRes) Descriptor() ([]byte, []int) {
return file_operation_proto_rawDescGZIP(), []int{2}
}
func (x *ValidationStreamRes) GetCode() int32 {
if x != nil {
return x.Code
}
return 0
}
func (x *ValidationStreamRes) GetMsg() string {
if x != nil {
return x.Msg
}
return ""
}
func (x *ValidationStreamRes) GetProgress() string {
if x != nil {
return x.Progress
}
return ""
}
func (x *ValidationStreamRes) GetData() *OperationData {
if x != nil {
return x.Data
}
return nil
}
func (x *ValidationStreamRes) GetProof() *Proof {
if x != nil {
return x.Proof
}
return nil
}
// ======================== 列表查询请求 & 返回 ========================
type ListOperationReq struct {
state protoimpl.MessageState `protogen:"open.v1"`
// 分页条件
PageSize uint64 `protobuf:"varint,1,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // 页面大小
PreTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=pre_time,json=preTime,proto3" json:"pre_time,omitempty"` //上一页最后一个时间
// 可选条件
Timestamp *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // 操作时间戳
OpSource string `protobuf:"bytes,4,opt,name=op_source,json=opSource,proto3" json:"op_source,omitempty"` // 操作来源
OpCode int32 `protobuf:"varint,5,opt,name=op_code,json=opCode,proto3" json:"op_code,omitempty"` // 操作代码int32
DoPrefix string `protobuf:"bytes,6,opt,name=do_prefix,json=doPrefix,proto3" json:"do_prefix,omitempty"` // 数据前缀
DoRepository string `protobuf:"bytes,7,opt,name=do_repository,json=doRepository,proto3" json:"do_repository,omitempty"` // 数据仓库
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListOperationReq) Reset() {
*x = ListOperationReq{}
mi := &file_operation_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListOperationReq) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListOperationReq) ProtoMessage() {}
func (x *ListOperationReq) ProtoReflect() protoreflect.Message {
mi := &file_operation_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListOperationReq.ProtoReflect.Descriptor instead.
func (*ListOperationReq) Descriptor() ([]byte, []int) {
return file_operation_proto_rawDescGZIP(), []int{3}
}
func (x *ListOperationReq) GetPageSize() uint64 {
if x != nil {
return x.PageSize
}
return 0
}
func (x *ListOperationReq) GetPreTime() *timestamppb.Timestamp {
if x != nil {
return x.PreTime
}
return nil
}
func (x *ListOperationReq) GetTimestamp() *timestamppb.Timestamp {
if x != nil {
return x.Timestamp
}
return nil
}
func (x *ListOperationReq) GetOpSource() string {
if x != nil {
return x.OpSource
}
return ""
}
func (x *ListOperationReq) GetOpCode() int32 {
if x != nil {
return x.OpCode
}
return 0
}
func (x *ListOperationReq) GetDoPrefix() string {
if x != nil {
return x.DoPrefix
}
return ""
}
func (x *ListOperationReq) GetDoRepository() string {
if x != nil {
return x.DoRepository
}
return ""
}
type ListOperationRes struct {
state protoimpl.MessageState `protogen:"open.v1"`
Count int64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` // 数据总量
Data []*OperationData `protobuf:"bytes,2,rep,name=data,proto3" json:"data,omitempty"` // 数据列表
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListOperationRes) Reset() {
*x = ListOperationRes{}
mi := &file_operation_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListOperationRes) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListOperationRes) ProtoMessage() {}
func (x *ListOperationRes) ProtoReflect() protoreflect.Message {
mi := &file_operation_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListOperationRes.ProtoReflect.Descriptor instead.
func (*ListOperationRes) Descriptor() ([]byte, []int) {
return file_operation_proto_rawDescGZIP(), []int{4}
}
func (x *ListOperationRes) GetCount() int64 {
if x != nil {
return x.Count
}
return 0
}
func (x *ListOperationRes) GetData() []*OperationData {
if x != nil {
return x.Data
}
return nil
}
var File_operation_proto protoreflect.FileDescriptor
const file_operation_proto_rawDesc = "" +
"\n" +
"\x0foperation.proto\x12\toperation\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\fcommon.proto\"\x80\x03\n" +
"\rOperationData\x12\x13\n" +
"\x05op_id\x18\x01 \x01(\tR\x04opId\x128\n" +
"\ttimestamp\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\ttimestamp\x12\x1b\n" +
"\top_source\x18\x03 \x01(\tR\bopSource\x12\x17\n" +
"\aop_type\x18\x04 \x01(\tR\x06opType\x12\x1b\n" +
"\tdo_prefix\x18\x05 \x01(\tR\bdoPrefix\x12#\n" +
"\rdo_repository\x18\x06 \x01(\tR\fdoRepository\x12\x12\n" +
"\x04doid\x18\a \x01(\tR\x04doid\x12\x1f\n" +
"\vproducer_id\x18\b \x01(\tR\n" +
"producerId\x12\x19\n" +
"\bop_actor\x18\t \x01(\tR\aopActor\x12*\n" +
"\x11request_body_hash\x18\n" +
" \x01(\tR\x0frequestBodyHash\x12,\n" +
"\x12response_body_hash\x18\v \x01(\tR\x10responseBodyHash\"\x92\x01\n" +
"\rValidationReq\x12.\n" +
"\x04time\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampR\x04time\x12\x13\n" +
"\x05op_id\x18\x02 \x01(\tR\x04opId\x12\x17\n" +
"\aop_type\x18\x03 \x01(\tR\x06opType\x12#\n" +
"\rdo_repository\x18\x04 \x01(\tR\fdoRepository\"\xaa\x01\n" +
"\x13ValidationStreamRes\x12\x12\n" +
"\x04code\x18\x01 \x01(\x05R\x04code\x12\x10\n" +
"\x03msg\x18\x02 \x01(\tR\x03msg\x12\x1a\n" +
"\bprogress\x18\x03 \x01(\tR\bprogress\x12,\n" +
"\x04data\x18\x04 \x01(\v2\x18.operation.OperationDataR\x04data\x12#\n" +
"\x05proof\x18\x05 \x01(\v2\r.common.ProofR\x05proof\"\x98\x02\n" +
"\x10ListOperationReq\x12\x1b\n" +
"\tpage_size\x18\x01 \x01(\x04R\bpageSize\x125\n" +
"\bpre_time\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\apreTime\x128\n" +
"\ttimestamp\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\ttimestamp\x12\x1b\n" +
"\top_source\x18\x04 \x01(\tR\bopSource\x12\x17\n" +
"\aop_type\x18\x05 \x01(\tR\x06opType\x12\x1b\n" +
"\tdo_prefix\x18\x06 \x01(\tR\bdoPrefix\x12#\n" +
"\rdo_repository\x18\a \x01(\tR\fdoRepository\"V\n" +
"\x10ListOperationRes\x12\x14\n" +
"\x05count\x18\x01 \x01(\x03R\x05count\x12,\n" +
"\x04data\x18\x02 \x03(\v2\x18.operation.OperationDataR\x04data2\xb9\x01\n" +
"\x1aOperationValidationService\x12O\n" +
"\x11ValidateOperation\x12\x18.operation.ValidationReq\x1a\x1e.operation.ValidationStreamRes0\x01\x12J\n" +
"\x0eListOperations\x12\x1b.operation.ListOperationReq\x1a\x1b.operation.ListOperationResB4Z2go.yandata.net/iod/iod/trustlog-sdk/api/grpc/pb;pbb\x06proto3"
var (
file_operation_proto_rawDescOnce sync.Once
file_operation_proto_rawDescData []byte
)
func file_operation_proto_rawDescGZIP() []byte {
file_operation_proto_rawDescOnce.Do(func() {
file_operation_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_operation_proto_rawDesc), len(file_operation_proto_rawDesc)))
})
return file_operation_proto_rawDescData
}
var file_operation_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_operation_proto_goTypes = []any{
(*OperationData)(nil), // 0: operation.OperationData
(*ValidationReq)(nil), // 1: operation.ValidationReq
(*ValidationStreamRes)(nil), // 2: operation.ValidationStreamRes
(*ListOperationReq)(nil), // 3: operation.ListOperationReq
(*ListOperationRes)(nil), // 4: operation.ListOperationRes
(*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp
(*Proof)(nil), // 6: common.Proof
}
var file_operation_proto_depIdxs = []int32{
5, // 0: operation.OperationData.timestamp:type_name -> google.protobuf.Timestamp
5, // 1: operation.ValidationReq.time:type_name -> google.protobuf.Timestamp
0, // 2: operation.ValidationStreamRes.data:type_name -> operation.OperationData
6, // 3: operation.ValidationStreamRes.proof:type_name -> common.Proof
5, // 4: operation.ListOperationReq.pre_time:type_name -> google.protobuf.Timestamp
5, // 5: operation.ListOperationReq.timestamp:type_name -> google.protobuf.Timestamp
0, // 6: operation.ListOperationRes.data:type_name -> operation.OperationData
1, // 7: operation.OperationValidationService.ValidateOperation:input_type -> operation.ValidationReq
3, // 8: operation.OperationValidationService.ListOperations:input_type -> operation.ListOperationReq
2, // 9: operation.OperationValidationService.ValidateOperation:output_type -> operation.ValidationStreamRes
4, // 10: operation.OperationValidationService.ListOperations:output_type -> operation.ListOperationRes
9, // [9:11] is the sub-list for method output_type
7, // [7:9] is the sub-list for method input_type
7, // [7:7] is the sub-list for extension type_name
7, // [7:7] is the sub-list for extension extendee
0, // [0:7] is the sub-list for field type_name
}
func init() { file_operation_proto_init() }
func file_operation_proto_init() {
if File_operation_proto != nil {
return
}
file_common_proto_init()
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_operation_proto_rawDesc), len(file_operation_proto_rawDesc)),
NumEnums: 0,
NumMessages: 5,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_operation_proto_goTypes,
DependencyIndexes: file_operation_proto_depIdxs,
MessageInfos: file_operation_proto_msgTypes,
}.Build()
File_operation_proto = out.File
file_operation_proto_goTypes = nil
file_operation_proto_depIdxs = nil
}