Categorygithub.com/sv-tools/mongoifc
modulepackage
1.16.1
Repository: https://github.com/sv-tools/mongoifc.git
Documentation: pkg.go.dev

# 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.

:bangbang: 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

# Packages

No description provided by the author
No description provided by the author

# Functions

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.
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.
No description provided by the author
NewCursorFromDocuments is a wrapper for NewCursorFromDocuments function of the mongodb to return Cursor https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#NewCursorFromDocuments.
NewSessionContext is wrapper for `mongo.NewSessionContext` Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#NewSessionContext.
NewSingleResultFromDocument is a wrapper for NewSingleResultFromDocument function of the mongodb to return SingleResult https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#NewSingleResultFromDocument.
SessionFromContext for `mongo.SessionFromContext` Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#SessionFromContext.
UnWrapClient returns original mongo.Client.
UnWrapCollection returns original mongo.Collection.
UnWrapDatabase returns original mongo.Database.
UnWrapSession returns original mongo.Session.
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.
WrapClient returns an instance of Client interface for given mongo.Client object.
WrapCollection returns an instance of Collection interface for given mongo.Collection object.
WrapDatabase returns an instance of Database interface for given mongo.Database object.
WrapSession returns an instance of Session interface for given mongo.Session object.

# Interfaces

ChangeStream is an interface for `mongo.ChangeStream` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#ChangeStream.
Client is an interface for `mongo.Client` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#Client.
ClientEncryption is an interface for `mongo.ClientEncryption` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#ClientEncryption.
Collection is an interface for `mongo.Collection` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#Collection.
Cursor is an interface for `mongo.Cursor` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#Cursor.
Database is an interface for `mongo.Database` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#Database.
IndexView is an interface for `mongo.IndexView` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#IndexView.
SearchIndexView is an interface for `mongo.SearchIndexView` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#SearchIndexView.
Session is an interface for `mongo.Session` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#Session.
SessionContext is an interface emulates `mongo.SessionContext` Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#SessionContext.
SingleResult is an interface for `mongo.SingleResult` structure Documentation: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#SingleResult.