package service import ( "encoding/json" "fmt" "strings" "browser.local/platform/domain" ) type pluginDataQueryResult struct { Rows []map[string]any `json:"rows"` } func (svc *CoreService) projectPluginDataJobResult(job domain.Job) error { if job.Capability != domain.JobCapabilityRemoteRunDBSQLiteQuery || job.State != domain.JobStateSucceeded { return nil } templateKey := strings.TrimSpace(job.ExecutionInput.Inputs["templateKey"]) if templateKey == "" { return nil } instance, err := svc.store.ServerInstances().Get(job.ServerInstanceID) if err != nil { return err } plugin, err := svc.store.GamePlugins().Get(instance.PluginID) if err != nil { return err } var template domain.GameClientBridgeQueryTemplateDeclaration for _, candidate := range plugin.GameClientBridge.QueryTemplates { if candidate.Key == templateKey { template = candidate break } } if template.RowTarget == nil { return nil } var result pluginDataQueryResult 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)) for _, row := range result.Rows { value := make(map[string]any, len(template.RowTarget.ColumnMappings)) for destination, source := range template.RowTarget.ColumnMappings { value[destination] = row[source] } key, err := pluginDataRowKey(value, template.RowTarget.UpsertKeys) if err != nil { return err } mutations = append(mutations, domain.PluginDataMutation{Operation: domain.PluginDataMutationPut, Key: key, Value: value}) } if len(mutations) == 0 { return nil } _, err = svc.applyPluginDataTransaction(domain.PluginDataTransaction{PluginID: plugin.ID, ServerInstanceID: instance.ID, Collection: template.RowTarget.Collection, Mutations: mutations}) return err } func pluginDataRowKey(value map[string]any, keys []string) (string, error) { parts := make([]string, len(keys)) for index, key := range keys { item, exists := value[key] if !exists || item == nil || strings.TrimSpace(fmt.Sprint(item)) == "" { return "", validationError("declared query row is missing an upsert key") } encoded, err := json.Marshal(item) if err != nil { return "", validationError("declared query row upsert key is invalid") } parts[index] = string(encoded) } if len(parts) == 1 { var key string if err := json.Unmarshal([]byte(parts[0]), &key); err == nil { return key, nil } } return strings.Join(parts, "\x1f"), nil }