Skip to content

Instantly share code, notes, and snippets.

@mashingan
Last active May 5, 2026 13:19
Show Gist options
  • Select an option

  • Save mashingan/4212d447f857cfdfbbba4f5436b779ac to your computer and use it in GitHub Desktop.

Select an option

Save mashingan/4212d447f857cfdfbbba4f5436b779ac to your computer and use it in GitHub Desktop.
Simple CRUD example working with Gorm
package main
import (
"fmt"
"net/http"
"strconv"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
"github.com/labstack/echo"
)
type User struct {
gorm.Model `json:"model"`
Name string `json:"name"`
Email string `json:"email"`
}
func handlerFunc(msg string) func(echo.Context) error {
return func(c echo.Context) error {
return c.String(http.StatusOK, msg)
}
}
func allUsers(db *gorm.DB) func(echo.Context) error {
return func(c echo.Context) error {
var users []User
db.Find(&users)
fmt.Println("{}", users)
return c.JSON(http.StatusOK, users)
}
}
func newUser(db *gorm.DB) func(echo.Context) error {
return func(c echo.Context) error {
name := c.Param("name")
email := c.Param("email")
db.Create(&User{Name: name, Email: email})
return c.String(http.StatusOK, name+" user successfully created")
}
}
func deleteUser(db *gorm.DB) func(echo.Context) error {
return func(c echo.Context) error {
name := c.Param("name")
var user User
db.Where("name = ?", name).Find(&user)
db.Delete(&user)
return c.String(http.StatusOK, name+" user successfully deleted")
}
}
func updateUser(db *gorm.DB) func(echo.Context) error {
return func(c echo.Context) error {
name := c.Param("name")
email := c.Param("email")
var user User
db.Where("name=?", name).Find(&user)
user.Email = email
db.Save(&user)
return c.String(http.StatusOK, name+" user successfully updated")
}
}
func usersByPage(db *gorm.DB) func(echo.Context) error {
return func(c echo.Context) error {
limit, _ := strconv.Atoi(c.QueryParam("limit"))
page, _ := strconv.Atoi(c.QueryParam("page"))
var result []User
db.Limit(limit).Offset(limit * (page - 1)).Find(&result)
return c.JSON(http.StatusOK, result)
}
}
func handleRequest(db *gorm.DB) {
e := echo.New()
e.GET("/users", allUsers(db))
e.GET("/user", usersByPage(db))
e.POST("/user/:name/:email", newUser(db))
e.DELETE("/user/:name", deleteUser(db))
e.PUT("/user/:name/:email", updateUser(db))
e.Logger.Fatal(e.Start(":3000"))
}
func initialMigration(db *gorm.DB) {
db.AutoMigrate(&User{})
}
func main() {
fmt.Println("Go ORM tutorial")
db, err := gorm.Open("sqlite3", "sqlite3gorm.db")
if err != nil {
fmt.Println(err.Error())
panic("failed to connect database")
}
defer db.Close()
initialMigration(db)
handleRequest(db)
}
package main
/*
This version using `dbops` as separate object that handle operation to database.
This can be expanded as a core functionality to separate handler and model/logic
and encourage separation of core business logic and transport.
*/
import (
"fmt"
"net/http"
"strconv"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
"github.com/labstack/echo"
)
type User struct {
gorm.Model `json:"model"`
Name string `json:"name"`
Email string `json:"email"`
}
type dbops struct {
db *gorm.DB
}
func (d dbops) findAll(users *[]User) error {
return d.db.Find(users).Error
}
func (d dbops) create(user *User) error {
return d.db.Create(user).Error
}
func (d dbops) findByPage(users *[]User, page, view int) error {
return d.db.Limit(view).Offset(view * (page - 1)).Find(&users).Error
}
func (d dbops) updateByName(name, email string) error {
var user User
d.db.Where("name=?", name).Find(&user)
user.Email = email
return d.db.Save(&user).Error
}
func (d dbops) deleteByName(name string) error {
var user User
d.db.Where("name=?", name).Find(&user)
return d.db.Delete(&user).Error
}
func handlerFunc(msg string) func(echo.Context) error {
return func(c echo.Context) error {
return c.String(http.StatusOK, msg)
}
}
func allUsers(dbobj dbops) func(echo.Context) error {
return func(c echo.Context) error {
var users []User
dbobj.findAll(&users)
fmt.Println("{}", users)
return c.JSON(http.StatusOK, users)
}
}
func newUser(dbobj dbops) func(echo.Context) error {
return func(c echo.Context) error {
name := c.Param("name")
email := c.Param("email")
dbobj.create(&User{Name: name, Email: email})
return c.String(http.StatusOK, name+" user successfully created")
}
}
func deleteUser(dbobj dbops) func(echo.Context) error {
return func(c echo.Context) error {
name := c.Param("name")
dbobj.deleteByName(name)
return c.String(http.StatusOK, name+" user successfully deleted")
}
}
func updateUser(dbobj dbops) func(echo.Context) error {
return func(c echo.Context) error {
name := c.Param("name")
email := c.Param("email")
dbobj.updateByName(name, email)
return c.String(http.StatusOK, name+" user successfully updated")
}
}
func usersByPage(dbobj dbops) func(echo.Context) error {
return func(c echo.Context) error {
limit, _ := strconv.Atoi(c.QueryParam("limit"))
page, _ := strconv.Atoi(c.QueryParam("page"))
var result []User
dbobj.findByPage(&result, page, limit)
return c.JSON(http.StatusOK, result)
}
}
func handleRequest(dbgorm *gorm.DB) {
e := echo.New()
db := dbops{dbgorm}
e.GET("/users", allUsers(db))
e.GET("/user", usersByPage(db))
e.POST("/user/:name/:email", newUser(db))
e.DELETE("/user/:name", deleteUser(db))
e.PUT("/user/:name/:email", updateUser(db))
e.Logger.Fatal(e.Start(":3000"))
}
func initialMigration(db *gorm.DB) {
db.AutoMigrate(&User{})
}
func main() {
fmt.Println("Go ORM tutorial")
db, err := gorm.Open("sqlite3", "sqlite3gorm.db")
if err != nil {
fmt.Println(err.Error())
panic("failed to connect database")
}
defer db.Close()
initialMigration(db)
handleRequest(db)
}
@srvmux
Copy link
Copy Markdown

srvmux commented Mar 9, 2022

I'm not sure if this possible now but in 1.18 it probably will be with generics not sure tho.

but what I want is an interface that has all my db logic that then I assign to a struct and pass that struct's value to the interface methods
basically something like this

type Foo struct{}
type Bar interface{}
func (bar *Bar) Create(db *gorm.DB)(err error){
//your logic here
}
var baz Bar = Foo{}
baz.create(db)

after some research I found out that it's not possible to do it this way because Foo is not addressable
if anyone has any idea please tell me

@Lichas
Copy link
Copy Markdown

Lichas commented May 6, 2022

type Foo struct{}
type Bar interface{}
func (*f Foo) Create(db *gorm.DB)(err error){
//your logic here
}
var baz Bar = Foo{}
baz.create(db)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment