mgs

package module
v0.0.0-alpha.2 Latest Latest
Warning

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

Go to latest
Published: Sep 2, 2023 License: Apache-2.0 Imports: 14 Imported by: 0

README

Go Mongoose driver

Mgs is a mongoose-like go mongodb odm. If you've used mongoose before or you're looking for a dev friendly mongodb odm for golang, then this is for you.

Features

  • Perform left join (lookup) on find operations without having to define aggregation pipelines for each query.
  • Register hooks on predefined collection schemas for CRUD operations.
  • Type safe schema & model validations.
  • Atomic WRITE operations (documents are not written to database if one or more hooks return errors).

Requirements

  • Go >=1.18 (for generics)
  • MongoDB >=4.4 (for atomic transactions)

Installation

go get github.com/0x-buidl/mgs@latest

License

This package is licensed under the Apache License.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AfterCreateHook

type AfterCreateHook[T Schema] interface {
	AfterCreate(ctx context.Context, arg *HookArg[T]) error
}

AfterCreateHook runs after executing [Model.Create] and Model.CreateMany operations. AfterSaveHook will run before this hook runs. Use options.Hook.SetDisabledHooks to disable AfterSaveHook. HookArg.Data will return the document(s) created.

type AfterDeleteHook

type AfterDeleteHook[T Schema] interface {
	AfterDelete(ctx context.Context, arg *HookArg[T]) error
}

AfterDeleteHook runs after a document is removed from the database. HookArg.Data will return *mongo.DeleteResult if this is called on a Model, otherwise it will return the deleted *Document.

type AfterFindHook

type AfterFindHook[T Schema] interface {
	AfterFind(ctx context.Context, arg *HookArg[T]) error
}

AfterFindHook runs after a find operation is executed. HookArg.Data will return the found document(s) *Document.

type AfterSaveHook

type AfterSaveHook[T Schema] interface {
	AfterSave(ctx context.Context, arg *HookArg[T]) error
}

AfterSaveHook runs after document(s) are written to the database when using Model.CreateOne, Model.CreateMany or Document.Save. This hook doesn't run on all Model Update operations. Document.IsNew will always return false in this hook. HookArg.Data will return the saved document(s).

type AfterUpdateHook

type AfterUpdateHook[T Schema] interface {
	AfterUpdate(ctx context.Context, arg *HookArg[T]) error
}

AfterUpdateHook runs after a document is updated in the database. This hook also runs on `replace` operations. HookArg.Data will return *mongo.UpdateResult if called on *Model, otherwise it will return the updated *Document.

type AfterValidateHook

type AfterValidateHook[T Schema] interface {
	AfterValidate(ctx context.Context, arg *HookArg[T]) error
}

AfterValidateHook runs after validate hook is called. HookArg.Data will return the validated *Document.

type BeforeCreateHook

type BeforeCreateHook[T Schema] interface {
	BeforeCreate(ctx context.Context, arg *HookArg[T]) error
}

BeforeCreateHook runs before executing [Model.Create] and Model.CreateMany operations. BeforeSaveHook will run after this hook runs. HookArg.Data will return pointer to document(s) being created.

type BeforeDeleteHook

type BeforeDeleteHook[T Schema] interface {
	BeforeDelete(ctx context.Context, arg *HookArg[T]) error
}

BeforeDeleteHook runs before a document is removed from the database. HookArg.Data will return the Query being executed if this is called on a Model, otherwise it will return the *Document being deleted.

type BeforeFindHook

type BeforeFindHook[T Schema] interface {
	BeforeFind(ctx context.Context, arg *HookArg[T]) error
}

BeforeFindHook runs before any find operation is executed. HookArg.Data will allways return the query being executed *Query.

type BeforeSaveHook

type BeforeSaveHook[T Schema] interface {
	BeforeSave(ctx context.Context, arg *HookArg[T]) error
}

BeforeSaveHook runs before document(s) are written to the database when using Model.CreateOne, Model.CreateMany or Document.Save. This hook doesn't run on all Model Update operations. To check if the document being saved is new, use the Document.IsNew method. HookArg.Data will return *Document(s) being saved.

type BeforeUpdateHook

type BeforeUpdateHook[T Schema] interface {
	BeforeUpdate(ctx context.Context, arg *HookArg[T]) error
}

BeforeUpdateHook runs before a document is updated in the database. This hook also runs on `replace` operations. HookArg.Data will return the *Query being executed if called on *Model, otherwise it will return *Document being updated.

type BeforeValidateHook

type BeforeValidateHook[T Schema] interface {
	BeforeValidate(ctx context.Context, arg *HookArg[T]) error
}

BeforeValidateHook runs before validate hook is called. HookArg.Data will return the *Document being validated.

type DefaultSchema

type DefaultSchema struct {
	ID        primitive.ObjectID `json:"_id,omitempty"       bson:"_id,omitempty"`
	CreatedAt time.Time          `json:"createdAt,omitempty" bson:"createdAt,omitempty"`
	UpdatedAt time.Time          `json:"updatedAt,omitempty" bson:"updatedAt,omitempty"`
}

func (*DefaultSchema) GenerateCreatedAt

func (s *DefaultSchema) GenerateCreatedAt()

func (*DefaultSchema) GenerateID

func (s *DefaultSchema) GenerateID()

func (*DefaultSchema) GenerateUpdatedAt

func (s *DefaultSchema) GenerateUpdatedAt()

func (DefaultSchema) GetCreatedAt

func (s DefaultSchema) GetCreatedAt() time.Time

func (DefaultSchema) GetID

func (s DefaultSchema) GetID() primitive.ObjectID

func (DefaultSchema) GetUpdatedAt

func (s DefaultSchema) GetUpdatedAt() time.Time

func (DefaultSchema) GetUpdatedAtTag

func (s DefaultSchema) GetUpdatedAtTag(t string) string

func (*DefaultSchema) SetCreatedAt

func (s *DefaultSchema) SetCreatedAt(t time.Time)

func (*DefaultSchema) SetID

func (s *DefaultSchema) SetID(id primitive.ObjectID)

func (*DefaultSchema) SetUpdatedAt

func (s *DefaultSchema) SetUpdatedAt(t time.Time)

type Document

type Document[T Schema, P IDefaultSchema] struct {
	IDefaultSchema `json:"-" bson:"-"`
	Doc            *T `json:",inline" bson:",inline"`
	// contains filtered or unexported fields
}

Document is a struct that represents a document in a MongoDB collection. Do not use this struct directly, instead use the Model.NewDocument method.

func (*Document[T, P]) BSON

func (doc *Document[T, P]) BSON() (bson.M, error)

func (*Document[T, P]) Collection

func (doc *Document[T, P]) Collection() *mongo.Collection

Returns the collection that the document belongs to.

func (*Document[T, P]) Delete

func (doc *Document[T, P]) Delete(ctx context.Context) error

Deletes a document from the database atomically. The operation fails if any of the hooks return an error.

func (*Document[T, P]) IsModified

func (doc *Document[T, P]) IsModified(field string) bool

func (*Document[T, P]) IsNew

func (doc *Document[T, P]) IsNew() bool

func (*Document[T, P]) JSON

func (doc *Document[T, P]) JSON() (map[string]any, error)

Returns the JSON representation of the document.

func (*Document[T, P]) MarshalBSON

func (doc *Document[T, P]) MarshalBSON() ([]byte, error)

Returns the document as a BSON bytes.

func (*Document[T, P]) MarshalJSON

func (doc *Document[T, P]) MarshalJSON() ([]byte, error)

Returns the document as a JSON bytes.

func (*Document[T, P]) Model

func (doc *Document[T, P]) Model() *Model[T, P]

Returns the model that the document belongs to.

func (*Document[T, P]) Save

func (doc *Document[T, P]) Save(ctx context.Context) error

Saves a document to the database atomically. This method creates a new document if the document is not already existing, Otherwise, it updates the existing document. The operation fails if any of the hooks return an error.

func (*Document[T, P]) UnmarshalBSON

func (doc *Document[T, P]) UnmarshalBSON(data []byte) error

type HookArg

type HookArg[T Schema] struct {
	// contains filtered or unexported fields
}

HookArg is the arguments passed to a hook function. It is advisable to only modify HookArg.Data and not the Hook receiver itself, doing so may cause unexpected behavior. To avoid this, the hook receiver should not bo a pointer.

func (*HookArg[T]) Data

func (arg *HookArg[T]) Data() interface{}

Data returns the data passed to the hook.

func (*HookArg[T]) Operation

func (arg *HookArg[T]) Operation() QueryOperation

Operation returns the operation being executed.

type IDefaultSchema

type IDefaultSchema interface {
	// Generates a new ObjectID and sets it to the ID field.
	GenerateID()
	// Generates a new time.Time and sets it to the CreatedAt field.
	GenerateCreatedAt()
	// Generates a new time.Time and sets it to the UpdatedAt field.
	GenerateUpdatedAt()
	// GetID returns the ID field.
	GetID() primitive.ObjectID
	// GetCreatedAt returns the CreatedAt field.
	GetCreatedAt() time.Time
	// GetUpdatedAt returns the UpdatedAt field.
	GetUpdatedAt() time.Time
	// Sets the ID field to id.
	SetID(id primitive.ObjectID)
	// Sets the CreatedAt field to t.
	SetCreatedAt(t time.Time)
	// Sets the UpdatedAt field to t.
	SetUpdatedAt(t time.Time)
	// Returns the tag name for the UpdatedAt field. t can be either "json", "bson" or any custom tag.
	// This is useful for setting the UpdatedAt field when updating with [Model.UpdateOne] and [Model.UpdateMany].
	GetUpdatedAtTag(t string) string
}

type Model

type Model[T Schema, P IDefaultSchema] struct {
	// contains filtered or unexported fields
}

func NewModel

func NewModel[T Schema, P IDefaultSchema](collection *mongo.Collection) *Model[T, P]

NewModel creates a new model. T is the schema type, P is the default schema type. Panics if T or P is not a struct .

func (*Model[T, P]) Collection

func (model *Model[T, P]) Collection() *mongo.Collection

func (*Model[T, P]) CountDocuments

func (model *Model[T, P]) CountDocuments(ctx context.Context,
	query bson.M, opts ...*options.CountOptions,
) (int64, error)

func (*Model[T, P]) CreateMany

func (model *Model[T, P]) CreateMany(
	ctx context.Context,
	docs []T,
	opts ...*mopt.InsertManyOptions,
) ([]*Document[T, P], error)

func (*Model[T, P]) CreateOne

func (model *Model[T, P]) CreateOne(
	ctx context.Context, doc T,
	opts ...*mopt.InsertOneOptions,
) (*Document[T, P], error)

func (*Model[T, P]) DeleteMany

func (model *Model[T, P]) DeleteMany(
	ctx context.Context,
	query bson.M,
	opts ...*options.DeleteOptions,
) (*mongo.DeleteResult, error)

func (*Model[T, P]) DeleteOne

func (model *Model[T, P]) DeleteOne(
	ctx context.Context,
	query bson.M,
	opts ...*options.DeleteOptions,
) (*mongo.DeleteResult, error)

func (*Model[T, P]) Find

func (model *Model[T, P]) Find(
	ctx context.Context,
	query bson.M,
	opts ...*mopt.FindOptions,
) ([]*Document[T, P], error)

func (*Model[T, P]) FindById

func (model *Model[T, P]) FindById(
	ctx context.Context, id any,
	opts ...*mopt.FindOneOptions,
) (*Document[T, P], error)

func (*Model[T, P]) FindOne

func (model *Model[T, P]) FindOne(
	ctx context.Context,
	query bson.M,
	opts ...*mopt.FindOneOptions,
) (*Document[T, P], error)

func (*Model[T, P]) NewDocument

func (model *Model[T, P]) NewDocument(data T) *Document[T, P]

func (*Model[T, P]) UpdateMany

func (model *Model[T, P]) UpdateMany(ctx context.Context,
	query bson.M, update bson.M, opts ...*options.UpdateOptions,
) (*mongo.UpdateResult, error)

func (*Model[T, P]) UpdateOne

func (model *Model[T, P]) UpdateOne(ctx context.Context,
	query bson.M, update bson.M,
	opts ...*options.UpdateOptions,
) (*mongo.UpdateResult, error)

type Query

type Query[T Schema] struct {
	// The document filter for this operation
	Filter bson.M
	// Update payload if Operation is an update operation
	Update *bson.M
	// Options specific to the current operation
	Options interface{}
	// Operation being executed
	Operation QueryOperation
}

Query is a struct that holds information about the current operation beign executed on a model.

func NewQuery

func NewQuery[T Schema]() *Query[T]

NewQuery returns and empty Query struct.

func (*Query[T]) SetFilter

func (q *Query[T]) SetFilter(f bson.M) *Query[T]

SetFilter sets the Query filter field.

func (*Query[T]) SetOperation

func (q *Query[T]) SetOperation(o QueryOperation) *Query[T]

SetOperation sets the Query Operation field.

func (*Query[T]) SetOptions

func (q *Query[T]) SetOptions(o interface{}) *Query[T]

SetOptions sets the Query Options field.

func (*Query[T]) SetUpdate

func (q *Query[T]) SetUpdate(u *bson.M) *Query[T]

SetUpdate sets the Query Update field.

type QueryOperation

type QueryOperation string

Model Query Operation

const (
	CreateOne        QueryOperation = "create-one"
	CreateMany       QueryOperation = "create-many"
	FindMany         QueryOperation = "find-many"
	FindOne          QueryOperation = "find-one"
	FindOneAndUpdate QueryOperation = "find-one-and-update"
	Replace          QueryOperation = "replace"
	UpdateOne        QueryOperation = "update-one"
	UpdateMany       QueryOperation = "update-many"
	DeleteOne        QueryOperation = "delete-one"
	DeleteMany       QueryOperation = "delete-many"
)

type Schema

type Schema interface{}

Schema is an interface that represents the structure of a document in a MongoDB collection. It must be a struct.

type ValidateHook

type ValidateHook[T Schema] interface {
	Validate(ctx context.Context, arg *HookArg[T]) error
}

ValidateHook is used to register a validation for a schema. This hook runs before a document is saved to the database. It only runs on Model.CreateOne, Model.CreateMany, Document.Save and [Document.Update] operations. HookArg.Data will return the *Document being validated.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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