Skip to content

Commit 83b175c

Browse files
refactor: split GraphQL package search and count into separate queries (#31)
Replace the combined package_search_with_count.gql (which fetched both results and aggregate count in one request) with two focused queries: - package_search.gql: fetches package results only (FilteredPackages) - package_search_count.gql: fetches aggregate count only (FilteredPackagesCounts) Add buildGraphQLPackageVariables helper to avoid duplicating variable construction between fetchGraphQLPackages and fetchGraphQLPackageCount. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4c422ae commit 83b175c

3 files changed

Lines changed: 118 additions & 111 deletions

File tree

package_search_count.gql

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
query FilteredPackagesCounts(
2+
$search: String
3+
$matchtags: _text
4+
$registries: _int8
5+
$hasfailures: Boolean
6+
$installed: Boolean
7+
$notinstalled: Boolean
8+
$licenses: _text
9+
$filter: package_rank_vw_bool_exp = {}
10+
) {
11+
package_search_aggregate(
12+
args: {
13+
search: $search
14+
matchtags: $matchtags
15+
licenses: $licenses
16+
isinstalled: $installed
17+
notinstalled: $notinstalled
18+
hasfailures: $hasfailures
19+
registrylist: $registries
20+
}
21+
where: { _and: [{ fit: { _gte: 1 } }, $filter] }
22+
) {
23+
aggregate {
24+
count
25+
}
26+
}
27+
}

package_search_with_count.gql

Lines changed: 0 additions & 78 deletions
This file was deleted.

packages.go

Lines changed: 91 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"time"
1212
)
1313

14-
//go:embed package_search_with_count.gql
14+
//go:embed package_search.gql package_search_count.gql
1515
var packageSearchFS embed.FS
1616

1717
type PackageMetadata struct {
@@ -51,20 +51,6 @@ type Package struct {
5151
Failures []PackageFailure `json:"failures"`
5252
}
5353

54-
type PackageSearchResponse struct {
55-
Data struct {
56-
PackageSearch []Package `json:"package_search"`
57-
PackageAggregate struct {
58-
Aggregate struct {
59-
Count int `json:"count"`
60-
} `json:"aggregate"`
61-
} `json:"package_search_aggregate"`
62-
} `json:"data"`
63-
Errors []struct {
64-
Message string `json:"message"`
65-
} `json:"errors"`
66-
}
67-
6854
type RESTPackage struct {
6955
Name string `json:"name"`
7056
UUID string `json:"uuid"`
@@ -305,32 +291,89 @@ func fetchRESTPackages(server, search string, limit, offset int, registryNames [
305291
return response.Packages, response.Meta.Total, nil
306292
}
307293

308-
// fetchGraphQLPackages executes the package search GraphQL query and returns raw results and total count.
309-
func fetchGraphQLPackages(server, search string, limit, offset int, registryIDs []int) ([]Package, int, error) {
294+
func buildGraphQLPackageVariables(search string, limit, offset int, registryIDs []int) map[string]interface{} {
295+
variables := map[string]interface{}{
296+
"filter": map[string]interface{}{},
297+
"order": map[string]string{"score": "desc"},
298+
"matchtags": "{}",
299+
"licenses": "{}",
300+
"search": search,
301+
"offset": offset,
302+
"hasfailures": false,
303+
"installed": true,
304+
"notinstalled": true,
305+
}
306+
if limit > 0 {
307+
variables["limit"] = limit
308+
}
309+
if len(registryIDs) > 0 {
310+
registryStrs := make([]string, len(registryIDs))
311+
for i, id := range registryIDs {
312+
registryStrs[i] = fmt.Sprintf("%d", id)
313+
}
314+
variables["registries"] = fmt.Sprintf("{%s}", strings.Join(registryStrs, ","))
315+
}
316+
return variables
317+
}
318+
319+
func fetchGraphQLPackages(server, search string, limit, offset int, registryIDs []int) ([]Package, error) {
310320
token, err := ensureValidToken()
311321
if err != nil {
312-
return nil, 0, fmt.Errorf("authentication required: %w", err)
322+
return nil, fmt.Errorf("authentication required: %w", err)
323+
}
324+
325+
queryBytes, err := packageSearchFS.ReadFile("package_search.gql")
326+
if err != nil {
327+
return nil, fmt.Errorf("failed to read GraphQL query: %w", err)
328+
}
329+
330+
body, err := executeGraphQL(server, token, GraphQLRequest{
331+
OperationName: "FilteredPackages",
332+
Query: string(queryBytes),
333+
Variables: buildGraphQLPackageVariables(search, limit, offset, registryIDs),
334+
})
335+
if err != nil {
336+
return nil, err
337+
}
338+
339+
var response struct {
340+
Data struct {
341+
PackageSearch []Package `json:"package_search"`
342+
} `json:"data"`
343+
Errors []struct {
344+
Message string `json:"message"`
345+
} `json:"errors"`
346+
}
347+
if err := json.Unmarshal(body, &response); err != nil {
348+
return nil, fmt.Errorf("failed to parse GraphQL response: %w", err)
349+
}
350+
if len(response.Errors) > 0 {
351+
return nil, fmt.Errorf("GraphQL errors: %v", response.Errors)
352+
}
353+
354+
return response.Data.PackageSearch, nil
355+
}
356+
357+
func fetchGraphQLPackageCount(server, search string, registryIDs []int) (int, error) {
358+
token, err := ensureValidToken()
359+
if err != nil {
360+
return 0, fmt.Errorf("authentication required: %w", err)
313361
}
314362

315-
queryBytes, err := packageSearchFS.ReadFile("package_search_with_count.gql")
363+
queryBytes, err := packageSearchFS.ReadFile("package_search_count.gql")
316364
if err != nil {
317-
return nil, 0, fmt.Errorf("failed to read GraphQL query: %w", err)
365+
return 0, fmt.Errorf("failed to read GraphQL query: %w", err)
318366
}
319367

320368
variables := map[string]interface{}{
321369
"filter": map[string]interface{}{},
322-
"order": map[string]string{"score": "desc"},
323370
"matchtags": "{}",
324371
"licenses": "{}",
325372
"search": search,
326-
"offset": offset,
327373
"hasfailures": false,
328374
"installed": true,
329375
"notinstalled": true,
330376
}
331-
if limit > 0 {
332-
variables["limit"] = limit
333-
}
334377
if len(registryIDs) > 0 {
335378
registryStrs := make([]string, len(registryIDs))
336379
for i, id := range registryIDs {
@@ -340,23 +383,34 @@ func fetchGraphQLPackages(server, search string, limit, offset int, registryIDs
340383
}
341384

342385
body, err := executeGraphQL(server, token, GraphQLRequest{
343-
OperationName: "FilteredPackagesWithCount",
386+
OperationName: "FilteredPackagesCounts",
344387
Query: string(queryBytes),
345388
Variables: variables,
346389
})
347390
if err != nil {
348-
return nil, 0, err
391+
return 0, err
349392
}
350393

351-
var response PackageSearchResponse
394+
var response struct {
395+
Data struct {
396+
PackageAggregate struct {
397+
Aggregate struct {
398+
Count int `json:"count"`
399+
} `json:"aggregate"`
400+
} `json:"package_search_aggregate"`
401+
} `json:"data"`
402+
Errors []struct {
403+
Message string `json:"message"`
404+
} `json:"errors"`
405+
}
352406
if err := json.Unmarshal(body, &response); err != nil {
353-
return nil, 0, fmt.Errorf("failed to parse GraphQL response: %w", err)
407+
return 0, fmt.Errorf("failed to parse GraphQL response: %w", err)
354408
}
355409
if len(response.Errors) > 0 {
356-
return nil, 0, fmt.Errorf("GraphQL errors: %v", response.Errors)
410+
return 0, fmt.Errorf("GraphQL errors: %v", response.Errors)
357411
}
358412

359-
return response.Data.PackageSearch, response.Data.PackageAggregate.Aggregate.Count, nil
413+
return response.Data.PackageAggregate.Aggregate.Count, nil
360414
}
361415

362416
func searchPackagesREST(params PackageSearchParams) error {
@@ -373,7 +427,11 @@ func searchPackagesREST(params PackageSearchParams) error {
373427
}
374428

375429
func searchPackagesGraphQL(params PackageSearchParams) error {
376-
pkgs, total, err := fetchGraphQLPackages(params.Server, params.Search, params.Limit, params.Offset, params.RegistryIDs)
430+
pkgs, err := fetchGraphQLPackages(params.Server, params.Search, params.Limit, params.Offset, params.RegistryIDs)
431+
if err != nil {
432+
return err
433+
}
434+
total, err := fetchGraphQLPackageCount(params.Server, params.Search, params.RegistryIDs)
377435
if err != nil {
378436
return err
379437
}
@@ -456,7 +514,7 @@ func getPackageInfoREST(server, packageName string, registryNames []string) erro
456514
}
457515

458516
func getPackageInfoGraphQL(server, packageName string, registryIDs []int, registryNames []string) error {
459-
pkgs, _, err := fetchGraphQLPackages(server, packageName, 100, 0, registryIDs)
517+
pkgs, err := fetchGraphQLPackages(server, packageName, 100, 0, registryIDs)
460518
if err != nil {
461519
return err
462520
}

0 commit comments

Comments
 (0)