mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-16 08:15:05 +00:00
fix(store): handle NULL JSONB columns in MCP server scan (#40)
* fix(store): handle NULL JSONB columns in MCP server scan Scan JSONB nullable columns (args, headers, env, settings) into *[]byte instead of directly into json.RawMessage to prevent silent scan failures when database values are SQL NULL. Also initialize result slices with make() to return empty JSON arrays instead of null. * fix(store): keep settings scanning direct since column is NOT NULL
This commit is contained in:
1 parent
53db5165a3
commit
846c217cf9
3 files changed
+27
-8
No files matched your search
@@ -55,6 +55,13 @@ func derefUUID(u *uuid.UUID) uuid.UUID {
|
||||
return *u
|
||||
}
|
||||
|
||||
func derefBytes(b *[]byte) []byte {
|
||||
if b == nil {
|
||||
return nil
|
||||
}
|
||||
return *b
|
||||
}
|
||||
|
||||
// --- JSON helpers ---
|
||||
|
||||
func jsonOrEmpty(data []byte) []byte {
|
||||
|
||||
@@ -74,9 +74,10 @@ func (s *PGMCPServerStore) GetServerByName(ctx context.Context, name string) (*s
|
||||
func (s *PGMCPServerStore) scanServer(row *sql.Row) (*store.MCPServerData, error) {
|
||||
var srv store.MCPServerData
|
||||
var displayName, command, url, apiKey, toolPrefix *string
|
||||
var args, headers, env *[]byte
|
||||
err := row.Scan(
|
||||
&srv.ID, &srv.Name, &displayName, &srv.Transport, &command,
|
||||
&srv.Args, &url, &srv.Headers, &srv.Env,
|
||||
&args, &url, &headers, &env,
|
||||
&apiKey, &toolPrefix, &srv.TimeoutSec,
|
||||
&srv.Settings, &srv.Enabled, &srv.CreatedBy, &srv.CreatedAt, &srv.UpdatedAt,
|
||||
)
|
||||
@@ -87,6 +88,9 @@ func (s *PGMCPServerStore) scanServer(row *sql.Row) (*store.MCPServerData, error
|
||||
srv.Command = derefStr(command)
|
||||
srv.URL = derefStr(url)
|
||||
srv.ToolPrefix = derefStr(toolPrefix)
|
||||
srv.Args = derefBytes(args)
|
||||
srv.Headers = derefBytes(headers)
|
||||
srv.Env = derefBytes(env)
|
||||
if apiKey != nil && *apiKey != "" && s.encKey != "" {
|
||||
decrypted, err := crypto.Decrypt(*apiKey, s.encKey)
|
||||
if err != nil {
|
||||
@@ -110,13 +114,14 @@ func (s *PGMCPServerStore) ListServers(ctx context.Context) ([]store.MCPServerDa
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result []store.MCPServerData
|
||||
result := make([]store.MCPServerData, 0)
|
||||
for rows.Next() {
|
||||
var srv store.MCPServerData
|
||||
var displayName, command, url, apiKey, toolPrefix *string
|
||||
var args, headers, env *[]byte
|
||||
if err := rows.Scan(
|
||||
&srv.ID, &srv.Name, &displayName, &srv.Transport, &command,
|
||||
&srv.Args, &url, &srv.Headers, &srv.Env,
|
||||
&args, &url, &headers, &env,
|
||||
&apiKey, &toolPrefix, &srv.TimeoutSec,
|
||||
&srv.Settings, &srv.Enabled, &srv.CreatedBy, &srv.CreatedAt, &srv.UpdatedAt,
|
||||
); err != nil {
|
||||
@@ -126,6 +131,9 @@ func (s *PGMCPServerStore) ListServers(ctx context.Context) ([]store.MCPServerDa
|
||||
srv.Command = derefStr(command)
|
||||
srv.URL = derefStr(url)
|
||||
srv.ToolPrefix = derefStr(toolPrefix)
|
||||
srv.Args = derefBytes(args)
|
||||
srv.Headers = derefBytes(headers)
|
||||
srv.Env = derefBytes(env)
|
||||
if apiKey != nil && *apiKey != "" && s.encKey != "" {
|
||||
if decrypted, err := crypto.Decrypt(*apiKey, s.encKey); err == nil {
|
||||
srv.APIKey = decrypted
|
||||
|
||||
@@ -113,15 +113,16 @@ func (s *PGMCPServerStore) ListAccessible(ctx context.Context, agentID uuid.UUID
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result []store.MCPAccessInfo
|
||||
result := make([]store.MCPAccessInfo, 0)
|
||||
for rows.Next() {
|
||||
var srv store.MCPServerData
|
||||
var displayName, command, url, apiKey, toolPrefix *string
|
||||
var toolAllowJSON, toolDenyJSON []byte
|
||||
var args, headers, env *[]byte
|
||||
var toolAllowJSON, toolDenyJSON *[]byte
|
||||
|
||||
if err := rows.Scan(
|
||||
&srv.ID, &srv.Name, &displayName, &srv.Transport, &command,
|
||||
&srv.Args, &url, &srv.Headers, &srv.Env,
|
||||
&args, &url, &headers, &env,
|
||||
&apiKey, &toolPrefix, &srv.TimeoutSec,
|
||||
&srv.Settings, &srv.Enabled, &srv.CreatedBy, &srv.CreatedAt, &srv.UpdatedAt,
|
||||
&toolAllowJSON, &toolDenyJSON,
|
||||
@@ -132,6 +133,9 @@ func (s *PGMCPServerStore) ListAccessible(ctx context.Context, agentID uuid.UUID
|
||||
srv.Command = derefStr(command)
|
||||
srv.URL = derefStr(url)
|
||||
srv.ToolPrefix = derefStr(toolPrefix)
|
||||
srv.Args = derefBytes(args)
|
||||
srv.Headers = derefBytes(headers)
|
||||
srv.Env = derefBytes(env)
|
||||
if apiKey != nil && *apiKey != "" && s.encKey != "" {
|
||||
if decrypted, err := crypto.Decrypt(*apiKey, s.encKey); err == nil {
|
||||
srv.APIKey = decrypted
|
||||
@@ -142,10 +146,10 @@ func (s *PGMCPServerStore) ListAccessible(ctx context.Context, agentID uuid.UUID
|
||||
|
||||
info := store.MCPAccessInfo{Server: srv}
|
||||
if toolAllowJSON != nil {
|
||||
json.Unmarshal(toolAllowJSON, &info.ToolAllow)
|
||||
json.Unmarshal(*toolAllowJSON, &info.ToolAllow)
|
||||
}
|
||||
if toolDenyJSON != nil {
|
||||
json.Unmarshal(toolDenyJSON, &info.ToolDeny)
|
||||
json.Unmarshal(*toolDenyJSON, &info.ToolDeny)
|
||||
}
|
||||
result = append(result, info)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user