mongoifc

package module
v1.17.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 24, 2024 License: MIT Imports: 10 Imported by: 1

README

mongoifc

Code Analysis Go Reference codecov GitHub tag (latest SemVer) OpenSSF Best Practices OpenSSF Scorecard

The Interfaces for the MongoDB driver

Versioning Policy

The mongoifc code is stabilized, so now the version will match the version of the MongoDB driver since v1.8.0.

In case of need for bug fixes in mongoifc, the version will be in this format v1.8.1+N, where v1.8.1 is the version of MongoDB driver and N is a patch of mongoifc. The new version for changes in README.md, tests, examples, GitHub workflows is not required.

Important

It is not a simple drop in replacement because of the limitations in Go. You should rewrite your code to use this library instead of mongo driver.

conn := mongoifc.Connect(...)

instead of

conn := mongo.Connect(...)

or if you have a special code that returns the mongo object then you need to use one of Wrap functions to wrap the mongo.Client or mongo.Database or mongo.Collection or mongo.Session objects:

orig := mongo.Connect(...)

...

conn := mongoifc.WrapClient(orig)

or

func GetTenantDB(ctx context.Context, tenantID, dbName string) (*mongo.Database, error) {
// a code that returns a special database for a given tenant and database name
}

...

orig, err := GetTenantDB(ctx, tenant, "users")
if err != nil {
...
}
db = mongoifc.WrapDatabase(orig)

Now let's dig a bit into the limitations. Assume that you have a function to return a list of admin users, and you rewrote it using mongoifc:

package users

// Original: func GetAdmins(ctx context.Context, db *mongo.Database) ([]*User, error)
func GetAdmins(ctx context.Context, db mongoifc.Database) ([]User, error) {
	var users []User
	cur, err := db.Collection(UsersCollection).Find(ctx, User{
		Active:  true,
		IsAdmin: true,
	})
	if err != nil {
		return nil, err
	}
	if err := cur.All(ctx, &users); err != nil {
		return nil, err
	}
	return users, err
}

and if you pass an object of *mongo.Database type instead of mongoifc.Database

conn, _ := mongo.Connect(context.Background(), ...)
db := conn.Database(...)

users.GetAdmins(context.Background(), db)

then compilation fails with such error:

 cannot use db (type *mongo.Database) as type mongoifc.Database in argument to simple.GetAdmins:
     *mongo.Database does not implement mongoifc.Database (wrong type for Aggregate method)
         have Aggregate(context.Context, interface {}, ...*"go.mongodb.org/mongo-driver/mongo/options".AggregateOptions) (*mongo.Cursor, error)
         want Aggregate(context.Context, interface {}, ...*"go.mongodb.org/mongo-driver/mongo/options".AggregateOptions) (mongoifc.Cursor, error)

This is the main reason of wrapping the original objects and using the mongoifc instead.

Wrapped Interfaces

Mocks

The mocks folder contains the mocks generated by mockery and gomock tools.

The examples of how to use the mocks can be found in the examples folder or check any of the *_test.go files as well.

Simple Example

user workflow
  1. Create 4 users, with two admins, using InsertMany function.
  2. Get the admin users only using Find function
  3. Delete all users using DeleteMany function
  • users.go is a file with a set of functions, like:
    • Create to create the users using InsertMany
    • Delete to delete the users by given IDs
    • GetAdmins to return the list of admin users
  • users_test.go is a file with TestUsersWorkflow unit tests:
    • mockery tests the workflow using mockery mocks
    • gomock tests the workflow using gomock mocks
    • docker tests the workflow using real mongo database run by docker
collection workflow
  1. Create a collection with random name.
  2. Check that the collection exists.
  3. Check that another collection does not exist.
  4. Drop collection.
  5. Check that the original collection does not exist.
  • collections.go is a file with a set of functions, like:
    • CreateCollection to create a collection using CreateCollection
    • DropCollection to delete a collection by given name
    • CollectionExists to check that a collection exists
  • collections_test.go is a file with TestCollectionsWorkflow unit tests:
    • mockery tests the workflow using mockery mocks
    • gomock tests the workflow using gomock mocks
    • docker tests the workflow using real mongo database run by docker

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func UnWrapClient added in v1.0.0

func UnWrapClient(cl Client) *mongo.Client

UnWrapClient returns original mongo.Client

func UnWrapCollection added in v1.8.2

func UnWrapCollection(co Collection) *mongo.Collection

UnWrapCollection returns original mongo.Collection

func UnWrapDatabase added in v1.8.2

func UnWrapDatabase(db Database) *mongo.Database

UnWrapDatabase returns original mongo.Database

func UnWrapSession added in v1.8.2

func UnWrapSession(ss Session) mongo.Session

UnWrapSession returns original mongo.Session

func WithSession

func WithSession(ctx context.Context, sess Session, fn func(sc SessionContext) error) error

WithSession is a wrapper for `mongo.WithSession` function to call then `mongo.WithSession` function Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#WithSession

Types

type ChangeStream

type ChangeStream interface {
	Current() bson.Raw
	Close(ctx context.Context) error
	Decode(val interface{}) error
	Err() error
	ID() int64
	Next(ctx context.Context) bool
	ResumeToken() bson.Raw
	SetBatchSize(size int32)
	TryNext(ctx context.Context) bool
}

ChangeStream is an interface for `mongo.ChangeStream` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#ChangeStream

type Client

type Client interface {
	Connect(ctx context.Context) error
	Database(name string, opts ...*options.DatabaseOptions) Database
	Disconnect(ctx context.Context) error
	ListDatabaseNames(
		ctx context.Context,
		filter interface{},
		opts ...*options.ListDatabasesOptions,
	) ([]string, error)
	ListDatabases(
		ctx context.Context,
		filter interface{},
		opts ...*options.ListDatabasesOptions,
	) (mongo.ListDatabasesResult, error)
	NumberSessionsInProgress() int
	Ping(ctx context.Context, rp *readpref.ReadPref) error
	StartSession(opts ...*options.SessionOptions) (Session, error)
	Timeout() *time.Duration
	UseSession(
		ctx context.Context,
		fn func(sc SessionContext) error,
	) error
	UseSessionWithOptions(
		ctx context.Context,
		opts *options.SessionOptions,
		fn func(sc SessionContext) error,
	) error
	Watch(
		ctx context.Context,
		pipeline interface{},
		opts ...*options.ChangeStreamOptions,
	) (ChangeStream, error)
}

Client is an interface for `mongo.Client` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#Client

func Connect

func Connect(ctx context.Context, opts ...*options.ClientOptions) (Client, error)

Connect is a wrapper for `mongo.Connect` function to return the object as `Client` interface Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#Connect

func NewClient deprecated

func NewClient(opts ...*options.ClientOptions) (Client, error)

NewClient is a wrapper for `mongo.NewClient` function to return the object as `Client` interface Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#NewClient

Deprecated: Use Connect instead.

func WrapClient

func WrapClient(cl *mongo.Client) Client

WrapClient returns an instance of Client interface for given mongo.Client object

type ClientEncryption added in v1.13.0

type ClientEncryption interface {
	AddKeyAltName(
		ctx context.Context,
		id primitive.Binary,
		keyAltName string,
	) SingleResult
	Close(ctx context.Context) error
	CreateDataKey(
		ctx context.Context,
		kmsProvider string,
		opts ...*options.DataKeyOptions,
	) (primitive.Binary, error)
	CreateEncryptedCollection(
		ctx context.Context,
		db Database,
		coll string,
		createOpts *options.CreateCollectionOptions,
		kmsProvider string,
		masterKey interface{},
	) (Collection, bson.M, error)
	Decrypt(ctx context.Context, val primitive.Binary) (bson.RawValue, error)
	DeleteKey(ctx context.Context, id primitive.Binary) (*mongo.DeleteResult, error)
	Encrypt(
		ctx context.Context,
		val bson.RawValue,
		opts ...*options.EncryptOptions,
	) (primitive.Binary, error)
	EncryptExpression(
		ctx context.Context,
		expr interface{},
		result interface{},
		opts ...*options.EncryptOptions,
	) error
	GetKey(ctx context.Context, id primitive.Binary) SingleResult
	GetKeyByAltName(ctx context.Context, keyAltName string) SingleResult
	GetKeys(ctx context.Context) (Cursor, error)
	RemoveKeyAltName(
		ctx context.Context,
		id primitive.Binary,
		keyAltName string,
	) SingleResult
	RewrapManyDataKey(
		ctx context.Context,
		filter interface{},
		opts ...*options.RewrapManyDataKeyOptions,
	) (*mongo.RewrapManyDataKeyResult, error)
}

ClientEncryption is an interface for `mongo.ClientEncryption` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#ClientEncryption

func NewClientEncryption added in v1.13.0

func NewClientEncryption(keyVaultClient Client, opts ...*options.ClientEncryptionOptions) (ClientEncryption, error)

type Collection

type Collection interface {
	Aggregate(ctx context.Context, pipeline interface{}, opts ...*options.AggregateOptions) (Cursor, error)
	BulkWrite(
		ctx context.Context,
		models []mongo.WriteModel,
		opts ...*options.BulkWriteOptions,
	) (*mongo.BulkWriteResult, error)
	Clone(opts ...*options.CollectionOptions) (Collection, error)
	CountDocuments(ctx context.Context, filter interface{}, opts ...*options.CountOptions) (int64, error)
	Database() Database
	DeleteMany(ctx context.Context, filter interface{}, opts ...*options.DeleteOptions) (*mongo.DeleteResult, error)
	DeleteOne(ctx context.Context, filter interface{}, opts ...*options.DeleteOptions) (*mongo.DeleteResult, error)
	Distinct(
		ctx context.Context,
		fieldName string,
		filter interface{},
		opts ...*options.DistinctOptions,
	) ([]interface{}, error)
	Drop(ctx context.Context) error
	EstimatedDocumentCount(ctx context.Context, opts ...*options.EstimatedDocumentCountOptions) (int64, error)
	Find(ctx context.Context, filter interface{}, opts ...*options.FindOptions) (Cursor, error)
	FindOne(ctx context.Context, filter interface{}, opts ...*options.FindOneOptions) SingleResult
	FindOneAndDelete(ctx context.Context, filter interface{}, opts ...*options.FindOneAndDeleteOptions) SingleResult
	FindOneAndReplace(
		ctx context.Context,
		filter interface{},
		replacement interface{},
		opts ...*options.FindOneAndReplaceOptions,
	) SingleResult
	FindOneAndUpdate(
		ctx context.Context,
		filter interface{},
		update interface{},
		opts ...*options.FindOneAndUpdateOptions,
	) SingleResult
	Indexes() IndexView
	InsertMany(
		ctx context.Context,
		documents []interface{},
		opts ...*options.InsertManyOptions,
	) (*mongo.InsertManyResult, error)
	InsertOne(
		ctx context.Context,
		document interface{},
		opts ...*options.InsertOneOptions,
	) (*mongo.InsertOneResult, error)
	Name() string
	ReplaceOne(
		ctx context.Context,
		filter interface{},
		replacement interface{},
		opts ...*options.ReplaceOptions,
	) (*mongo.UpdateResult, error)
	SearchIndexes() SearchIndexView
	UpdateByID(
		ctx context.Context,
		id interface{},
		update interface{},
		opts ...*options.UpdateOptions,
	) (*mongo.UpdateResult, error)
	UpdateMany(
		ctx context.Context,
		filter interface{},
		update interface{},
		opts ...*options.UpdateOptions,
	) (*mongo.UpdateResult, error)
	UpdateOne(
		ctx context.Context,
		filter interface{},
		update interface{},
		opts ...*options.UpdateOptions,
	) (*mongo.UpdateResult, error)
	Watch(ctx context.Context, pipeline interface{}, opts ...*options.ChangeStreamOptions) (ChangeStream, error)
}

Collection is an interface for `mongo.Collection` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#Collection

func WrapCollection added in v1.8.2

func WrapCollection(co *mongo.Collection) Collection

WrapCollection returns an instance of Collection interface for given mongo.Collection object

type Cursor

type Cursor interface {
	Current() bson.Raw
	All(ctx context.Context, results interface{}) error
	Close(ctx context.Context) error
	Decode(val interface{}) error
	Err() error
	ID() int64
	Next(ctx context.Context) bool
	RemainingBatchLength() int
	SetBatchSize(batchSize int32)
	SetComment(comment interface{})
	SetMaxTime(dur time.Duration)
	TryNext(ctx context.Context) bool
}

Cursor is an interface for `mongo.Cursor` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#Cursor

func NewCursorFromDocuments added in v1.9.0

func NewCursorFromDocuments(documents []interface{}, err error, registry *bsoncodec.Registry) (Cursor, error)

NewCursorFromDocuments is a wrapper for NewCursorFromDocuments function of the mongodb to return Cursor https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#NewCursorFromDocuments

type Database

type Database interface {
	Aggregate(ctx context.Context, pipeline interface{}, opts ...*options.AggregateOptions) (Cursor, error)
	Client() Client
	Collection(name string, opts ...*options.CollectionOptions) Collection
	CreateCollection(ctx context.Context, name string, opts ...*options.CreateCollectionOptions) error
	CreateView(
		ctx context.Context,
		viewName, viewOn string,
		pipeline interface{},
		opts ...*options.CreateViewOptions,
	) error
	Drop(ctx context.Context) error
	ListCollectionNames(
		ctx context.Context,
		filter interface{},
		opts ...*options.ListCollectionsOptions,
	) ([]string, error)
	ListCollectionSpecifications(
		ctx context.Context,
		filter interface{},
		opts ...*options.ListCollectionsOptions,
	) ([]*mongo.CollectionSpecification, error)
	ListCollections(ctx context.Context, filter interface{}, opts ...*options.ListCollectionsOptions) (Cursor, error)
	Name() string
	ReadConcern() *readconcern.ReadConcern
	ReadPreference() *readpref.ReadPref
	RunCommand(ctx context.Context, runCommand interface{}, opts ...*options.RunCmdOptions) SingleResult
	RunCommandCursor(ctx context.Context, runCommand interface{}, opts ...*options.RunCmdOptions) (Cursor, error)
	Watch(
		ctx context.Context,
		pipeline interface{},
		opts ...*options.ChangeStreamOptions,
	) (ChangeStream, error)
	WriteConcern() *writeconcern.WriteConcern
}

Database is an interface for `mongo.Database` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#Database

func WrapDatabase added in v1.8.2

func WrapDatabase(db *mongo.Database) Database

WrapDatabase returns an instance of Database interface for given mongo.Database object

type IndexView

type IndexView interface {
	CreateMany(ctx context.Context, models []mongo.IndexModel, opts ...*options.CreateIndexesOptions) ([]string, error)
	CreateOne(ctx context.Context, model mongo.IndexModel, opts ...*options.CreateIndexesOptions) (string, error)
	DropAll(ctx context.Context, opts ...*options.DropIndexesOptions) (bson.Raw, error)
	DropOne(ctx context.Context, name string, opts ...*options.DropIndexesOptions) (bson.Raw, error)
	DropOneWithKey(
		ctx context.Context,
		keySpecDocument interface{},
		opts ...*options.DropIndexesOptions,
	) (bson.Raw, error)
	List(ctx context.Context, opts ...*options.ListIndexesOptions) (Cursor, error)
	ListSpecifications(ctx context.Context, opts ...*options.ListIndexesOptions) ([]*mongo.IndexSpecification, error)
}

IndexView is an interface for `mongo.IndexView` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#IndexView

type SearchIndexView added in v1.13.0

type SearchIndexView interface {
	CreateMany(
		ctx context.Context,
		models []mongo.SearchIndexModel,
		opts ...*options.CreateSearchIndexesOptions,
	) ([]string, error)
	CreateOne(
		ctx context.Context,
		model mongo.SearchIndexModel,
		opts ...*options.CreateSearchIndexesOptions,
	) (string, error)
	DropOne(
		ctx context.Context,
		name string,
		opts ...*options.DropSearchIndexOptions,
	) error
	List(
		ctx context.Context,
		searchIdxOpts *options.SearchIndexesOptions,
		opts ...*options.ListSearchIndexesOptions,
	) (Cursor, error)
	UpdateOne(
		ctx context.Context,
		name string,
		definition interface{},
		opts ...*options.UpdateSearchIndexOptions,
	) error
}

SearchIndexView is an interface for `mongo.SearchIndexView` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#SearchIndexView

type Session

type Session interface {
	StartTransaction(opts ...*options.TransactionOptions) error
	AbortTransaction(ctx context.Context) error
	CommitTransaction(ctx context.Context) error
	WithTransaction(
		ctx context.Context,
		fn func(sc SessionContext) (interface{}, error),
		opts ...*options.TransactionOptions,
	) (interface{}, error)
	EndSession(ctx context.Context)

	ClusterTime() bson.Raw
	OperationTime() *primitive.Timestamp
	Client() Client
	ID() bson.Raw

	AdvanceClusterTime(bson.Raw) error
	AdvanceOperationTime(*primitive.Timestamp) error
}

Session is an interface for `mongo.Session` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#Session

func SessionFromContext added in v1.10.1

func SessionFromContext(ctx context.Context) Session

SessionFromContext for `mongo.SessionFromContext` Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#SessionFromContext

func WrapSession added in v1.8.2

func WrapSession(ss mongo.Session) Session

WrapSession returns an instance of Session interface for given mongo.Session object

type SessionContext added in v1.0.0

type SessionContext interface {
	context.Context
	Session
}

SessionContext is an interface emulates `mongo.SessionContext` Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#SessionContext

func NewSessionContext added in v1.10.1

func NewSessionContext(ctx context.Context, sess Session) SessionContext

NewSessionContext is wrapper for `mongo.NewSessionContext` Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#NewSessionContext

type SingleResult

type SingleResult interface {
	Decode(v interface{}) error
	DecodeBytes() (bson.Raw, error)
	Err() error
	Raw() (bson.Raw, error)
}

SingleResult is an interface for `mongo.SingleResult` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#SingleResult

func NewSingleResultFromDocument added in v1.9.0

func NewSingleResultFromDocument(document interface{}, err error, registry *bsoncodec.Registry) SingleResult

NewSingleResultFromDocument is a wrapper for NewSingleResultFromDocument function of the mongodb to return SingleResult https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#NewSingleResultFromDocument

Directories

Path Synopsis
examples
mocks
gomock
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL