Маршал / Унмаршал нестандартного типа с mongodb-go-driver - PullRequest
0 голосов
/ 26 января 2019

Итак, я пробую официальный драйвер mongodb go (раньше использовал mgo), и я застрял.Я пытаюсь маршалировать / демаршировать пользовательский тип, который по умолчанию явно не работает.Документация вроде не хватает.По сути, я хотел бы сделать следующее:

type X struct {
    Y Z
}


type Z interface {
    ...
}

Есть ли способ сделать это, или в данный момент у него полностью отсутствует эта функция?Я знаю, что это все еще бета-версия, но альтернативы там немного.

Редактировать:

Пример того, что я хотел бы сделать:

cur, err := mongo.Collection("coll").Find(ctx, bson.M{})
if err != nil {
  return err
}
defer cur.Close(ctx)
for cur.Next(ctx) {
  var el X
  err := cur.Decode(&el)
  if err == nil {
    // Do whatever...
  }
}
if err = cur.Err(); err != nil {
  return err
}

Ия получаю ошибку: no decoder found for Z

Пример теста:

package examples

import (
    "context"
    "testing"

    "github.com/mongodb/mongo-go-driver/bson"
    "github.com/mongodb/mongo-go-driver/mongo"
)

type X struct {
    Color string `json:"color" bson:"color"`
    Y     Z      `bson:"y"`
}

type Z interface {
    echo() string
}

func (x X) echo() string {
    return x.Color
}

func TestFindCars(t *testing.T) {
    var err error
    var client *mongo.Client
    var collection *mongo.Collection
    var cur mongo.Cursor
    var ctx = context.Background()
    if client, err = mongo.Connect(ctx, "mongodb://localhost/so?replicaSet=replset"); err != nil {
        t.Fatal(err)
    }
    collection = client.Database("so").Collection(collectionName)
    collection.InsertOne(ctx, bson.M{"color": "Red", "y": 12})
    if cur, err = collection.Find(ctx, bson.M{}); err != nil {
        t.Fatal(err)
    }
    if err != nil {
        t.Fatal(err)
    }
    defer cur.Close(ctx)
    for cur.Next(ctx) {
        var el X
        if err = cur.Decode(&el); err != nil {
            t.Fatal(err)
        }
        t.Log(el.echo())
    }
    if err = cur.Err(); err != nil {
        t.Fatal(err)
    }
}

1 Ответ

0 голосов
/ 26 января 2019

Вот полный пример использования вашего примера, и он работает нормально.

package examples

import (
    "context"
    "testing"

    "github.com/mongodb/mongo-go-driver/bson"
    "github.com/mongodb/mongo-go-driver/mongo"
)

type X struct {
    Color string `json:"color" bson:"color"`
    Y     Z
}

type Z interface {
    echo() string
}

func (x X) echo() string {
    return x.Color
}

func TestFindCars(t *testing.T) {
    var err error
    var client *mongo.Client
    var collection *mongo.Collection
    var cur mongo.Cursor
    var ctx = context.Background()
    if client, err = mongo.Connect(ctx, "mongodb://localhost/so?replicaSet=replset"); err != nil {
        t.Fatal(err)
    }
    collection = client.Database("so").Collection(collectionName)
    collection.InsertOne(ctx, bson.M{"color": "Red"})
    if cur, err = collection.Find(ctx, bson.M{}); err != nil {
        t.Fatal(err)
    }
    if err != nil {
        t.Fatal(err)
    }
    defer cur.Close(ctx)
    for cur.Next(ctx) {
        var el X
        if err = cur.Decode(&el); err != nil {
            t.Fatal(err)
        }
        t.Log(el.echo())
    }
    if err = cur.Err(); err != nil {
        t.Fatal(err)
    }
}

Test

$ GOCACHE=off go test -v -run TestFindCars
=== RUN   TestFindCars
--- PASS: TestFindCars (0.09s)
    find2_test.go:49: Red
PASS
...