package driver import ( "context" "errors" "local/dndex/config" "log" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type Mongo struct { client *mongo.Client db string } func NewMongo() Mongo { opts := options.Client().ApplyURI(config.New().DBURI) c, err := mongo.NewClient(opts) if err != nil { panic(err) } if err := c.Connect(context.TODO()); err != nil { panic(err) } ctx, can := context.WithTimeout(context.Background(), time.Second) defer can() if _, err := c.ListDatabaseNames(ctx, map[string]interface{}{}); err != nil { panic(err) } return Mongo{ client: c, db: config.New().Database, } } func (m Mongo) Find(ctx context.Context, namespace string, filter interface{}) (chan bson.Raw, error) { c := m.client.Database(m.db).Collection(namespace) cursor, err := c.Find(ctx, filter) if err != nil { return nil, err } return m.page(ctx, cursor), nil } func (m Mongo) page(ctx context.Context, cursor *mongo.Cursor) chan bson.Raw { ch := make(chan bson.Raw) go func(chan<- bson.Raw) { defer close(ch) defer cursor.Close(ctx) for cursor.Next(ctx) { ch <- cursor.Current } }(ch) return ch } func (m Mongo) Update(ctx context.Context, namespace string, filter, apply interface{}) error { c := m.client.Database(m.db).Collection(namespace) _, err := c.UpdateMany(ctx, filter, apply) return err } func (m Mongo) Insert(ctx context.Context, namespace string, apply interface{}) error { b, err := bson.Marshal(apply) if err != nil { return err } var mapp map[string]interface{} if err := bson.Unmarshal(b, &mapp); err != nil { return err } if _, ok := mapp["_id"]; !ok { return errors.New("no _id in new object") } else if _, ok := mapp["_id"].(string); !ok { return errors.New("non-string _id in new object") } c := m.client.Database(m.db).Collection(namespace) _, err = c.InsertOne(ctx, apply) return err } func (m Mongo) Delete(ctx context.Context, namespace string, filter interface{}) error { c := m.client.Database(m.db).Collection(namespace) _, err := c.DeleteMany(ctx, filter) return err } func peekBSON(v interface{}) { b, err := bson.Marshal(v) if err != nil { panic(err) } var m map[string]interface{} if err := bson.Unmarshal(b, &m); err != nil { panic(err) } log.Printf("PEEK: %+v", m) }