Skip to content

Commit cfc6ece

Browse files
thisisaaronlandthisisaaronland
andauthored
add resolver.MultiResolver (#27)
Co-authored-by: thisisaaronland <thisisaaronland@localhost>
1 parent 31f2fbe commit cfc6ece

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

resolver/multi.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package resolver
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log/slog"
7+
"net/url"
8+
)
9+
10+
// type MultiResolver implements the `Resolver` interface for resolving data using one or more `Resolver` instances.
11+
type MultiResolver struct {
12+
Resolver
13+
resolvers []Resolver
14+
}
15+
16+
func init() {
17+
ctx := context.Background()
18+
RegisterResolver(ctx, "multi", NewMultiResolver)
19+
}
20+
21+
// NewMultiResolver will return a new `Resolver` instance for resolving data using one or more `Resolver` instances.
22+
func NewMultiResolver(ctx context.Context, uri string) (Resolver, error) {
23+
24+
u, err := url.Parse(uri)
25+
26+
if err != nil {
27+
return nil, fmt.Errorf("Failed to parse URL, %w", err)
28+
}
29+
30+
q := u.Query()
31+
32+
if !q.Has("resolver") {
33+
return nil, fmt.Errorf("URI has no ?resolver= parameters")
34+
}
35+
36+
resolvers := make([]Resolver, len(q["resolver"]))
37+
38+
for idx, r_uri := range q["resolver"] {
39+
40+
r, err := NewResolver(ctx, r_uri)
41+
42+
if err != nil {
43+
return nil, fmt.Errorf("Failed to create resolver for '%s', %w", r_uri, err)
44+
}
45+
46+
resolvers[idx] = r
47+
}
48+
49+
multi_r := &MultiResolver{
50+
resolvers: resolvers,
51+
}
52+
53+
return multi_r, nil
54+
}
55+
56+
// GetRepo returns the name of the repository associated with this ID from the first of one or more matching `Resolver` instances.
57+
func (r *MultiResolver) GetRepo(ctx context.Context, id int64) (string, error) {
58+
59+
for _, other_r := range r.resolvers {
60+
61+
repo, err := other_r.GetRepo(ctx, id)
62+
63+
if err != nil {
64+
slog.Debug("Failed to get repo", "id", id, "resolver", fmt.Sprintf("%T", other_r), "error", err)
65+
continue
66+
}
67+
68+
return repo, nil
69+
}
70+
71+
return "", fmt.Errorf("Not found")
72+
}

resolver/multi_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package resolver
2+
3+
import (
4+
"context"
5+
"net/url"
6+
"testing"
7+
)
8+
9+
func TestMultiResolver(t *testing.T) {
10+
11+
ctx := context.Background()
12+
13+
resolver_uris := []string{
14+
"https://static.sfomuseum.org/findingaid?template=https://raw.githubusercontent.com/sfomuseum-data/{repo}/main/data/",
15+
"https://data.whosonfirst.org/findingaid?template=https://raw.githubusercontent.com/whosonfirst-data/{repo}/master/data/",
16+
}
17+
18+
r_query := url.Values{}
19+
20+
for _, uri := range resolver_uris {
21+
r_query.Set("resolver", uri)
22+
}
23+
24+
r_uri := url.URL{}
25+
r_uri.Scheme = "multi"
26+
r_uri.RawQuery = r_query.Encode()
27+
28+
r, err := NewResolver(ctx, r_uri.String())
29+
30+
if err != nil {
31+
t.Fatalf("Failed to create new resolver for %s, %v", r_uri.String(), err)
32+
}
33+
34+
id := int64(85865975)
35+
repo, err := r.GetRepo(ctx, id)
36+
37+
if err != nil {
38+
t.Fatalf("Failed to get repo for %d, %v", id, err)
39+
}
40+
41+
if repo != "whosonfirst-data-admin-us" {
42+
t.Fatalf("Unexpected repo, %s", repo)
43+
}
44+
}

0 commit comments

Comments
 (0)