-
Notifications
You must be signed in to change notification settings - Fork 152
Hooks
This is the first version of Hook
of Qmgo
. The Usage may change.
Generally, User use Hook
will implement the callback method through the operated document. But many operations of Qmgo
don't have documents as parameter(like Update method), which we think it's a very concise way.
So the Hook v1
of Qmgo
will be different from the "general" Hook
implementation:
-The user implements the struct method of Hook, and passes it to Qmgo
through options
of a specific operation, and Qmgo
automatically do callback.
-If the Hook
operation fails, there is no function to roll back the database operation in this version.
User need to implement struct methods to use Insert Hook
:
BeforeInsert() error
AfterInsert() error
In the InsertOne
process
-
Implement the
Hook
method ofInsert
through a custom struct (User
in the following example) -
Pass in
options.InsertOneOptions
to makeHook
work. -
If you use the document
User
to directly implement the method and modify the document inBeforeInsert()
, the modified document will be inserted into the database
type User struct {
Name string `bson:"name"`
Age int `bson:"age"`
}
func (u *User) BeforeInsert() error {
fmt.Println("before insert called")
return nil
}
func (u *User) AfterInsert() error {
fmt.Println("before insert called")
return nil
}
// --- running codes:
u := &User{Name: "Alice", Age: 7}
_, err := cli.InsertOne(context.Background(), u, options.InsertOneOptions{
InsertHook: u,
})
In the InsertMany
process
-
Implement the
Hook
method ofInsert
through a custom structure (User
in the following example), -
Pass in
options.InsertManyOptions
to makeHook
work. -
If you use the document
User
to implement method and modify the document inBeforeInsert()
, the modified document will be inserted into the database -
Because multiple documents are inserted, and
Hook
happens for each document, soHook
will be called back multiple times according to the number of inserted documents
type User struct {
Name string `bson:"name"`
Age int `bson:"age"`
}
func (u *User) BeforeInsert() error {
fmt.Println("before insert called")
return nil
}
func (u *User) AfterInsert() error {
fmt.Println("before insert called")
return nil
}
// --- running codes:
u1 := &User{Name: "jz", Age: 7}
u2 := &User{Name: "xm", Age: 7}
us := []*User{u1, u2}
_, err := cli.InsertMany(ctx, us, options.InsertManyOptions{
InsertHook: us,
})
User need to implement struct methods to use Update Hook
:
BeforeUpdate() error
AfterUpdate() error
In the UpdateOne
/UpdateAll
process
-
Implement the
Hook
method ofInsert
through a custom struct (MyUpdateHook
in the following example) -
Pass in
options.UpdateOptions
to makeHook
work. -
If you use the document
User
to directly implement methods and modify the document in theBeforeUpdate()
, will not affect the document written in the database.
type MyUpdateHook struct {
beforeUpdateCount int
afterUpdateCount int
}
func (u *MyUpdateHook) BeforeUpdate() error {
u.beforeUpdateCount++
return nil
}
func (u *MyUpdateHook) AfterUpdate() error {
u.afterUpdateCount++
return nil
}
u := User{Name: "jz", Age: 7}
uh := &MyUpdateHook{}
_, err := cli.InsertOne(context.Background(), u)
ast.NoError(err)
err = cli.UpdateOne(ctx, bson.M{"name": "jz"}, bson.M{operator.Set: bson.M{"age": 27}}, options.UpdateOptions{
UpdateHook: uh,
})
cli.UpdateAll(ctx, bson.M{"name": "jz"}, bson.M{operator.Set: bson.M{"age": 27}}, options.UpdateOptions{
UpdateHook: uh,
})
User need to implement struct methods to use Remove Hook
:
BeforeRemove() error
AfterRemove() error
In the Remove
/RemoveAll
process
-
A custom structure (
MyRemoveHook
in the following example) implements theHook
method ofRemove
-
Pass in
options.RemoveOptions
to makeHook
work.
type MyRemoveHook struct {
beforeCount int
afterCount int
}
func (m *MyRemoveHook) BeforeRemove() error {
m.beforeCount++
return nil
}
func (m *MyRemoveHook) AfterRemove() error {
m.afterCount++
return nil
}
rh := &MyRemoveHook{}
err = cli.Remove(ctx, bson.M{"age": 17}, options.RemoveOptions{
RemoveHook: rh,
})
rh = &MyRemoveHook{}
_, err = cli.RemoveAll(ctx, bson.M{"age": "7"}, options.RemoveOptions{
RemoveHook: rh,
})
User need to implement struct methods to use Query Hook
:
BeforeQuery() error
AfterQuery() error
In the Find().One/Find().All()
process,
- A custom struct (
MyQueryHook
in the following example) implements theHook
method ofQuery
- Pass in
options.FindOptions
to makeHook
work.
type MyQueryHook struct {
beforeCount int
afterCount int
}
func (q *MyQueryHook) BeforeQuery() error {
q.beforeCount++
return nil
}
func (q *MyQueryHook) AfterQuery() error {
q.afterCount++
return nil
}
qk := &MyQueryHook{}
err = cli.Find(ctx, bson.M{"age": 17}, options.FindOptions{
QueryHook: qk,
}).One(ur)
err = cli.Find(ctx, bson.M{"age": 17}, options.FindOptions{
QueryHook: qh,
}).All(&ur)