listDatabases lists databases matching the filter in the user's workspace. Uses the workspace ID from the JWT token stored in context.
(ctx context.Context, filter string)
| 77 | // listDatabases lists databases matching the filter in the user's workspace. |
| 78 | // Uses the workspace ID from the JWT token stored in context. |
| 79 | func (s *Server) listDatabases(ctx context.Context, filter string) ([]databaseEntry, error) { |
| 80 | workspaceID := getWorkspaceID(ctx) |
| 81 | if workspaceID == "" { |
| 82 | return nil, &toolError{ |
| 83 | Code: "AUTH_ERROR", |
| 84 | Message: "workspace ID not found in token", |
| 85 | Suggestion: "re-authenticate with Bytebase", |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | var databases []databaseEntry |
| 90 | pageToken := "" |
| 91 | for { |
| 92 | body := map[string]any{ |
| 93 | "parent": fmt.Sprintf("workspaces/%s", workspaceID), |
| 94 | "filter": filter, |
| 95 | "pageSize": 1000, |
| 96 | } |
| 97 | if pageToken != "" { |
| 98 | body["pageToken"] = pageToken |
| 99 | } |
| 100 | resp, err := s.apiRequest(ctx, "/bytebase.v1.DatabaseService/ListDatabases", body) |
| 101 | if err != nil { |
| 102 | return nil, errors.Wrap(err, "failed to list databases") |
| 103 | } |
| 104 | if resp.Status == http.StatusForbidden { |
| 105 | return nil, &toolError{ |
| 106 | Code: "PERMISSION_DENIED", |
| 107 | Message: "you don't have permission to list databases in this workspace", |
| 108 | Suggestion: "ask your workspace admin to grant you the bb.databases.list permission", |
| 109 | } |
| 110 | } |
| 111 | if resp.Status >= 400 { |
| 112 | return nil, errors.Errorf("failed to list databases: HTTP %d: %s", resp.Status, parseError(resp.Body)) |
| 113 | } |
| 114 | |
| 115 | var listResp listDatabasesResponse |
| 116 | if err := json.Unmarshal(resp.Body, &listResp); err != nil { |
| 117 | return nil, errors.Wrap(err, "failed to parse database list") |
| 118 | } |
| 119 | databases = append(databases, listResp.Databases...) |
| 120 | |
| 121 | if listResp.NextPageToken == "" { |
| 122 | break |
| 123 | } |
| 124 | pageToken = listResp.NextPageToken |
| 125 | } |
| 126 | return databases, nil |
| 127 | } |
| 128 | |
| 129 | // matchDatabases applies tiered matching (exact > case-insensitive > substring) and |
| 130 | // returns the resolved result, an ambiguous result, or a not-found error. |
no test coverage detected