Skip to content

Commit b15c950

Browse files
feat:
- hook/field: Restore model hook
1 parent ed95a6d commit b15c950

File tree

3 files changed

+757
-0
lines changed

3 files changed

+757
-0
lines changed

internal/hook/model/interface.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2025 chenmingyong0423
2+
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package model
16+
17+
import "context"
18+
19+
type BeforeInsert interface {
20+
BeforeInsert(ctx context.Context) error
21+
}
22+
23+
type AfterInsert interface {
24+
AfterInsert(ctx context.Context) error
25+
}
26+
27+
type BeforeUpdate interface {
28+
BeforeUpdate(ctx context.Context) error
29+
}
30+
31+
type AfterUpdate interface {
32+
AfterUpdate(ctx context.Context) error
33+
}
34+
35+
type BeforeUpsert interface {
36+
BeforeUpsert(ctx context.Context) error
37+
}
38+
39+
type AfterUpsert interface {
40+
AfterUpsert(ctx context.Context) error
41+
}
42+
43+
type BeforeDelete interface {
44+
BeforeDelete(ctx context.Context) error
45+
}
46+
47+
type AfterDelete interface {
48+
AfterDelete(ctx context.Context) error
49+
}
50+
51+
type BeforeFind interface {
52+
BeforeFind(ctx context.Context) error
53+
}
54+
55+
type AfterFind interface {
56+
AfterFind(ctx context.Context) error
57+
}

internal/hook/model/model.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright 2025 chenmingyong0423
2+
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package model
16+
17+
import (
18+
"context"
19+
"reflect"
20+
21+
"github.com/chenmingyong0423/go-mongox/v2/operation"
22+
)
23+
24+
func getPayload(opCtx *operation.OpContext, opType operation.OpType) any {
25+
if opCtx == nil {
26+
return nil
27+
}
28+
if opCtx.ModelHook != nil {
29+
return opCtx.ModelHook
30+
}
31+
32+
switch opType {
33+
case operation.OpTypeBeforeInsert, operation.OpTypeAfterInsert, operation.OpTypeAfterFind:
34+
return opCtx.Doc
35+
case operation.OpTypeBeforeUpdate, operation.OpTypeAfterUpdate, operation.OpTypeBeforeUpsert, operation.OpTypeAfterUpsert:
36+
return opCtx.Updates
37+
default:
38+
return opCtx.ModelHook
39+
}
40+
}
41+
42+
func Execute(ctx context.Context, opCtx *operation.OpContext, opType operation.OpType, opts ...any) error {
43+
payLoad := getPayload(opCtx, opType)
44+
if payLoad == nil {
45+
return nil
46+
}
47+
valueOf := reflect.ValueOf(payLoad)
48+
49+
switch valueOf.Type().Kind() {
50+
case reflect.Slice:
51+
return executeSlice(ctx, valueOf, opType, opts...)
52+
case reflect.Ptr:
53+
if valueOf.IsZero() {
54+
return nil
55+
}
56+
return execute(ctx, payLoad, opType, opts...)
57+
default:
58+
return nil
59+
}
60+
}
61+
62+
func executeSlice(ctx context.Context, docs reflect.Value, opType operation.OpType, opts ...any) error {
63+
for i := 0; i < docs.Len(); i++ {
64+
doc := docs.Index(i)
65+
if err := execute(ctx, doc.Interface(), opType, opts...); err != nil {
66+
return err
67+
}
68+
}
69+
return nil
70+
}
71+
72+
func execute(ctx context.Context, doc any, opType operation.OpType, _ ...any) error {
73+
if doc == nil {
74+
return nil
75+
}
76+
switch opType {
77+
case operation.OpTypeBeforeInsert:
78+
if m, ok := doc.(BeforeInsert); ok {
79+
return m.BeforeInsert(ctx)
80+
}
81+
case operation.OpTypeAfterInsert:
82+
if m, ok := doc.(AfterInsert); ok {
83+
return m.AfterInsert(ctx)
84+
}
85+
case operation.OpTypeBeforeDelete:
86+
if m, ok := doc.(BeforeDelete); ok {
87+
return m.BeforeDelete(ctx)
88+
}
89+
case operation.OpTypeAfterDelete:
90+
if m, ok := doc.(AfterDelete); ok {
91+
return m.AfterDelete(ctx)
92+
}
93+
case operation.OpTypeBeforeUpdate:
94+
if m, ok := doc.(BeforeUpdate); ok {
95+
return m.BeforeUpdate(ctx)
96+
}
97+
case operation.OpTypeAfterUpdate:
98+
if m, ok := doc.(AfterUpdate); ok {
99+
return m.AfterUpdate(ctx)
100+
}
101+
case operation.OpTypeBeforeUpsert:
102+
if m, ok := doc.(BeforeUpsert); ok {
103+
return m.BeforeUpsert(ctx)
104+
}
105+
case operation.OpTypeAfterUpsert:
106+
if m, ok := doc.(AfterUpsert); ok {
107+
return m.AfterUpsert(ctx)
108+
}
109+
case operation.OpTypeBeforeFind:
110+
if m, ok := doc.(BeforeFind); ok {
111+
return m.BeforeFind(ctx)
112+
}
113+
case operation.OpTypeAfterFind:
114+
if m, ok := doc.(AfterFind); ok {
115+
return m.AfterFind(ctx)
116+
}
117+
}
118+
return nil
119+
}

0 commit comments

Comments
 (0)