Skip to content

Instantly share code, notes, and snippets.

@tauraamui
Created September 12, 2019 08:00
Show Gist options
  • Save tauraamui/786df5fc81f9148cfd3922f1d088647a to your computer and use it in GitHub Desktop.
Save tauraamui/786df5fc81f9148cfd3922f1d088647a to your computer and use it in GitHub Desktop.
To show how to potentially populate a slice of interface from MongoDB and GCS
"store.go"
type Store interface {
Save(ctx context.Context, model interface{}) (interface{}, error)
FindAll(ctx context.Context, key string, value string, dst interface{}) error
}
type MongoDBStore struct {
db *mongo.Collection
}
func NewMongoStore(db *mongo.Collection) Store {
return MongoDBStore{
db: db,
}
}
func (store MongoDBStore) Save(
ctx context.Context,
model interface{},
) (interface{}, error) {
result, err := store.db.InsertOne(ctx, model)
if err != nil {
return nil, err
}
if objectID, ok := result.InsertedID.(primitive.ObjectID); ok {
return &objectID, nil
}
return nil, errors.New("unable to cast ID from DB to primitive.ObjectID")
}
func (store MongoDBStore) FindAll(
ctx context.Context,
key string,
value string,
dst interface{},
) error {
dv := reflect.ValueOf(dst)
if dv.Kind() != reflect.Ptr || dv.IsNil() {
return errors.New("must be of type pointer")
}
dv = dv.Elem()
elemType := dv.Type().Elem()
cursor, err := store.db.Find(ctx, bson.D{{key, value}})
if err != nil {
return err
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
ev := reflect.New(elemType.Elem())
err := cursor.Decode(ev.Interface())
if err != nil {
return err
}
dv.Set(reflect.Append(dv, ev))
}
return nil
}
type GCStore struct {
db *datastore.Client
kind string
}
func NewGCStore(client *datastore.Client, kind string) Store {
return GCStore{
db: client,
kind: kind,
}
}
func (store GCStore) Save(
ctx context.Context,
model interface{},
) (interface{}, error) {
key := datastore.IncompleteKey(store.kind, nil)
savedKey, err := store.db.Put(ctx, key, model)
if err != nil {
return nil, err
}
return savedKey, nil
}
func (store GCStore) FindAll(
ctx context.Context,
key string,
value string,
dst interface{},
) error {
q := datastore.NewQuery(store.kind).Filter(fmt.Sprintf("%s =,", key), value)
_, err := store.db.GetAll(ctx, q, dst)
if err != nil {
return err
}
return nil
}
"fancyhandler.go"
userID, passphrase, httpErr := getDataFromRequest(c)
if httpErr != nil {
return httpErr
}
contactsToSend := []*models.Contact{}
db := models.NewMongoStore(database.Collection("contacts"))
err := db.FindAll(ctx, "userid", userID.Hex(), &contactsToSend)
if err != nil {
c.Logger().Error(err)
return c.JSON(http.StatusInternalServerError, web.ResponseBody{
Error: err.Error(),
})
}
for _, contact := range contactsToSend {
contact.Decrypt(passphrase)
}
return c.JSON(http.StatusOK, web.ResponseBody{
Data: contactsToSend,
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment