From 40bd640e819cc8b683bb795ce83d222bfbe3c8ed Mon Sep 17 00:00:00 2001 From: Chinmaya Bharadwaj Date: Wed, 26 Jul 2023 09:51:58 +0530 Subject: [PATCH] feat: add partial support for composite primary keys (#252) * feat: add partial support for composite primary keys Currently, a single PK was getting handled. This PR attempts to add the support for composite primary keys, so that generated methods are predictable. Currently, only read, list & delete are handled in the current PR. Additional method support will be added in the upcoming PRs. Added department user proto to demonstrate the same. * consider field name "id" as well --- example/user/user.pb.go | 288 ++++++++++++++++++++------------ example/user/user.pb.gorm.go | 311 ++++++++++++++++++++++++++++++++++- example/user/user.proto | 10 ++ plugin/plugin.go | 82 +++++++-- 4 files changed, 567 insertions(+), 124 deletions(-) diff --git a/example/user/user.pb.go b/example/user/user.pb.go index 60d66b7b..81e6a42e 100644 --- a/example/user/user.pb.go +++ b/example/user/user.pb.go @@ -43,6 +43,7 @@ type User struct { Friends []*User `protobuf:"bytes,13,rep,name=friends,proto3" json:"friends,omitempty"` ShippingAddressId *resource.Identifier `protobuf:"bytes,14,opt,name=shipping_address_id,json=shippingAddressId,proto3" json:"shipping_address_id,omitempty"` ExternalUuid *resource.Identifier `protobuf:"bytes,15,opt,name=external_uuid,json=externalUuid,proto3" json:"external_uuid,omitempty"` + Department *Department `protobuf:"bytes,16,opt,name=department,proto3" json:"department,omitempty"` } func (x *User) Reset() { @@ -182,6 +183,13 @@ func (x *User) GetExternalUuid() *resource.Identifier { return nil } +func (x *User) GetDepartment() *Department { + if x != nil { + return x.Department + } + return nil +} + type Email struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -569,6 +577,62 @@ func (x *Task) GetId() string { return "" } +// Department added example for composite primary keys +type Department struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Id int64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *Department) Reset() { + *x = Department{} + if protoimpl.UnsafeEnabled { + mi := &file_user_user_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Department) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Department) ProtoMessage() {} + +func (x *Department) ProtoReflect() protoreflect.Message { + mi := &file_user_user_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Department.ProtoReflect.Descriptor instead. +func (*Department) Descriptor() ([]byte, []int) { + return file_user_user_proto_rawDescGZIP(), []int{6} +} + +func (x *Department) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Department) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + var File_user_user_proto protoreflect.FileDescriptor var file_user_user_proto_rawDesc = []byte{ @@ -578,7 +642,7 @@ var file_user_user_proto_rawDesc = []byte{ 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x12, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2f, 0x67, 0x6f, 0x72, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb6, + 0x6f, 0x6e, 0x73, 0x2f, 0x67, 0x6f, 0x72, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe8, 0x06, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x0e, 0xba, 0xb9, 0x19, 0x0a, @@ -629,81 +693,89 @@ var file_user_user_proto_rawDesc = []byte{ 0x75, 0x75, 0x69, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x0c, 0xba, 0xb9, 0x19, 0x08, 0x0a, 0x06, 0x12, 0x04, 0x75, 0x75, 0x69, 0x64, 0x52, - 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x55, 0x75, 0x69, 0x64, 0x3a, 0x08, 0xba, - 0xb9, 0x19, 0x04, 0x08, 0x01, 0x20, 0x01, 0x22, 0x81, 0x02, 0x0a, 0x05, 0x45, 0x6d, 0x61, 0x69, - 0x6c, 0x12, 0x35, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x42, 0x0e, 0xba, 0xb9, 0x19, 0x0a, 0x0a, 0x08, 0x12, 0x04, 0x75, 0x75, - 0x69, 0x64, 0x28, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, - 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1e, - 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0a, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x12, 0x2e, - 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x55, 0x75, 0x69, 0x64, 0x12, 0x30, 0x0a, + 0x0a, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, + 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x3a, + 0x08, 0xba, 0xb9, 0x19, 0x04, 0x08, 0x01, 0x20, 0x01, 0x22, 0x81, 0x02, 0x0a, 0x05, 0x45, 0x6d, + 0x61, 0x69, 0x6c, 0x12, 0x35, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x51, - 0x0a, 0x11, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x6e, - 0x75, 0x6c, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, - 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, - 0x42, 0x0e, 0xba, 0xb9, 0x19, 0x0a, 0x0a, 0x08, 0x12, 0x04, 0x75, 0x75, 0x69, 0x64, 0x40, 0x01, - 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4e, 0x6f, 0x74, 0x4e, 0x75, 0x6c, - 0x6c, 0x3a, 0x08, 0xba, 0xb9, 0x19, 0x04, 0x08, 0x01, 0x20, 0x01, 0x22, 0xbd, 0x02, 0x0a, 0x07, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x38, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x11, 0xba, 0xb9, 0x19, 0x0d, - 0x0a, 0x0b, 0x12, 0x07, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x28, 0x01, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x31, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x31, 0x12, 0x20, - 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x08, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x32, 0x88, 0x01, 0x01, - 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x70, 0x6f, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, - 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x0d, 0xba, - 0xb9, 0x19, 0x09, 0x0a, 0x07, 0x12, 0x05, 0x6a, 0x73, 0x6f, 0x6e, 0x62, 0x52, 0x08, 0x65, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x4b, 0x0a, 0x0b, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x63, - 0x69, 0x74, 0x5f, 0x66, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x0e, 0xba, 0xb9, 0x19, 0x0a, 0x0a, 0x08, 0x12, 0x04, + 0x75, 0x75, 0x69, 0x64, 0x28, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x64, + 0x12, 0x2e, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x51, 0x0a, 0x11, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x74, + 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x42, 0x13, 0xba, 0xb9, 0x19, 0x0f, 0x0a, 0x06, 0x12, 0x04, 0x74, 0x65, 0x78, 0x74, - 0x3a, 0x05, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x0a, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x63, 0x69, - 0x74, 0x46, 0x6b, 0x3a, 0x08, 0xba, 0xb9, 0x19, 0x04, 0x08, 0x01, 0x20, 0x01, 0x42, 0x0c, 0x0a, - 0x0a, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x32, 0x22, 0xc1, 0x01, 0x0a, 0x08, - 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x38, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, 0x70, 0x63, - 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x11, 0xba, 0xb9, 0x19, - 0x0d, 0x0a, 0x0b, 0x12, 0x07, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x28, 0x01, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x49, 0x0a, 0x0c, 0x65, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x0f, 0xba, 0xb9, 0x19, 0x0b, 0x0a, 0x09, 0x12, - 0x07, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x52, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x3a, 0x08, 0xba, 0xb9, 0x19, 0x04, 0x08, 0x01, 0x20, 0x01, 0x22, - 0x8e, 0x02, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, 0x12, 0x38, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, - 0x61, 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, - 0x72, 0x42, 0x11, 0xba, 0xb9, 0x19, 0x0d, 0x0a, 0x0b, 0x12, 0x07, 0x69, 0x6e, 0x74, 0x65, 0x67, - 0x65, 0x72, 0x28, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, - 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x06, - 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x3a, 0x08, 0xba, 0xb9, 0x19, 0x04, 0x08, 0x01, 0x20, 0x01, - 0x22, 0x7e, 0x0a, 0x04, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, - 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x13, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x88, 0x01, 0x01, 0x3a, - 0x08, 0xba, 0xb9, 0x19, 0x04, 0x08, 0x01, 0x20, 0x01, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, + 0x65, 0x72, 0x42, 0x0e, 0xba, 0xb9, 0x19, 0x0a, 0x0a, 0x08, 0x12, 0x04, 0x75, 0x75, 0x69, 0x64, + 0x40, 0x01, 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4e, 0x6f, 0x74, 0x4e, + 0x75, 0x6c, 0x6c, 0x3a, 0x08, 0xba, 0xb9, 0x19, 0x04, 0x08, 0x01, 0x20, 0x01, 0x22, 0xbd, 0x02, + 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x38, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, 0x70, + 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x11, 0xba, 0xb9, + 0x19, 0x0d, 0x0a, 0x0b, 0x12, 0x07, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x28, 0x01, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x31, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x31, + 0x12, 0x20, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x32, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x32, 0x88, + 0x01, 0x01, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, + 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, + 0x0d, 0xba, 0xb9, 0x19, 0x09, 0x0a, 0x07, 0x12, 0x05, 0x6a, 0x73, 0x6f, 0x6e, 0x62, 0x52, 0x08, + 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x4b, 0x0a, 0x0b, 0x69, 0x6d, 0x70, 0x6c, + 0x69, 0x63, 0x69, 0x74, 0x5f, 0x66, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x42, 0x13, 0xba, 0xb9, 0x19, 0x0f, 0x0a, 0x06, 0x12, 0x04, 0x74, 0x65, + 0x78, 0x74, 0x3a, 0x05, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x0a, 0x69, 0x6d, 0x70, 0x6c, 0x69, + 0x63, 0x69, 0x74, 0x46, 0x6b, 0x3a, 0x08, 0xba, 0xb9, 0x19, 0x04, 0x08, 0x01, 0x20, 0x01, 0x42, + 0x0c, 0x0a, 0x0a, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x32, 0x22, 0xc1, 0x01, + 0x0a, 0x08, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x38, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, + 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x11, 0xba, + 0xb9, 0x19, 0x0d, 0x0a, 0x0b, 0x12, 0x07, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x28, 0x01, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x49, 0x0a, 0x0c, + 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x0f, 0xba, 0xb9, 0x19, 0x0b, 0x0a, + 0x09, 0x12, 0x07, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x52, 0x0b, 0x65, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x3a, 0x08, 0xba, 0xb9, 0x19, 0x04, 0x08, 0x01, 0x20, + 0x01, 0x22, 0x8e, 0x02, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x43, 0x61, 0x72, 0x64, + 0x12, 0x38, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, + 0x74, 0x6c, 0x61, 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x72, 0x42, 0x11, 0xba, 0xb9, 0x19, 0x0d, 0x0a, 0x0b, 0x12, 0x07, 0x69, 0x6e, 0x74, + 0x65, 0x67, 0x65, 0x72, 0x28, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x6c, 0x61, + 0x73, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x3a, 0x08, 0xba, 0xb9, 0x19, 0x04, 0x08, 0x01, + 0x20, 0x01, 0x22, 0x7e, 0x0a, 0x04, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x13, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x88, 0x01, + 0x01, 0x3a, 0x08, 0xba, 0xb9, 0x19, 0x04, 0x08, 0x01, 0x20, 0x01, 0x42, 0x05, 0x0a, 0x03, 0x5f, + 0x69, 0x64, 0x22, 0x4c, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x61, 0x72, 0x74, 0x6d, 0x65, 0x6e, 0x74, + 0x12, 0x1c, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, + 0xba, 0xb9, 0x19, 0x04, 0x0a, 0x02, 0x28, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x42, 0x08, 0xba, 0xb9, 0x19, 0x04, + 0x0a, 0x02, 0x28, 0x01, 0x52, 0x02, 0x69, 0x64, 0x3a, 0x06, 0xba, 0xb9, 0x19, 0x02, 0x08, 0x01, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x62, 0x6c, 0x6f, 0x78, 0x6f, 0x70, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x72, 0x6d, 0x2f, 0x65, 0x78, 0x61, 0x6d, @@ -723,7 +795,7 @@ func file_user_user_proto_rawDescGZIP() []byte { return file_user_user_proto_rawDescData } -var file_user_user_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_user_user_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_user_user_proto_goTypes = []interface{}{ (*User)(nil), // 0: user.User (*Email)(nil), // 1: user.Email @@ -731,14 +803,15 @@ var file_user_user_proto_goTypes = []interface{}{ (*Language)(nil), // 3: user.Language (*CreditCard)(nil), // 4: user.CreditCard (*Task)(nil), // 5: user.Task - (*resource.Identifier)(nil), // 6: atlas.rpc.Identifier - (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp + (*Department)(nil), // 6: user.Department + (*resource.Identifier)(nil), // 7: atlas.rpc.Identifier + (*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp } var file_user_user_proto_depIdxs = []int32{ - 6, // 0: user.User.id:type_name -> atlas.rpc.Identifier - 7, // 1: user.User.created_at:type_name -> google.protobuf.Timestamp - 7, // 2: user.User.updated_at:type_name -> google.protobuf.Timestamp - 7, // 3: user.User.birthday:type_name -> google.protobuf.Timestamp + 7, // 0: user.User.id:type_name -> atlas.rpc.Identifier + 8, // 1: user.User.created_at:type_name -> google.protobuf.Timestamp + 8, // 2: user.User.updated_at:type_name -> google.protobuf.Timestamp + 8, // 3: user.User.birthday:type_name -> google.protobuf.Timestamp 4, // 4: user.User.credit_card:type_name -> user.CreditCard 1, // 5: user.User.emails:type_name -> user.Email 5, // 6: user.User.tasks:type_name -> user.Task @@ -746,25 +819,26 @@ var file_user_user_proto_depIdxs = []int32{ 2, // 8: user.User.shipping_address:type_name -> user.Address 3, // 9: user.User.languages:type_name -> user.Language 0, // 10: user.User.friends:type_name -> user.User - 6, // 11: user.User.shipping_address_id:type_name -> atlas.rpc.Identifier - 6, // 12: user.User.external_uuid:type_name -> atlas.rpc.Identifier - 6, // 13: user.Email.id:type_name -> atlas.rpc.Identifier - 6, // 14: user.Email.user_id:type_name -> atlas.rpc.Identifier - 6, // 15: user.Email.external_not_null:type_name -> atlas.rpc.Identifier - 6, // 16: user.Address.id:type_name -> atlas.rpc.Identifier - 6, // 17: user.Address.external:type_name -> atlas.rpc.Identifier - 6, // 18: user.Address.implicit_fk:type_name -> atlas.rpc.Identifier - 6, // 19: user.Language.id:type_name -> atlas.rpc.Identifier - 6, // 20: user.Language.external_int:type_name -> atlas.rpc.Identifier - 6, // 21: user.CreditCard.id:type_name -> atlas.rpc.Identifier - 7, // 22: user.CreditCard.created_at:type_name -> google.protobuf.Timestamp - 7, // 23: user.CreditCard.updated_at:type_name -> google.protobuf.Timestamp - 6, // 24: user.CreditCard.user_id:type_name -> atlas.rpc.Identifier - 25, // [25:25] is the sub-list for method output_type - 25, // [25:25] is the sub-list for method input_type - 25, // [25:25] is the sub-list for extension type_name - 25, // [25:25] is the sub-list for extension extendee - 0, // [0:25] is the sub-list for field type_name + 7, // 11: user.User.shipping_address_id:type_name -> atlas.rpc.Identifier + 7, // 12: user.User.external_uuid:type_name -> atlas.rpc.Identifier + 6, // 13: user.User.department:type_name -> user.Department + 7, // 14: user.Email.id:type_name -> atlas.rpc.Identifier + 7, // 15: user.Email.user_id:type_name -> atlas.rpc.Identifier + 7, // 16: user.Email.external_not_null:type_name -> atlas.rpc.Identifier + 7, // 17: user.Address.id:type_name -> atlas.rpc.Identifier + 7, // 18: user.Address.external:type_name -> atlas.rpc.Identifier + 7, // 19: user.Address.implicit_fk:type_name -> atlas.rpc.Identifier + 7, // 20: user.Language.id:type_name -> atlas.rpc.Identifier + 7, // 21: user.Language.external_int:type_name -> atlas.rpc.Identifier + 7, // 22: user.CreditCard.id:type_name -> atlas.rpc.Identifier + 8, // 23: user.CreditCard.created_at:type_name -> google.protobuf.Timestamp + 8, // 24: user.CreditCard.updated_at:type_name -> google.protobuf.Timestamp + 7, // 25: user.CreditCard.user_id:type_name -> atlas.rpc.Identifier + 26, // [26:26] is the sub-list for method output_type + 26, // [26:26] is the sub-list for method input_type + 26, // [26:26] is the sub-list for extension type_name + 26, // [26:26] is the sub-list for extension extendee + 0, // [0:26] is the sub-list for field type_name } func init() { file_user_user_proto_init() } @@ -845,6 +919,18 @@ func file_user_user_proto_init() { return nil } } + file_user_user_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Department); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_user_user_proto_msgTypes[2].OneofWrappers = []interface{}{} file_user_user_proto_msgTypes[5].OneofWrappers = []interface{}{} @@ -854,7 +940,7 @@ func file_user_user_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_user_user_proto_rawDesc, NumEnums: 0, - NumMessages: 6, + NumMessages: 7, NumExtensions: 0, NumServices: 0, }, diff --git a/example/user/user.pb.gorm.go b/example/user/user.pb.gorm.go index 07854a53..8e1fa5a5 100644 --- a/example/user/user.pb.gorm.go +++ b/example/user/user.pb.gorm.go @@ -22,6 +22,7 @@ type UserORM struct { Birthday *time.Time CreatedAt *time.Time CreditCard *CreditCardORM `gorm:"foreignKey:UserId;references:Id"` + Department *DepartmentORM `gorm:"foreignKey:UserId;references:Id"` Emails []*EmailORM `gorm:"foreignKey:UserId;references:Id"` ExternalUuid *string `gorm:"type:uuid"` Friends []*UserORM `gorm:"foreignKey:Id;references:Id;many2many:user_friends;joinForeignKey:UserId;joinReferences:FriendId"` @@ -147,6 +148,13 @@ func (m *User) ToORM(ctx context.Context) (UserORM, error) { to.ExternalUuid = &vv } } + if m.Department != nil { + tempDepartment, err := m.Department.ToORM(ctx) + if err != nil { + return to, err + } + to.Department = &tempDepartment + } accountID, err := auth.GetAccountID(ctx, nil) if err != nil { return to, err @@ -265,6 +273,13 @@ func (m *UserORM) ToPB(ctx context.Context) (User, error) { to.ExternalUuid = v } } + if m.Department != nil { + tempDepartment, err := m.Department.ToPB(ctx) + if err != nil { + return to, err + } + to.Department = &tempDepartment + } if posthook, ok := interface{}(m).(UserWithAfterToPB); ok { err = posthook.AfterToPB(ctx, &to) } @@ -821,6 +836,76 @@ type TaskWithAfterToPB interface { AfterToPB(context.Context, *Task) error } +type DepartmentORM struct { + Id int64 `gorm:"primaryKey"` + Name string `gorm:"primaryKey"` + UserId *string +} + +// TableName overrides the default tablename generated by GORM +func (DepartmentORM) TableName() string { + return "departments" +} + +// ToORM runs the BeforeToORM hook if present, converts the fields of this +// object to ORM format, runs the AfterToORM hook, then returns the ORM object +func (m *Department) ToORM(ctx context.Context) (DepartmentORM, error) { + to := DepartmentORM{} + var err error + if prehook, ok := interface{}(m).(DepartmentWithBeforeToORM); ok { + if err = prehook.BeforeToORM(ctx, &to); err != nil { + return to, err + } + } + to.Name = m.Name + to.Id = m.Id + if posthook, ok := interface{}(m).(DepartmentWithAfterToORM); ok { + err = posthook.AfterToORM(ctx, &to) + } + return to, err +} + +// ToPB runs the BeforeToPB hook if present, converts the fields of this +// object to PB format, runs the AfterToPB hook, then returns the PB object +func (m *DepartmentORM) ToPB(ctx context.Context) (Department, error) { + to := Department{} + var err error + if prehook, ok := interface{}(m).(DepartmentWithBeforeToPB); ok { + if err = prehook.BeforeToPB(ctx, &to); err != nil { + return to, err + } + } + to.Name = m.Name + to.Id = m.Id + if posthook, ok := interface{}(m).(DepartmentWithAfterToPB); ok { + err = posthook.AfterToPB(ctx, &to) + } + return to, err +} + +// The following are interfaces you can implement for special behavior during ORM/PB conversions +// of type Department the arg will be the target, the caller the one being converted from + +// DepartmentBeforeToORM called before default ToORM code +type DepartmentWithBeforeToORM interface { + BeforeToORM(context.Context, *DepartmentORM) error +} + +// DepartmentAfterToORM called after default ToORM code +type DepartmentWithAfterToORM interface { + AfterToORM(context.Context, *DepartmentORM) error +} + +// DepartmentBeforeToPB called before default ToPB code +type DepartmentWithBeforeToPB interface { + BeforeToPB(context.Context, *Department) error +} + +// DepartmentAfterToPB called after default ToPB code +type DepartmentWithAfterToPB interface { + AfterToPB(context.Context, *Department) error +} + // DefaultCreateUser executes a basic gorm create call func DefaultCreateUser(ctx context.Context, in *User, db *gorm.DB) (*User, error) { if in == nil { @@ -1004,6 +1089,15 @@ func DefaultStrictUpdateUser(ctx context.Context, in *User, db *gorm.DB) (*User, if err = db.Where(filterCreditCard).Delete(CreditCardORM{}).Error; err != nil { return nil, err } + filterDepartment := DepartmentORM{} + if ormObj.Id == "" { + return nil, errors.EmptyIdError + } + filterDepartment.UserId = new(string) + *filterDepartment.UserId = ormObj.Id + if err = db.Where(filterDepartment).Delete(DepartmentORM{}).Error; err != nil { + return nil, err + } filterEmails := EmailORM{} if ormObj.Id == "" { return nil, errors.EmptyIdError @@ -1150,6 +1244,7 @@ func DefaultApplyFieldMaskUser(ctx context.Context, patchee *User, patcher *User var updatedCreditCard bool var updatedBillingAddress bool var updatedShippingAddress bool + var updatedDepartment bool for i, f := range updateMask.Paths { if f == prefix+"Id" { patchee.Id = patcher.Id @@ -1319,6 +1414,27 @@ func DefaultApplyFieldMaskUser(ctx context.Context, patchee *User, patcher *User patchee.ExternalUuid = patcher.ExternalUuid continue } + if !updatedDepartment && strings.HasPrefix(f, prefix+"Department.") { + updatedDepartment = true + if patcher.Department == nil { + patchee.Department = nil + continue + } + if patchee.Department == nil { + patchee.Department = &Department{} + } + if o, err := DefaultApplyFieldMaskDepartment(ctx, patchee.Department, patcher.Department, &field_mask.FieldMask{Paths: updateMask.Paths[i:]}, prefix+"Department.", db); err != nil { + return nil, err + } else { + patchee.Department = o + } + continue + } + if f == prefix+"Department" { + updatedDepartment = true + patchee.Department = patcher.Department + continue + } } if err != nil { return nil, err @@ -2920,9 +3036,6 @@ func DefaultReadTask(ctx context.Context, in *Task, db *gorm.DB) (*Task, error) if err != nil { return nil, err } - if ormObj.Id == nil || *ormObj.Id == "" { - return nil, errors.EmptyIdError - } if hook, ok := interface{}(&ormObj).(TaskORMWithBeforeReadApplyQuery); ok { if db, err = hook.BeforeReadApplyQuery(ctx, db); err != nil { return nil, err @@ -2964,9 +3077,6 @@ func DefaultDeleteTask(ctx context.Context, in *Task, db *gorm.DB) error { if err != nil { return err } - if ormObj.Id == nil || *ormObj.Id == "" { - return errors.EmptyIdError - } if hook, ok := interface{}(&ormObj).(TaskORMWithBeforeDelete_); ok { if db, err = hook.BeforeDelete_(ctx, db); err != nil { return err @@ -3240,3 +3350,192 @@ type TaskORMWithBeforeListFind interface { type TaskORMWithAfterListFind interface { AfterListFind(context.Context, *gorm.DB, *[]TaskORM) error } + +// DefaultCreateDepartment executes a basic gorm create call +func DefaultCreateDepartment(ctx context.Context, in *Department, db *gorm.DB) (*Department, error) { + if in == nil { + return nil, errors.NilArgumentError + } + ormObj, err := in.ToORM(ctx) + if err != nil { + return nil, err + } + if hook, ok := interface{}(&ormObj).(DepartmentORMWithBeforeCreate_); ok { + if db, err = hook.BeforeCreate_(ctx, db); err != nil { + return nil, err + } + } + if err = db.Omit().Create(&ormObj).Error; err != nil { + return nil, err + } + if hook, ok := interface{}(&ormObj).(DepartmentORMWithAfterCreate_); ok { + if err = hook.AfterCreate_(ctx, db); err != nil { + return nil, err + } + } + pbResponse, err := ormObj.ToPB(ctx) + return &pbResponse, err +} + +type DepartmentORMWithBeforeCreate_ interface { + BeforeCreate_(context.Context, *gorm.DB) (*gorm.DB, error) +} +type DepartmentORMWithAfterCreate_ interface { + AfterCreate_(context.Context, *gorm.DB) error +} + +func DefaultReadDepartment(ctx context.Context, in *Department, db *gorm.DB) (*Department, error) { + if in == nil { + return nil, errors.NilArgumentError + } + ormObj, err := in.ToORM(ctx) + if err != nil { + return nil, err + } + if ormObj.Id == 0 { + return nil, errors.EmptyIdError + } + if ormObj.Name == "" { + return nil, errors.EmptyIdError + } + if hook, ok := interface{}(&ormObj).(DepartmentORMWithBeforeReadApplyQuery); ok { + if db, err = hook.BeforeReadApplyQuery(ctx, db); err != nil { + return nil, err + } + } + if hook, ok := interface{}(&ormObj).(DepartmentORMWithBeforeReadFind); ok { + if db, err = hook.BeforeReadFind(ctx, db); err != nil { + return nil, err + } + } + ormResponse := DepartmentORM{} + if err = db.Where(&ormObj).First(&ormResponse).Error; err != nil { + return nil, err + } + if hook, ok := interface{}(&ormResponse).(DepartmentORMWithAfterReadFind); ok { + if err = hook.AfterReadFind(ctx, db); err != nil { + return nil, err + } + } + pbResponse, err := ormResponse.ToPB(ctx) + return &pbResponse, err +} + +type DepartmentORMWithBeforeReadApplyQuery interface { + BeforeReadApplyQuery(context.Context, *gorm.DB) (*gorm.DB, error) +} +type DepartmentORMWithBeforeReadFind interface { + BeforeReadFind(context.Context, *gorm.DB) (*gorm.DB, error) +} +type DepartmentORMWithAfterReadFind interface { + AfterReadFind(context.Context, *gorm.DB) error +} + +func DefaultDeleteDepartment(ctx context.Context, in *Department, db *gorm.DB) error { + if in == nil { + return errors.NilArgumentError + } + ormObj, err := in.ToORM(ctx) + if err != nil { + return err + } + if ormObj.Name == "" { + return errors.EmptyIdError + } + if ormObj.Id == 0 { + return errors.EmptyIdError + } + if hook, ok := interface{}(&ormObj).(DepartmentORMWithBeforeDelete_); ok { + if db, err = hook.BeforeDelete_(ctx, db); err != nil { + return err + } + } + err = db.Where(&ormObj).Delete(&DepartmentORM{}).Error + if err != nil { + return err + } + if hook, ok := interface{}(&ormObj).(DepartmentORMWithAfterDelete_); ok { + err = hook.AfterDelete_(ctx, db) + } + return err +} + +type DepartmentORMWithBeforeDelete_ interface { + BeforeDelete_(context.Context, *gorm.DB) (*gorm.DB, error) +} +type DepartmentORMWithAfterDelete_ interface { + AfterDelete_(context.Context, *gorm.DB) error +} + +// DefaultApplyFieldMaskDepartment patches an pbObject with patcher according to a field mask. +func DefaultApplyFieldMaskDepartment(ctx context.Context, patchee *Department, patcher *Department, updateMask *field_mask.FieldMask, prefix string, db *gorm.DB) (*Department, error) { + if patcher == nil { + return nil, nil + } else if patchee == nil { + return nil, errors.NilArgumentError + } + var err error + for _, f := range updateMask.Paths { + if f == prefix+"Name" { + patchee.Name = patcher.Name + continue + } + if f == prefix+"Id" { + patchee.Id = patcher.Id + continue + } + } + if err != nil { + return nil, err + } + return patchee, nil +} + +// DefaultListDepartment executes a gorm list call +func DefaultListDepartment(ctx context.Context, db *gorm.DB) ([]*Department, error) { + in := Department{} + ormObj, err := in.ToORM(ctx) + if err != nil { + return nil, err + } + if hook, ok := interface{}(&ormObj).(DepartmentORMWithBeforeListApplyQuery); ok { + if db, err = hook.BeforeListApplyQuery(ctx, db); err != nil { + return nil, err + } + } + if hook, ok := interface{}(&ormObj).(DepartmentORMWithBeforeListFind); ok { + if db, err = hook.BeforeListFind(ctx, db); err != nil { + return nil, err + } + } + db = db.Where(&ormObj) + db = db.Order("name, id") + ormResponse := []DepartmentORM{} + if err := db.Find(&ormResponse).Error; err != nil { + return nil, err + } + if hook, ok := interface{}(&ormObj).(DepartmentORMWithAfterListFind); ok { + if err = hook.AfterListFind(ctx, db, &ormResponse); err != nil { + return nil, err + } + } + pbResponse := []*Department{} + for _, responseEntry := range ormResponse { + temp, err := responseEntry.ToPB(ctx) + if err != nil { + return nil, err + } + pbResponse = append(pbResponse, &temp) + } + return pbResponse, nil +} + +type DepartmentORMWithBeforeListApplyQuery interface { + BeforeListApplyQuery(context.Context, *gorm.DB) (*gorm.DB, error) +} +type DepartmentORMWithBeforeListFind interface { + BeforeListFind(context.Context, *gorm.DB) (*gorm.DB, error) +} +type DepartmentORMWithAfterListFind interface { + AfterListFind(context.Context, *gorm.DB, *[]DepartmentORM) error +} diff --git a/example/user/user.proto b/example/user/user.proto index ab583b1d..e5fae109 100644 --- a/example/user/user.proto +++ b/example/user/user.proto @@ -31,6 +31,7 @@ message User { repeated User friends = 13 [(gorm.field).many_to_many = {}]; atlas.rpc.Identifier shipping_address_id = 14; atlas.rpc.Identifier external_uuid = 15 [(gorm.field).tag = {type: "uuid"}]; + Department department = 16; } message Email { @@ -91,3 +92,12 @@ message Task { int64 priority = 3; optional string id = 4; } + +// Department added example for composite primary keys +message Department { + option (gorm.opts) = { + ormable: true, + }; + string name = 1 [(gorm.field).tag = {primary_key: true}]; + int64 id = 2 [(gorm.field).tag = {primary_key: true}]; +} diff --git a/plugin/plugin.go b/plugin/plugin.go index 34eccd2a..38d899d3 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -546,6 +546,19 @@ func (b *ORMBuilder) hasPrimaryKey(ormable *OrmableType) bool { return false } +func (b *ORMBuilder) hasCompositePrimaryKey(ormable *OrmableType) bool { + keys := 0 + for _, field := range ormable.Fields { + if field.GetTag().GetPrimaryKey() && keys <= 1 { + keys++ + } + } + if keys > 1 { + return true + } + return false +} + func (b *ORMBuilder) isOrmable(typeName string) bool { _, ok := b.ormableTypes[typeName] return ok @@ -566,6 +579,22 @@ func (b *ORMBuilder) findPrimaryKey(ormable *OrmableType) (string, *Field) { panic("no primary_key") } +func (b *ORMBuilder) getPrimaryKeys(ormable *OrmableType) map[string]*Field { + mapPK := make(map[string]*Field) + for fieldName, field := range ormable.Fields { + if field.GetTag().GetPrimaryKey() { + mapPK[fieldName] = field + } + } + // consider field name "id" as well + for fieldName, field := range ormable.Fields { + if strings.ToLower(fieldName) == "id" { + mapPK[fieldName] = field + } + } + return mapPK +} + func (b *ORMBuilder) getOrmable(typeName string) *OrmableType { r, err := GetOrmable(b.ormableTypes, typeName) if err != nil { @@ -1611,7 +1640,11 @@ func (b *ORMBuilder) generateDefaultHandlers(file *protogen.File, g *protogen.Ge typeName := string(message.Desc.Name()) ormable := b.getOrmable(typeName) - if b.hasPrimaryKey(ormable) { + if b.hasCompositePrimaryKey(ormable) { + // TODO support for Update,Patch,DeleteSet when composite primary keys exist + b.generateReadHandler(message, g) + b.generateDeleteHandler(message, g) + } else if b.hasPrimaryKey(ormable) { b.generateReadHandler(message, g) b.generateDeleteHandler(message, g) b.generateDeleteSetHandler(message, g) @@ -1818,14 +1851,16 @@ func (b *ORMBuilder) generateReadHandler(message *protogen.Message, g *protogen. g.P(`return nil, err`) g.P(`}`) - k, f := b.findPrimaryKey(ormable) - if strings.Contains(f.TypeName, "*") { - g.P(`if ormObj.`, k, ` == nil || *ormObj.`, k, ` == `, b.guessZeroValue(f.TypeName, g), ` {`) - } else { - g.P(`if ormObj.`, k, ` == `, b.guessZeroValue(f.TypeName, g), ` {`) + mapPK := b.getPrimaryKeys(ormable) + for k, f := range mapPK { + if strings.Contains(f.TypeName, "*") { + g.P(`if ormObj.`, k, ` == nil || *ormObj.`, k, ` == `, b.guessZeroValue(f.TypeName, g), ` {`) + } else { + g.P(`if ormObj.`, k, ` == `, b.guessZeroValue(f.TypeName, g), ` {`) + } + g.P(`return nil, `, "errors", `.EmptyIdError`) + g.P(`}`) } - g.P(`return nil, `, "errors", `.EmptyIdError`) - g.P(`}`) var fs string if b.readHasFieldSelection(ormable) { @@ -1957,14 +1992,16 @@ func (b *ORMBuilder) generateDeleteHandler(message *protogen.Message, g *protoge g.P(`}`) ormable := b.getOrmable(typeName) - pkName, pk := b.findPrimaryKey(ormable) - if strings.Contains(pk.TypeName, "*") { - g.P(`if ormObj.`, pkName, ` == nil || *ormObj.`, pkName, ` == `, b.guessZeroValue(pk.TypeName, g), ` {`) - } else { - g.P(`if ormObj.`, pkName, ` == `, b.guessZeroValue(pk.TypeName, g), `{`) + mapPKs := b.getPrimaryKeys(ormable) + for pkName, pk := range mapPKs { + if strings.Contains(pk.TypeName, "*") { + g.P(`if ormObj.`, pkName, ` == nil || *ormObj.`, pkName, ` == `, b.guessZeroValue(pk.TypeName, g), ` {`) + } else { + g.P(`if ormObj.`, pkName, ` == `, b.guessZeroValue(pk.TypeName, g), `{`) + } + g.P(`return `, generateImport("EmptyIdError", gerrorsImport, g)) + g.P(`}`) } - g.P(`return `, generateImport("EmptyIdError", gerrorsImport, g)) - g.P(`}`) b.generateBeforeDeleteHookCall(ormable, g) g.P(`err = db.Where(&ormObj).Delete(&`, ormable.Name, `{}).Error`) @@ -2633,8 +2670,19 @@ func (b *ORMBuilder) generateListHandler(message *protogen.Message, g *protogen. b.generateBeforeListHookCall(ormable, "Find", g) g.P(`db = db.Where(&ormObj)`) - // add default ordering by primary key - if b.hasPrimaryKey(ormable) { + // TODO handle composite primary keys order considering priority tag + if b.hasCompositePrimaryKey(ormable) { + pksMap := b.getPrimaryKeys(ormable) + var columns []string + for fieldName, field := range pksMap { + column := field.GetTag().GetColumn() + if len(column) == 0 { + column = gschema.NamingStrategy{SingularTable: true}.TableName(fieldName) + } + columns = append(columns, column) + } + g.P(`db = db.Order("`, strings.Join(columns, ", "), `")`) + } else if b.hasPrimaryKey(ormable) { pkName, pk := b.findPrimaryKey(ormable) column := pk.GetTag().GetColumn() if len(column) == 0 {