Mongo Go Models (mgm) is a fast and simple MongoDB ODM for Go (based on official Mongo Go Driver)

GoDoc Build Status

Mongo Go Models

The Mongo ODM for Go

Features

  • Define your models and perform CRUD operations with hooks before/after each operation.
  • mgm makes Mongo search and aggregation super easy to do in Golang.
  • Just set up your configs once and get collections anywhere you need them.
  • mgm predefines all Mongo operators and keys, so you don't have to hardcode them yourself.
  • mgm wraps the official Mongo Go Driver.

Requirements

  • Go 1.10 or higher.
  • MongoDB 2.6 and higher.

Installation

Important Note: We changed the package name from github.com/Kamva/mgm/v3 (uppercase Kamva) to github.com/kamva/mgm/v3 (lowercase kamva) starting with version 3.1.0.

go get github.com/kamva/mgm/v3

Usage

To get started, import the mgm package and setup the default config:

import (
   "github.com/kamva/mgm/v3"
   "go.mongodb.org/mongo-driver/mongo/options"
)

func init() {
   // Setup the mgm default config
   err := mgm.SetDefaultConfig(nil, "mgm_lab", options.Client().ApplyURI("mongodb://root:12345@localhost:27017"))
}

Define your model:

type Book struct {
   // DefaultModel adds _id, created_at and updated_at fields to the Model
   mgm.DefaultModel `bson:",inline"`
   Name             string `json:"name" bson:"name"`
   Pages            int    `json:"pages" bson:"pages"`
}

func NewBook(name string, pages int) *Book {
   return &Book{
      Name:  name,
      Pages: pages,
   }
}

Insert new document:

book := NewBook("Pride and Prejudice", 345)

// Make sure to pass the model by reference.
err := mgm.Coll(book).Create(book)

Find one document

// Get the document's collection
book := &Book{}
coll := mgm.Coll(book)

// Find and decode the doc to a book model.
_ = coll.FindByID("5e0518aa8f1a52b0b9410ee3", book)

// Get the first doc of the collection 
_ = coll.First(bson.M{}, book)

// Get the first doc of a collection using a filter
_ = coll.First(bson.M{"pages":400}, book)

Update a document

// Find your book
book := findMyFavoriteBook()

// and update it
book.Name = "Moulin Rouge!"
err := mgm.Coll(book).Update(book)

Delete a document

// Just find and delete your document
err := mgm.Coll(book).Delete(book)

Find and decode a result:

result := []Book{}

err := mgm.Coll(&Book{}).SimpleFind(&result, bson.M{"pages": bson.M{operator.Gt: 24}})

A Model's Default Fields

Each model by default (by using DefaultModel struct) has the following fields:

  • _id : The document ID.

  • created_at: The creation date of a doc. When saving a new doc, this is automatically populated by the Creating hook.

  • updated_at: The last updated date of a doc. When saving a doc, this is automatically populated by the Saving hook.

A Model's Hooks

Each model has the following hooks:

  • Creating: Called when creating a new model. Signature : Creating(context.Context) error

  • Created: Called after a new model is created. Signature : Created(context.Context) error

  • Updating: Called when updating model. Signature : Updating(context.Context) error

  • Updated : Called after a model is updated. Signature : Updated(ctx context.Context, result *mongo.UpdateResult) error

  • Saving: Called when creating or updating a model. Signature : Saving(context.Context) error

  • Saved: Called after a model is created or updated. Signature: Saved(context.Context) error

  • Deleting: Called when deleting a model. Signature: Deleting(context.Context) error

  • Deleted: Called after a model is deleted. Signature: Deleted(ctx context.Context, result *mongo.DeleteResult) error

Notes about hooks:

  • Each model by default uses the Creating and Saving hooks, so if you want to define those hooks yourself, remember to invoke the DefaultModel hooks from your own hooks.
  • Collection methods that call these hooks:
    • Create & CreateWithCtx
    • Update & UpdateWithCtx
    • Delete & DeleteWithCtx

Example:

func (model *Book) Creating(ctx context.Context) error {
   // Call the DefaultModel Creating hook
   if err := model.DefaultModel.Creating(ctx); err!=nil {
      return err
   }

   // We can validate the fields of a model and return an error to prevent a document's insertion.
   if model.Pages < 1 {
      return errors.New("book must have at least one page")
   }

   return nil
}

Configuration

The mgm default configuration has a context timeout:

func init() {
   _ = mgm.SetDefaultConfig(&mgm.Config{CtxTimeout:12 * time.Second}, "mgm_lab", options.Client().ApplyURI("mongodb://root:12345@localhost:27017"))
}

// To get the context, just call the Ctx() method, assign it to a variable
ctx := mgm.Ctx()

// and use it
coll := mgm.Coll(&Book{})
coll.FindOne(ctx, bson.M{})

// Or invoke Ctx() and use it directly
coll.FindOne(mgm.Ctx(), bson.M{})

Collections

Get a model's collection:

coll := mgm.Coll(&Book{})

// Do something with the collection

mgm automatically detects the name of a model's collection:

book := Book{}

// Print your model's collection name.
collName := mgm.CollName(&book)
fmt.Println(collName) // output: books

You can also set a custom collection name for your model by implementing the CollectionNameGetter interface:

func (model *Book) CollectionName() string {
   return "my_books"
}

// mgm returns the "my_books" collection
coll := mgm.Coll(&Book{})

Get a collection by its name (without needing to define a model for it):

coll := mgm.CollectionByName("my_coll")
   
// Do Aggregation, etc. with the collection

Customize the model db by implementing the CollectionGetter interface:

func (model *Book) Collection() *mgm.Collection {
    // Get default connection client
   _, client, _, err := mgm.DefaultConfigs()

   if err != nil {
      panic(err)
   }

   db := client.Database("another_db")
   return mgm.NewCollection(db, "my_collection")
}

Or return a model's collection from another connection:

func (model *Book) Collection() *mgm.Collection {
   // Create new client
   client, err := mgm.NewClient(options.Client().ApplyURI("mongodb://root:12345@localhost:27017"))

   if err != nil {
      panic(err)
   }

   // Get the model's db
   db := client.Database("my_second_db")

   // return the model's custom collection
   return mgm.NewCollection(db, "my_collection")
}

Aggregation

While we can use Mongo Go Driver Aggregate features, mgm also provides simpler methods to perform aggregations:

Run an aggregation and decode the result:

authorCollName := mgm.Coll(&Author{}).Name()
result := []Book{}

// Lookup with just a single line of code
_ := mgm.Coll(&Book{}).SimpleAggregate(&result, builder.Lookup(authorCollName, "auth_id", "_id", "author"))

// Multi stage (mix of mgm builders and raw stages)
_ := mgm.Coll(&Book{}).SimpleAggregate(&result,
		builder.Lookup(authorCollName, "auth_id", "_id", "author"),
		M{operator.Project: M{"pages": 0}},
)

// Do something with result...

Do aggregations using the mongo Aggregation method:

import (
   "github.com/kamva/mgm/v3"
   "github.com/kamva/mgm/v3/builder"
   "github.com/kamva/mgm/v3/field"
   . "go.mongodb.org/mongo-driver/bson"
   "go.mongodb.org/mongo-driver/bson/primitive"
)

// The Author model collection
authorColl := mgm.Coll(&Author{})

cur, err := mgm.Coll(&Book{}).Aggregate(mgm.Ctx(), A{
    // The S function accepts operators as parameters and returns a bson.M type.
    builder.S(builder.Lookup(authorColl.Name(), "author_id", field.Id, "author")),
})

A more complex example and mixes with mongo raw pipelines:

import (
   "github.com/kamva/mgm/v3"
   "github.com/kamva/mgm/v3/builder"
   "github.com/kamva/mgm/v3/field"
   "github.com/kamva/mgm/v3/operator"
   . "go.mongodb.org/mongo-driver/bson"
   "go.mongodb.org/mongo-driver/bson/primitive"
)

// Author model collection
authorColl := mgm.Coll(&Author{})

_, err := mgm.Coll(&Book{}).Aggregate(mgm.Ctx(), A{
    // S function get operators and return bson.M type.
    builder.S(builder.Lookup(authorColl.Name(), "author_id", field.Id, "author")),
    builder.S(builder.Group("pages", M{"books": M{operator.Push: M{"name": "$name", "author": "$author"}}})),
    M{operator.Unwind: "$books"},
})

if err != nil {
    panic(err)
}

Transactions

  • To run a transaction on the default connection use the mgm.Transaction() function, e.g:
d := &Doc{Name: "Mehran", Age: 10}

err := mgm.Transaction(func(session mongo.Session, sc mongo.SessionContext) error {

   // do not forget to pass the session's context to the collection methods.
	err := mgm.Coll(d).CreateWithCtx(sc, d)

	if err != nil {
		return err
	}

	return session.CommitTransaction(sc)
})
  • To run a transaction with your own context, use the mgm.TransactionWithCtx() method.
  • To run a transaction on another connection, use the mgm.TransactionWithClient() method.

Other Mongo Go Models Packages

We implemented these packages to simplify queries and aggregations in mongo

builder: simplify mongo queries and aggregations.

operator : contains mongo operators as predefined variables.
(e.g Eq = "$eq" , Gt = "$gt")

field : contains mongo fields used in aggregations and ... as predefined variable. (e.g LocalField = "localField", ForeignField = "foreignField")

Example:

import (
  "github.com/kamva/mgm/v3"
  f "github.com/kamva/mgm/v3/field"
  o "github.com/kamva/mgm/v3/operator"
  "go.mongodb.org/mongo-driver/bson"
)

// Instead of hard-coding mongo operators and fields
_, _ = mgm.Coll(&Book{}).Aggregate(mgm.Ctx(), bson.A{
   bson.M{"$count": ""},
   bson.M{"$project": bson.M{"_id": 0}},
})

// Use the predefined operators and pipeline fields.
_, _ = mgm.Coll(&Book{}).Aggregate(mgm.Ctx(), bson.A{
   bson.M{o.Count: ""},
   bson.M{o.Project: bson.M{f.Id: 0}},
})

Bugs / Feature request

New features can be requested and bugs can be reported on Github issue tracker.

Communicate With Us

Contributing

Open in Gitpod

  1. Fork the repository
  2. Clone your fork (git clone https://github.com/<your_username>/mgm && cd mgm)
  3. Create your feature branch (git checkout -b my-new-feature)
  4. Make changes and add them (git add .)
  5. Commit your changes (git commit -m 'Add some feature')
  6. Push to the branch (git push origin my-new-feature)
  7. Create new pull request

License

Mongo Go Models is released under the Apache License

Comments
  • Mock package

    Mock package

    I am loving mgm! I am also willing to help contribute to make it better.

    I think adding a mock package to make mocking the DB easier would be a great improvement to this project

  • Get Create inserted ID

    Get Create inserted ID

    Hello,

    I would like to retrieve the ID of the fresh inserted document.

    Taking this snippet from the documentation:

    book := NewBook("Pride and Prejudice", 345)
    
    // Make sure to pass the model by reference.
    err := mgm.Coll(book).Create(book)
    

    I would like to retrieve the "book" ID, how can i do this without perform another search ?

    Best regards

  • CreatedAt is overwritten with a zero value during Save

    CreatedAt is overwritten with a zero value during Save

    Describe the bug

    I have a model with the DefaultModel included.

    I have a method which does something like the following:

    func  Update(dto dto.MyModel) error {
            // Convert from a DTO
    	m, err := (&MyModel{}).FromDTO(dto)
    	if err != nil {
    		return fmt.Errorf("converting from DTO: %w", err)
    	}
    
    	if err := m.Save(); err != nil {
    		return fmt.Errorf("saving model: %w", err)
    	}
    
    	return nil
    }
    

    The conversion from a DTO leaves CreatedAt as the zero-value, because that info is left out of my DTOs.

    The problem is that CreatedAt is not declared as omitempty, so when I .Save() like this, it is overwritten with a zero value.

    To Reproduce Steps to reproduce the behavior:

    1. Create a document
    2. Instantiate another document struct with the same primary key and set CreatedAt to nothing (or anything you want)
    3. Save the document

    Expected behavior

    Changes to CreatedAt are ignored, or at least ignored if CreatedAt is the zero value of time.Time.

    Screenshots

    N/A

    Environment (please complete the following information):

    • OS: a Docker container running golang:bullseye

    Additional context

    As a workaround, I can stick to a get-modify-save pattern where I save the original CreatedAt time and restore it before the save instead of attempting to directly update/upsert.

  • Type safe partial updates?

    Type safe partial updates?

    Let's say you have this model:

    type Book struct {
      mgm.DefaultModel `bson:",inline"`
    
      Author string `bson:"author"`
    
      // ... more fields ...
    }
    

    Somewhere in your code you want to change the author's name, so you have:

    book := &Book{}
    _, err := mgm.Coll(book).UpdateOne(mgm.Ctx(), bson.M{
      "_id": id
    }, bson.M{
      "$set": bson.M{
        "author": authorName,
      },
    })
    

    Time goes on, the codebase grows, many contributors, and the realization is made that a book can have multiple authors, so the model is changed to:

    type Book struct {
      mgm.DefaultModel `bson:",inline"`
    
      Authors []string `bson:"authors"`
    
      // ... more fields ...
    }
    

    The update code won't throw any sort of error or warning because there is no type safety. Without many lines of code to perform tag reflection (and even more lines if it's a nested field), is there a clean way to make a partial update to a model where type safety is preserved?

  • Auth fails with mongodb atlas cluster

    Auth fails with mongodb atlas cluster

    Describe the bug "connection() : auth error: sasl conversation error: unable to authenticate using mechanism "SCRAM-SHA-1": (AtlasError) Authentication failed.

    Everything was working fine till today I get error with authentication failed. I didn't changed anything, not a single line of code but still I get error on any operation with mgm connection() : auth error: sasl conversation error: unable to authenticate using mechanism \"SCRAM-SHA-1\": (AtlasError) Authentication failed.

    To Reproduce Steps to reproduce the behavior: 1.

    err = mgm.SetDefaultConfig(nil, "directory", options.Client().ApplyURI(os.Getenv("MONGODB_URI")))
    if err != nil {
    	log.Fatal(err)
    }
    
    1. Export MONGODB_URI with mongodb atlas cluster uri.
    2. Run the server.
    3. Do Some operation.

    Expected behavior Operation should complete without any error.

    Environment (please complete the following information):

    • OS: Ubuntu 20.04
  • Removed interface{} as a return type for Get/Set/PrepareID

    Removed interface{} as a return type for Get/Set/PrepareID

    The following functions GetID, SetID and PrepareID all know there return type... There is no need to return a interface{} as this causes unneeded casting by anyone using the package.

    Also cleaned up some of the reflection in those functions above to make them "smarter" using switch on type.

    This makes it always assume we can take either a string (gets converted) or a primitive.ObjectID

  • Mgm.Update is not working properly

    Mgm.Update is not working properly

    While creating a new data using mgm.create method, its successfully created the data with created at and updated at details in defaultmodel field. But While updating the data using updateOne or FindOneandUpdate, its successfully updated but the created at and Updated at field details became 0001-01-01T00:00:00.000+00:00 in the database. I know, here i am using mongo drive function so that defaultmodel fields are not accessed so that the created at and updated at becames 0001-01-01T00:00:00.000+00:00.

    why I am using mongo drive function because while update using mgm.update, there is only one parameter as model. so I find the data which i need to update and manually map the details and send the parameter to that function. Even though, it's not updating properly in database.

    Expected behavior:

    1. please provide an extra filter parameter to update function in mgm. so that it will be easy to use mgm.update function Or tell us how to use the mgm.update function, Because the Previous information provided by you is not clear.

    Environment (please complete the following information):

    • OS: Ubuntu
  • Added context support in hooks

    Added context support in hooks

    Have added support for passing context in hooks. This tackles this issue

    Have added new interfaces for hooks like OldNameWithCtx e.g (CreatingHookWithCtx) and have deprecated the old interface. This was done to support the backward compatibility

    The new Interfaces follow the same func names but additionally takes a context field

    // CreatingHookWithCtx is called before saving a new model to the database
    type CreatingHookWithCtx interface {
    	Creating(context.Context) error
    }
    

    Have added appropriate test as well in hooks_test.go file

  • Get All from a collection

    Get All from a collection

    Describe the bug

    Syntax is wrong

    result := []Book{}
    
    err := mgm.Coll(&Book{}).SimpleFind(&result, bson.M{"age": bson.M{operator.Gt: 24}})
    

    Should be:

    result := []Book
    
    err := mgm.Coll(&Book{}).SimpleFind(&result, bson.M{"age": bson.M{operator.Gt: 24}})
    

    Or maybe i miss something ?

    Additionnaly, maybe add the FindAll method example:

    	var result []Book
    
    	err := collection.SimpleFind(&result, bson.D{})
    
    	log.Fatalf("here is the books: %v", result)
    

    best regards

  • Updating by id fails to find document in update query

    Updating by id fails to find document in update query

    Describe the bug I'm building a simple CRUD API, and when trying to use the "FindOneAndUpdate" method, it's not completing the update call when passing in the document id as a filter parameter

    Models:

    type Car struct{
    	CarName   string  `json:"car_name"   bson:"car_name"`
    	Make      string  `json:"make"       bson:"make"`
    	ModelYear int     `json:"model_year" bson:"model_year"`
    	CarType   string  `json:"car_type"   bson:"car_type"`
    	Price     float64 `json:"price"      bson:"price"`
    }
    
    
    type User struct{
    	mgm.DefaultModel `bson:",inline"`
    	Name            string `json:"name" bson:"name"`
    	FavoriteCarType string `json:"favorite_car_type" bson:"favorite_car_type"`
    	FavoriteCar     string `json:"favorite_car" bson:"favorite_car"`
    	FavoriteCars    []Car  `json:"favorite_cars" bson:"favorite_cars"`
    }
    

    Update user method:

    type UserController struct{
    	router *mux.Router
    }
    
    func (u *UserController) updateUser(res http.ResponseWriter, req *http.Request){
    	id := mux.Vars(req)["id"]
    	user := bson.M{}
    
    	json.NewDecoder(req.Body).Decode(&user)
    
    	result := mgm.Coll(&model.User{}).FindOneAndUpdate(mgm.Ctx(), bson.M{"_id": id}, bson.M{"$set": user})
    
            //The above method call causes the following error message to be returned
    	if result.Err() != nil{
    		utilities.SendJSON(http.StatusNotFound, res, utilities.M{"message":  result.Err().Error()})
    		return
    	}
    
    	utilities.SendJSON(200, res, utilities.M{"result": result})
    }
    

    Update query (Postman):

    
    {
        "favorite_car_type": "performance van",
        "favorite_car": "Pacifica SRT"
    }
    
    

    route to "updateUser()" method: localhost:8080/users/{id}

    Utilities:

    type M map[string]interface{} 
    
    //SendJSON - Utility function to send JSON
    func SendJSON(statusCode int, res http.ResponseWriter, body interface{}){
    	res.Header().Set("Content-Type", "application/json")
    	res.WriteHeader(statusCode)
    	json.NewEncoder(res).Encode(body)
    	
    	return
    }
    
    
    

    When getting a user by id by calling the FindByID method:

     id := mux.Vars(req)["id"]
    	user := model.User{}
    
    	//find all the user in the "users" collection who have "id" as their favorite car type
    	result := mgm.Coll(&model.User{}).FindByID(id, &user)
    
    

    the above code works, but for the updateUser method, the error block is hit every time. Is there something I'm missing?

  • ID, created_at, updated_at is not generated with nested field

    ID, created_at, updated_at is not generated with nested field

    Describe the bug When using mgm model with mgm.DefaultModel in nested struct inside model, ID, created_at and updated_at of this struct is not updated when using Save() and Update().

    To Reproduce Save/Update model with nested struct that has mgm.DefaultModel. Saved/Updated collection does have null _id, created_at and updated_at fields.

    Example model:

    type GameReview struct {
      mgm.DefaultModel `bson:",inline"`
      Content string `bson:"content"`
    }
    
    type Game struct {
      mgm.DefaultModel  `bson:",inline"`
      Name string `bson:"name"`
    }
    

    Expected behavior ID, created_at and updated_at fields should be updated.

    Environment (please complete the following information):

    • Ubuntu 20.04
    • go1.14.7

    Due to the nature of the error, it will occur on every environment.

  • Authentication Failure

    Authentication Failure

    Describe the bug Authentication error when trying to connect to Mongo. I get the following error when trying to connect to mongo using user credentials -

    {
        "error": "connection() error occured during connection handshake: auth error: sasl conversation error: unable to authenticate using mechanism \"SCRAM-SHA-1\": (AuthenticationFailed) Authentication failed.",
        "ok": false
    }
    

    I am able to login via mongo-shell using the same creds as in the screenshot below. However the ORM throws error -

    Screenshot 2022-02-26 at 6 45 08 PM

    Note: This is similar to this closed issue.

    To Reproduce Steps to reproduce the behavior:

    1. Create a test user with the following creds -
      MONGODB_PORT="27017"
      MONGODB_URL="localhost"
      MONGODB_USERNAME="test"
      MONGODB_PASSWORD="test123"
      MONGODB_DB="todos"
      
    2. Connect to mongo using the ODM
      	package main
      
      	import (
      		"log"
      
      		"github.com/Kamva/mgm/v2"
      		"go.mongodb.org/mongo-driver/mongo/options"
      	)
      
      	func init() {
      		err = mgm.SetDefaultConfig(nil, "todos", options.Client().ApplyURI("mongodb://test:test123@localhost:27017"))
      		if err != nil {
      			log.Fatal("Error setting default config")
      			log.Fatal(err)
      		}
      	}
      

    Expected behavior Connection should not fail when trying to connect via above piece of code

    Screenshots If applicable, add screenshots to help explain your problem.

    Environment (please complete the following information):

    • OS: MacOS Big Sur
    • Mongo: v5.0.6

    Additional context Add any other context about the problem here.

  • Add support for Create, Update and Delete multiple entries with hooks

    Add support for Create, Update and Delete multiple entries with hooks

    Is your feature request related to a problem? Please describe.

    • Problem
      • Currently, hook is supported only for the following methods.
        • Create & CreateWithCtx
        • Update & UpdateWithCtx
        • Delete & DeleteWithCtx
      • This is inconvenient to create/update/delete multiple entries as the hook support does not exist. One must loop over the above methods to operate over multiple entries.
      • It's difficult to perform atomic operations and rollback (when dealing with multiple entries), if using just the above mentioned function, as one must define transaction and so on, creating verbose code.

    Describe the solution you'd like

    • Add support for methods that allows creating/updating/deleting multiple entries, with support for hooks.

    Describe alternatives you've considered

    • Currently the solution with the above mentioned methods include,
      • Looping over the methods to perform batch operations
      • Wrapping batch operation in transaction, so that rollback can be performed in case of failure
      • Using native methods (e.g. InsertMany, UpdateMany, DeleteMany). But, hook support does not exist.

    Additional context

    • N/A
  • Change tracking for updates

    Change tracking for updates

    Is your feature request related to a problem? Please describe. When saving an update to a model, the entire document is overwritten in the database, as opposed to only the fields that have changed, which could open you up to concurrency issues. Tracking changes can also be useful when implementing something like audit log.

    Describe the solution you'd like An update that only $sets the changed fields and a function API (e.g. model.HasChanged("FieldName")) to check what fields have changed in the hooks.

    Describe alternatives you've considered I'm not sure how this could implemented without changes to mgm, but open to ideas for sure!

    Additional context Would you all be open to a PR to add this if I put some work into it?

  • Optimistic locking

    Optimistic locking

    Hi,

    I needed to have optimistic locking behavior on my project so implemented it in this pull request. It is based on a version field that gets incremented when saving. It can also be done through an updatedOn field but this PR uses the version technique for the DefaultModel.

    It works the following way : A new field called "Version" has been added to DefaultModel (saves to "version" in the db) Models have to implement a Versionable interface so that the behavior kicks in. DefaultModel implements it and so documents using the DefaultModel will have this enabled by default). This interface has 3 methods : GetVersion() -> returns the version number of this document IncrementVersion() -> responsible for updating the version number GetVersionFieldName() -> returns the name of the field that holds the version number

    Then when the actual update is called, we can simply check that in the query part of the udpate that the version is the same as when the document was retrieved. If not, a custom error is raised.

  • Query builder

    Query builder

    Hey, first of all, great project!

    Is your feature request related to a problem? Please describe. One of the most annoying things about MongoDB and GOlang is querying.

    Describe the solution you'd like I would like to see a query build that is simple enough and doesn't involve bson. For example

    q := Query("field1", "value1") // optional "and"
    q.And("field2", "value2").And("field3", "value3")
      .And(Query("foo1", "v1").Or("foo2", "v2"))
    

    This would greatly simplify most generic queries.

Simple-crm-system - Simple CRM system CRUD backend using Go, Fiber, SQLite, Gorm

Simple CRM system CRUD backend using GO, Fiber, Gorm, SQLite Developent go mod t

Nov 13, 2022
A better ORM for Go, based on non-empty interfaces and code generation.

reform A better ORM for Go and database/sql. It uses non-empty interfaces, code generation (go generate), and initialization-time reflection as oppose

Dec 31, 2022
A better ORM for Go, based on non-empty interfaces and code generation.
A better ORM for Go, based on non-empty interfaces and code generation.

A better ORM for Go and database/sql. It uses non-empty interfaces, code generation (go generate), and initialization-time reflection as opposed to interface{}, type system sidestepping, and runtime reflection. It will be kept simple.

Dec 29, 2022
Simple and Powerful ORM for Go, support mysql,postgres,tidb,sqlite3,mssql,oracle, Moved to https://gitea.com/xorm/xorm

xorm HAS BEEN MOVED TO https://gitea.com/xorm/xorm . THIS REPOSITORY WILL NOT BE UPDATED ANY MORE. 中文 Xorm is a simple and powerful ORM for Go. Featur

Jan 3, 2023
Simple and performant ORM for sql.DB

Simple and performant ORM for sql.DB Main features are: Works with PostgreSQL, MySQL, SQLite. Selecting into a map, struct, slice of maps/structs/vars

Jan 4, 2023
Simple project in Go to play around with some CRUD operations using a PostgreSQL database and pgx

Record Store November 2021 I started learning Go a few weeks ago and this is my first proper project using Go. I wanted to use it to get to grips with

Nov 26, 2021
A simple CRUD API made with Go, Postgres, FIber, Gorm and Docker.

golang-test-api A simple CRUD API made with Go, Postgres, FIber, Gorm and Docker. Cloning the repository To clone the repository run the following com

Dec 14, 2022
A simple wrapper around sql.DB to help with structs. Not quite an ORM.

go-modeldb A simple wrapper around sql.DB to help with structs. Not quite an ORM. Philosophy: Don't make an ORM Example: // Setup require "modeldb" db

Nov 16, 2019
Simple Go ORM for Google/Firebase Cloud Firestore

go-firestorm Go ORM (Object-relational mapping) for Google Cloud Firestore. Goals Easy to use Non intrusive Non exclusive Fast Features Basic CRUD ope

Dec 1, 2022
Very simple example of golang buffalo CRUD

Buffalo CRUD exemple Introduction Site du projet : https://gobuffalo.io/fr Documentation générale : https://gobuffalo.io/fr/docs/overview/ Documentati

Nov 7, 2021
Simple REST API application using GO [/net/http & mux]

REST-API-CRUD Simple REST API application using GOLANG [/net/http & mux] Available URLs: URL METHOD http://127.0.0.1:8888/ GET http://127.0.0.1:8888/l

Dec 3, 2021
A simple CRUD app built with Go for Shopify Backend Developer Intern Challenge - Summer 2022

Shopify Backend Developer Intern Challenge - Summer 2022 A simple CRUD app built with Go and Gin. This let you update track your inventory, add new it

Jan 18, 2022
Query: A Simple db helper with golang

Query: A Simple db helper with golang

Jul 20, 2022
Go tool for generating sql scanners, sql statements and other helper functions

sqlgen generates SQL statements and database helper functions from your Go structs. It can be used in place of a simple ORM or hand-written SQL. See t

Nov 24, 2022
100% type-safe ORM for Go (Golang) with code generation and MySQL, PostgreSQL, Sqlite3, SQL Server support. GORM under the hood.

go-queryset 100% type-safe ORM for Go (Golang) with code generation and MySQL, PostgreSQL, Sqlite3, SQL Server support. GORM under the hood. Contents

Dec 30, 2022
Golang ORM with focus on PostgreSQL features and performance

go-pg is in a maintenance mode and only critical issues are addressed. New development happens in Bun repo which offers similar functionality but works with PostgreSQL, MySQL, and SQLite.

Jan 8, 2023
Converts a database into gorm structs and RESTful api

gen The gen tool produces a CRUD (Create, read, update and delete) REST api project template from a given database. The gen tool will connect to the d

Dec 28, 2022
Examples of using various popular database libraries and ORM in Go.

Introduction Examples of using various popular database libraries and ORM in Go. sqlx sqlc Gorm sqlboiler ent The aim is to demonstrate and compare us

Dec 12, 2021
Examples of using various popular database libraries and ORM in Go.

Introduction Examples of using various popular database libraries and ORM in Go. sqlx sqlc Gorm sqlboiler ent The aim is to demonstrate and compare us

Dec 28, 2022