Rebuild SCUM plugin-owned data flow
This commit is contained in:
@@ -2,10 +2,13 @@ package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"browser.local/platform/domain"
|
||||
"browser.local/platform/repo"
|
||||
)
|
||||
|
||||
type pluginDataQueryResult struct {
|
||||
@@ -42,7 +45,7 @@ func (svc *CoreService) projectPluginDataJobResult(job domain.Job) error {
|
||||
if err := json.Unmarshal([]byte(job.ExecutionResult.Content), &result); err != nil {
|
||||
return validationError("declared query result is not valid JSON")
|
||||
}
|
||||
mutations := make([]domain.PluginDataMutation, 0, len(result.Rows))
|
||||
mutationsByKey := make(map[string]domain.PluginDataMutation, len(result.Rows))
|
||||
for _, row := range result.Rows {
|
||||
value := make(map[string]any, len(template.RowTarget.ColumnMappings))
|
||||
for destination, source := range template.RowTarget.ColumnMappings {
|
||||
@@ -52,15 +55,54 @@ func (svc *CoreService) projectPluginDataJobResult(job domain.Job) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mutations = append(mutations, domain.PluginDataMutation{Operation: domain.PluginDataMutationPut, Key: key, Value: value})
|
||||
if template.RowTarget.WriteMode == domain.PluginDataRowWriteModeMerge {
|
||||
existing, getErr := svc.store.PluginDataRecords().Get(pluginDataID(instance.ID, plugin.ID, template.RowTarget.Collection, key))
|
||||
if getErr == nil {
|
||||
value = mergePluginDataValues(existing.Value, value)
|
||||
} else if !errors.Is(getErr, repo.ErrNotFound) {
|
||||
return getErr
|
||||
}
|
||||
}
|
||||
mutationsByKey[key] = domain.PluginDataMutation{Operation: domain.PluginDataMutationPut, Key: key, Value: value}
|
||||
}
|
||||
if len(mutations) == 0 {
|
||||
if template.RowTarget.WriteMode == domain.PluginDataRowWriteModeReplace {
|
||||
existing, listErr := svc.store.PluginDataRecords().List(domain.PluginDataFilter{PluginID: plugin.ID, ServerInstanceID: instance.ID, Collection: template.RowTarget.Collection})
|
||||
if listErr != nil {
|
||||
return listErr
|
||||
}
|
||||
for _, record := range existing {
|
||||
if _, present := mutationsByKey[record.Key]; !present {
|
||||
mutationsByKey[record.Key] = domain.PluginDataMutation{Operation: domain.PluginDataMutationDelete, Key: record.Key}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(mutationsByKey) == 0 {
|
||||
return nil
|
||||
}
|
||||
keys := make([]string, 0, len(mutationsByKey))
|
||||
for key := range mutationsByKey {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
mutations := make([]domain.PluginDataMutation, 0, len(keys))
|
||||
for _, key := range keys {
|
||||
mutations = append(mutations, mutationsByKey[key])
|
||||
}
|
||||
_, err = svc.applyPluginDataTransaction(domain.PluginDataTransaction{PluginID: plugin.ID, ServerInstanceID: instance.ID, Collection: template.RowTarget.Collection, Mutations: mutations})
|
||||
return err
|
||||
}
|
||||
|
||||
func mergePluginDataValues(existing, incoming map[string]any) map[string]any {
|
||||
merged := domain.CopyGameClientBridgePayload(existing)
|
||||
if merged == nil {
|
||||
merged = make(map[string]any, len(incoming))
|
||||
}
|
||||
for key, value := range incoming {
|
||||
merged[key] = value
|
||||
}
|
||||
return merged
|
||||
}
|
||||
|
||||
func pluginDataRowKey(value map[string]any, keys []string) (string, error) {
|
||||
parts := make([]string, len(keys))
|
||||
for index, key := range keys {
|
||||
|
||||
Reference in New Issue
Block a user