mirror of
https://github.com/pocketbase/pocketbase.git
synced 2024-11-28 10:03:42 +02:00
fixed realtime delete event to be called after the record was deleted from the db
This commit is contained in:
parent
729f9f142e
commit
7de346b532
@ -21,6 +21,10 @@
|
||||
|
||||
- (@todo docs) Changed the After* hooks to be called right before writing the user response, allowing users to return response errors from the after hooks.
|
||||
|
||||
- Fixed realtime delete event to be called after the record was deleted from the DB (_including transactions and cascade delete operations_).
|
||||
|
||||
- Added `subscriptions.Client.Unset()` helper to remove a single cached item from the client store.
|
||||
|
||||
|
||||
## v0.16.4-WIP
|
||||
|
||||
|
@ -267,7 +267,7 @@ func (api *realtimeApi) bindEvents() {
|
||||
|
||||
api.app.OnModelAfterCreate().PreAdd(func(e *core.ModelEvent) error {
|
||||
if record := api.resolveRecord(e.Model); record != nil {
|
||||
if err := api.broadcastRecord("create", record); err != nil && api.app.IsDebug() {
|
||||
if err := api.broadcastRecord("create", record, false); err != nil && api.app.IsDebug() {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
@ -276,7 +276,7 @@ func (api *realtimeApi) bindEvents() {
|
||||
|
||||
api.app.OnModelAfterUpdate().PreAdd(func(e *core.ModelEvent) error {
|
||||
if record := api.resolveRecord(e.Model); record != nil {
|
||||
if err := api.broadcastRecord("update", record); err != nil && api.app.IsDebug() {
|
||||
if err := api.broadcastRecord("update", record, false); err != nil && api.app.IsDebug() {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
@ -285,7 +285,16 @@ func (api *realtimeApi) bindEvents() {
|
||||
|
||||
api.app.OnModelBeforeDelete().Add(func(e *core.ModelEvent) error {
|
||||
if record := api.resolveRecord(e.Model); record != nil {
|
||||
if err := api.broadcastRecord("delete", record); err != nil && api.app.IsDebug() {
|
||||
if err := api.broadcastRecord("delete", record, true); err != nil && api.app.IsDebug() {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
api.app.OnModelAfterDelete().Add(func(e *core.ModelEvent) error {
|
||||
if record := api.resolveRecord(e.Model); record != nil {
|
||||
if err := api.broadcastDryCachedRecord("delete", record); err != nil && api.app.IsDebug() {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
@ -367,7 +376,7 @@ type recordData struct {
|
||||
Record *models.Record `json:"record"`
|
||||
}
|
||||
|
||||
func (api *realtimeApi) broadcastRecord(action string, record *models.Record) error {
|
||||
func (api *realtimeApi) broadcastRecord(action string, record *models.Record, dryCache bool) error {
|
||||
collection := record.Collection()
|
||||
if collection == nil {
|
||||
return errors.New("Record collection not set.")
|
||||
@ -399,9 +408,6 @@ func (api *realtimeApi) broadcastRecord(action string, record *models.Record) er
|
||||
|
||||
dataBytes, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
if api.app.IsDebug() {
|
||||
log.Println(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@ -438,17 +444,46 @@ func (api *realtimeApi) broadcastRecord(action string, record *models.Record) er
|
||||
}
|
||||
}
|
||||
|
||||
routine.FireAndForget(func() {
|
||||
if !client.IsDiscarded() {
|
||||
client.Channel() <- msg
|
||||
}
|
||||
})
|
||||
if dryCache {
|
||||
client.Set(action+"/"+data.Record.Id, msg)
|
||||
} else {
|
||||
routine.FireAndForget(func() {
|
||||
if !client.IsDiscarded() {
|
||||
client.Channel() <- msg
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// broadcastDryCachedRecord broadcasts record if it is cached in the client context.
|
||||
func (api *realtimeApi) broadcastDryCachedRecord(action string, record *models.Record) error {
|
||||
clients := api.app.SubscriptionsBroker().Clients()
|
||||
|
||||
for _, client := range clients {
|
||||
key := action + "/" + record.Id
|
||||
|
||||
msg, ok := client.Get(key).(subscriptions.Message)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
client.Unset(key)
|
||||
|
||||
client := client
|
||||
|
||||
routine.FireAndForget(func() {
|
||||
if !client.IsDiscarded() {
|
||||
client.Channel() <- msg
|
||||
}
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type getter interface {
|
||||
Get(string) any
|
||||
}
|
||||
|
@ -35,6 +35,9 @@ type Client interface {
|
||||
// Set stores any value to the client's context.
|
||||
Set(key string, value any)
|
||||
|
||||
// Unset removes a single value from the client's context.
|
||||
Unset(key string)
|
||||
|
||||
// Get retrieves the key value from the client's context.
|
||||
Get(key string) any
|
||||
|
||||
@ -157,6 +160,14 @@ func (c *DefaultClient) Set(key string, value any) {
|
||||
c.store[key] = value
|
||||
}
|
||||
|
||||
// Unset implements the [Client.Unset] interface method.
|
||||
func (c *DefaultClient) Unset(key string) {
|
||||
c.mux.Lock()
|
||||
defer c.mux.Unlock()
|
||||
|
||||
delete(c.store, key)
|
||||
}
|
||||
|
||||
// Discard implements the [Client.Discard] interface method.
|
||||
func (c *DefaultClient) Discard() {
|
||||
c.mux.Lock()
|
||||
|
Loading…
Reference in New Issue
Block a user