Skip to content

Instantly share code, notes, and snippets.

@mashingan
Last active August 20, 2023 16:04
Show Gist options
  • Save mashingan/4212d447f857cfdfbbba4f5436b779ac to your computer and use it in GitHub Desktop.
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)
}
@0x0000F1
Copy link

0x0000F1 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

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