-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
internal/fstore: support for firestore
Add a package that provides common support functions for the GCP Firestore service. Use it in the internal/jobs package. Change-Id: Iac3bdcc22bb5abe6a3609d9545b66958c37e0cb9 Reviewed-on: https://go-review.googlesource.com/c/pkgsite-metrics/+/551755 TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Zvonimir Pavlinovic <[email protected]> Run-TryBot: Jonathan Amsterdam <[email protected]>
- Loading branch information
Showing
2 changed files
with
89 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright 2023 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// Package fstore provides general support for Firestore. | ||
// Its main feature is separate namespaces, to mimic separate | ||
// databases for different purposes (prod, dev, test, etc.). | ||
package fstore | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
|
||
"cloud.google.com/go/firestore" | ||
"golang.org/x/pkgsite-metrics/internal/derrors" | ||
) | ||
|
||
const namespaceCollection = "Namespaces" | ||
|
||
// A Namespace is a top-level collection for partitioning a Firestore | ||
// database into separate segments. | ||
type Namespace struct { | ||
client *firestore.Client | ||
name string | ||
doc *firestore.DocumentRef | ||
} | ||
|
||
// OpenNamespace creates a new Firestore client whose collections will be located in the given namespace. | ||
func OpenNamespace(ctx context.Context, projectID, name string) (_ *Namespace, err error) { | ||
defer derrors.Wrap(&err, "OpenNamespace(%q, %q)", projectID, name) | ||
|
||
if name == "" { | ||
return nil, errors.New("empty namespace") | ||
} | ||
client, err := firestore.NewClient(ctx, projectID) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &Namespace{ | ||
client: client, | ||
name: name, | ||
doc: client.Collection(namespaceCollection).Doc(name), | ||
}, nil | ||
} | ||
|
||
// Name returns the Namespace's name. | ||
func (ns *Namespace) Name() string { return ns.name } | ||
|
||
// Client returns the underlying Firestore client. | ||
func (ns *Namespace) Client() *firestore.Client { return ns.client } | ||
|
||
// Close closes the underlying client. | ||
func (ns *Namespace) Close() error { return ns.client.Close() } | ||
|
||
// Collection returns a reference to the named collection in the namespace. | ||
func (ns *Namespace) Collection(name string) *firestore.CollectionRef { | ||
return ns.doc.Collection(name) | ||
} | ||
|
||
// Get gets the DocumentRef and decodes the result to a value of type T. | ||
func Get[T any](ctx context.Context, dr *firestore.DocumentRef) (_ *T, err error) { | ||
defer derrors.Wrap(&err, "fstore.Get(%q)", dr.Path) | ||
docsnap, err := dr.Get(ctx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return Decode[T](docsnap) | ||
} | ||
|
||
// Decode decodes a DocumentSnapshot into a value of type T. | ||
func Decode[T any](ds *firestore.DocumentSnapshot) (*T, error) { | ||
var t T | ||
if err := ds.DataTo(&t); err != nil { | ||
return nil, err | ||
} | ||
return &t, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters