Coder Social home page Coder Social logo

sv-tools / mongoifc Goto Github PK

View Code? Open in Web Editor NEW
31.0 2.0 2.0 271 KB

The implementation of the interfaces for the official MongoDB driver in Go

License: MIT License

Makefile 4.61% Go 95.39%
interfaces mongodb go mongo golang database database-layer mongodb-wrapper

mongoifc's Introduction

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

mongoifc's People

Contributors

amincheloh avatar dependabot[bot] avatar svilgelm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

mongoifc's Issues

Trying to use these interfaces for mocking and receive and error about the `Wrapped` methods being missing

I'm trying to have my code use one of these instead of an actual mongo driver *Client so that I can swap it out for testing but it appears they are incompatible. Curious as to why the Wrapped* methods have been added to the interfaces as well as if you can offer any example code as to how these are meant to be used in testing given this subtle incompatibility.

Example error:

Cannot use 'client' (type *Client) as the type mongoifc.Client Type does not implement 'mongoifc.Client' as some methods are missing: WrappedClient() *mongo.Client

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.